Type/to search
2
Follow
484
Followers
Количественная стратегия фильтрации по скользящим средним: количественная практика идеи Harness Engineer
Discussions
Created 2026-04-17 11:55:34  Updated 2026-04-21 09:00:18
 0
 374

img

Введение: Идея Harness Engineer

В последнее время в сообществе инженеров AI/ML всё чаще обсуждается подход — Harness Engineer.

Его основная идея проста:

Вместо того чтобы самому придумывать ответ, лучше построить фреймворк, позволяющий данным и экспериментам самим найти ответ.

Традиционный инженер думает: "Я считаю, что параметр A хорош, напишу код для A". Harness Engineer делает иначе: "Я не знаю, какой из A, B, C лучше, я построю фреймворк, запущу A, B, C одновременно, и данные скажут мне ответ".

Инженер отвечает за определение пространства поиска и критериев оценки, а система — за автоматическую оптимизацию внутри этого пространства. Эта идея в ML соответствует walk-forward optimization, AutoML; в квантитативной торговле у неё тоже есть естественная область применения.

img

Агрессивные монеты: самая очевидная арена трендов

На рынке криптовалютных контрактов есть одна категория монет, заслуживающая особого внимания — агрессивные монеты с огромным объёмом торгов.

У таких монет есть общие черты:

  • Высокая концентрация капитала, заметное поведение крупного игрока
  • Относительно сильная продолженность тренда — как только тренд начинается, он часто длится долго
  • Высокая волатильность, при этом некоторые монеты с большими объёмами в определённые периоды демонстрируют сильную трендовость, и стратегии на скользящих средних на таких инструментах показывают относительно хорошие исторические результаты.

Именно поэтому использование классической стратегии пересечения двух скользящих средних для таких монет — разумная отправная точка. Быстрая линия пересекает медленную вверх — тренд начинается, входим; быстрая пересекает медленную вниз — тренд разворачивается, выходим. Логика проста, но на инструментах с явным трендом историческая доходность часто неплоха.

Проблема только одна: какие монеты являются агрессивными? И какие параметры скользящих средних использовать?

Если решать эти вопросы вручную, субъективность слишком высока. Другой человек даст совершенно иные ответы. К тому же рынок динамичен: сегодняшняя агрессивная монета может перестать быть таковой завтра, а сегодня эффективный набор параметров завтра может стать неработающим.

Именно здесь и вступает в игру идея Harness Engineer.

Вместо ручного выбора монет и ручной настройки параметров лучше доверить оба вопроса фреймворку: определить критерии оценки и позволить историческим данным пробежаться по пространству кандидатов, чтобы они сами выдали ответ. Человеку остаётся только решить, по каким критериям оценивать качество, а остальное делает система.

Исходя из этой идеи, вся стратегия была спроектирована как роллинг-фреймворк фильтрации, работающий на трёх уровнях.

img

Архитектура стратегии: двухуровневый механизм отбора

Первый уровень: формирование пула инструментов

Из всех контрактных инструментов рынка выбираются топ-150 монет по убыванию объёма в долларах США (USD).

Почему объём? Там, где большой объём, наиболее сосредоточен капитал, легче формируется тренд, и агрессивные монеты наиболее сконцентрированы. На этом этапе никаких субъективных суждений — чистое голосование рыночного капитала: у кого объём больше, тот и попадает в пул.

javascript
const filtered = tickers .filter(t => t.Symbol.endsWith('USDT.swap')) .map(t => ({ symbol: t.Symbol, quoteVolume: t.Last * t.Volume })) .sort((a, b) => b.quoteVolume - a.quoteVolume) .slice(0, topN) .map(t => t.symbol);

Логика предельно прямая: фильтруем контракты в USDT, вычисляем объём в долларах, сортируем по убыванию, берём первые N. Никаких субъективных суждений — рыночный капитал сам голосует.

Второй уровень: двухслойный отбор лучших

Это самая важная часть стратегии, где идея Harness проявляется наиболее ярко.

