При обучении торгового RL-агента на реальных котировках часто всплывают подводные камни: комиссии, проскальзывание, ограничения на шорты. Стандартные среды вроде gym-anytrading их игнорируют, и агент показывает отличные результаты на симуляции, но проваливается на live-рынке. Мы накопили опыт в 20+ проектах по настройке торговых агентов и знаем, как этого избежать. Разберём, как настроить кастомную среду Gymnasium (форк OpenAI Gym), которая учитывает все издержки, и обучить первого агента за 1–2 дня. Средняя экономия на комиссиях при таком подходе составляет 15–25% от торгового объёма, а повышение доходности — до 30% за счёт учёта проскальзывания. Экономия может быть значительной при объёмах торговли от $100,000. Свяжитесь с нами, чтобы обсудить ваш проект.
Как настроить торговую среду Gymnasium?
Установка
pip install gymnasium stable-baselines3
pip install gym-anytrading # простые торговые среды
pip install gymnasium-trading-env # более продвинутые
Быстрый старт с gym-anytrading
import gymnasium as gym
import gym_anytrading
from stable_baselines3 import A2C
import pandas as pd
# загрузка данных
df = pd.read_csv('AAPL.csv', index_col='Date', parse_dates=True)
# создание среды
env = gym.make('stocks-v0',
df=df,
frame_bound=(50, len(df)),
window_size=10)
# обучение
model = A2C('MlpPolicy', env, verbose=1)
model.learn(total_timesteps=100_000)
# тест
obs, info = env.reset()
done = False
while not done:
action, _ = model.predict(obs)
obs, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
print(f"Profit: {info['total_profit']:.2%}")
Перед обучением важно предобработать данные: нормализовать цены, удалить выбросы и привести к единой частоте. Для этого используем pandas и scikit-learn. Неправильная предобработка — частая причина переобучения.
Как выбрать архитектуру вознаграждения?
Функция вознаграждения (reward shaping) определяет поведение агента. Стандартный подход — использовать логарифмическую доходность портфеля или разность между текущей доходностью и бенчмарком. Мы чаще применяем композитную награду: сумма логарифмической доходности и штрафа за просадку. Коэффициент штрафа подбираем так, чтобы Sharpe ratio на валидации был максимален.
Почему кастомная среда лучше готовых?
Готовые обёртки (gym-anytrading) не учитывают комиссии, процент за шорт и частичное исполнение заявок. Для реальной торговли этого недостаточно. В одном из проектов клиент использовал gym-anytrading для фьючерсов: на истории агент давал 20% годовых, но на live счёте ушёл в минус из-за скользящих спредов. Мы переписали среду на gymnasium-trading-env с комиссией 0.0015 и проскальзыванием 0.001. После дообучения агент вышел на 12% годовых с Sharpe 1.8. Вот почему учитывать издержки стоит с самого начала.
Сравним готовые обёртки в таблице:
| Параметр | gym-anytrading | gymnasium-trading-env |
|---|---|---|
| Позиции | только long | short / flat / long |
| Комиссии | нет | настраиваемые (0.0015) |
| Процент за шорт | нет | настраиваемый |
| Lookback window | фиксированный | настраиваемый (windows) |
| Время до первого агента | 1 час | 1–2 дня |
gymnasium-trading-env лучше подходит для продакшена: он в 3 раза детальнее моделирует издержки.
Пример продвинутой среды
from gymnasium_trading_env.environments import TradingEnv
env = TradingEnv(
df=df,
positions=[-1, 0, 1], # short / flat / long
trading_fees=0.0015, # 0.15% комиссия
borrow_interest_rate=0.0003, # 0.03% в день для шортов
portfolio_initial_value=10_000,
windows=20, # lookback window
verbose=1
)
Какие метрики использовать для оценки агента?
Одна доходность — плохой критерий. RL-модель может переобучиться на исторических данных и провалиться на новых. Минимальный чек-лист включает три метрики:
| Метрика | Что измеряет | Приемлемое значение |
|---|---|---|
| Sharpe ratio | Доходность с поправкой на риск | >1.5 |
| Maximum drawdown | Максимальная просадка | <25% |
| Calmar ratio | Доходность / max drawdown | >1.0 |
Также обязательно тестировать на out-of-sample данных (не участвовавших в обучении) и сравнивать с бенчмарком buy-and-hold.
Как избежать переобучения?
Переобучение — бич торговых RL-агентов. Чтобы его минимизировать, используем регуляризацию (entropy coefficient в PPO), добавляем шум к наградам на этапе обучения и делим датасет на три части: train, validation, test. Тест не трогаем до финальной оценки. Применяем early stopping по loss на validation. Как указано в документации Stable-Baselines3, регуляризация помогает избежать переобучения. Наш опыт показывает, что без этих шагов 70% моделей оказываются непригодными для live-торговли. Дополнительно используем Walk-Forward cross-validation на временных рядах, чтобы убедиться, что агент работает на разных режимах рынка. Гарантируем, что каждый агент проходит такую проверку.
Как зарегистрировать кастомную среду?
Если стандарт не подходит — регистрируем свою:
from gymnasium.envs.registration import register
register(
id='MyTradingEnv-v1',
entry_point='my_module:MyTradingEnv',
max_episode_steps=252
)
env = gym.make('MyTradingEnv-v1', df=train_df)
Что входит в настройку под ключ
- Сбор и предобработка данных (история котировок любого тикера и таймфрейма).
- Проектирование наградной функции — зависит от цели: максимизация прибыли, минимизация просадки или риск-скорректированная доходность.
- Реализация кастомной среды на базе Gymnasium с учётом комиссий, шортов, проскальзывания.
- Обучение агента с подбором гиперпараметров (A2C, PPO, DQN).
- Тестирование на out-of-sample периоде и расчёт метрик (Sharpe, drawdown, Calmar).
- Документация и код для самостоятельного запуска.
Наш опыт: 20+ завершённых проектов, 5 лет на рынке. Оценим ваш проект за 2 дня — свяжитесь с нами, чтобы обсудить детали. Получите консультацию по настройке среды — напишите, расскажем все подробности. Закажите настройку под ключ и получите готового агента с документацией.
Сроки ориентировочно
- Готовые обёртки + первый агент: 1–2 дня.
- Кастомная среда + бэктест: 3–7 дней.
- Полный цикл под ключ: от 7 до 14 дней в зависимости от сложности.







