Розробка 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, але й ентропію політики — агент учиться бути ефективним І максимально різноманітним. Для трейдингу це означає: не застрявати в одній стратегії, краще досліджувати режими ринку.

Принцип Maximum Entropy RL

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

H(π) = -E[log π(a|s)] — ентропія політики. α — температура (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 бажаний при: обмеженому обсязі історичних даних, неперервних діях (ваги портфеля), необхідності sample-efficient навчання.

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

Три мережі:

  1. Policy network π_θ(a|s): Gaussian політика з 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 політики):

  • 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 на 10–15% по Sharpe Ratio за рахунок кращого дослідження і sample efficiency. Але потребує більше GPU пам'яті (replay buffer) і складніше в налагодженні.

Терміни: 6–10 тижнів

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