AI-трейдинг симулятор ArenaGo: обучение на реальных котировках без риска | AiManual
AiManual Logo Ai / Manual.
21 Янв 2026 Гайд

ArenaGo.ru: собираем AI-трейдинг симулятор на реальных данных, который не сломает ваш банк

Пошаговый гайд по созданию симулятора алгоритмической торговли с AI. Используем реальные котировки, API и Python. Учимся трейдингу без потерь.

Вы когда-нибудь видели, как очередной гений из Twitter хвастается графиком доходности своего AI-трейдера? Показывает красивую кривую, которая растет ровно вверх, и обещает поделиться секретом за $999. А вы думаете: "Интересно, а на реальных деньгах это тоже работает? Или он просто переобучил модель на исторических данных?"

Проблема в том, что проверить это невозможно. Точнее, было невозможно. Пока вы не начнете тестировать стратегии в условиях, максимально приближенных к реальным, но без риска потерять деньги. Именно для этого нужен симулятор.

Главная ошибка новичков в алгоритмическом трейдинге - тестировать стратегии на исторических данных без учета спреда, комиссий и ликвидности. В симуляторе вы проигрываете виртуальные деньги. В реальности - настоящие.

Зачем вообще симулятор, если есть бэктесты?

Отличный вопрос. Бэктестинг - это когда вы прогоняете стратегию по историческим данным. Симулятор - когда вы запускаете стратегию "вживую", но на виртуальные деньги, используя реальные котировки в реальном времени.

Разница как между просмотром записи футбольного матча и игрой в футбол. В записи вы видите результат. В реальной игре - испытываете давление, принимаете решения в условиях неопределенности, ошибаетесь.

  • Бэктест: "Моя стратегия заработала бы 150% за 2024 год"
  • Симулятор: "Моя стратегия потеряла 30% виртуальных денег за первую неделю, потому что я не учел комиссию на частые сделки"

Второй вариант полезнее. Намного.

Архитектура: из чего состоит ArenaGo

Представьте, что вы строите гоночный симулятор. Вам нужна трасса (рыночные данные), машина (торговая стратегия), физический движок (исполнение сделок) и приборная панель (мониторинг).

Вот как это выглядит в коде:

# core/architecture.py

class TradingArena:
    """
    Главный класс симулятора.
    Соединяет все компоненты в работающую систему.
    """
    def __init__(self):
        self.data_feed = MarketDataFeed()      # Источник котировок
        self.execution_engine = ExecutionEngine()  # Исполнение сделок
        self.portfolio = Portfolio()           # Виртуальный портфель
        self.strategy = None                   # AI-стратегия (подключается)
        self.metrics = PerformanceMetrics()    # Сбор статистики
        
    def run(self, days: int):
        """Запускает симуляцию на N торговых дней"""
        for day in range(days):
            # Получаем новые данные
            market_data = self.data_feed.get_next()
            
            # Стратегия принимает решение
            decision = self.strategy.decide(market_data)
            
            # Исполняем сделку (если нужно)
            if decision:
                self.execution_engine.execute(
                    decision, 
                    self.portfolio
                )
            
            # Обновляем метрики
            self.metrics.update(self.portfolio)
💡
Ключевая фишка ArenaGo - разделение данных, логики и исполнения. Это позволяет менять стратегии, не переписывая весь код. Как в настоящем продакшене, только без риска.

1 Где брать реальные котировки (бесплатно)

Первый вопрос, который всех волнует. На 2026 год есть несколько проверенных вариантов:

Источник Что дает Лимиты Стоимость
Alpha Vantage Исторические данные, индикаторы 5 запросов/мин, 500/день Бесплатно (с лимитами)
Twelve Data Реалтайм, Forex, крипта 800 запросов/день Бесплатный тариф
Yahoo Finance Исторические данные (yfinance) Неограниченно Полностью бесплатно
Polygon.io Агрегированные тики, реальное время 5 запросов/мин на бесплатном Бесплатно (базовый)

Для симулятора я рекомендую комбинацию: Yahoo Finance для загрузки истории + Twelve Data для симуляции реального времени. Почему? Yahoo дает данные бесплатно и без ограничений (через библиотеку yfinance), а Twelve Data имеет хороший бесплатный лимит и WebSocket для реального времени.

