Кастомная Gym-среда для торговой стратегии RL

Стандартные среды из Gymnasium (CartPole, LunarLander) не годятся для трейдинга. Они игнорируют проскальзывание, комиссии и рыночное влияние. Результат: Sharpe 2 на бэктесте, а в реальности — слив депозита. Представьте: вы обучили агента на стандартной среде, получили Sharpe 2.5, запускаете на реаль

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

Часто задаваемые вопросы

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

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

Стандартные среды из Gymnasium (CartPole, LunarLander) не годятся для трейдинга. Они игнорируют проскальзывание, комиссии и рыночное влияние. Результат: Sharpe 2 на бэктесте, а в реальности — слив депозита. Представьте: вы обучили агента на стандартной среде, получили Sharpe 2.5, запускаете на реальном счете — и через месяц просадка 40%. Знакомая ситуация? Проблема в том, что стандартные среды не учитывают микроструктуру рынка: проскальзывание при исполнении, комиссии брокера (0.05–0.2% за сделку), рыночное влияние крупных ордеров (до 5% от объема). Агент учится торговать на идеальных данных, а в реальности все иначе. Мы решаем эту проблему, создавая кастомные Gym-среды, которые включают все ключевые факторы: спреды, комиссии, глубину стакана для HFT, и даже риск-менеджмент. Это позволяет агенту обучаться в условиях, максимально приближенных к реальным, и показывать состоятельные результаты на live-рынке. Оценим ваш проект за 1 день — свяжитесь с нами.

Почему кастомная Gym-среда критична для торговой стратегии?

Стандартные среды дают завышенные результаты на 20–40%. Например, стратегия с лимитными ордерами на нескольких биржах в обычной среде покажет отличный результат, а в реальности проскальзывание в 0.2% и комиссия 0.1% съедают 30% прибыли. Агент учится торговать неправильно, принимая шум за сигнал. В денежном выражении для портфеля в $100,000 это означает потерю $30,000 в год — только на издержках. Кастомная среда моделирует эти эффекты, и агент учится их избегать.

Как мы разрабатываем кастомную среду?

Мы строим среду на базе Gymnasium с точным моделированием всех аспектов торговли.

Структура класса CustomTradingEnv

import gymnasium as gym from gymnasium import spaces import numpy as np class CustomTradingEnv(gym.Env): metadata = {'render_modes': ['human', 'rgb_array']} def __init__(self, df, config): super().__init__() self.df = df self.config = config # observation space: OHLCV + indicators + portfolio state n_features = config['n_features'] self.observation_space = spaces.Box( low=-np.inf, high=np.inf, shape=(n_features,), dtype=np.float32 ) # action space: position size [-1, 1] per asset n_assets = config['n_assets'] self.action_space = spaces.Box( low=-1.0, high=1.0, shape=(n_assets,), dtype=np.float32 ) self._reset_portfolio() def reset(self, seed=None, options=None): super().reset(seed=seed) self._reset_portfolio() self.current_step = self.config['window_size'] obs = self._get_observation() return obs, {} def step(self, action): # 1. Исполнение действия (с реалистичным моделированием) executed_action = self._execute_order(action) # 2. Переход к следующему шагу self.current_step += 1 # 3. Обновление портфеля по новым ценам self._update_portfolio() # 4. Расчёт reward reward = self._compute_reward() # 5. Наблюдение obs = self._get_observation() # 6. Условие завершения terminated = self.current_step >= len(self.df) - 1 truncated = self.portfolio_value < self.config['min_capital'] info = { 'portfolio_value': self.portfolio_value, 'positions': self.positions.copy(), 'total_trades': self.total_trades } return obs, reward, terminated, truncated, info 

Реалистичное исполнение ордеров

Крупные ордера двигают рынок — игнорирование этого даёт ложные сигналы. Мы моделируем проскальзывание и комиссии:

def _execute_order(self, target_weights): current_prices = self.df.iloc[self.current_step][['open', 'high', 'low', 'close']] # проскальзывание: зависит от размера ордера и spread order_size = np.abs(target_weights - self.current_weights) slippage = order_size * self.config['slippage_factor'] execution_price = current_prices['open'] * (1 + slippage) # комиссия trade_value = np.abs(order_size) * execution_price * self.portfolio_value commission = trade_value * self.config['commission_rate'] self.portfolio_value -= commission.sum() self.current_weights = target_weights.copy() self.total_trades += (order_size > 0.01).sum() return target_weights 

Для HFT-стратегий добавляем симуляцию стакана:

