Обучение 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 рабочих дней.







