Опубликовано 17.08.2026
КАК МЫ ПЫТАЛИСЬ ОБЫГРАТЬ БИРЖУ РОБОТОМ И ВЕРНУЛИСЬ К ОБЛИГАЦИЯМ
(честная история двух месяцев, трёх ботов и одной мудрой таблицы)
ГЛАВА 1. МЕЧТА
Всё начиналось красиво. У нас был счёт у брокера, немного свободных
денег и большая идея: «Почему бы не написать робота, который будет
торговать за нас, пока мы спим?»
План был прост и гениален, как все планы:
1. Берём API брокера (T-Банк Инвестиции, он же T-Invest API v2).
2. Пишем бота, который ловит сигналы.
3. Бот зарабатывает, мы молчим и не спугнём удачу.
Спойлер: удача не пришла. Но зато пришли знания, несколько седых
волос и твёрдая уверенность, что ОФЗ — это не скучно, а мудро.
ГЛАВА 2. БОТ А — «КУПИ НА ПАНИКЕ»
ПЕРВАЯ ГИПОТЕЗА (mean-reversion, возврат к среднему)
Логика звучала научно: «Если акция упала слишком резко (RSI < 20),
она перепродана и должна отскочить вверх. Если взлетела (RSI > 80) —
перегрета и должна упасть. Ловим эти крайности и зарабатываем на
откате».
Звучит как здравый смысл. Похоже на то, как человек покупает на
распродаже: «SBER упал на 5% за день — беру, он же отскочит!»
ЧТО МЫ СДЕЛАЛИ
Бот А торговал на 5-минутных свечах:
- RSI 20/80 как сигнал перепроданности/перекупленности
- Полосы Боллинджера (BB) как дополнительный фильтр
- Объём как подтверждение
- Экстремальный RSI (< 5 / > 95) как «усиленный» сигнал
ЧТО ПОШЛО НЕ ТАК
1. Проблема №1 — «против тренда». RSI < 20 на падающем рынке — это
не «скоро отскок», это «тренд вниз, и он только начинается».
Мы покупали падающий нож, а он продолжал падать. Экстремальный
обход тренда (RSI < 5) вообще оказался входом ПРОТИВ сильного
движения — мы входили в шорт, когда всё летело вверх, и наоборот.
2. Проблема №2 — перевес около нуля. Бэктест на 30-90 днях показал
Profit Factor (PF) около 1.0. Это значит: на каждый заработанный
рубль приходится рубль потерянный. С учётом комиссии 0.05% за
сторону — получался гарантированный минус.
3. Проблема №3 — «шум вместо сигнала». На 5-минутках 90% движений —
это шум. RSI прыгает туда-сюда как заяц, и бот открывал сделки
на каждый чих, платя комиссию за каждый вход-выход.
ВЕРДИКТ: Бот А ушёл на пенсию. Гипотеза «покупай на панике» красива
в теории, но на практике паника — это начало тренда, а не его конец.
ГЛАВА 3. БОТ Б — «ЛОВИ ТРЕНД»
ВТОРАЯ ГИПОТЕЗА (trend-following, следование за трендом)
«Окей, — подумали мы. — Раз ловить развороты не вышло, давай ловить
тренды. Классика: скользящая средняя 5 периодов пересекает среднюю
20 периодов снизу вверх — покупаем. Сверху вниз — продаём (шорт)».
Это та самая стратегия, на которой в 80-х разбогатели знаменитые
«Черепахи» (Turtle Traders). Ну, почти. Они торговали на дневных
свечах и 40 рынках, а мы — на часовых и одной акции. Но кто считает.
ЧТО МЫ СДЕЛАЛИ
Бот Б торговал GAZP на часовых свечах: MA5 пересекла MA20 — входим,
пересекла обратно — выходим.
ЧТО ПОШЛО НЕ ТАК
Бот Б сам по себе не был плох. Просто мы быстро поняли, что одна
акция (GAZP) — это не портфель, а лотерея. И что MA-кроссовер на
часовиках даёт много ложных сигналов в боковике. Плюс всплыла
маржинальная боль: шорт требовал кэш, а у нас всё лежало в ОФЗ,
и брокер отвечал загадочным кодом 30042 «Not enough assets for a
margin trade» — «не хватает активов для маржинальной сделки».
ВЕРДИКТ: Бот Б стал прототипом Бота C. Идея «лови тренд» осталась,
но захотелось больше инструментов и умнее фильтры.
ГЛАВА 4. БОТ C — «НАШ МАЛЕНЬКИЙ ХЕДЖ-ФОНД»
ТРЕТЬЯ ГИПОТЕЗА (тренд-следование на корзине)
«Раз одна акция — лотерея, давай возьмём девять!» — решили мы и
собрали корзину лучших по бэктесту: АЛРОСА, Газпром, Сургутнефтегаз,
МТС, Т-Технологии, Татнефть, Московская Биржа, ВТБ, Полюс.
Бот C торговал на часовых свечах:
- Вход: пересечение MA5/20 + «догон тренда» (если тренд уже есть и
объём высокий — тоже входим)
- Стоп-лосс 2×ATR (двойная средняя волатильность)
- Тейк-профит 3×ATR
- Лимит 20 000 ₽ на инструмент, максимум 4 позиции одновременно
- Проверка каждые 5 минут
И ВОТ ТУТ НАЧАЛОСЬ ВОЛШЕБСТВО.
Бэктест на 90 днях показал PF 1.42–2.53. «Ого!» — подумали мы.
«+9% в месяц! Это же 100%+ годовых! Мы богаты!»
ГЛАВА 5. ТЕХНИЧЕСКАЯ КУХНЯ (КАК ЭТО РАБОТАЛО ИЗНУТРИ)
Интеграция с T-Банк Инвестиции (T-Invest API v2):
1. ПРОТОКОЛ — gRPC (не REST!). Библиотека t_tech.invest оборачивает
gRPC в удобный Python-клиент. Авторизация — токен и account_id.
2. СВЕЧИ — get_all_candles отдаёт исторические свечи (5-мин, часовые
и т.д.). На них мы считали MA, RSI, ATR, Bollinger — всю эту
индикаторную магию.
3. ОРДЕРА — post_order отправляет рыночные ордера. И вот тут нас
ждал самый жирный грабли (см. Главу 6).
4. БАЛАНС — get_positions / get_portfolio отдают текущие позиции,
кэш, облигации. Мы синхронизировали state.json каждые 5 минут.
5. ОПЕРАЦИИ — get_operations для истории сделок, купонов, комиссий.
Пригодилось потом для отчёта по облигациям.
6. КРОН — cron в МСК каждые 5 минут запускал бота. Бот читал state,
считал сигналы, слал ордера, писал уведомления в Telegram.
Технически всё было красиво. А вот математически...
ГЛАВА 6. ГРАБЛИ, ПО КОТОРЫМ МЫ ПРОШЛИ
Грабли №1. РАЗМЕР ЛОТА (самый дорогой грабли)
В API quantity — это ЛОТЫ, а не акции. Мы по незнанию считали акции.
Для МТС (лот = 10 акций) это значило, что «скромная позиция на 15 000»
превратилась в шорт на 148 000 — в ДЕСЯТЬ раз больше задуманного!
Мы обнаружили это, когда сверили баланс и увидели «-830 акций» вместо
«-83». Хорошо, что вовремя. Урок: читай документацию API, а не
предполагай.
Грабли №2. ОБЪЁМНЫЙ ФИЛЬТР ПО НЕЗАКРЫТОЙ СВЕЧЕ
Бот брал объём ТЕКУЩЕГО часа (который ещё идёт и всегда занижен)
вместо ПОСЛЕДНЕГО ЗАКРЫТОГО. В результате фильтр объёма блокировал
все входы — свеча «в процессе» всегда выглядит как слабая.
Грабли №3. ЛОЖНЫЕ СТОПЫ ПОРТФЕЛЯ
При пропаже поля bonds_value из state.json эквити считалось как
«409 ₽ вместо 80 000 ₽» → бот думал, что мы разорились, и ставил
аварийный стоп. Классика: баг в одном поле — паника в системе.
Грабли №4. МАРЖА ДЛЯ ШОРТОВ (код 30042)
Шорт (продажа заёмных акций) требует ДЕНЕЖНУЮ маржу. А у нас деньги
лежали в ОФЗ, которые брокер не считал обеспечением для шортов.
Итог: бот честно пытался шортить, а брокер вежливо отказывал.
Грабли №5. НЕТ СТОП-ОРДЕРОВ В API
В API для акций нет типа «стоп-лосс ордер» — только MARKET/LIMIT/
BESTPRICE. Значит, «жёсткий» стоп выставить нельзя, только «мягкий»:
бот сам проверял цену каждые 5 минут. Если рынок резко падал между
проверками — стоп срабатывал с задержкой.
Грабли №6. ИНТУИЦИЯ ВМЕСТО ДАННЫХ
Мы трижды предлагали «улучшения» по ощущениям — и трижды бэктест
их опроверг:
- Тейк-профит 0.2% (скальпинг): «забираем по чуть-чуть». Бэктест:
PF 0.23, минус 60 000 ₽. Маленькие плюсы не покрывают редкие
большие стопы.
- Объёмный порог 1.25× (компромисс между 1.0 и 1.5): оказался
ХУДШИМ из трёх (PF 1.36). Немонотонность — вещь коварная.
- Фильтр времени дня («торгуем только утром»): PF упал с 1.42 до
1.12. Дневные входы оказались прибыльными, а мы хотели их выкинуть.
ГЛАВА 7. МОМЕНТ ИСТИНЫ (WALK-FORWARD ТЕСТ)
----------------------------------------------------------------
И вот, когда бот уже торговал вживую и даже открыл четыре шорта на
падающем рынке, мы решили проверить главное: а есть ли у нас вообще
ПЕРЕВЕС?
Сделали walk-forward тест на 180 днях (а не на 90, как раньше).
Разбили историю на сегменты по 30 дней и прогнали стратегию по каждому:
18.02–20.03: PF 0.51 (минус 7 870 ₽)
20.03–19.04: PF 0.85 (минус 2 054 ₽)
19.04–19.05: PF 0.63 (минус 5 800 ₽)
19.05–18.06: PF 0.92 (минус 1 152 ₽)
18.06–18.07: PF 1.48 (плюс 10 973 ₽) ← НАШЕ окно
ЧЕТЫРЕ ИЗ ПЯТИ сегментов — убыточны. Единственный прибыльный период
совпал с теми самыми 90 днями, на которых мы крутили параметры.
Это называется ПЕРЕПОДГОНКА (overfitting). Мы подогнали бота под
конкретный удачный кусок истории, как студент, заучивший билет №7.
На экзамене по билету №7 — отлично. На любом другом — двойка.
Урок, который стоит запомнить навсегда: КРАСИВЫЙ БЭКТЕСТ — ЭТО ЕЩЁ
НЕ ПЕРЕВЕС. Это может быть просто удачное окно.
ГЛАВА 8. ВЫВОД: ОБЛИГАЦИИ И АВТООТЧЁТ
----------------------------------------------------------------
Когда пыль осела, мы честно спросили себя: «А что у нас реально
работает?»
Ответ был прост и скучен, как всё надёжное: ОФЗ. Государственные
облигации с доходностью 12.5% годовых. Без риска, без бессонных
ночей, без седых волос.
И вместо того чтобы продолжать сражаться с рынком, мы сделали то,
что реально полезно:
АВТООТЧЁТ ПО ОБЛИГАЦИЯМ В TELEGRAM
Скрипт bond_report.py раз в неделю (понедельник, 09:00 МСК) присылает
аккуратную таблицу:
- Купоны (полученные выплаты)
- Налог 13%
- Комиссия (только по облигациям)
- НКД за период владения (сколько «накапало» с момента покупки)
- Переоценка (изменение рыночной цены)
- Итог по каждому выпуску + общий итог
Всё по-честному: FIFO-учёт лотов, НКД как дельта с момента покупки
(оплаченный при входе НКД вычитаем), комиссия 0.05% только по бондам.
ЭПИЛОГ. ЧТО МЫ ПОНЯЛИ
----------------------------------------------------------------
1. Бэктест на 90 дней — это не доказательство, а реклама. Верь
только walk-forward на длинной истории.
2. Тренд-следование работает у тех, у кого 50+ рынков и дневные
свечи. На 9 акциях и часовиках — это казино с комиссией.
3. Читай документацию API. Лоты — это не акции. Свеча «в процессе» —
не свеча.
4. Любую «гениальную идею» сначала проверяй на данных. Интуиция в
трейдинге — это дорогой советчик.
5. ОФЗ 12.5% — это не «скучно», это «стабильно». А автоотчёт в
Telegram — это то немногое из всего проекта, что реально приносит
пользу каждый понедельник.
Финал истории: бот уволен, шорты закрыты, облигации работают, отчёт
приходит. А опыт — бесценен. Ну, почти бесценен. Если не считать
комиссий.