В прошлый раз я рассказывал, как моя платформа забраковала все 231 стратегии, которые я в неё загнал. Там был абзац про данные, который я сам назвал самой скучной частью проекта и проскочил в пять строк.
Соврал. Это не скучная часть. Это и есть проект.
Скачать тридцать лет дневных котировок по американским акциям — вопрос одного вечера и трёх строк на Python. Бесплатно, без регистрации. Дальше начинается интересное: эти данные врут, и врут они ровно в ту сторону, в которую вам приятно.
Расскажу, где именно, — по всем ловушкам, в которые я успел свалиться.
Ловушка первая: цены, которых никогда не былоВы качаете Adj Close и радуетесь: цены уже скорректированы на сплиты и дивиденды, считать доходность удобно. Проблема в том, что скорректированная история переписывается задним числом. Прошла выплата дивиденда — и все цены до неё сдвинулись. Был сплит — сдвинулись ещё раз.
Практический смысл: цена, которую вы видите в исторической строке за 2003 год, никогда не появлялась ни на одном экране. По ней нельзя проверить, сработал бы стоп. Нельзя понять, пробила ли бумага круглый уровень. Нельзя посчитать проскальзывание — вы считаете его от числа, которого не существовало.
Пришлось держать два ряда параллельно: 16 921 596 скорректированных котировок для расчёта доходности и 15 382 482 сырых, нескорректированных — для всего, что связано с исполнением. Плюс отдельно события корпоративных действий, чтобы одно можно было получить из другого и сверить.
Ловушка вторая: в вашей выборке нет покойников«Тестирую на акциях S&P 500» звучит солидно. Вопрос: состав индекса вы взяли какой? Сегодняшний.
А в сегодняшнем нет Enron, нет Lehman, нет Bear Stearns и ещё пары сотен компаний, которые за тридцать лет обанкротились, были поглощены или тихо ушли с биржи. Ваша стратегия торгует исключительно теми, кто гарантированно дожил до 2026 года. Это не бэктест, это машина времени с читом.
Лечится только одним способом: покойников надо вернуть в выборку. Я вытащил 1 083 делистинга из формы SEC Form 25 — официального уведомления о снятии бумаги с торгов — и восстановил исторические составы индекса на каждую дату. Не «какие бумаги в индексе», а «какие бумаги были в индексе именно в тот день прошлого».
Разница на глаз не видна. На результатах видна прекрасно.
Ловушка третья: отчётность, которой ещё не былоЭта ломает пополам всё фундаментальное. Квартальная прибыль лежит в базе с датой окончания квартала — 31 марта. Ваш бэктест честно берёт её 31 марта и принимает решение.
В реальности отчёт публикуется недели через три-четыре после закрытия квартала. Всё это время рынок его не знает. А ваша стратегия — знает.
Единственное лекарство — хранить фундаменталку point-in-time: с привязкой не к отчётному периоду, а к дате, когда цифра стала публичной. У меня это 2 830 167 записей из SEC EDGAR, и каждая знает свой день рождения.
Ловушка четвёртая: доходность, которая не полнаяСравниваете эквити стратегии с графиком S&P 500 и выигрываете? Поздравляю, вы выиграли у индекса без дивидендов. Это фора примерно в полтора-два процента годовых, подаренная вам просто так.
Мелочь? На тридцати годах это разница между «обогнал рынок» и «не обогнал».
Ловушка пятая, техническая: бесплатные источники молчат, когда врутВсе четыре ловушки выше — методологические, про них хотя бы пишут. А есть пятая, про которую не пишет никто, потому что она неинтересная.
Бесплатный источник данных иногда отдаёт мусор. Не падает с ошибкой — просто отдаёт: пропущенный день, нулевой объём, цену закрытия ниже минимума дня, тикер, который сменил владельца и теперь означает другую компанию. Если вы качаете данные скриптом раз в сутки, вы этого не заметите никогда.
Пришлось строить конвейер с несколькими источниками — yfinance, Stooq, SEC EDGAR, FRED — и автопереключением между ними, когда один замолчал или начал спорить с другим. И отдельно набор проверок целостности, который ругается на физически невозможные свечи.
Как понять, что данные всё-таки не врутСамая полезная вещь, которую я построил, — не конвейер, а автотест на тождество: сырая цена плюс все дивиденды и сплиты за период обязаны сойтись с полной доходностью. Это замкнутая проверка: если хоть где-то потерялась корпоративная выплата или задвоился сплит, равенство разъезжается.
Сходится с расхождением меньше десятой доли процента годовых. Именно этот тест ловил мои ошибки чаще всего — и, в отличие от меня, он не устаёт и ничего не хочет доказать.
Во что это вылилось по объёмуОколо 39 миллионов записей в аналитических слоях: котировки в двух видах, фундаментальные показатели, размеченные паттерны, факторные оценки. Тридцать лет, 5 264 тикера, 1996–2026.
И вот теперь — главное, ради чего я это всё пишу.
Данные — это не подготовка к исследованиюМне казалось, что загрузка данных — скучный подготовительный этап перед настоящей работой: генерацией стратегий, оптимизацией, поиском грааля. По времени вышло наоборот. Конвейер данных занял в разы больше, чем всё остальное вместе взятое.
И только благодаря ему результат прошлого поста чего-то стоит. Когда я говорю «из 231 кандидата не прошёл никто» — это утверждение имеет смысл ровно настолько, насколько честны данные под ним. На кривых данных я бы нашёл граали. Много. Красивых. Они бы даже работали — на бумаге, до первого реального ордера.
Если строите своё, короткий чек-лист, который сэкономит вам полгода:
1. Храните сырые цены рядом со скорректированными. Всегда.
2. Верните в выборку тех, кто умер. Их отсутствие — самая дорогая ошибка из всех.
3. Фундаменталку привязывайте к дате публикации, а не к отчётному периоду.
4. Сравнивайтесь с полной доходностью индекса, а не с ценовым графиком.
5. Сделайте один замкнутый автотест на тождество данных — он найдёт то, что вы не догадаетесь проверить.
Это не гарантирует, что вы найдёте прибыльную стратегию. Это гарантирует другое: если не найдёте, то узнаете об этом за компьютером, а не на брокерском счёте.
—
Про кухню, если интересно: headless-база на 1С (сто с лишним объектов, ноль форм, всё через HTTP-API) + Python для расчётов + LLM-агент в Telegram, через которого я гоняю бэктесты. Ордера уходят брокеру только после подтверждения кнопкой — никакого автопилота. Разбор архитектуры с картинками: tezbase.kz/keysy/stratlab-kvant-platforma-na-1c
Дисклеймер: личный исследовательский проект, режим paper-trading. Не инвестиционная рекомендация.
Я не использую фундаментал и мне было проще. А сейчас совсем просто — волевым усилием отказался от идеи торговли американских акций. Пока готовлю инструмент только для QQQ. И не знаю, придет ли его время.
Сколько акций у Вас в базе, кстати.
Но чтобы этот состав вообще восстановить, нужны все 5 264: пока не сложишь входы, выходы и делистинги, не узнаешь, кто и когда в индексе был. Плюс широкий срез работает как контроль: если эффект жив только на узком списке, это чаще подгонка, чем находка.
«У лисы 33 уловки от собак, а у кошки только одна» ©