Правильный порядок выполнения такой:

img

⚠️ Внимание: использование наилучшего параметра для представления способности монеты само по себе несёт риск переобучения — параметры, показавшие себя наилучшим образом в истории, могут не работать в будущем. Это ограничение будет обсуждаться далее во второй половине статьи.

Процесс бэктестирования

Для каждой монеты из пула кандидатов одновременно запускается несколько комбинаций параметров MA, каждая из которых независимо исполняется на исторических свечах, имитируя реальную логику входа/выхода по пересечению:

javascript
// Перебираем каждую монету × каждую комбинацию параметров for (const params of maParamsList) { const bt = backtest_MA(records, params.fast, params.slow); // Каждое бэктестирование независимо даёт: процент побед, коэффициент прибыли, максимальную просадку, количество сигналов }

Основная логика каждого бэктеста — стандартное пересечение двух скользящих средних:

javascript
const crossUp = fastMA[i-1] <= slowMA[i-1] && fastMA[i] > slowMA[i]; const crossDown = fastMA[i-1] >= slowMA[i-1] && fastMA[i] < slowMA[i]; if (crossUp) position = { side: 'long', entryPrice: records[i].Close }; if (crossDown) position = { side: 'short', entryPrice: records[i].Close };

Комплексная оценка

После завершения бэктеста для каждой группы параметров вычисляется комплексный балл. Балл состоит из двух частей:

Взвешенная нормализованная оценка (суммарный коэффициент 0.80):

javascript
const score = Math.min(bt.winRate * 100, 100) * 0.30 // процент побед, ограничен сверху 100 + Math.min(bt.profitFactor * 20, 60) * 0.30 // коэффициент прибыли, ограничен сверху 60 + Math.max(0, 1 - bt.maxDrawdown / maxMDD) * 100 * 0.20 // контроль максимальной просадки + volPct * volPctBonus // бонус за перцентиль волатильности

Бонус за перцентиль волатильности: последний элемент volPct × volPctBonus (коэффициент по умолчанию 10) — это независимый от весовой системы бонус, который при прочих равных баллах склоняет выбор в пользу монет, чья текущая волатильность находится на исторически высоком процентиле — такие монеты чаще демонстрируют более активный тренд.

Следует отметить, что эти веса и бонусы установлены эмпирически, а не получены оптимизацией, и в реальном использовании могут быть скорректированы в зависимости от рыночной среды.

Первый уровень конкуренции: конкуренция параметров

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