class LOBSimulator: """Level-2 order book simulation""" def __init__(self, spread_bps=5, depth_levels=10): self.spread_bps = spread_bps self.depth_levels = depth_levels def get_fill_price(self, mid_price, order_size_usd): # fill price зависит от глубины стакана spread = mid_price * self.spread_bps / 10000 market_impact = np.sqrt(order_size_usd / 1e6) * spread return mid_price + spread/2 + market_impact 

Как выбрать reward функцию для торговой стратегии?

Выбор reward — самая важная часть кастомной среды. Мы предлагаем несколько вариантов:

Функция Преимущества Недостатки Когда использовать
Простой return (daily_return) Прозрачность, простота Не учитывает риск Для стратегий с низкой толерантностью к риску? Нет. Лучше для тестов
Sharpe-adjusted Учитывает риск через rolling window Чувствителен к окну Для долгосрочных стратегий, где важна стабильность
Penalized drawdown Штраф за просадку Сложнее настройка penalty Для стратегий с защитой капитала
def _compute_reward(self): daily_return = (self.portfolio_value / self.prev_portfolio_value) - 1 # вариант 1: простой return reward = daily_return # вариант 2: Sharpe-adjusted (rolling window) self.returns_history.append(daily_return) if len(self.returns_history) >= 20: sharpe = np.mean(self.returns_history[-20:]) / (np.std(self.returns_history[-20:]) + 1e-8) reward = daily_return * (1 + sharpe) # вариант 3: penalized drawdown current_dd = (self.peak_value - self.portfolio_value) / self.peak_value reward = daily_return - self.config['dd_penalty'] * current_dd # штраф за чрезмерную торговлю reward -= self.config['turnover_penalty'] * self.daily_turnover return float(reward) 

Штраф за turnover особенно важен для HFT — он учит агента не торговать, когда выгоды нет.

Observation Engineering

def _get_observation(self): window = self.df.iloc[self.current_step - self.window_size:self.current_step] features = [] # ценовые returns (нормализованы) returns = window['close'].pct_change().fillna(0).values features.extend(returns[-self.window_size:]) # технические индикаторы features.extend([ window['rsi'].iloc[-1] / 100, window['macd_norm'].iloc[-1], window['bb_position'].iloc[-1] # (price - lower) / (upper - lower) ]) # portfolio state features.extend(self.current_weights) features.append(self.portfolio_value / self.initial_capital - 1) return np.array(features, dtype=np.float32) 

Мы добавляем нормализованные признаки — это ускоряет сходимость агента.

Сравнение стандартной и кастомной сред

Параметр Стандартная среда Кастомная среда
Проскальзывание Не учитывается Моделируется на основе объема и спреда (0.1–0.5 бп)
Комиссии Нет Брокерские + биржевые (0.05–0.2%)
Рыночное влияние Нет Учитывается через LOB (impact до 5%)
Поддержка нескольких активов Только один Любое количество (до 20+ в проектах)
Reward Обычный return Sharpe, drawdown, turnover штраф

Процесс работы и сроки

Этап Длительность
Анализ стратегии 1 день
Проектирование среды 1–2 дня
Реализация 2–7 дней
Тестирование (validation) 1–2 дня
Деплой и документация 1 день

Общий срок — от 3–5 дней для одного актива до 3–4 недель для multi-asset с order book. Стоимость рассчитывается индивидуально — оставьте заявку на консультацию, и мы оценим проект.

Что вы получите в результате

  • Исходный код кастомной среды на Python (Gymnasium) с поддержкой ваших данных.
  • Конфигурационные файлы для single-asset, multi-asset и HFT режимов.
  • Документацию по API, reward функциям и моделированию исполнения.
  • Jupyter-ноутбук с обучением агента и визуализацией результатов.
  • Поддержку при интеграции в пайплайн (MLflow, Weights & Biases).
  • Гарантию прохождения проверок gymnasium.utils.env_checker.

Свяжитесь с нами для обсуждения вашей стратегии — и получите консультацию в течение дня.

Типичные проблемы при разработке среды

  • Look-ahead bias: нормализация на всем датасете. Мы проверяем временное разделение и не допускаем утечки будущих данных.
  • Игнорирование комиссий в reward: агент учится часто торговать, что снижает доходность на 20–30%.
  • Слишком простой reward (только return): ведет к высокой волатильности и просадкам. Мы используем комбинированные reward с штрафами.

Для верификации среды используем gymnasium.utils.env_checker и sanity checks:

  • Random policy теряет капитал из-за комиссий.
  • Buy & Hold воспроизводится при постоянных весах.
  • Нет look-ahead: observation не содержит будущих цен.

Наши инженеры с сертификатами по машинному обучению и трейдингу гарантируют качество. Получите консультацию по вашей стратегии — свяжитесь с нами.