# data/yahoo_source.py
import yfinance as yf
import pandas as pd

class YahooDataFeed:
    """Загрузка исторических данных с Yahoo Finance"""
    
    def __init__(self, ticker: str, period: str = "1y"):
        self.ticker = ticker
        self.period = period
        
    def load(self) -> pd.DataFrame:
        """Загружает OHLCV данные"""
        stock = yf.Ticker(self.ticker)
        df = stock.history(period=self.period)
        
        # Добавляем расчетные поля
        df['returns'] = df['Close'].pct_change()
        df['volatility'] = df['returns'].rolling(20).std()
        
        return df

Важный нюанс: Yahoo Finance иногда меняет структуру ответа. Всегда обновляйте yfinance до последней версии и добавляйте обработку ошибок. В 2025 была проблема с временными зонами - данные приходили со смещением на час.

2 Движок исполнения: как симулировать реальный трейдинг

Вот где большинство симуляторов отрываются от реальности. Они предполагают, что вы можете купить или продать по цене закрытия свечи. В реальном мире есть спред, комиссии, проскальзывание и ограниченная ликвидность.

Правильный движок исполнения должен учитывать:

  • Спред: разница между ценой покупки и продажи
  • Комиссия: биржа берет процент от сделки
  • Проскальзывание: цена успевает измениться пока ваш ордер исполняется
  • Лимиты объема: нельзя купить больше, чем есть в стакане
# execution/realistic_engine.py

class RealisticExecutionEngine:
    """Движок исполнения с реалистичными условиями"""
    
    def __init__(self, 
                 commission: float = 0.001,  # 0.1%
                 spread: float = 0.0005,     # 0.05%
                 slippage: float = 0.0002):  # 0.02%
        self.commission = commission
        self.spread = spread
        self.slippage = slippage
        
    def execute(self, 
                signal: str,  # 'BUY' или 'SELL'
                price: float,
                quantity: float,
                portfolio: Portfolio) -> TradeResult:
        """Исполняет сделку с учетом всех издержек"""
        
        # Корректируем цену на спред
        if signal == 'BUY':
            execution_price = price * (1 + self.spread)
        else:  # SELL
            execution_price = price * (1 - self.spread)
        
        # Добавляем проскальзывание (случайное)
        slippage_effect = np.random.uniform(-self.slippage, self.slippage)
        execution_price *= (1 + slippage_effect)
        
        # Рассчитываем комиссию
        trade_value = execution_price * quantity
        commission_fee = trade_value * self.commission
        
        # Общая стоимость сделки
        total_cost = trade_value + commission_fee
        
        # Обновляем портфель
        if signal == 'BUY':
            portfolio.cash -= total_cost
            portfolio.positions[asset] += quantity
        else:
            portfolio.cash += (trade_value - commission_fee)
            portfolio.positions[asset] -= quantity
        
        return TradeResult(
            price=execution_price,
            commission=commission_fee,
            slippage=slippage_effect
        )

Звучит сложно? На самом деле, это базовая финансовая математика. Без этих расчетов ваш симулятор будет показывать завышенную доходность. Иногда на 20-30% завышенную. Представьте, что вы протестировали стратегию, она показала +50% в симуляторе. Запускаете на реальные деньги - а она едва выходит в ноль. Потому что комиссии съели всю прибыль.

3 AI-стратегия: от простого ML до RL-агента

Теперь самое интересное - мозги нашего трейдера. Здесь есть градация сложности:

  1. Правила на индикаторах: "Купить, когда RSI < 30, продать когда RSI > 70"
  2. Классический ML: Логистическая регрессия или градиентный бустинг для предсказания направления
  3. Временные ряды: LSTM или Transformer для предсказания цены
  4. Reinforcement Learning: Агент, который учится торговать через trial-and-error

Для начала рекомендую второй вариант. Почему? Потому что RL-агенты - это круто звучит, но на практике их обучать сложно, долго и нестабильно. Классический ML дает предсказуемый результат.

Вот минимальный рабочий пример:

# strategies/ml_strategy.py
from sklearn.ensemble import GradientBoostingClassifier
import numpy as np

