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

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1564 послуг
Кастомне Gym-середовище для торгової стратегії RL
Середній
~2-3 дні
Часті запитання

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

Етапи розробки AI-рішення

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1348
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    949
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1183
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    642
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    921

Стандартні середовища з 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 не містить майбутніх цін.

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

Навчання з підкріпленням: PPO, SAC, DQN та промислове застосування

Ми щодня бачимо проєкти, які гинуть не через слабкий алгоритм, а через неправильну винагороду. Інженер пише reward = +1 за правильну дію, запускає навчання, а через 10 млн кроків агент знаходить спосіб отримати максимум, не вирішивши завдання. Це reward hacking — системний біль промислового RL. Наш досвід показує: правильний reward займає 70% успіху.

Чому RL складніше, ніж supervised learning?

У supervised learning є датасет з правильними відповідями. У RL правильної відповіді немає — є скалярний сигнал «краще/гірше», який надходить із затримкою в сотні кроків. Агент сам досліджує простір і знаходить стратегію.

Наслідки: нестабільність навчання, висока чутливість до гіперпараметрів, повільна збіжність. PPO (Proximal Policy Optimization) на Atari сходиться за 10 млн кроків — це години. На роботизованих завданнях з реальною фізикою — дні або тижні в симуляторі.

Чому reward engineering вирішальний для RL?

Без якісної reward-функції навчання перетворюється на лотерею. Reward hacking — класична пастка: агент знаходить неочевидний спосіб максимізувати винагороду, ігноруючи справжню ціль. Один із проєктів — сортування компонентів на PCB — demand: ми витратили 2 тижні на формалізацію reward: штраф за зіткнення, бонус за швидкість, penalty за неправильне розташування. Без цього агент навчився скидати деталі з конвеєра, отримуючи +1 за кожну скинуту, а не за відсортовану.

Як обрати алгоритм під задачу?

Завдання Алгоритм Причина
Безперервне керування (роботика, техпроцеси) SAC, TD3 Sample efficiency, стабільність
Дискретні дії, game‑playing PPO, DQN + Rainbow Простота, вивчений в індустрії
Multi‑agent MAPPO, QMIX Кооперація/конкуренція
Offline RL (датасет без середовища) CQL, IQL, TD3+BC Навчання без середовища
RLHF (alignment LLM) PPO, GRPO Інтеграція з reward model

Як налаштувати PPO та уникнути типових проблем?

PPO — робоча конячка RL. Основна ідея: обмежуємо оновлення політики через кліпування ratio clip_range=0.2. Це дає стабільність порівняно з vanilla policy gradient. Але без грамотного налаштування агент не сходиться.

Одна з частих пасток — entropy collapse: агент занадто швидко стає детермінованим, перестає досліджувати. Симптом — entropy coefficient падає до нуля. Лікування — ent_coef=0.01–0.05 і не знижувати нижче 0.001. Інша проблема — value function розходиться, коли vf_loss_coef високий, а explained_variance від'ємний. Рекомендуємо vf_coef=0.5 і gradient clipping max_grad_norm=0.5.

Неправильний n_steps також ламає навчання. n_steps=2048 — дефолт Stable‑Baselines3. Для завдань з довгим горизонтом (>500 кроків) потрібно збільшувати, для швидких (10–50 кроків) — зменшувати до 256–512.

Для швидкого старту використовуємо stable‑baselines3 + sb3‑contrib. Для research і кастомних алгоритмів — tianshou або CleanRL.

SAC для безперервного керування

SAC (Soft Actor‑Critic) додає в objective максимізацію ентропії — агент вчиться бути і ефективним, і різноманітним. Це дає відмінну sample efficiency та стійкість до шуму в reward. На задачах керування техпроцесами SAC зазвичай обходить PPO за збіжністю: потребує на 30–40% менше взаємодій для досягнення тієї ж якості. Ключовий параметр — target_entropy. Стандартне значення ‑dim(action_space) часто підходить, але для специфічних завдань краще налаштовувати вручну.