javascript
if (score > bestScore) { bestScore = score; bestResult = bt; bestParams = params; // записываем оптимальный набор параметров по историческим данным }

Второй уровень конкуренции: конкуренция монет

Все монеты представляют свои лучшие баллы. Сортируются по убыванию, и топ N попадают в белый список:

javascript
results.sort((a, b) => b.score - a.score); const whitelist = results.slice(0, topCoins).map(r => r.coin);

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

Третий уровень: исполнение на реальном рынке и управление рисками

С отобранной конфигурацией осуществляется реальная торговля с наложением многоуровневых механизмов риск-контроля:

Генерация сигналов: в реальном времени отслеживается состояние пересечения скользящих средних для монет из белого списка. Золотое пересечение — лонг, смертельное пересечение — шорт:

javascript
const crossUp = fastPrev <= slowPrev && fastCur > slowCur; const crossDown = fastPrev >= slowPrev && fastCur < slowCur; if (crossUp) longList.push(sym); if (crossDown && allowShort) shortList.push(sym);

Динамический трейлинг-стоп: активируется, когда плавающая прибыль достигает порогового значения, причём порог отката динамически ужесточается с ростом прибыли. 3 порога установлены эмпирически. Логика: чем выше прибыль, тем меньше терпимость к откату — фиксация уже полученной прибыли:

javascript
function getDynamicTrailDrawdown(maxPnl) { if (maxPnl >= 7) return 3; // высокая прибыль — терпимость к откату ужесточается if (maxPnl >= 4) return 2; return 1.5; // низкая прибыль — даём больше пространства движению }

Восприятие рыночного состояния: отслеживается процентиль волатильности BTC. В условиях высокой волатильности автоматически снижается коэффициент позиции, в экстремальных случаях шорт полностью запрещается:

javascript
if (marketState === 'volatile') positionScaleDown = 0.5; else if (marketState === 'high_vol') positionScaleDown = 0.8; else if (marketState === 'low_vol') positionScaleDown = 0.7;

Весь процесс фильтрации периодически повторяется с роллинг-обновлением, не зацикливаясь на одной конфигурации, а динамически обновляя белый список и параметры вместе с рынком.


Базовое предположение: продолженность тренда

Работоспособность этого фреймворка опирается на одно ключевое предположение:

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

Это не мистика, за этим стоит определённая рыночная логика — инерция капитала, продолжение рыночных настроений, последовательность действий крупных игроков — всё это позволяет тренду оставаться эффективным в определённом временном окне.

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


В чём отличие от настоящего Harness Engineer

Это нужно прояснить.

У этой стратегии есть форма Harness, но по сравнению с системой настоящего Harness Engineer остаются значительные различия:

АспектНастоящий HarnessЭта стратегия
Разделение выборкиОбучающий набор + валидационный набор + holdout-тестовый наборБэктестинг на полных исторических данных, без проверки на выборке вне выборки (out-of-sample)
Защита от переобученияЧёткая проверка обобщающей способностиЧастичное хеджирование за счёт разнообразия параметров, неполное
Изоляция экспериментовКаждый вариант работает независимо, без влияния друг на другаИспользуют одни и те же свечные данные, скрытая связь
Порог для развёртыванияТребуется пройти валидацию перед развёртываниемСамый высокий рейтинг напрямую идёт в эксплуатацию, без вторичного проверочного слоя
Накопление ошибокОценка на каждом уровне независимаОба уровня отбора основаны на историческом оптимуме, ошибки накапливаются

Ключевое различие в том, что настоящий Harness задаётся вопросом: «сохранится ли этот результат на выборке вне выборки (out-of-sample)?», тогда как «оптимум», выбранный этой стратегией в двухуровневых гонках (двухуровневом соревновании), по своей сути является историческим оптимумом — переобучение на уровне параметров накладывается на переобучение на уровне монет. Сможет ли он сохраниться в будущем — это всегда открытый вопрос.


Заключение: «Искать меч по зарубке на лодке» или всё же стоит попробовать?

В мире количественного трейдинга предсказание всегда было чрезвычайно сложным делом.

Многие скажут: использовать исторические данные для выбора параметров, а потом идти в реальную торговлю — это по сути «искать меч по зарубке на лодке» — меч уже упал в воду, и та метка, которую вы вырезали на лодке, не поможет вам его найти. Рынок меняется, эффективные параметры устаревают, сегодняшняя странная монета завтра может стать обычной, а вчерашняя оптимальная скользящая средняя сегодня может оказаться шумом.

Эта критика не лишена оснований.

Но, с другой стороны, попробовать всё равно стоит.

Суть количественного подхода — никогда не в том, чтобы найти вечно правильный ответ, а в том, чтобы систематически повышать вероятность успеха в условиях неопределённости. Даже если это «искать меч по зарубке на лодке», сначала нужно иметь лодку и сделать на ней зарубку — локализация стратегии (лодка) сама по себе является началом количественного анализа.

Конечно, сам фреймворк не гарантирует прибыль. Наличие фреймворка — это только отправная точка; настоящая ценность заключается в постоянном выполнении и итерации: можно настраивать белый список, менять веса оценок, расширять пространство параметров, оптимизировать стоп-лосс и тейк-профит. Каждая корректировка — это новый эксперимент, который приближает этот фреймворк к настоящему Harness.

Дороги прокладываются шагами, а не мыслями.

Исходный код стратегии: Количественная стратегия фильтрации скользящих средних Harness Engineer

Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)