TLDR; https://github.com/alterfo/moex-trader
Здравствуйте, меня зовут Олег. 11+ лет опыта в архитектуре и управлении разработкой.
Я как кузнец — не могу не куя, и сейчас, в меж-работье, занимаюсь своими проектами. Среди них — интерактивный нотный тренажер для игры на пианино, шифрованный личный дневник, игра по мотивам Космических Рейнджеров - Вакуумные Пройдохи и ещё штук 6, включая движок базы знаний по коду, чатам, докам и таскам и редактор IDEF0.
Сейчас в фокусе проект AI-трейдинга.
Мысль о заработке с помощью ИИ не даёт мне покоя уже три года. Когда слово “агентные” можно было услышать только в интервью Сергея Брина, а опенсорсные модели годились только для adult-ботов, я создал своего первого агента с помощью nerve-cli. Это утилита, которая запускает запросы модели в цикле с доступом к утилитам и промптом-целью.
Агент сам писал себе тулу для сбора новостей на заданную тему, проводил анализ настроений и выдавал рекомендации по инвестициям. По сути, это был прототип News Sentiment Trading. Дело было в начале 2024-го. Эта система выдавала конечный результат 1 раз из 10, и лишь один из 10 конечных результатов я брал в работу. Под капотом была первая опенсорсная gemma.
Система сгенерировала мне значительную прибыль, которую я потратил на двухнедельный отпуск в пятизвездочном отеле на Хайнане. Но счастье длилось недолго. Где как не в Китае осознать непостоянную природу бытия.
Сентимент, который перестал работать.
В 2025-м году с рынком что-то случилось. Новостной анализ перестал приносить желаемый результат. Вооруженный нейросетями (Claude, DeepSeek, Qwen, и бесплатные от Opencode) я принялся искать рабочий подход.
Первым делом я начал искать корелляции между новостями и стоимостью бумаг. Каждый день система собирала новости, считала сентимент, писала отчёт с калибровкой. За месяц таких отчётов накопилось несколько десятков — я честно пытался подкрутить веса источников, отсеять шум, разбить на категории, добавить доверие проверенным изданиям и штрафовать желтизну.
Появился зачаточный бэктест — анализ влияния новостей на котировки на горизонте 1/3/5/10 дней. Все попытки откалибровать (не только сентимент) и найти корелляцию находили только шум и 50/50. Из интересного — обнаружилось что PR/маркетинговые новости приводили к росту на горизонте 5 дней с вероятностью 80% тогда как и за негативными новостями, вроде выпиливания Озон из стора — следовал рост акций. Получил несколько полезных инсайтов для долгих ставок и прогнозов.
В это время Google выложила в опенсорс продвинутую модель для анализа временных рядов — TimesFM 3, она была обучена на сезонных данных и могала находить корелляцию между разными данными. Она обнаружила корелляцию между Полюсом (золотодобыча) и МТС, и между МТС и Сбером с лагом в 3 дня за последние 90 дней, но это не подтвердилось анализом других таймфреймов, поэтому эту идею я выбросил. Для сезонного пронозирования очень хорошая модель, но для моих нужд не подошла.
Движок
Испробовав идею на python, я переписываю её на Go. Просто меньше проблем при доработках. И в этот раз мне не хотелось снова собирать особенности Python-среды и я создал модульный Go-монолит, который:
каждые 5 минут забирает котировки и стакан по MOEX IIS,
торгует в песочнице,
тянет новости из проверенных на прошлом этапе источников,
считает
FeatureContext(моментум, RSI, отклонение от скользящей, реализованная волатильность, z-score объема, дисбаланс стакана, новостной сентимент),проверяет заявки по набору правил (не съест ли комиссия прибыль, не много ли заявок, нет ли новостных блокеров, и тд),
реализует простейший кластер доступности — если вдруг макбук выключится, приложение, запущенное на ai-box переходит в режим трейдера, а когда макбук оживает — он становится основной системой,
шлёт исполненные заявки в телеграм бота и в аудит лог,
при запуске делает бэктест на свежих данных, и если тот показывает минус - не запускается.
LLM я исключил из системы, мне был нужен детерминизм и быстрый бэктест, а модель могла отвечать по-разному на одни и те же входные данные, а бэктест занимал 8 часов.
Дальше пошёл перебор моделей, настроек торговли и данных. Логистическую регрессию я собрал в ансамбль вместе с LightGBM и XGBoost (через инференс в Go) — три модели голосуют, финальный сигнал усредняется. Для анализа новостей я обучил собственный bag-of-words классификатор на чистом Go, который размечает заголовок по восьми категориям событий (дивиденды, байбэк, санкции и т. п.) вместо расплывчатого “сентимента”. Это было продолжением активностей по поиску корелляций.
Чтобы собственный классификатор показывал честный результат, я обучил его на старых новостях и данных, до таймфрейма бэктеста (90 дней).
Результаты
Итоговые результаты прогона бэктеста на свежих MOEX данных (2026-06-19 — 2026-09-16). 18 тикеров, депозит 1 000 000 ₽, комиссия 0,05 %, kill-switch включён:
Вариант | Сделок | Net P&L | Hit rate | Просадка | Sharpe |
|---|---|---|---|---|---|
| 599 | −3 458 ₽ | 45,9 % | 0,39 % | −2,13 |
| 3 | +2 668 ₽ | 100 % | 0,27 % | 1,44 |
| 45 | +5 583 ₽ | 84,4 % | 0,07 % | 5,70 |
| 91 | +14 890 ₽ | 72,5 % | 0,20 % | 6,10 |
| 114 | +48 932 ₽ | 68,4 % | 0,57 % | 6,29 |
| 136 | +75 029 ₽ | 64,0 % | 0,84 % | 6,38 |
| 143 | +99 016 ₽ | 61,5 % | 1,10 % | 6,38 |
Вы спросите почему боевой вариант не последний? Потому что на окне в 6 кварталов (18 месяцев) у него была большая просадка, которая не пролезла в kill-switch (он срабатывает при просадке портфеля на 3%)
Для меня это инженерная задача. Все цифры — результат тестирования на исторических данных MOEX и той же защитой, что в живой системе. Это не инвестиционная рекомендация и не обещание доходности.
Выводы
Несмотря на волатильность рынка в последние годы, ансамбль из трёх нейросетей, двух специализированных (LightGBM и XGBoost) и одной самостоятельно обученной показали возможность дохода.
Процесс обучения классификатора, бэктесты и другие детали реализации предлагаю вынести в комментарии чтобы не нагружать статью.

