Торговый агент на DQN (Deep Q-Network)
Дискретная торговля — классическая задача для RL. Но DQN в сыром виде даёт сбои: overestimation bias, нестабильность, шум финансовых данных. Мы проектируем и разрабатываем RL-агентов на базе DQN/DDQN под конкретный инструмент с учётом всех нюансов. Наш опыт — 5+ лет в RL для финансов, более 20 внедрённых проектов. Гарантируем стабильность обучения и валидацию на out-of-sample данных.
Deep Q-Network — первый deep RL алгоритм, продемонстрировавший superhuman performance в играх Atari. Для трейдинга: дискретное пространство действий (buy/sell/hold), experience replay, target network. Подходит для single-asset торговли с чёткими входами/выходами.
Как DQN справляется с шумом финансовых данных?
Финансовые ряды зашумлены и нестационарны. DQN не требует модели рынка, но страдает от high variance. Решения: Double DQN (снижает overestimation), Dueling DQN (разделяет value и advantage), медленный epsilon decay (decay_factor=0.9995, epsilon_min=0.01). Мы используем эти техники, чтобы агент не переобучался на шуме.
Что такое Rainbow DQN и зачем он в трейдинге?
Rainbow DQN — комбинация шести улучшений: Double, Dueling, Prioritized Experience Replay (PER), Multi-step returns (n=3), Distributional RL (C51/QR-DQN), Noisy Networks. Для трейдинга наиболее ценны: distributional даёт risk-aware policy (видит не только среднюю доходность, но и волатильность), multi-step ускоряет кредитное присваивание, PER фокусируется на редких, но значимых движениях (например, gap-открытия).
DQN для трейдинга
Оригинальный DQN работает с дискретными действиями. Это делает его естественным для сигнальных стратегий:
Action space:
- 0: Hold (ничего не делать)
- 1: Buy (открыть длинную позицию)
- 2: Sell / Close (закрыть позицию / открыть шорт)
Для single-asset это разумно. Для multi-asset нужен DQN с factored action space или переход на SAC/PPO.
Q-функция оценивает ожидаемую суммарную дисконтированную награду из состояния s при действии a.
| Алгоритм | Тип действий | Переобучение | Стабильность | Когда использовать |
|---|---|---|---|---|
| DQN/DDQN | Дискретные (3-10) | Риск high variance | Средняя (нужна настройка) | Single-asset, чёткие сигналы |
| SAC/PPO | Непрерывные | Ниже | Высокая | Multi-asset, continuous position sizing |
Архитектура
import torch import torch.nn as nn class DQNTrading(nn.Module): def __init__(self, state_dim, n_actions=3, hidden=256): super().__init__() # Dueling DQN архитектура self.feature = nn.Sequential( nn.Linear(state_dim, hidden), nn.ReLU(), nn.Linear(hidden, hidden), nn.ReLU() ) # Value stream: V(s) self.value = nn.Sequential( nn.Linear(hidden, 128), nn.ReLU(), nn.Linear(128, 1) ) # Advantage stream: A(s, a) self.advantage = nn.Sequential( nn.Linear(hidden, 128), nn.ReLU(), nn.Linear(128, n_actions) ) def forward(self, x): feat = self.feature(x) V = self.value(feat) A = self.advantage(feat) # Q = V + (A - mean(A)) return V + (A - A.mean(dim=1, keepdim=True)) Dueling DQN разделяет V(s) и A(s,a). В трейдинге: часто состояние рынка определяет общую ценность (V), а выбор действия — относительное преимущество (A). Обычно быстрее сходится.
Experience Replay и Target Network
Два ключевых механизма: Experience replay buffer:
from collections import deque import random class ReplayBuffer: def __init__(self, capacity=100_000): self.buffer = deque(maxlen=capacity) def push(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): batch = random.sample(self.buffer, batch_size) states, actions, rewards, next_states, dones = zip(*batch) return (torch.FloatTensor(np.array(states)), torch.LongTensor(actions), torch.FloatTensor(rewards), torch.FloatTensor(np.array(next_states)), torch.FloatTensor(dones)) Target network (замороженная копия Q-сети):
# обновление каждые C шагов if step % target_update_freq == 0: target_net.load_state_dict(online_net.state_dict()) Без target network: Q-targets движутся одновременно с Q-predictions → нестабильность → divergence.
Обучение
def train_step(batch, online_net, target_net, optimizer, gamma=0.99): states, actions, rewards, next_states, dones = batch # текущие Q-значения q_values = online_net(states).gather(1, actions.unsqueeze(1)) # Double DQN: online выбирает действие, target оценивает with torch.no_grad(): next_actions = online_net(next_states).argmax(1) next_q = target_net(next_states).gather(1, next_actions.unsqueeze(1)) target_q = rewards.unsqueeze(1) + gamma * next_q * (1 - dones.unsqueeze(1)) loss = nn.SmoothL1Loss()(q_values, target_q) # Huber loss optimizer.zero_grad() loss.backward() nn.utils.clip_grad_norm_(online_net.parameters(), 10) # gradient clipping optimizer.step() return loss.item() Double DQN устраняет overestimation bias оригинального DQN. В финансовых средах с высоким шумом это критично — без Double DQN Q-значения систематически завышены.
Epsilon-greedy для финансовых сред
# Экспоненциальный decay epsilon epsilon = max(epsilon_min, epsilon_start * (epsilon_decay ** step)) if np.random.random() < epsilon: action = env.action_space.sample() # случайное исследование else: with torch.no_grad(): q_vals = online_net(state_tensor) action = q_vals.argmax().item() Финансовая специфика epsilon:
- epsilon_start = 1.0 (полное исследование вначале)
- epsilon_min = 0.01 (1% случайных действий всегда)
- Медленный decay (decay=0.9995) — рынок сложнее Atari
Когда DQN, когда SAC/PPO
DQN уместен для: single-asset, чёткие сигналы buy/sell, небольшой action space (3–10 действий), binary decision making. SAC/PPO предпочтительнее для: multi-asset portfolio, continuous position sizing, когда размер позиции важен.
Что входит в работу
- Архитектура агента (Dueling DQN, Double DQN, Rainbow).
- Скрипты обучения и бэктестинга на PyTorch.
- Конфигурация гиперпараметров под ваш инструмент (learning rate, batch size, replay buffer size, target update frequency).
- Модель карда (model card) с метриками (Sharpe, Max Drawdown, Win Rate, P99 latency).
- Документация по воспроизведению.
- Интеграция с live trading (опционально, +3-4 недели).
- Поддержка 2 месяца после деплоя.
Сроки ориентировочно
Базовый DQN агент — от 2 до 3 недель. Rainbow с PER, Distributional, multi-step — от 6 до 8 недель. Live trading интеграция с риск-менеджментом — дополнительно от 3 до 4 недель. Стоимость рассчитывается индивидуально после анализа данных.
Почему стоит заказать разработку у нас?
Мы внедрили RL-агентов для 20+ проектов в финансах. Используем production-ready стек: PyTorch, Ray, Weights & Biases, MLflow. Гарантируем воспроизводимость экспериментов (seed, конфиги в YAML) и валидацию на out-of-sample данных. Свяжитесь с нами — обсудим ваш кейс и подготовим коммерческое предложение.