class MLTradingStrategy:
    """Стратегия на основе градиентного бустинга"""
    
    def __init__(self):
        self.model = GradientBoostingClassifier(
            n_estimators=100,
            max_depth=3,
            random_state=42
        )
        self.is_trained = False
        
    def prepare_features(self, data: pd.DataFrame) -> np.array:
        """Готовит фичи из рыночных данных"""
        features = []
        
        # Простые технические индикаторы
        data['sma_20'] = data['Close'].rolling(20).mean()
        data['sma_50'] = data['Close'].rolling(50).mean()
        data['rsi'] = self.calculate_rsi(data['Close'])
        data['bb_upper'], data['bb_lower'] = self.bollinger_bands(data['Close'])
        
        # Относительные изменения
        data['returns_1d'] = data['Close'].pct_change(1)
        data['returns_5d'] = data['Close'].pct_change(5)
        
        # Объем
        data['volume_sma'] = data['Volume'].rolling(20).mean()
        data['volume_ratio'] = data['Volume'] / data['volume_sma']
        
        # Убираем NaN
        features_df = data.dropna()
        
        return features_df[['sma_20', 'sma_50', 'rsi', 
                           'bb_upper', 'bb_lower',
                           'returns_1d', 'returns_5d',
                           'volume_ratio']].values
    
    def train(self, X: np.array, y: np.array):
        """Обучает модель на исторических данных"""
        # y - целевая переменная: 1 если цена вырастет, 0 если упадет
        self.model.fit(X, y)
        self.is_trained = True
        
    def decide(self, current_features: np.array) -> str:
        """Принимает торговое решение"""
        if not self.is_trained:
            return 'HOLD'  # Не торговать, если модель не обучена
            
        prediction = self.model.predict(current_features.reshape(1, -1))
        probability = self.model.predict_proba(current_features.reshape(1, -1))
        
        # Торгуем только если уверенность высокая
        if prediction[0] == 1 and probability[0][1] > 0.65:
            return 'BUY'
        elif prediction[0] == 0 and probability[0][0] > 0.65:
            return 'SELL'
        else:
            return 'HOLD'
💡
Ключевой момент - стратегия должна возвращать не только 'BUY' или 'SELL', но и 'HOLD'. Большинство времени рынок движется боком, и лучшая стратегия - ничего не делать. AI должен это понимать.

Если хотите пойти дальше, посмотрите на CodeAct - агента, который пишет и исполняет торговый код. Или изучите Real-Time Bidding репозиторий с RL-агентами - там много пересекающихся идей.

4 API слой: как сделать симулятор доступным

Вы построили крутой симулятор. Теперь нужно дать к нему доступ. Вариантов несколько:

  • Локальный скрипт: Запускаете Python файл, смотрите результаты в консоли
  • Jupyter Notebook: Интерактивная среда с графиками
  • REST API: Можно запускать симуляции через HTTP запросы
  • Web интерфейс: Красивые графики, кнопки, слайдеры

Для ArenaGo я выбрал комбинацию REST API + простой фронтенд. Почему? Потому что это позволяет:

  1. Интегрировать симулятор в другие системы
  2. Запускать симуляции удаленно
  3. Строить дашборды на любой платформе
  4. Делиться доступом с командой

Вот минимальный FastAPI сервер:

# api/server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn

app = FastAPI(title="ArenaGo Trading Simulator API")

# Глобальный объект симулятора (в продакшене нужно иначе)
simulator = None

class SimulationRequest(BaseModel):
    ticker: str
    strategy: str
    initial_capital: float = 10000.0
    days: int = 30
    
class SimulationResponse(BaseModel):
    simulation_id: str
    final_portfolio: float
    sharpe_ratio: float
    max_drawdown: float
    trades_count: int

@app.post("/simulate", response_model=SimulationResponse)
def run_simulation(request: SimulationRequest):
    """Запускает новую симуляцию"""
    try:
        # Инициализируем симулятор с заданными параметрами
        simulator = TradingArena(
            ticker=request.ticker,
            initial_capital=request.initial_capital
        )
        
        # Загружаем выбранную стратегию
        if request.strategy == "ml_basic":
            simulator.strategy = MLTradingStrategy()
        elif request.strategy == "rsi_simple":
            simulator.strategy = RSITradingStrategy()
        else:
            raise HTTPException(status_code=400, 
                              detail=f"Unknown strategy: {request.strategy}")
        
        # Запускаем симуляцию
        results = simulator.run(days=request.days)
        
        # Возвращаем результаты
        return SimulationResponse(
            simulation_id=generate_id(),
            final_portfolio=results['final_value'],
            sharpe_ratio=results['sharpe'],
            max_drawdown=results['max_drawdown'],
            trades_count=results['trades']
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, 
                          detail=f"Simulation failed: {str(e)}")

