
Эта стратегия сочетает в себе пересечение скользящих средних и динамических индикаторов, что позволяет эффективно отслеживать тренд и своевременно обращаться вспять. Сначала стратегия использует быстрое перемещение средних и медленное перемещение средних, чтобы сформировать золотой форк-овер и мертвый форк-овер. Затем в сочетании с динамическими индикаторами с определенными параметрами, когда золотой форк-овер, если динамический индикатор на быстрое перемещение средних снова поднимается, считается, что тренд продолжается, и остается; когда динамический индикатор падает, считается, что тренд переворачивается, и плавающий позиции.
Основная логика стратегии основана на трендовых сигналах, образующихся при перекрестном формировании скользящих средних, и динамических показателях, определяющих обратный тренд. Логика ключевых частей кода выглядит следующим образом:
Вычислите скоростную скользящую среднюю цену 1 и медленную скользящую среднюю цену 2. При этом цена 1 - это 5-циклическая HMA, а цена 2 - 7-циклическая HMA.
При прохождении price1 через price2 генерируется сигнал многого, а при прохождении price1 через price2 - сигнал пустого. Это обычное использование, основанное на движущихся средних.
Если после запуска мультисигнала динамический показатель price1 в скором времени снова повысится, то это будет рассматриваться как продолжение тренда и будет сохраняться в состоянии мультисигнала.
Когда динамический показатель roc1 снижается, считается, что тенденция изменилась, и выполняется равновесное положение. Логика обработки сигналов об удалении одинакова.
Введение ADX-терминалов, используемых для фильтрации ошибочных сигналов в не трендовых состояниях, только когда ADX выше терминалов, будет производиться фактический сигнал до-до-до.
Самым большим преимуществом этой стратегии по сравнению с простой стратегией движущихся средних является введение динамического индикатора, определяющего обратный тренд, который позволяет более своевременно и точно отслеживать тренд и обратный тренд. Конкретные преимущества следующие:
Сам по себе движущийся средний отстает в реакции на ценовые изменения, тогда как динамический индикатор может быстрее поймать обратный сигнал, что способствует своевременному остановке или обратному открытию позиции.
Сигналы обратного курса, основанные на динамических показателях, являются более надежными, что позволяет уменьшить ненужное повторное открытие позиций в трендовых торгах.
Использование ADX-индикаторов позволяет избежать ошибочных сигналов в не трендовых рынках и позволяет стратегии сосредоточиться на трендовых этапах, что повышает вероятность получения прибыли.
Логика стратегии ясна, проста, легко понятна и отслеживается, и подходит для начинающих в алгоритмической торговле.
Оптимизация параметров показателя имеет большое пространство для оптимизации для различных рынков, например, путем корректировки циклов движущихся средних и динамических параметров.
Основные риски, связанные с этой стратегией, исходят из следующих аспектов:
Сам по себе движущийся средний откладывает реакцию на изменение цены, что может привести к задержке сигнала и пропуску оптимального момента входа.
Ложный прорыв приводит к ненужному открытию или закрытию позиции, требует дальнейшей оптимизации параметров показателя или введения дополнительных фильтрующих условий.
В реверсии тренда используются динамические показатели, которые могут быть дисконтированы при резких изменениях на рынке.
Индекс ADX не может быть идеальным в определении тенденций и свертывания, и слишком высокие или слишком низкие отметки могут привести к проблемам.
Стратегия не учитывает затраты на торговлю, при практическом использовании следует обратить внимание на установку стоп-лосса для контроля риска.
Эта стратегия может быть улучшена в следующих аспектах:
Попробуйте другие типы скользящих средних или скорректируйте параметры скользящих средних, чтобы оптимизировать эффективность показателя.
Оптимизация параметров длины динамического индикатора, чтобы он был более чувствительным к ценовым переменам.
Попытайтесь установить ценовую фильтрацию во время обратного движения динамического индикатора, чтобы избежать мизерных краткосрочных колебаний.
Дальнейшее расширение использования ADX, например, использование различных параметров для разных уровней ADX и т. д.
Введение дополнительных условий, таких как показатель объема торгов, повышение качества сигналов, фильтрация ложных прорывов.
Добавление механизма сдерживания убытков для контроля за убытками. Оценка уровня комиссионных на реальных рынках, установление разумных сдерживающих убытков.
Стратегия объединяет преимущества показателей движущихся средних и динамических показателей, позволяя отслеживать тенденции и улавливать их обратные стороны. По сравнению с чистым отслеживанием тенденций, стратегия может более гибко реагировать на различные этапы рынка, сохраняя трендовую торговлю и избегая убытков, вызванных отскоком.
/*backtest
start: 2023-09-23 00:00:00
end: 2023-10-23 00:00:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=3
//study(title="MA Crossover Strategy", overlay = true)
strategy("MA Crossover Strategy with MA Turning Point Exits", overlay=true)
src = input(open, title="Source")
price = request.security(syminfo.tickerid, timeframe.period, src)
ma1 = input(5, title="1st MA Length")
type1 = input("HMA", "1st MA Type", options=["SMA", "EMA", "HMA"])
ma2 = input(7, title="2nd MA Length")
type2 = input("HMA", "2nd MA Type", options=["SMA", "EMA", "HMA"])
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Length")
adxthreshold = input(20, title="ADX threshold")
dirmov(len) =>
up = change(high)
down = -change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
truerange = rma(tr, len)
plus = fixnan(100 * rma(plusDM, len) / truerange)
minus = fixnan(100 * rma(minusDM, len) / truerange)
[plus, minus]
adx(dilen, adxlen) =>
[plus, minus] = dirmov(dilen)
sum = plus + minus
adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
sig = adx(dilen, adxlen)
//study("Average Directional Index", shorttitle="ADX", format=format.price, precision=2, resolution="")
//plot(sig, color=color.red, title="ADX")
f_hma(_src, _length)=>
_return = wma((2*wma(_src, _length/2))-wma(_src, _length), round(sqrt(_length)))
price1 = if (type1 == "SMA")
sma(price, ma1)
else
if (type1 == "EMA")
ema(price, ma1)
else
f_hma(price, ma1)
price2 = if (type2 == "SMA")
sma(price, ma2)
else
if (type2 == "EMA")
ema(price, ma2)
else
f_hma(price, ma2)
//plot(series=price, style=line, title="Price", color=black, linewidth=1, transp=0)
plot(series=price1, style=line, title="1st MA", color=blue, linewidth=2, transp=0)
plot(series=price2, style=line, title="2nd MA", color=green, linewidth=2, transp=0)
//longCondition = price1> price2
longCondition = price1> price2 and sig > adxthreshold
if (longCondition)
strategy.entry("Long", strategy.long)
shortCondition = price1 < price2 and sig > adxthreshold
if (shortCondition)
strategy.entry("Short", strategy.short)
lookback1 = input(1, "Lookback 1")
roc1 = roc(price1, lookback1)
ma1up = false
ma1down = false
ma2up = false
ma2down = false
ma1up := nz(ma1up[1])
ma1down := nz(ma1down[1])
ma2up := nz(ma2up[1])
ma2down := nz(ma2down[1])
trendStrength1 = input(2, title="Minimum slope magnitude * 100", type=float) * 0.01
if crossover(roc1, trendStrength1)
ma1up := true
ma1down := false
if crossunder(roc1, -trendStrength1)
ma1up := false
ma1down := true
shortexitCondition = ma1up and ma1down[1] and sig > adxthreshold
if (shortexitCondition)
strategy.close("Short")
longexitCondition = ma1down and ma1up[1] and sig > adxthreshold
if (longexitCondition)
strategy.close("Long")