Идея коротко
Tom Basso хотел показать, как мало значит точка входа. Он взял 20 фьючерсов, около 10 лет дневных данных и заменил сигнал монеткой. Если на закрытии дня позиции нет, бросаем монетку: орёл покупаем утром, решка продаём. Дальше позицию ведёт механический трейлинг-стоп на 1 или 2 ATR (сам Basso точно не помнит). Размер задаёт одинаковый процент риска от текущего капитала.
Один прогон с монеткой ничего не доказывает, поэтому он запустил цикл из 1000 прогонов и усреднил результаты. По его словам, каждая такая серия в среднем давала прибыль. Вывод Basso: одержимость входом переоценена, а работу делают выход, размер позиции, диверсификация и тысячи сделок.
Эта карточка не про торговую систему. Это эксперимент и эталон: с ним можно сравнить любой вход и понять, добавляет ли он что-то сверх выхода и размера.
Почему это может работать
Логика Basso такая. Задача трендовой системы быть в каждом крупном движении, а поймать сегодняшний обвал мог любой сигнал, поставивший в шорт позавчера или в пятницу. Трейлинг-стоп быстро режет сделки, которые пошли не туда, и оставляет те, что пошли в нашу сторону. Равный риск не даёт одной сделке испортить результат, а 20 рынков дают достаточно сделок, чтобы преимущество проявилось.
Оговорка Finetiq важнее самого вывода. Если в ценах нет трендов, правило выхода само по себе не создаёт положительного ожидания: на случайном блуждании средний результат такой системы равен нулю до издержек и отрицателен после. Значит, прибыль в эксперименте Basso это тренды, которые были в этих 20 рынках за эти годы, собранные трейлинг-стопом. Эксперимент показывает, что вход не главное для трендовой системы на трендовых рынках. Утверждения «вход не важен вообще» из него не следует.
Правила
Эксперимент (автор, параметры Finetiq)
// дневные бары, каждый рынок портфеля считается отдельно
IF MarketPosition = 0 на закрытии дня
U = Coin(Seed, MarketId, BarDate) // Finetiq: случайное число 0..1, см. блок ниже
IF U < 0.5 THEN BUY AT NEXT BAR OPEN // автор: орёл, покупка утром
ELSE SELL SHORT AT NEXT BAR OPEN // автор: решка, продажа
ATRn = ATR(21) // Finetiq: 21, как ATR в Keltner у автора
k = 2 // автор: «1 или 2 ATR», помнит неточно
// трейлинг-стоп подтягивается только в сторону сделки (автор: «тянул за ценой»)
Long: Stop = MAX(Stop[1], Close - k * ATRn) // Finetiq: от закрытия бара
Short: Stop = MIN(Stop[1], Close + k * ATRn)
SELL STOP at Stop // лонг
BUY STOP at Stop // шорт
// после выстрела стопа позиции нет, на ближайшем закрытии снова монетка (автор)
// цели нет: выход только по стопу (автор)
Размер позиции (автор, процент Finetiq)
RiskMoney = Equity * 0.5% // автор: одинаковый % текущего капитала
// Finetiq: 0.5%, как стартовый риск в текущей торговле автора
Contracts = floor(RiskMoney / (k * ATRn * PointValue))
// Finetiq: Equity = закрытые сделки + открытая прибыль по всем рынкам, считается перед каждым входом
// Finetiq: если Contracts = 0, сделка пропускается и счётчик пропусков пишется в отчёт
Воспроизводимость: зерно, много прогонов, распределение (Finetiq)
// 1. монетка как функция от (зерно, рынок, дата), а не очередной вызов генератора
Coin(Seed, MarketId, BarDate) = Hash(Seed, MarketId, BarDate) / HashMax
// последовательный генератор ломает сравнение: другой выход даёт другое число сделок,
// и все следующие монетки сдвигаются. Хеш даёт тот же бросок в тот же день при любом выходе
// 2. серия прогонов
FOR Seed = 1 TO 1000
прогнать весь портфель
записать: итог после издержек, CAGR, MaxDD, число сделок, % прибыльных, итог по рынкам
// 3. читаем распределение, а не среднее
Median, P5, P95 для итога и MaxDD
ShareProfitable = доля прогонов с итогом > 0 после издержек
// 4. сравнение вариантов: те же 1000 зёрен, меняется только одно правило
// (множитель стопа, сайзинг, список рынков). Разница считается попарно по каждому Seed
Применение к карточке turtle-4w-2w
// A: черепахи как есть. Вход на пробое 20 баров, выход по 10-барному экстремуму, одинаковый риск
// B: тот же выход и тот же риск, вход по монетке, Seed = 1..1000
Percentile = доля прогонов B, у которых итог хуже, чем у A
// A выше 95-го перцентиля B: пробой 20 баров добавляет эдж сверх выхода
// A в середине распределения B: результат делают выход и размер
// Finetiq: у B монетка бросается только в дни, когда A тоже мог бы войти (нет позиции),
// иначе B проводит в рынке больше времени и сравнение нечестное
Параметры
| Параметр | Значение | Откуда |
|---|---|---|
| Рынки | 20 фьючерсов | автор |
| История | около 10 лет, дневные бары | автор |
| Вход | монетка на закрытии без позиции, исполнение утром | автор |
| Выход | трейлинг-стоп на k ATR, без цели | автор |
| Множитель k | 1 или 2 | автор (помнит неточно) |
| Период ATR | 21 | Finetiq (как в Keltner автора) |
| Расчёт трейлинга | от закрытия, только в сторону сделки | Finetiq |
| Риск на сделку | одинаковый % текущего капитала | автор |
| Процент риска | 0.5% | Finetiq (стартовый риск в торговле автора) |
| Число прогонов | 1000 | автор |
| Итог серии | среднее | автор |
| Итог серии в карточке | медиана, 5-й и 95-й перцентили | Finetiq |
| Источник случайности | хеш от зерна, рынка и даты | Finetiq |
Что проверить
- Распределение после издержек. Повторите 1000 прогонов с комиссией и проскальзыванием в один тик на вход и выход. Смотрите медиану и долю прибыльных прогонов, а не среднее: несколько удачных зёрен тянут среднее вверх.
- Контроль на данных без трендов. Перемешайте дневные изменения цены каждого рынка и прогоните те же 1000 зёрен. Прибыль должна исчезнуть. Если она осталась, в коде заглядывание вперёд или ошибка расчёта стопа.
- Множитель и период ATR. k = 1, 2, 3 и период 10, 21, 50 на одних и тех же зёрнах. При k = 1 сделок в разы больше, и издержки весят сильнее.
- Сайзинг. Равный процент риска против одного контракта на рынок, те же зёрна. Так видно, какую часть результата даёт размер, а какую выход.
- Периоды и рынки. Разбейте историю на отрезки по 5 лет и прогоните отдельно. Затем 1, 5 и 20 рынков. Basso опирался на портфель: на одном рынке разброс по зёрнам будет огромным.
- Эталон для своей стратегии. Схема из блока «Применение»: где итог вашей системы лежит в распределении случайного входа с тем же выходом и тем же временем в рынке.
Особенности платформ
TradingView (Pine Script)
math.random(min, max, seed)с заданнымseedдаёт повторяемую последовательность. Но это последовательный генератор: при другом выходе монетки сдвинутся. Для попарного сравнения считайте свой хеш от зерна иtime.- Стратегия торгует только символ графика, портфельного теста нет (раздел 5 справочника). Эксперимент на 20 рынках в Pine не повторить, только по одному рынку.
- Штатного перебора входных параметров в тестере стратегий нет. 1000 зёрен вручную нереальны, поэтому выгружайте сделки и собирайте распределение вне платформы.
- Трейлинг в
strategy.exit(trail_points, trail_offset)задаётся в тиках. ATR-стоп надёжнее передавать ценой черезstop =, пересчитывая на каждом баре.ta.atrсглаживает по Уайлдеру.
MultiCharts и TradeStation (EasyLanguage)
- У встроенной функции
Randomзадаётся только верхняя граница, зерна в параметрах нет, и одинаковая последовательность между запусками не гарантирована. Для воспроизводимости напишите свой генератор от входаSeed, номера рынка и даты, например линейный конгруэнтный на целых числах в пределах точности double. - 1000 прогонов делаются оптимизацией по входу
Seedот 1 до 1000: отчёт оптимизации и есть таблица результатов по зёрнам. - Портфель из 20 рынков с общим капиталом нужен для правила «процент от текущего капитала». Это Portfolio Maestro или Portfolio Trader. Проверьте, поддерживает ли ваша версия портфельного модуля перебор входов, иначе выгружайте сделки по каждому зерну.
AvgTrueRangeэто простое среднее TrueRange, а не Уайлдер. Стоп ставьте ценой:Sell next bar at StopPrice stop, ордер отправляйте на каждом баре.
MetaTrader 5 (MQL5)
- Генератор:
MathSrand(Seed)вOnInitиMathRand(). Для попарных сравнений лучше тот же хеш от зерна, символа и даты бара, что и на других платформах. - Перебор
Seedот 1 до 1000 делается оптимизацией в тестере. Нужен полный перебор: генетический алгоритм пропустит часть зёрен. - Мультисимвольный режим тестера позволяет вести 20 символов одним советником. У брокера должны быть все рынки, а у CFD на фьючерсы история часто короче 10 лет.
iATRэто простое среднее TR. Размер лота из риска:SYMBOL_TRADE_TICK_VALUE,SYMBOL_TRADE_TICK_SIZE, округление доSYMBOL_VOLUME_STEP. На малом счёте многие сделки округлятся в ноль лотов.
Где идея может сломаться
- Сам Basso называет такой способ торговли глупым и считает, что индикаторы добавляют немного пользы. Это демонстрация, а не стратегия.
- Цифр нет. Мы знаем только, что среднее по 1000 прогонам было положительным. Каким был разброс, худший прогон, просадка и учитывались ли издержки, в интервью не сказано. Число лет Basso называет по памяти.
- Результат зависит от трендов в конкретных 20 рынках за конкретное десятилетие. На другом отрезке или на рынках без устойчивых трендов случайный вход с трейлингом может дать ноль или убыток после издержек.
- Множитель стопа неизвестен точно. Между 1 и 2 ATR число сделок и вес издержек различаются в разы.
- Случайная система почти всё время в рынке: после стопа позиция открывается уже на следующий день. Сравнивать её со стратегией, которая большую часть времени вне рынка, без выравнивания экспозиции некорректно.