Навчання 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 робочих днів.







