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

Стандартні середовища з Gymnasium (CartPole, LunarLander) не підходять для трейдингу. Вони ігнорують прослизання, комісії та ринковий вплив. Результат: Sharpe 2 на бектесті, а в реальності — злив депозиту. Уявіть: ви навчили агента на стандартному середовищі, отримали Sharpe 2.5, запускаєте на реаль

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1440
  • 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 не містить майбутніх цін.

Наші інженери з сертифікатами з машинного навчання та трейдингу гарантують якість. Отримайте консультацію по вашій стратегії — зв'яжіться з нами.