Разработка RL-агента для торговли на базе SAC

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1566 услуг
Разработка RL-агента для торговли на базе SAC
Сложный
~2-4 недели
Часто задаваемые вопросы

Направления AI-разработки

Этапы разработки AI-решения

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    901
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1119
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    853

Торговый агент на SAC (Soft Actor-Critic)

SAC — off-policy алгоритм с maximum entropy reinforcement learning. Оптимизирует не только reward, но и энтропию policy — агент учится быть хорошим И максимально разнообразным. Для трейдинга это означает: не застрять в одной стратегии, лучше исследовать рыночные режимы.

Принцип Maximum Entropy RL

Стандартный RL: max E[R]. SAC: max E[R + α·H(π)].

H(π) = -E[log π(a|s)] — энтропия policy. α — температура (auto-tuning в SAC v2).

Практически: агент предпочитает две одинаково прибыльные стратегии той, которая более стохастична. В трейдинге: устойчивость к переобучению к конкретному рыночному режиму.

SAC vs PPO для трейдинга

Характеристика SAC PPO
Тип Off-policy On-policy
Replay buffer Есть (1M+) Нет
Sample efficiency Высокая Средняя
Стабильность обучения Высокая Высокая
Action space Continuous (лучше) Continuous/Discrete
Инфраструктура Сложнее (replay) Проще

SAC предпочтителен при: ограниченном объёме исторических данных, непрерывных action (веса портфеля), необходимости sample-efficient обучения.

Архитектура SAC

Три сети:

  1. Policy network π_θ(a|s): Gaussian policy с reparameterization trick
  2. Two Q-networks Q_φ1, Q_φ2: double Q trick для уменьшения overestimation bias
  3. Target Q-networks (EMA копии): стабилизация обучения
import torch
import torch.nn as nn
from torch.distributions import Normal

class SACPolicy(nn.Module):
    def __init__(self, state_dim, action_dim, hidden=256):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, hidden), nn.ReLU(),
            nn.Linear(hidden, hidden), nn.ReLU()
        )
        self.mean_layer = nn.Linear(hidden, action_dim)
        self.log_std_layer = nn.Linear(hidden, action_dim)
        self.LOG_STD_MIN, self.LOG_STD_MAX = -20, 2

    def forward(self, state):
        feat = self.net(state)
        mean = self.mean_layer(feat)
        log_std = self.log_std_layer(feat).clamp(self.LOG_STD_MIN, self.LOG_STD_MAX)
        std = log_std.exp()
        dist = Normal(mean, std)
        # reparameterization: a = tanh(mean + std * ε)
        action = torch.tanh(dist.rsample())
        log_prob = dist.log_prob(action).sum(-1, keepdim=True)
        # поправка для tanh squashing
        log_prob -= torch.log(1 - action.pow(2) + 1e-6).sum(-1, keepdim=True)
        return action, log_prob

Автоматическая настройка температуры α

SAC v2 убирает ручную настройку α. Целевая энтропия = -dim(action_space):

target_entropy = -action_dim  # для 5 активов = -5
log_alpha = torch.zeros(1, requires_grad=True)
alpha_optimizer = torch.optim.Adam([log_alpha], lr=3e-4)

# alpha loss (обновляется каждый шаг)
alpha_loss = -(log_alpha * (log_pi + target_entropy).detach()).mean()
alpha_optimizer.zero_grad()
alpha_loss.backward()
alpha_optimizer.step()
alpha = log_alpha.exp().item()

Replay Buffer для финансовых временных рядов

Стандартный uniform replay buffer не учитывает временную структуру. Prioritized Experience Replay (PER): сэмплирует transitions с высоким TD-error чаще.

Temporal replay buffer: хранит не i.i.d. transitions, а последовательности (для LSTM policy):

  • Sequence length = 20 (20 дней контекст)
  • При сэмплировании берётся случайный непрерывный отрезок
  • BPTT через всю последовательность
class SequenceReplayBuffer:
    def __init__(self, capacity, seq_len):
        self.buffer = deque(maxlen=capacity)
        self.seq_len = seq_len

    def sample_sequences(self, batch_size):
        starts = np.random.randint(0, len(self.buffer) - self.seq_len, batch_size)
        return [list(self.buffer)[s:s+self.seq_len] for s in starts]

Реализация через Stable Baselines3

from stable_baselines3 import SAC

model = SAC(
    "MlpPolicy",
    env,
    learning_rate=3e-4,
    buffer_size=1_000_000,
    learning_starts=10_000,    # прогрев без обновлений
    batch_size=256,
    tau=0.005,                  # EMA для target networks
    gamma=0.99,
    train_freq=1,
    gradient_steps=1,
    ent_coef='auto',            # auto-tuning α
    target_entropy='auto',
    verbose=1
)
model.learn(total_timesteps=500_000)

learning_starts критично для трейдинга: первые 10K шагов — случайное исследование без обновления сетей. Наполняет replay buffer разнообразными experiences.

Сравнение производительности

При прочих равных SAC обычно превосходит PPO по Sharpe Ratio на 10–15% за счёт лучшего исследования и sample efficiency. Но требует больше GPU памяти (replay buffer) и сложнее в отладке.

Сроки: 6–10 недель

Базовый SAC на OHLCV данных — 3–5 недель. PER + sequence replay, LSTM policy, live подключение к брокеру — 8–10 недель.