Як перенести навченого агента на реальний пристрій?

Навчати RL на реальному роботі — дорого та небезпечно. Стандартний підхід: навчання в симуляторі → трансфер на реальне залізо. Основна проблема — reality gap: симулятор не відтворює фізику, тертя, шум датчиків.

Головний інструмент — domain randomization. Під час навчання випадково варіюємо параметри середовища: маса об'єктів ±30%, коефіцієнт тертя ±50%, затримка дій 0–100 мс, шум спостережень σ=0.01–0.1. Агент навчається бути робастним до варіацій, і реальний світ стає лише ще однією варіацією.

Порівняння популярних симуляторів:

Симулятор Особливості Продуктивність
MuJoCo Стандарт для роботики, фізика середнього рівня Один робот — CPU
Isaac Gym / Isaac Lab (NVIDIA) GPU‑accelerated, 10 000+ паралельних середовищ Висока (на A100 до 50 000 fps)
PyBullet Безкоштовний, зручний для прототипів Низька, CPU
Gazebo Інтеграція з ROS, повний цикл Середня, CPU+GPU
Кейс: маніпулятор для сортування компонентів на PCB

Використовували Isaac Gym з 4096 паралельними середовищами на A100, PPO з domain randomization (випадкова маса, освітлення, позиція камери). 500 млн кроків — 18 годин. Після трансферу на реальний UR5 success rate 78% без додаткового fine‑tuning. Після 2 годин на реальному роботі (10 k кроків) — 94%. Весь process — 3 тижні.

RLHF: навчання LLM з людського зворотного зв'язку

RLHF став стандартом після InstructGPT. Класична схема: supervised fine‑tuning → reward model → PPO.

Проблеми класичного PPO: нестабільність (KL‑дивергенція може вибухнути), повільна збіжність, складність налаштування. Тому популярні альтернативи:

  • DPO — обходить reward model, вчиться на парах уподобань. Простіше, стабільніше, але менш гнучкий.
  • GRPO — використовується в DeepSeek‑R1, хороший для reasoning tasks.
  • ORPO — об'єднує SFT та alignment в одну стадію.

Бібліотека trl від Hugging Face — стандарт. Підтримує PPO, DPO, ORPO, GRPO з коробки, працює з PEFT/LoRA для memory‑efficient fine‑tuning.

Reward hacking залишається однією з головних причин провалів у RL, поряд з неправильно обраною архітектурою середовища. Це підтверджують дослідження з відкритих джерел (Reward hacking in reinforcement learning, Wikipedia).

Що входить в роботу

  • Архітектурне рішення та обґрунтування вибору алгоритму
  • Розробка та документування reward‑функції
  • Створення симулятора або налаштування існуючого
  • Навчання, hyper‑parameter sweep (Optuna / Ray Tune)
  • Трансфер на реальне залізо або інтеграція в продукт
  • Документація, доступи до коду та симуляторів
  • Навчання команди та 3‑місячна підтримка після деплою

Процес роботи

  1. Аудит завдання — фіксуємо цілі, ресурси, обмеження.
  2. Reward engineering — формалізація бажаної поведінки, перевірка на reward hacking.
  3. Вибір середовища та алгоритму — baseline, перші прогони.
  4. Систематичний hyperparameter sweep — використовуємо Optuna.
  5. Навчання в симуляторі з domain randomization.
  6. Тестування на реальному обладнанні (за потреби).
  7. Деплой, моніторинг, підтримка.

Терміни: proof of concept — 2–4 тижні; production‑система з sim‑to‑real — 3–8 місяців; RLHF для LLM — 4–10 тижнів. Вартість розраховується індивідуально — оцінимо ваш проєкт за 2 дні. Замовте консультацію, щоб уникнути типових пасток RL.

Наша команда — понад п’ять років досвіду в RL, 30+ успішних проєктів у роботиці, оптимізації ланцюгів постачання та LLM alignment. Гарантуємо прозору архітектуру та повну технічну документацію. Зв'яжіться з нами для отримання детальної оцінки вашого проєкту.