При обучении торгового 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 дней в зависимости от сложности.







