Навчання RL-агента (PPO/SAC/DQN) для торгової стратегії
Уявіть: ви витратили місяці на навчання DQN-агента на історичних даних, а на реальному ринку він втрачає капітал через невраховане прослизання. В одному з наших проектів клієнт прийшов з такою проблемою: навчали PPO на хвилинних свічках, його Sharpe ratio на тесті був 1.8, але в live просадка досягла 40%. Клієнт втрачав близько $15,000 щомісяця через ці недоліки. Ми з'ясували, що середовище не враховувало комісії та ліквідність. Після калібрування reward та додавання walk-forward validation Sharpe знову виріс до 1.5, а просадка скоротилася до 12%. Економія склала $4,000 на місяць.
Проектування RL-агента для криптотрейдингу — це не просто вибір алгоритму. Ви стикаєтеся з нестаціонарністю ринку, прихованими комісіями, прослизанням та ризиком перенавчання. Ми беремо на себе повний цикл — від формування data pipeline до live trading. Використовуємо перевірені алгоритми PPO, SAC та DQN, адаптуючи їх під вашу стратегію. Наш досвід — понад п'ять років у блокчейн-розробці, 15+ проектів для DeFi та CEX, включаючи інтеграцію з Binance API. Зв'яжіться з нами для детального аналізу вашої стратегії.
Три робочих алгоритми: DQN, PPO, SAC
Кожен алгоритм має свою нішу. Розглянемо їх сильні сторони та типові сценарії застосування.
DQN (Deep Q-Network)
Підходить для дискретних дій (buy/hold/sell) та простих стратегій. DQN апроксимує Q-функцію: Q(state, action) — очікувана дисконтована винагорода при виборі дії action у стані state.
import torch import torch.nn as nn from collections import deque import random class DQNNetwork(nn.Module): def __init__(self, state_dim, n_actions, hidden_dim=256): super().__init__() # Dueling architecture: окремі Value та Advantage потоки self.shared = nn.Sequential( nn.Linear(state_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU() ) self.value_stream = nn.Linear(hidden_dim, 1) self.advantage_stream = nn.Linear(hidden_dim, n_actions) def forward(self, x): shared = self.shared(x) value = self.value_stream(shared) advantage = self.advantage_stream(shared) # Dueling: Q = V + (A - mean(A)) q_values = value + (advantage - advantage.mean(dim=1, keepdim=True)) return q_values class PrioritizedReplayBuffer: """Prioritized Experience Replay — частіше семплюємо важливі transitions""" def __init__(self, capacity=50000, alpha=0.6): self.buffer = deque(maxlen=capacity) self.priorities = deque(maxlen=capacity) self.alpha = alpha def push(self, state, action, reward, next_state, done, td_error=1.0): priority = (abs(td_error) + 1e-5) ** self.alpha self.buffer.append((state, action, reward, next_state, done)) self.priorities.append(priority) def sample(self, batch_size, beta=0.4): probs = np.array(self.priorities) / sum(self.priorities) indices = np.random.choice(len(self.buffer), batch_size, p=probs) # Importance sampling weights weights = (len(self.buffer) * probs[indices]) ** (-beta) weights /= weights.max() batch = [self.buffer[i] for i in indices] return batch, indices, weights Double DQN усуває overestimation Q-значень: online мережа вибирає дію, target мережа оцінює.
# Double DQN target calculation with torch.no_grad(): next_actions = online_net(next_states).argmax(dim=1) # online net вибирає next_q = target_net(next_states).gather(1, next_actions.unsqueeze(1)) # target оцінює targets = rewards + gamma * next_q * (1 - dones) PPO (Proximal Policy Optimization)
Підходить для дискретних та неперервних дій, on-policy, стабільне навчання. PPO обмежує розмір оновлення політики через clipping.
class PPOActor(nn.Module): def __init__(self, state_dim, action_dim, hidden_dim=256): super().__init__() self.network = nn.Sequential( nn.Linear(state_dim, hidden_dim), nn.Tanh(), nn.Linear(hidden_dim, hidden_dim), nn.Tanh() ) self.policy_head = nn.Linear(hidden_dim, action_dim) self.value_head = nn.Linear(hidden_dim, 1) def forward(self, x): features = self.network(x) logits = self.policy_head(features) value = self.value_head(features) return logits, value def ppo_update(model, optimizer, states, actions, old_log_probs, advantages, returns, clip_eps=0.2, n_epochs=4): for _ in range(n_epochs): logits, values = model(states) dist = torch.distributions.Categorical(logits=logits) new_log_probs = dist.log_prob(actions) entropy = dist.entropy() # PPO clipped objective ratio = (new_log_probs - old_log_probs).exp() surr1 = ratio * advantages surr2 = torch.clamp(ratio, 1 - clip_eps, 1 + clip_eps) * advantages actor_loss = -torch.min(surr1, surr2).mean() critic_loss = (returns - values.squeeze()).pow(2).mean() entropy_loss = -entropy.mean() total_loss = actor_loss + 0.5 * critic_loss + 0.01 * entropy_loss optimizer.zero_grad() total_loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5) optimizer.step() SAC (Soft Actor-Critic)
Підходить для неперервного action space (позиціонування 0%–100% капіталу), off-policy, максимальна sample efficiency. SAC максимізує: J(π) = E[Σ γ^t (r_t + α H(π(·|s_t)))]. Ентропійний член H заохочує exploration.
class SACActorContinuous(nn.Module): def __init__(self, state_dim, action_dim, hidden_dim=256): super().__init__() self.network = nn.Sequential( nn.Linear(state_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU() ) self.mean_head = nn.Linear(hidden_dim, action_dim) self.log_std_head = nn.Linear(hidden_dim, action_dim) def forward(self, x): features = self.network(x) mean = self.mean_head(features) log_std = self.log_std_head(features).clamp(-20, 2) std = log_std.exp() dist = torch.distributions.Normal(mean, std) action = dist.rsample() # reparameterization trick # Squash to [-1, 1] action_tanh = torch.tanh(action) log_prob = dist.log_prob(action) - torch.log(1 - action_tanh.pow(2) + 1e-6) return action_tanh, log_prob.sum(-1, keepdim=True) Який алгоритм обрати для вашої стратегії?
Вибір залежить від action space та вимог до sample efficiency. Якщо стратегія оперує лише дискретними сигналами (покупка/продаж/утримання) — DQN з dueling та PER дасть стабільний результат. Для неперервного управління капіталом (наприклад, відсоток від портфеля) SAC поза конкуренцією: він у 2–3 рази ефективніший за PPO у використанні даних. PPO — універсальний вибір, коли потрібна надійність і простота налаштування.
Ми часто комбінуємо алгоритми в multi-agent архітектурі: macro-агент на DQN визначає загальний напрямок, micro-агент на SAC виконує угоди. Це знижує variance та покращує Sharpe ratio на 15–30%.
Чому важлива коректна функція винагороди?
Reward shaping — ключовий етап, від якого залежить адекватність поведінки агента. Типові помилки: агент вчиться накопичувати нереалізований прибуток (без урахування прослизання) або починає торгувати дуже рідко, щоб уникнути комісій. Ми використовуємо багатокомпонентну винагороду: PnL, штраф за просадку, комісії та спред. Наприклад, reward = ΔP&L - λ1 * fee - λ2 * max_drawdown. Коефіцієнти λ підбираються так, щоб симулювати реалістичні умови.
В одному з проектів для DeFi-протоколу неправильний reward призвів до того, що агент відкривав сотні мікро-угод, генеруючи збиток від комісій. Після редизайну винагороди (штраф за кількість угод) агент почав працювати в плюс.
Порівняння алгоритмів для крипто-торгівлі
| Алгоритм | Action Space | Sample Efficiency | Стабільність | Найкраще застосування |
|---|---|---|---|---|
| DQN | Дискретний | Середня | Середня | Прості buy/sell стратегії |
| PPO | Обидва | Низька (on-policy) | Висока | Загальне застосування, надійний |
| SAC | Неперервний | Висока | Висока | Position sizing як action |
Як налаштувати навчання RL-агента: покроковий план
- Визначте action space та state space. Для дискретних дій (buy/sell/hold) підходить DQN, для неперервного позиціонування — SAC. Стан включає ціни, обсяги, індикатори.
- Спроектуйте функцію винагороди. Враховуйте PnL, комісії, прослизання, штраф за просадку.
- Виберіть алгоритм та архітектуру нейромережі. Використовуємо dueling DQN, PPO з clipping, SAC з автоматичним регулюванням ентропії.
- Навчіть з валідацією. Застосовуємо walk-forward validation з 36 rolling windows та early stopping.
- Протестуйте на out-of-sample даних. Оцінюємо Sharpe ratio, max drawdown, stability reward.
Типові складнощі та як ми їх вирішуємо
Нестаціонарність ринку — агент, навчений на спокійному ринку, може провалитися при високій волатильності. Як зазначається в специфікації reinforcement learning, зміна розподілу даних — серйозний виклик. Ми застосовуємо curriculum learning: поетапно збільшуємо волатильність середовища, а в продакшені — continuous fine-tuning з детектором дрифту.
Reward hacking — штучно завищені винагороди. Захист через reward clipping та використання реалістичного симулятора з ринковими даними (Level 2, історичні свічки).
Overfitting — agent memorization. Використовуємо walk-forward validation з 36 rolling windows та тестування на повністю виключених періодах (out-of-sample).
Приклад підбору гіперпараметрів
Для PPO підбираємо learning rate (3e-4), clip epsilon (0.2), entropy coefficient (0.01) через Bayesian optimization на 50 trials. Найкращі конфігурації зберігаємо в MLflow. Типовий час пошуку — 2 дні на GPU.Що входить у роботу
- Аналіз стратегії та підготовка data pipeline.
- Проектування кастомного середовища (gymnasium) з урахуванням комісій, прослизання та просадок.
- Вибір алгоритму та архітектури нейромережі.
- Навчання з підбором гіперпараметрів (grid/random search, Bayesian optimization).
- Walk-forward validation та робастність до зміни режимів ринку.
- Інтеграція з брокерським API (Binance, Bybit, KuCoin).
- Документування, навчання вашої команди, супровід 3 місяці.
Зв'яжіться з нами, щоб ми могли проаналізувати вашу стратегію. Ми гарантуємо якість результату та супровід на всіх етапах.
Орієнтовні терміни та етапи
| Етап | Тривалість | Результат |
|---|---|---|
| Аналіз та data pipeline | 1–2 тижні | Підготовлені дані, специфікація середовища |
| Проектування середовища та алгоритму | 1–2 тижні | Кастомне середовище, baseline модель |
| Навчання та підбір гіперпараметрів | 2–4 тижні | Оптимальна політика, метрики в MLflow |
| Walk-forward validation та тестування | 1–2 тижні | Звіт по Sharpe, drawdown, out-of-sample |
| Інтеграція та деплой | 1–2 тижні | Live trading агент, документація |
Замовте консультацію — ми підберемо алгоритм та архітектуру під вашу задачу. Оцінимо проект безкоштовно протягом 2 робочих днів.