@app.get("/results/{simulation_id}")
def get_results(simulation_id: str):
    """Возвращает детальные результаты симуляции"""
    # Здесь логика загрузки из БД или кэша
    pass

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Теперь вы можете запускать симуляции командой:

curl -X POST "http://localhost:8000/simulate" \
  -H "Content-Type: application/json" \
  -d '{"ticker":"AAPL", "strategy":"ml_basic", "days":90}'

Что чаще всего ломается (и как это чинить)

За 3 года работы с такими системами я собрал коллекцию самых частых проблем:

Проблема Симптомы Решение
Look-ahead bias Стратегия показывает нереальную доходность Разделять данные на train/test по времени, никогда не использовать будущие данные для текущего решения
Overfitting На исторических данных работает идеально, на новых - ужасно Упрощать модели, использовать кросс-валидацию во времени, добавлять регуляризацию
Синхронизация времени Сделки исполняются по "прошлым" ценам Использовать временные метки с наносекундной точностью, учитывать задержки API
Утечка памяти Симулятор замедляется со временем Очищать исторические данные, использовать генераторы вместо списков, мониторить memory_profiler
API лимиты Источник данных блокирует запросы Добавлять кэширование, использовать очереди запросов, иметь fallback источник

От симулятора к продакшену: что меняется

Допустим, ваш симулятор стабильно показывает +15% годовых с просадкой не более 5%. Вы хотите запустить его на реальные деньги. Что нужно изменить?

Все.

Ну, почти все. Основные отличия:

  1. Брокерский API вместо симулятора: Подключаетесь к реальному брокеру (Interactive Brokers, Alpaca, Tinkoff API)
  2. Мониторинг и алерты: Система должна уведомлять вас о сбоях, необычной активности, превышении лимитов
  3. Риск-менеджмент: Лимиты на размер позиции, стоп-лоссы на уровне системы (не только в стратегии)
  4. Резервное копирование и откат: Возможность быстро остановить систему и откатить сделку при ошибке
  5. Логирование всего: Каждое решение, каждая сделка, каждый запрос к API
  6. Юридические аспекты: В зависимости от юрисдикции могут быть ограничения на алгоритмическую торговлю

Для продакшена рекомендую изучить гайд по production-ready AI агентам. Многие принципы пересекаются.

Никогда не запускайте на реальные деньги стратегию, которая не протестирована хотя бы на 100 разных рыночных сценариях в симуляторе. Никогда. Даже если она показывала +100% последние 3 месяца. Рынок имеет привычку менять режимы, и то, что работало вчера, завтра может слить весь депозит.

Что дальше? Эволюция ArenaGo

Базовый симулятор - это только начало. Дальше можно развивать систему в нескольких направлениях:

  • Мультиагентная симуляция: Запустить 1000 AI-трейдеров с разными стратегиями и посмотреть, как они взаимодействуют
  • Генерация стресс-сценариев: Искусственно создавать обвалы рынка, всплески волатильности, ликвидные кризисы
  • Transfer learning: Обучить стратегию на одном активе, адаптировать для другого
  • Explainable AI: Не просто "купить", а "купить, потому что RSI показал перепроданность при росте объема"
  • Интеграция с новостями: Анализ финансовых новостей и твитов для принятия решений

Самый интересный путь, на мой взгляд - создание AI-компаньона с памятью, который не только торгует, но и учится на своих ошибках, запоминает, что работало в прошлом, и адаптируется к новым условиям.

Или построить что-то вроде BigCodeArena для трейдинга - платформу, где разные AI-модели соревнуются в торговле, а вы выбираете лучшую.

Главное - начать с простого. С симулятора, который работает на вашем ноутбуке. Который позволяет тестировать идеи без риска. Который показывает не красивую картинку для Twitter, а реальные проблемы вашей стратегии.

Потому что в трейдинге, как и в любом сложном деле, первый шаг к успеху - перестать обманывать себя. А ArenaGo помогает именно в этом.