Привет, Хабр. Видел в интернете кейс. где сделали бота с LLM для торговли на Polymarket и он сделал $10k из $1k за месяц. Ну и чо бы не попробовать что то такое же сделать! Побочный проект, чисто по приколу. Вооружил его вирутальным стартовым капиталом — $100 нарисованных.
И вот на второй день этот несерьёзный проект показал +9% на счёте.
Сразу дисклеймер: я не трейдер. Вообще! Фрилансер-разработчик, IoT, телеграм-боты — это моё. А в трейдинге я плохо шарю, по-честному, и если в комментариях окажутся настоящие трейдеры и увидят очевидные глупости — это потому что я в этой теме очевидно глуп. Статья не про trading expertise (у меня её нет). Она про методологию измерения и про то, как я четыре раза подряд обманывал себя на ней. Тут у меня получше.
Обычно такой текст заканчивается на: «И вот как я поднял иксы на ставках». Но нет! Следующие две недели я доказывал себе, что эти 9% — не прибыль, а артефакт измерения, причем четыре раза подряд. Параметрика, риск-слой, LLM-как-трейдер, FLB-харвест. И каждый раз казалось — вот сейчас, ну вот же оно!… УВЫ.
TL;DR. Negative result. Если ждёте «как я поднял иксы» — закройте вкладку. Если интересно, как на живых (пусть и бумажных) деньгах отличить настоящий edge от артефакта измерения, и почему рынок прогнозов сопротивляется наивным подходам — добро пожаловать. Код открыт, цифры воспроизводятся.
Эпиграф для внимательного: у всех четырёх провалов один общий корень. Но назову не сразу — сначала нужно почувствовать, как легко в него провалиться.
0. Что такое Polymarket и почему казалось что тут есть деньги
Polymarket — рынок предсказаний. Контракт торгуется в диапазоне $0…$1, и цена читается как вероятность: 0.10 = «рынок оценивает шанс в 10%». Резолвится в $1 (да) или $0 (нет). Меня привлекла, так же, его прозрачность.
Гипотеза, запускающая 90% таких проектов (моего в том числе): толпа на рынках предсказаний систематически ошибается, а новостной поток + LLM позволяют поймать ошибку раньше рынка. В литературе даже есть имя для одной такой неэффективности — favorite-longshot bias (FLB): игроки переплачивают за маловероятные исходы. Бесплатный сыр, ну.
Сыр был в мышеловке (конечно жеж), а мышеловка — в моей собственной методике измерения.
1. Архитектура
Сам репозиторий
Стек намеренно скучный:
-
FastAPI — API-слой (
api). -
Aiogram 3 — телеграм-бот как фронт аналитики.
-
PostgreSQL — рынки, снапшоты цен, новости, анализы, сигналы, сделки.
-
Redis + Celery —
worker+beat: инжест новостей, снятие снапшотов, генерация сигналов, мониторинг сделок. -
Docker Compose;
seed— единственный источник правды по активной стратегии (dev-режим: БД периодически вайпается, миграций нет). -
CometAPI — доступ к LLM. Две модели: дешёвая для релевантности новостей, сильная (Sonnet 4.6) для торговых решений.
Модули (app/modules/):
news_ingestion → забор новостей, дедуп по хэшуllm_analysis → LLM оценивает новость: relevance, impact_direction, impact_strength, confidencesignal_engine → превращал анализ в "edge" и сигнал (v1–v4)paper_trading → открывал/вёл/закрывал бумажные сделки (v1–v4)llm_trader → LLM сам принимает ВСЕ торговые решения (v5)llm_scorer → измерительный инструмент: грейдит решения (v5)analytics → агрегаты для дашбордаmarket_data → клиент Polymarket (Gamma / CLOB / Data API)telegram_ui → бот-меню
В v1–v4 конвейер линейный: новость → анализ → сигнал → сделка → дашборд. Развалился он не там, где я ожидал.
2. v1–v2: болезнь time_limit
Первая рабочая версия (коммит 3ed8777) имела весь конвейер. v2 закрывала сделки по take-profit, stop-loss либо тайм-ауту удержания. Всё как у людей.
Результат v2 (n=260 закрытых):
-
+$0.21 суммарно, средняя сделка +$0.0008, winrate 49%;
-
100% сделок закрылись по тайм-ауту. TP/SL не сработали ни разу.
Сижу, смотрю на это и думаю — да быть такого не может! Ну хоть один раз! Замерил фактическую амплитуду цены за окно удержания (120 минут): медиана 0.7 п.п., максимум 7 п.п. А пороги стояли на 10/7 п.п. Пороги были математически недостижимы.
Короче — бот физически не мог по ним сработать. Я поставил TP так, чтобы он не мог сработать никогда. БРАВО 🙂
Прежде чем крутить пороги — измерь распределение того, что они должны ловить. Это видно из данных за пять минут, а не за две недели бэктеста. Но этот же вывод и завёл меня в ловушку — я решил, что проблема в порогах. Спойлер: проблема не в порогах.
3. v3: +9% за два дня, которые оказались ничем
v3 (коммит 4c2d98d) починил пороги по измеренной амплитуде:
take_profit_abs: 0.02 (было 0.10)stop_loss_abs: 0.015 (было 0.07)max_holding_minutes: 240 (было 120)default_position_size: 1.0 (было 0.1)
И стало красиво. Замер на n=1052 закрытых сделках:
-
механика ожила: TP 49%, SL 33%, time_limit 18%;
-
equity $109.03, +9% за два дня.
Если бы я остановился здесь — была бы статья «как я поднял 9% на Polymarket». Но обычно я двигался так: никогда не верить заголовочному PnL без разбивки по концентрации. И эта разбивка убила всё.
По рынкам: 2 рынка из 17 дали +$14.35, остальные 15 — −$6.10. Весь профит — в двух рынках. Главный герой:
US x Iran peace by May 31: NO, 371 сделка, winrate 94.6%, +$10.55
По цене входа: весь профит сидел в одной полосе entry_price |0.10, 0.15) = +$10.33 на 394 сделках. Уберём её — оставшиеся 660 сделок дают −$1.98.
Так что тут произошло? Бот нашёл рынок, который почти наверняка резолвится в NO (мира с Ираном к 31 мая не будет), и 371 раз перезаходил в одну и ту же near-resolved позицию, собирая детерминированный календарный распад. winrate 94.6% — не навык, а структура почти-решённого рынка.
И тут я сначала предложил гениальное: «v4 = только NO». Неправильно — это бы УСИЛИЛО концентрацию на Иране. Направление — не рычаг, хорошо что не закодил.
4. Оказалось: один корень на четыре провала
Пора назвать то, что я обещал в эпиграфе. У всех провалов было два сросшихся корня.
Первый: я измерял отметку, а не исход
Бумажная сделка «оценивается» по текущей цене рынка (mark). Открыл NO по 0.10, цена уехала на 0.08 — на бумаге у тебя +$0.02 «прибыли». Но это же не прибыль, а переоценка позиции по текущему марку! Реализованный результат известен только в момент резолюции: $1 или $0.
Почти весь «edge» в v1–v5 был артефактом измерения по марку и по дрейфу цены на горизонте +Nч, а не по тому, чем рынок реально закончился. Календарный распад почти-решённого рынка по марку выглядит как стабильная прибыль. На этом и стоят иранские +$10.55.
Корень второй: формула edge была тавтологией
Открываю app/modules/signal_engine/service.py. Смотрю как считается edge. Вот формула (сохранена в git и в докстринге текущего no-op):
sign = self._direction_sign(impact_direction) # +1 / -1strength = self._clamp01(impact_strength) # 0..1 из LLMdelta = strength * confidence * 0.5 * sign # масштаб конвикшена LLMmodel_probability = self._clamp01(market_probability + delta)edge = model_probability - market_probability
Подставляю одно в другое, пока clamp не упёрся в границу:
edge = (market_probability + delta) − market_probability = delta = strength · confidence · 0.5 · sign
Ещё разок: «edge» — это буквально собственная уверенность LLM ×0.5. Он НИКОГДА не сравнивается с исходом. То есть — замкнутый круг: модель уверена → значит есть edge → потому что модель уверена. Можно сколько угодно крутить пороги, поднимать min_edge, можно фильтровать по min_confidence. Но это не поможет, потому что величина, которую мы зовём «edge», не содержит информации о реальности. Это тавтология, замаскированная под метрику.
А вырождение clamp на краях ещё коварнее! Когда market_probability + delta упирается в 0 (низковероятный рынок, NO), clamp срезает model_probability в 0:
edge = 0 − market_probability = −market_probability
Самый большой по модулю edge — ровно у границы 0/1. А в paper_trading:
direction = "YES" if edge >= 0 else "NO"
На дешёвых лонгшотах edge всегда отрицательный → бот структурно всегда берёт NO. «100% NO на Иране» — артефакт клампа, а не стратегия, машинка по сбору распада была вшита в формулу. И вот так я её три недели принимал за альфу 🙂
А как должно было быть??
Edge на рынке предсказаний по определению — расхождение вашей независимой оценки вероятности с ценой:
edge = P_independent(event) − market_price
Оценка P_independent должна строиться БЕЗ участия рыночной цены. Варианты: базовая ставка по историческим аналогам (как часто события такого класса реально случались), внешняя предсказательная модель, ансамбль прогнозов, парсинг условий резолва. Моя формула вместо этого брала рыночную цену и прибавляла к ней конвикшен LLM. То есть P_independent была функцией от market_price, и edge схлопывался в тавтологию. Согласиться с ценой, которую толпа уже загнала в край — это, вообще то, не edge…
Если в оценке вероятности фигурирует текущая цена — это не независимая оценка, а дорогой способ согласиться с рынком.
5. v3, шестой день: волна, которую принимают за тренд
Прошло шесть дней. Equity рисовала «бычью» пилу: 100 → 93 → 104 → 96 → 108 → 98 → 111.
Соблазн назвать это растущим трендом — огромный. Особенно если ты только что выпустил релиз и хочется верить. И я в своем канале даже кликбейтовый пост писал. Тут разбивка — это суперпозиция двух процессов:
-
conc_band (полоса 0.10–0.15, та самая иранская машинка распада): +$20.1 за 6 дней, ноль стоп-лоссов в большие дни — но нерепрезентативно и истекает 31 мая вместе с резолюцией.
-
rest (настоящие направленные ставки движка): −$12.0 за 6 дней.
Equity растёт ТОЛЬКО потому, что +$20 распада обгоняют −$12 движка, а как закончится распад — закончится «тренд».
Нюанс: выкинув один день-провал (05-16: 384 стоп-лосса из 501, −$11.56), rest ≈ −$0.45 — на нормальных днях движок около нуля, но регулярно ловит неконтролируемый коррелированный хвост (~раз в 6 дней; YES-лонгшоты — спортивные фавориты + геополитика — двигаются вместе в risk-off дни). Тут нет ни edge, ни контроля хвоста.
6. v4: строим риск-слой и получаем неопровержимую улику
Решил добавить структурный риск-слой, не трогая пороги (коммит 720e642). Три гварда в paper_trading:
daily_loss_limit_abs = 5.0 # дневной ранний стопmax_trades_per_market_per_day = 10 # потолок перезаходов в один рынокmax_same_direction_open = 10 # анти-корреляционный гвард
v4 не создаёт edge — она снимает маску концентрации, чтобы стала видна истинная ожидаемость движка. Замер v4 (n=288 за ~5 дней), и доказательства её отсутствия:
(1) Та же ставка — перевёрнутый знак. Тот самый иранский рынок:
US x Iran peace by May 31: v3: +$10.55, winrate 94.6% v4: −$2.80, winrate 16.7%
Тот же рынок и тот же движок, а знак перевернулся за дни.
В v3 он ловил удачу распада, в v4 потолок перезаходов это убрал, и «навык» испарился. Был бы это edge — он бы не зависел от того, разрешил ли я заходить 371 раз или 10, dtlm edge от количества заходов не зависит, а сбор премии распада — да.
(2) Бимодальный winrate. Рынки кучкуются на 62–100% ИЛИ 0–17%. Ни одного в зоне «навыка» 45–58%. Это лотерея направления дрейфа, а не предсказание.
(3) Профит снова концентрирован: 2 рынка (Spurs +$3.64, Iran-2027 +$1.56) = +$5.2, весь остальной стакан = −$2.32.
Неожиданный прикол — иллюстрация закона Литтла: потолок перезаходов срезал rate входов ~в 9 раз, и среднее число открытых позиций упало с 16 до 3. «16 открытых» в v3 были не диверсификацией.
Вывод: параметрическая глава закрыта. Никакая настройка порогов / направления / размера не создаёт edge — проблема выше по течению, в фейковой формуле.
7. v5: «Отдадим всё LLM» и нарвёмся на инверсную калибровку
Логичный шаг: убрать фейковую формулу совсем. v5 (коммит ea1847a) — параметрический торговый код выходит на пенсию (signal_engine и paper_trading — inert no-op), а ВСЕ решения (открыть/закрыть/держать/изменить, сторона, размер, риск) принимает LLM-трейдер. Ноль кодовых риск-лимитов, единственный инвариант — не заполнять сделку по невалидной цене, это защита от мусорного PnL. Каждое решение логируется в новую таблицу llm_decisions.
Первый же поведенческий сигнал (n=5) был ну прям дежавю: LLM сам, за часы, переоткрыл ловушку распада. Все 4 позиции NO на низковероятных рынках (p0 = 0.295, 0.155, 0.152, 0.008). Позиция по 0.008 — это максимум +$0.08 против −$9.92 риска! Справедливости ради, одно его решение было корректным hold с формулировкой «цена уже у пола, edge нет». То есть распознать ловушку он МОЖЕТ, просто непоследовательно. Ну прям как я!
Замер v5 показал инверсную калибровку: в зоне core (p0 0.15–0.85) рынок шёл против решений модели ~70% времени. В полосе максимальной уверенности [0.70, 0.85] — 1 из 10 благоприятных на +1ч и 0 из 9 на +4ч. То есть — модель ошибалась сильнее всего там, где была увереннее всего.
Честная оговорка, без которой раздел разваливается. Я только что (раздел 4) объявил: мерить надо ИСХОД, а не марк или дрейф на +Nч, и тут же строю вердикт v5 ровно на горизонтах +1ч/+4ч. То есть на марках, тот же самый корневой баг измерения.
Поэтому вот что:
-
n=18 направленных решений — это не выборка для калибровочного утверждения. На 18 точках любой паттерн чувствителен к 1-2 рынкам. «p ≈ 0.2%» формально считается, но статистически это сигнал, а не доказательство — для устойчивого вывода нужен n ≥ 100.
-
Разбивку по рынкам я привести не могу — серверную БД v5 я стёр до того, как осознал важность пересчёта к исходам. Тут так: если те 18 решений были по 3-5 рынкам — я мерил удачу на этих рынках, а не калибровку модели. Это ограничение, и я его не закрываю 🙁
-
Поэтому снижаю риторику: v5 дала сигнал инверсной калибровки на марк-горизонтах, согласующийся с последующим честным замером, однако сам по себе он недостаточен. Чистый вердикт дал только replay к резолюции в v6, вот именно осознание слабости v5-замера и заставило меня построить v6 правильно.
Заголовочная equity v5 ($85.66 → $108.33 за неделю) — шум марка на n=18.
8. v6: последняя честная гипотеза и как её правильно убить
Я смешивал два утверждения:
-
(A) «модель умеет прогнозировать» — опровергнуто;
-
(B) «входы fade-the-longshot, к которым вёл клампа, имеют реализованный edge» — а вот это к резолюции ни разу чисто не мерилось.
FLB — реальная вещь из литературы! Может, иранские +$10.55 были настоящим харвестом FLB, просто я случайно его собирал? Два победителя — это survivorship, не доказательство, это надо проверить чисто!
Математика всё решает, ибо царица наук
Продать YES-контракт по цене p = взять сторону NO. Выплата: +p, если резолв NO (вероятность 1−q), и −(1−p), если YES (вероятность q), где q — эмпирическая частота срабатывания лонгшота. Ожидание на контракт:
EV = (1−q)·p + q·(−(1−p)) = p − q
+EV тогда и только тогда, когда p > q. То есть лонгшоты систематически ПЕРЕоценены. Чистый тайм-распад — мартингейл, в ноль на справедливой книге. Edge ограничен размером мисприсинга и ОБЯЗАН побить спред! Ну обязан же…
«Починим правилами, чтобы увернуться от хвоста» — самоподрыв: отфильтровать «новостные» лонгшоты = протащить обратно claim-A («модель умеет прогнозировать новости»), уже мёртвый.
Survivorship-free replay
Офлайн-харнес app/research/flb_replay.py (коммит 04a706a) не ходит в БД и ничего не пишет — только читает публичный API. Реальная воронка (числа из реального прогона):
2100 закрытых рынков, вытянутых из Gamma (closed=true, по убыванию объёма)1202 бинарных Yes/No1202 резолвнулись чисто в ~0/1 (ambiguous: 0, malformed: 0)1176 с YES-токеном, датой резолва и объёмом ≥ $10k 400 топ по объёму — прогон сэмплил их (max_markets) 48 имели тик цены в полосе [0.05, 0.15] с runway (7, 90]d → сработали
Для каждого сработавшего: вход — первая точка в полосе (ex-ante, исход не подсматривается), скоринг — к РЕАЛЬНОЙ резолюции из outcomePrices. Чистые функции покрыты юнит-тестами (tests/unit/research/test_flb_replay.py): парсинг исходов, ex-ante вход без look-ahead, тождество mean_pnl == p̄ − q при нулевом спреде.
Базовый якорь: по всем 1202 бинарным рынкам безусловный YES-rate = 318/1202 = 26.5%. Триггер «лонгшот» опускает q до 10–21% — то есть он действительно отбирает низковероятные рынки, как задумано. Ну это я хотя бы не наврал!
Три прогона — и приговор
|
прогон |
вселенная / вход |
n |
p̄ (цена) |
q (выбило YES) |
gross edge |
@ спред 2c |
|---|---|---|---|---|---|---|
|
исходный |
ликвид, earliest-in-band |
48 |
0.104 |
0.208 |
−0.105 |
−0.11 |
|
stable |
ликвид, сидит в полосе ≥14д |
52 |
0.081 |
0.096 |
−0.015 |
−0.025 |
|
tail |
ликвид, vol $2k–50k** |
58 |
0.111 |
0.103 |
+0.008 |
−0.002 |
Что тут вообще:
-
Ликвид — анти-FLB. Лонгшоты по ~10% выбивали YES в 20.8%. То есть они НЕДОоценены, а не переоценены. Тут фейд теряет −0.105 на контракт, а ликвид — единственное место, где можно реально разместить капитал.
-
Фильтр стабильности работает как сигнал, но приземляется на справедливую цену. Требование «цена сидела в полосе ≥14 дней» (это стилман моего же v6-правила про календарный распад без новостей) срезало q с 0.208 до 0.096 — вычистило climbers и news-волатильность. Фильтр молодчик, короче! Но q (9.6%) ≈ p̄ (8.1%): премии для «страховщика» под спокойными лонгшотами нет, цена справедливая.
-
Остаток FLB живёт в illiquid-хвосте (p̄ 11.1% > q 10.3%) — ровно как предсказывает теория (шарпам невыгодно чинить мелкие рынки). Но он (а) статистически ноль (при n=58 σ(q) ≈ 0.039, edge 0.0078 ≈ 1/5 сигмы), и (б) экономически мёртв.
Ограничения, к которым я пришел:
-
outcomePricesпринимаются как истина без аудита UMA-историй. UMA-резолв исторически имел спорные кейсы (определения «happens», временны́е границы, ручные оверрайды). В моей видимой выборке 0% неоднозначных резолвов — но это потому, чтоclosed=trueпо построению отдаёт только формально-резолвнутые, а диспьюты я не аудировал. -
Selection bias вселенной. Воид/отменённые/зависшие-нерезолвнутые лонгшоты в
closed=trueне попадают вовсе и их долю отсюда не видно, ведь лонгшоты снимаются чаще среднего — значит часть вселенной я просто не вижу. Направление биаса, скорее, консервативно к моему выводу: если воиднутые лонгшоты — это в основном несостоявшиеся события (были бы NO), их исключение завышает измеренный q и делает мой анти-FLB-результат ещё пессимистичнее для стратегии, но без аудита пропущенного это догадка. -
Earliest-in-band — оптимистичная цена входа. Я вхожу в момент первого касания полосы, но в реальной торговле сигнал был бы позже (увидеть → подтвердить → исполнить), а на illiquid-рынках разница в днях — это другая цена и другой q. Sensitivity по delayed-entry я не гонял, приведённый gross edge — это ВЕРХНЯЯ оценка, лучший случай для стратегии и даже верхняя оценка ≤ 0 после спреда.
-
Спред в хвосте занижен референсом. Брейкивен illiquid-прогона = 2 × gross = 2 × 0.0078 ≈ 0.0156 (1.6c). В модели платишь полспреда на входе и держишь до резолюции, без спреда на выходе, а на лонгшотах с объёмом $2–10k реальный bid-ask чаще 8–20c плюс слиппедж от собственного ордера. Вот вам точная формулировка: edge мёртв при любом реалистичном спреде — точка безубыточности 1.6c, а такого спреда на этих рынках не бывает.
v6 не построен. Закрыт ДО единой строчки торгового кода.
9. Технические засады в API Polymarket
Несколько вещей, на которых я потерял время:
-
Gamma кодирует списочные поля как JSON-строки.
outcomes,outcomePrices,clobTokenIdsприходят строками вида'["Yes", "No"]'. Нужен ручнойjson.loads. Прям как в нулевых. -
Gamma отдаёт 422 на большом offset. Это конец пагинации, не ошибка! Ловите и останавливайтесь.
-
CLOB
/prices-historyрежет окно ~14 днями независимо отfidelity.interval=max/1d/1wдля тестовых токенов возвращал пусто. Лечится чанкингом по 13 дней со склейкой и дедупом по timestamp. Голыйexcept: returnэто глушил и давал «0 сработало». -
Offset-пагинация упирается в ~2100 строк на направление. Mid-tail (vol $2k–50k) сидит МЕЖДУ «верхними 2100» и «нижними 2100» и недостижим через offset. Достаётся серверным фильтром
volume_num_min/volume_num_max.
10. Почему это не работает: синтез
Три независимые главы — параметрика (v1–v4), LLM-как-трейдер (v5), FLB-харвест (v6) — дали no/negative edge. Складываем:
-
Не было модели. Формула edge была тавтологией (конвикшен LLM ×0.5), не сравнённой с реальностью.
-
«Прибыль» была артефактом измерения. Календарный распад почти-решённых рынков по марку маскировался под альфу; survivorship по двум победителям достраивал иллюзию.
-
LLM не спасает. Сильная модель не создаёт edge автоматически — v5 дала сигнал инверсной калибровки (на крошечной выборке).
-
FLB неторгуем. Там, где ликвидно — его нет или он обратный. Где он шепчет (хвост) — он ниже стоимости транзакции.
И сразу — чего я НЕ доказал. «Рынок эффективен» — утверждение сильнее моих данных. Я показал ровно следующее: в той части рынка, где можно разместить капитал, методы, которые я пробовал (predictive-бот на новостях + ex-ante FLB-харвест), edge не дают, но это не исключает других ниш, которые мой опыт просто не покрывает:
-
resolution arbitrage — LLM парсит точные условия UMA-резолва и ловит расхождение буквы условия с тем, как рынок его понимает;
-
cross-market coherence — арбитраж логически связанных рынков (если A⇒B, цены должны быть согласованы, и если нет — есть бесплатные деньги);
-
market making на широких спредах в хвосте.
Их держите отдельно от моего вывода — я их не трогал.
11. Что я вынес: методология дороже стратегии
Стратегии у меня нет, а вот метод — есть. И он, по-моему, ценнее самой стратегии:
-
Никогда не верь заголовочному PnL. Первое — разбивка по концентрации (по рынкам и по полосам цены входа). Один-два рынка, делающие весь результат — красный флаг survivorship. Если бы я в первый день после +9% не пошёл в разбивку, я бы реально публиковал статью о «успехе».
-
Измеряй ИСХОД, а не отметку. Единственная честная метрика — survivorship-free replay к реальной резолюции, так как марки и +Nч-дрейф врут систематически в одну сторону.
-
Перед настройкой порогов измерь распределение того, что они ловят. Если бы я это сделал в v1, не было бы v2.
-
Различай «баг измерения» и «отсутствие edge». Я честно смешал их в v3/v4 (и в v5) и потерял время. Чистый тест каждой гипотезы по отдельности экономит недели.
-
Negative result — это результат. Четыре гипотезы закрыты и могу написать об этом статью.
Контрфактическое
Ели бы я остановился на втором дне, опубликовал «+9% за два дня», вечером того же дня прочитал статью про favorite-longshot bias. И решил бы: «Ого, я случайно делаю именно это! Бесплатные деньги!». Я поверил в свой edge, и, блин, вполне возможно — занёс бы на этот рынок реальные деньги, а через две недели потерял бы их на флипе иранского рынка после первой реальной новости.
Защищает одна привычка: разбей PnL и измерь к исходу, прежде чем поверить себе.
Эта статья — лог того, как эта привычка четыре раза спасала меня от собственного оптимизма.
12. Масштаб и репозиторий
Фейковый капитал — стартовые $100, ноль реализованного edge на выходе.
Расход на LLM-токены — $20, из них $13 — Claude Sonnet 4.6 по $2.40/Mtok (трейдер-LLM). Остальное — ChatGPT 5.1 для оценки релевантности новостей.
Это 20% от paper-капитала, ушедшие на инференс ради количественного нуля. Если читать как unit economics реального проекта — даже идеальная стратегия с 20% APR на $100 капитала просто окупила бы токены, и не принесла бы ничего сверху.
Одностишная мораль для подобных проектов: слил $20 на LLM, чтобы количественно показать ноль на бумажных $100.
Открыты: код, журнал стратегий с замерами по каждой версии (docs/STRATEGY_JOURNAL.md), полный отчёт по FLB pre-mortem (docs/research/flb_pre_mortem.md) и воспроизводимый харнес.
Навигация по эволюции:
3ed8777 начальный конвейер (v1/v2)4c2d98d v3: пороги по измеренной амплитуде720e642 v4: структурный риск-слойea1847a v5: pivot на LLM-as-traderc9722f3 v5: скорер (калибровка + edge)04a706a v6: survivorship-free FLB replay
Проект разрабатывался в плотной паре с Claude Code — это не вайбкодинг ради хайпа! Вся аналитика, замеры, разбор кода и формулировки — мои, но писались и проверялись в диалоге. Результаты подобных экспериментов и мысли выкладываю тут
ссылка на оригинал статьи https://habr.com/ru/articles/1039642/