Перейти к содержимому
Все стратегии

Стратегии

Точный перенос FMZ «Python ML: SVM предсказывает покупку/продажу» (автор Zero): скользящий линейный классификатор направления следующего бара на SVM 3 классов по исходным [Open, Close], длинная/короткая позиция/вне рынка, SpreadVal=2, BTCUSD_PERP.BINANCE_CM 1H

Итог: Отменено

BtcCmLinearSvmNextBarDirection

Сводка по итогам

В этой гипотезе реализован FMZ скользящий линейный классификатор SVM направления следующего бара для бессрочного контракта Binance COIN-M BTC с периодом 1H; заранее была заявлена близкая к нулю прогнозная доходность. После 2 итераций бэктест дал 1,408 сделок со средним результатом -0.129% на сделку, PF 0.80 и коэффициентом Шарпа -0.38; счёт был ликвидирован с доходностью -100%, тогда как стратегия «купи и держи» BTC выросла примерно на 3x. Аналитик отказался от неё при проверке бэктеста до оптимизации, поскольку нулевое валовое преимущество не покрывает торговые издержки. Аналитик также отметил неправдоподобные суточные колебания COIN-M MTM и противоречивые даты ликвидации для проверки движка, указав, что они не меняют знак преимущества.

Гипотеза

Точный перенос стратегии FMZ Quant с открытым исходным кодом «Python 机器学习之 SVM 预测买卖» автора Zero (https://www.fmz.com/strategy/21370;; исходные данные: Bitfinex BTC_USD, бары по 1 ч). Благодарность автору. Описание механизма своими словами: на каждом новом часовом баре линейный классификатор опорных векторов обучается заново с нуля на недавней истории баров. Каждый обучающий пример — это прошлый бар i, его вектор признаков из двух ценовых уровней RAW [open_i, close_i] (без масштабирования и доходности) и метка……Показать большеСвернуть

Точный перенос стратегии FMZ Quant с открытым исходным кодом «Python 机器学习之 SVM 预测买卖» автора Zero (https://www.fmz.com/strategy/21370;; исходные данные: Bitfinex BTC_USD, бары по 1 ч). Благодарность автору. Описание механизма своими словами: на каждом новом часовом баре линейный классификатор опорных векторов обучается заново с нуля на недавней истории баров. Каждый обучающий пример — это прошлый бар i, его вектор признаков из двух ценовых уровней RAW [open_i, close_i] (без масштабирования и доходности) и метка направления изменения цены закрытия бара NEXT: d = close_{i+1} - close_i: класс UP, если d > SpreadVal, класс DOWN, если d < -SpreadVal, иначе класс FLAT; SpreadVal = 2 (единицы цены, USD) — в точности как в исходнике. Затем обученная модель классифицирует [open, close] последнего бара как UP/DOWN/FLAT, и прогноз задаёт единственную позицию: лонг, шорт или без позиции. Изменены только следующие параметры: площадка и инструмент заменены с спота Bitfinex BTC_USD на BTCUSD_PERP.BINANCE_CM (обратный бессрочный контракт Binance COIN-M). Котировка также ведётся в USD за BTC, поэтому SpreadVal=2 сохраняет исходный смысл единиц; у инструмента самые низкие из наших площадок расходы за полный круг сделки (~0.06% против ~0.10% USD-M), что важно для стратегии с почасовой сменой позиций. Также это заполняет недостающую квоту категории COIN-M (3.2% против целевого значения >=5%). BTC сохранён, несмотря на концентрацию корпуса, только потому, что исходная стратегия относится к типу BTC_USD, а пользователь запросил точный перенос. Размер позиции переведён с «половины начального счёта» на 50% от текущего номинала капитала при плече 1.0. Классификатор реализован на numpy, поскольку импорт sklearn в песочнице запрещён. Это повторная реализация sklearn svm.LinearSVC со стандартными параметрами. Исходник работает на текущем, ещё формирующемся баре FMZ: при обнаружении нового бара используются [open, close] только что открытого бара (где close примерно равен open). В нашем движке, работающем на закрытии бара, эквивалентный расчёт на момент времени использует только что CLOSED бар t как входные данные для прогноза. Обучающие пары — это (признаки бара i, метка по close_{i+1} - close_i), где бар i+1 уже закрылся, поэтому заглядывания вперёд нет. Важное замечание: SpreadVal=2 USD при цене около $60k-120k BTC составляет примерно 0.002%, поэтому класс FLAT возникает почти никогда, и модель фактически представляет собой бинарный классификатор роста/падения на ценовых уровнях. Исходные уровни [open, close] практически не несут информации о знаке следующего часового изменения. Вывод фабрики L167 предсказывает, что это семейство точных переносов погибнет при fee_edge. Стратегия предложена по прямому запросу пользователя на точный перенос; решение принимает бэктест с реальными комиссиями. Прогноз ниже заранее зафиксирован как почти нулевое преимущество.

Итерация 2 устраняет критический дефект размера позиции QA, не меняя ничего другого. Сигнал, метки, решатель и логика входа и выхода остаются прежними. На BINANCE_CM обратный PnL, комиссии и влияние на цену учитываются в BTC, поэтому get_account_equity() (баланс в USD) не менялся, а размер каждой сделки составлял около $50k вплоть до ликвидации портфеля. Теперь position_size() использует USD собственный капитал по рыночной оценке: стабильный баланс плюс разница между текущим балансом BTC и балансом BTC,……Показать большеСвернуть

Итерация 2 устраняет критический дефект размера позиции QA, не меняя ничего другого. Сигнал, метки, решатель и логика входа и выхода остаются прежними. На BINANCE_CM обратный PnL, комиссии и влияние на цену учитываются в BTC, поэтому get_account_equity() (баланс в USD) не менялся, а размер каждой сделки составлял около $50k вплоть до ликвидации портфеля. Теперь position_size() использует USD собственный капитал по рыночной оценке: стабильный баланс плюс разница между текущим балансом BTC и балансом BTC, зафиксированным на первом баре до первой сделки, умноженная на текущую цену. При расчёте размера позиции стратегия всегда вне рынка, поэтому нереализованный PnL равен нулю. Номинал ограничивается минимумом из (position_frac x MTM x плечо, MTM), округляется вниз до целого числа контрактов по $100, а функция возвращает 0, если MTM <= 0. Базовый баланс в монете хранится в обычных скалярных атрибутах (_coin0, _coin0_set), поэтому сохраняется после перезапуска. Ожидаемый эффект: номинал позиции уменьшается вместе с убытками, avg_position_pct должен составлять около 50% от капитала MTM вместо примерно 97%, а портфель 1x больше нельзя ликвидировать. Разворот с выходом на один бар и переопределение min_bars_required оставлены такими, какими их принял QA. Честное ожидание, зафиксированное заранее: PnL до издержек примерно безубыточен, а около 1,800 сделок туда и обратно при издержках около 0.06% RT делают это измеренной проверкой несостоятельности fee_edge, а не поводом для настройки.

negative_expectancy: точный перенос FMZ «SVM предсказывает покупку/продажу» (Zero) на BTCUSD_PERP.BINANCE_CM 1H. На 1,408 сделках avg_trade_return_pct составляет -0.129% (нижняя граница COIN-M — +0.10%), PF составляет 0.80, а коэффициент Шарпа — -0.38. Счёт был ликвидирован (total_return -100%), и стратегия понесла убытки в каждом режиме волатильности. Убыток на сделку примерно равен стоимости сделки тейкера туда-обратно плюс влиянию на цену, поэтому PnL до затрат примерно равен нулю: исходные уровни цен в……Показать большеСвернуть

negative_expectancy: точный перенос FMZ «SVM предсказывает покупку/продажу» (Zero) на BTCUSD_PERP.BINANCE_CM 1H. На 1,408 сделках avg_trade_return_pct составляет -0.129% (нижняя граница COIN-M — +0.10%), PF составляет 0.80, а коэффициент Шарпа — -0.38. Счёт был ликвидирован (total_return -100%), и стратегия понесла убытки в каждом режиме волатильности. Убыток на сделку примерно равен стоимости сделки тейкера туда-обратно плюс влиянию на цену, поэтому PnL до затрат примерно равен нулю: исходные уровни цен в качестве признаков SVM не содержат информации о направлении следующего бара. Это соответствует собственному прогнозу гипотезы о почти нулевом преимуществе. Опасения QA относительно преимущества подтвердились. Оптимизация не может поднять нулевое валовое преимущество выше затрат, а перенастройка spread_val или train_bars нарушила бы требование точного переноса (выводы L120/L141). Код неудачи: fee_edge (первый измеренный отчёт). Примечание: дневной ряд COIN-M MTM показывает неправдоподобные колебания (-70%, а затем +224% в два последовательных дня при портфеле 0.5x), и liquidation_date расходится с дневным рядом. Механизм не проверен; отметьте это для проверки движка. Это не меняет знак преимущества, рассчитанного по реестру сделок.

Реализация

Точный перенос FMZ «Python ML: SVM Predicts Buy/Sell» от Zero (fmz.com/strategy/21370). На каждом закрытом баре 1H инструмента BTCUSD_PERP.BINANCE_CM модель заново обучается с нуля: это линейный SVM на numpy, эквивалентный настройкам LinearSVC по умолчанию в sklearn (квадратичная функция потерь hinge, L2, C=1, OvR, регуляризованный свободный член). Строки обучающей выборки — исходные значения [open, close] за последние 300 баров, размеченные как UP/DOWN/FLAT на основе изменения цены закрытия следующего бара с SpreadVal=2 USD. Модель классифицирует только что закрывшийся бар. Стратегия открывает длинную позицию при UP, короткую — при DOWN, а в остальных случаях не имеет позиции; размер позиции составляет 50% от текущей оценки капитала USD по рыночной цене и выражается целыми контрактами по $100.

Результаты верификации

Для точного переноса изменение кода не требуется. Аналитик должен использовать 0.10% + влияние на цену в качестве нижней границы затрат.

Несоответствие предпосылки о затратах. В гипотезе обосновывается BINANCE_CM при стоимости сделки туда-обратно около 0.06%, но для входов и выходов используются рыночные ордера базового шаблона (0.05% тейкера с каждой стороны), поэтому сделка туда-обратно стоит около 0.10% плюс смоделированное влияние на цену. Это не меняет корректность. Предварительно зарегистрированный результат fee_edge просто достигается быстрее.

Необязательно: отправь заявку на вход в противоположную сторону сразу после выхода на том же баре, если это допускает базовый шаблон.

При развороте позиция остаётся закрытой на один бар. should_exit закрывает позицию, когда прогноз отличается от текущей стороны позиции. Противоположную позицию можно открыть только на следующем баре и только если прогноз к тому моменту всё ещё такой же. В исходнике позиция сразу переворачивается на каждом новом баре. Предыдущий QA принял это. Это немного снижает экспозицию и добавляет один пропущенный бар при каждом развороте.

Убедись, что в режиме бумажной и реальной торговли восстанавливается состояние стратегии с обычными скалярными значениями, либо пересоздай базовый баланс по начальному балансу монет на счёте.

_coin0 (базовый баланс BTC) фиксируется при первом вызове calculate_signal. В строке документации сказано, что он сохраняется после перезапуска. Если при перезапуске реальной торговли его значение не восстановится, реализованный PnL в монетах до перезапуска не войдёт в капитал MTM. На бэктест это не влияет. Кроме того, в песочнице ликвидация вызвана тем, что влияние на цену учли задним числом, и капитал внутри движка этого не видит. Это ограничение тестовой системы, а не ошибка стратегии.

Песочница представляет собой завершённое измерение fee_edge, именно такое, какое было предварительно зарегистрировано в гипотезе. 3,598 сделок туда-обратно, доля прибыльных сделок 48.8%, avg_trade_return_pct -0.102%, комиссии составляют 42% от валовой прибыли. Убыток на сделку примерно равен реальной стоимости сделки туда-обратно, поэтому PnL до учёта затрат приблизительно равен нулю. PF 0.71 обусловлен затратами, а не перевёрнутым сигналом, поэтому подозрение L125 относительно полярности неприменимо. В гипотезе……Показать большеСвернуть

Песочница представляет собой завершённое измерение fee_edge, именно такое, какое было предварительно зарегистрировано в гипотезе. 3,598 сделок туда-обратно, доля прибыльных сделок 48.8%, avg_trade_return_pct -0.102%, комиссии составляют 42% от валовой прибыли. Убыток на сделку примерно равен реальной стоимости сделки туда-обратно, поэтому PnL до учёта затрат приблизительно равен нулю. PF 0.71 обусловлен затратами, а не перевёрнутым сигналом, поэтому подозрение L125 относительно полярности неприменимо. В гипотезе указано, что сделка туда-обратно COIN-M стоит примерно 0.06%, но код отправляет ордера MARKET по ставке тейкера 0.05%, поэтому реальные затраты составляют примерно 0.10% плюс влияние на цену ($44.5 тыс. всего). Результат liquidated=true / -100% не вызван размером позиции. avg_position_pct — это 41%, поэтому исправление итерации-2 MTM работает. Суммарный PnL сделок составляет около -$76 тыс., а учтённое постфактум совокупное влияние на цену в размере -$44.5 тыс. опускает кривую капитала ниже нуля. Капитал стратегии внутри движка не учитывает эти совокупные затраты. Фандинг также не моделируется (funding_events_available=0), тогда как экспозиция составляет 81%, поэтому реальный результат был бы немного хуже. Сырые уровни цен в качестве признаков SVM не содержат информации о направлении. Считайте гипотезу опровергнутой (форма L117: более 1,000 сделок, при этом PF до затрат примерно равен 1). Не перенастраивайте пороги.

Обзор бэктеста

Шарп
-0,38
Общая доходность
-100,00%
Максимальная просадка
100,00%
Всего сделок
1408
Доля прибыльных
53,6%
Профит-фактор
0,80

Перенос точный: классификатор — LinearSVC со стандартными настройками, использующий исходные признаки [open, close]. Метки строятся только по уже закрытым барам, поэтому заглядывания вперёд нет.

Выборка надёжна: 1,408 закрытых сделок (2,815 исполнений) с 2020-08 до ликвидации. Этого достаточно, чтобы точно оценить преимущество на сделку.

Доходность на сделку отрицательна. avg_trade_return_pct составляет -0.129%, при минимуме COIN-M в +0.10%. Код отправляет рыночные ордера тейкера, поэтому реальные расходы на полный круг сделки составляют около 0.10% плюс влияние на цену. PnL до издержек примерно нулевой, что согласуется с долей выигрышных сделок 0.536 и средней прибылью $230 против среднего убытка $333.

Фактор прибыли равен 0.80. Коэффициент Шарпа — -0.38, при CI от -4.43 до 1.80 и PSR 0.41. Комиссии составили $43.7k, а расчётное влияние на цену — ещё $47.0k. Стратегия убыточна во всех трёх режимах волатильности (коэффициент Шарпа в спокойном режиме -3.7, в обычном — -2.0).

Счёт был ликвидирован, а total_return равен -100%. Месячная доходность была отрицательной каждый месяц с 2020-09 по 2021-01 до полной потери средств.

Сравнение с ориентиром: стратегия «купи и держи» BTC с 2020-08 по 2021-02 выросла примерно на 3x. Бета стратегии равна -0.99, альфа — -2.28, то есть она торговала против сильного тренда без компенсирующего преимущества.

Примечание, не основание для вердикта: в дневном ряду есть неправдоподобные колебания обратного контракта на счёте 0.5x (2021-01-24 -70%, 2021-01-25 +224%, 2020-11-28/29 -20%/+25%). В отчёте также указаны две разные даты ликвидации: дневной ряд заканчивается 2021-02-07, но в liquidation_date указано 2021-10-11. Похоже на аномалию COIN-M MTM или учёта. Я не проверял механизм, а журнал сделок отрицательный независимо от того, реально ли это.

История итераций

Проверка не пройдена (уровень 4 — проверка QA) [класс=code_defect]: - [edge_concern] Песочница: 1,779 сделок, PF 0.72, avg_trade_return_pct -0.095%. Комиссия в размере $89k и влияние на цену в размере $56k сопоставимы с чистым убытком около $85k: до издержек портфель примерно безубыточен или немного прибыльный BEFORE, но теряет средства из-за оборота (~1,970x). Сделка длится около 3.5h, поэтому издержки близки к движению цены за сделку. Это соответствует заранее зафиксированному прогнозу fee_edge. Значение PF <……Показать большеСвернуть

Проверка не пройдена (уровень 4 — проверка QA) [класс=code_defect]: - [edge_concern] Песочница: 1,779 сделок, PF 0.72, avg_trade_return_pct -0.095%. Комиссия в размере $89k и влияние на цену в размере $56k сопоставимы с чистым убытком около $85k: до издержек портфель примерно безубыточен или немного прибыльный BEFORE, но теряет средства из-за оборота (~1,970x). Сделка длится около 3.5h, поэтому издержки близки к движению цены за сделку. Это соответствует заранее зафиксированному прогнозу fee_edge. Значение PF < примерно 0.70 при более чем 100 сделках обычно вызывает подозрение на перепутанное направление (L125). Здесь доля прибыльных сделок 53% и положительный PnL до издержек указывают, что результат объясняется издержками, а не знаком сигнала. После исправления размера позиции ожидается измеренная проверка несостоятельности, а не повод для настройки. - [критично] На BINANCE_CM размер позиции не зависит от фактического капитала, и в песочнице использовано плечо 1.0 (LIQUIDATED, ликвидация=true, 2025-04-22, total_return -100%). Стратегия должна держать 50% капитала, поэтому портфель 1x нельзя ликвидировать. position_size() использует get_account_equity(), которая на этой площадке считывает баланс счёта в USD (начальный капитал 100k). Прибыль и убыток, комиссии и влияние на цену по обратному контракту учитываются в BTC, из отдельного начального капитала 50-BTC, поэтому этот стабильный баланс не меняется. Каждая сделка, таким образом, открывается на постоянный номинал около $50k (500 контрактов), независимо от накопленных убытков. Расчёты сходятся: avg_trade_pnl_usd -47.70 / avg_trade_return_pct -0.0954% даёт около $50k номинала в каждой сделке. avg_position_pct составляет 96.9% уменьшающегося капитала MTM, при заявленном значении 50%. Поэтому просадка заканчивается ликвидацией, а не уменьшением позиции. Это дефект расчёта размера позиции и учёта средств, а не результат торгового преимущества (сравни L148/L156: размер позиции ограничивался только устаревшим значением капитала). (строка 176) — исправление: рассчитывать размер по капиталу по рыночной оценке в USD: стабильный баланс плюс изменение баланса BTC с начала периода, умноженное на текущую цену (сохранить баланс BTC, зафиксированный в момент on_start), плюс нереализованный PnL. Либо самостоятельно учитывать реализованный PnL по закрытым позициям. Затем установить ограничения: контракты x 100 <= position_frac x капитал MTM x плечо и не более MTM капитала. Добавить резервный возврат 0, если капитал MTM <= 0. В обосновании указать, что avg_position_pct в следующей песочнице показывает около 50%. - [предупреждение] Исходник FMZ выполняет разворот в пределах одного бара. Здесь разворот означает выход на баре t и возможный повторный вход на баре t+1, если новый прогноз всё ещё совпадает. Разработчик сообщил об этом, а базовый шаблон требует такого поведения. После каждого разворота стратегия остаётся вне рынка один бар, а повторные развороты теряются. Механизм от этого не меняется. (строка 164) — исправление: допустимо, как и было указано. Другой вариант — сразу после _submit_exit отправить вход в противоположную сторону, используя _submit_entry_instrument в should_exit, чтобы соответствовать развороту в исходнике на том же баре. - [предупреждение] Переопределение min_bars_required перекрывает базовый метод (предупреждение статического анализа). Это безвредно: train_bars+2 = 302 баров 1H. Дек ограничен (maxlen=train_bars+1), поэтому предупреждение о «неограниченном росте» — ложноположительное. Затраты на бар постоянны (300 строк, не более 3 небольших шагов Ньютона), поэтому сложность не O(span) (L124 OK). (строка 50) — исправление: изменений не требуется. - [предупреждение] В журнале песочницы показано avg_holding_bars 0.0 и avg_holding_period 3h27m, а также trades_count 3557 против total_trades 1779 (исполнения и сделки туда и обратно). Похоже на известный артефакт метрик тестовой среды, а не на ошибку стратегии. Кроме того, funding_folded=false при 0 событиях финансирования: финансирование COIN-M не включено в PnL, поэтому время на рынке около 78% несёт неучтённые расходы на финансирование. — учесть при разборе бэктеста. Менять стратегию не требуется.

Сводка по итогам

Исходные ценовые уровни, использованные как признаки классификатора, не несут информации о направлении следующего бара, поэтому переносы с почасовой сменой позиций на их основе терпят крах при fee_edge, как и предсказывали заранее зарегистрированный прогноз и вывод L167. Отдельно передай на проверку движка дневные колебания COIN-M MTM (-70%, затем +224% на счёте 0.5x) и противоречивые даты ликвидации.

При проверке бэктеста аналитик выбрал отказ от стратегии (fee_edge / negative_expectancy): валовое преимущество было около нуля, поэтому убыток на сделку примерно равнялся стоимости сделки тейкера туда-обратно плюс влиянию на цену. Оптимизация не могла это исправить, а перенастройка spread_val или train_bars нарушила бы требование точного переноса.

Точный перенос стратегии Zero FMZ «SVM предсказывает покупку/продажу»: каждый час модель заново обучала линейный SVM (повторная реализация стандартных настроек sklearn LinearSVC на numpy) на исходных значениях [open, close] последних 300 баров, чтобы предсказать направление следующего бара (SpreadVal=2), и торговала BTCUSD_PERP.BINANCE_CM с таймфреймом 1H, открывая лонг, шорт или оставаясь без позиции, на 50% капитала при плече 1x.

С 2020-08-11 до ликвидации счёта 1,408 сделок в среднем приносили -0.129% за сделку (COIN-M: нижний предел +0.10%); коэффициент прибыльности составил 0.80, коэффициент Шарпа — -0.38 (CI -4.43 до 1.80), доля прибыльных сделок — 53.6%, общая доходность — -100%. Комиссии составили $43.7 тыс., а смоделированное влияние на рынок — ещё $47.0 тыс.; стратегия теряла деньги в спокойном, обычном и стрессовом режимах волатильности.

Stratmill — это инструмент для исследований и бумажной торговли, а не финансовая консультация или брокер. Результаты бэктестов и бумажной торговли являются гипотетическими. Торговля сопряжена с риском убытков.