Стратегия кроссовера MA Mondrian Multi-Time Frame


Дата создания: 2023-11-16 17:28:43 Последнее изменение: 2023-11-16 17:28:43
Копировать: 0 Количество просмотров: 661
1
Подписаться
1617
Подписчики

Стратегия кроссовера MA Mondrian Multi-Time Frame

Эта стратегия применяет пересечение линий MA в многократных временных рамках (MTF) для определения направления тренда и в сочетании с конкретными условиями фильтрует сигналы, выбирая покупку или продажу, когда направление тренда более четкое, и относится к типу стратегии отслеживания тренда.

Стратегический принцип

  1. Введите пользовательский диапазон времени отслеживания.

  2. Вводите, используется ли диаграмма Heikin-Ashi с использованием синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического синтаксического

  3. Определяем медленную MA-линию, быструю MA-линию и дополнительную третью MA-линию, используемую при возбуждении.

  4. Для каждой MA-линии можно настроить тип MA, временной период и параметры и т. д.

  5. В зависимости от того, насколько быстро на MA проходит медленное MA, формируется сигнал покупки, а на основании того, насколько быстро на MA проходит медленное MA, формируется сигнал продажи.

  6. Можно использовать третью MA-линию в качестве многонаправленного фильтра, который создает сигнал покупки только тогда, когда цена закрытия превышает третью MA.

  7. Автоматическая торговля с помощью модуля strategy.entry.

  8. Можно настроить количество сделок на руку или использовать фиксированный объем сделок.

Стратегические преимущества

  1. Используя MTF-архитектуру, различные MA-линии могут использовать различные периоды, чтобы идентифицировать тенденционные признаки на нескольких временных масштабах.

  2. Можно настроить тип MA, выбрать плавный тип MA для повышения стабильности, а также выбрать ответный MA.

  3. В сочетании с Heikin-Ashi можно отфильтровать ложные прорывы.

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

  5. Гибко адаптируются к различным рыночным условиям.

  6. С помощью модуля strategy.entry можно автоматически размещать заказы, без необходимости вручную вмешиваться в сделки.

  7. Поддержка обратной измерения параметров оптимизации для поиска оптимального сочетания параметров.

Стратегический риск

  1. MA-крестная стратегия чувствительна к ложным сигналам прорыва, которые могут привести к ненужным сделкам. Можно соответствующим образом изменить цикл MA или добавить фильтрующие условия, чтобы снизить риск.

  2. В шокирующих ситуациях пересечение линий MA часто и легко приводит к убыткам. Для снижения риска можно соответствующим образом расширить интервал MA или продлить цикл MA.

  3. Фиксированный объем торговли не может контролировать риск, можно рассмотреть возможность установки объема торговли в процентах от средств счета.

  4. Торговые сборы и скольжение также влияют на прибыльность стратегии. Параметры могут быть адаптированы соответствующим образом, чтобы гарантировать достаточно высокую выигрышную вероятность.

Направление оптимизации

  1. Тестируйте различные типы МА, чтобы найти оптимальное сочетание параметров. Smooth MA повышает стабильность, а быстро MA повышает ловкость.

  2. Оптимизация параметров MA, адекватный длительный цикл способствует распознаванию тенденций, укороченный цикл повышает чувствительность. Найти оптимальные точки равновесия.

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

  4. Можно оптимизировать параметры цикла MA для конкретного сорта, чтобы найти параметры, наиболее подходящие для торговой среды этого сорта.

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

  6. Оптимизация комбинации параметров для данных обратной связи, поиск оптимальных параметров для повышения эффективности стратегии.

Подвести итог

В целом, многовременная MA-крестовая стратегия относится к более распространенным стратегиям отслеживания тенденций. Ее преимущества заключаются в простоте, гибкости параметров и адаптации к различным рыночным условиям. Но также существует определенный риск ложного сигнала.

Исходный код стратегии
/*backtest
start: 2023-11-08 00:00:00
end: 2023-11-15 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(shorttitle="MZ MA Cross",title="MA MTF Cross Strategy", overlay=true, calc_on_order_fills=false, calc_on_every_tick=false, default_qty_type=strategy.fixed, default_qty_value=5,commission_value=0.1)

timeFrameticker  = input('D',type=input.resolution, title="Chart Timeframe")
uha   =input(true, title="Use Heikin Ashi Candles")

// Use only Heikinashi Candles for all calculations
haclose = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, close) : security(syminfo.tickerid, timeFrameticker, close)
haopen = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, open) : security(syminfo.tickerid, timeFrameticker, open)
hahigh = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, high) : security(syminfo.tickerid, timeFrameticker, high)
halow = uha ?security(heikinashi(syminfo.tickerid), timeFrameticker, low) : security(syminfo.tickerid, timeFrameticker, low)

//Backtest dates
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2021, title = "From Year",       type = input.integer, minval = 1970)
thruMonth = input(defval = 12,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 30,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2021, title = "Thru Year",       type = input.integer, minval = 1970)

showDate  = input(defval = true, title = "Show Date Range", type = input.bool)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => true

src = security(heikinashi(syminfo.tickerid), timeFrameticker, close)

//  INPUT MA TYPE
slowMAtype = input(title="Slow MA Type", type=input.string, defval="LRC", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])
fastMAtype = input(title="Fast MA Type", type=input.string, defval="EDSMA", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])
upMAcond =input(false, title="Use Uptrend Conditional 3rd MA for Confirmation")
upMAtype=input(title="Uptrend Conditional MA Type", type=input.string, defval="HMA", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])


//  INPUT RESOLUTION
slowMAresolution = input("D",type=input.resolution, title="Slow MA Resolution")
fastMAresolution = input("D",type=input.resolution, title="Fast MA Resolution")
upMAresolution = input("D",type=input.resolution, title="Uptrend Conditional MA Resolution")
haMAslow = uha ? security(heikinashi(syminfo.tickerid), slowMAresolution, close) : security(syminfo.tickerid, slowMAresolution, close)
haMAfast = uha ?security(heikinashi(syminfo.tickerid), fastMAresolution, close) : security(syminfo.tickerid, fastMAresolution, close)
haMAup =  uha ?security(heikinashi(syminfo.tickerid), upMAresolution, close) : security(syminfo.tickerid, upMAresolution, close)

//  INPUT LENGTHS
slowMAlength = input(50, minval=1, title="Slow MA Length")
fastMAlength = input(30, minval=1, title="Fast MA Length")
upMAlength =  input(200, minval=1, title="Uptrend Conditional MA Length")

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////                      MA Function                         //////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

//           Pre-reqs
//
tema(src, len) =>
    ema1 = ema(src, len)
    ema2 = ema(ema1, len)
    ema3 = ema(ema2, len)
    (3 * ema1) - (3 * ema2) + ema3
kidiv = input(defval=1,maxval=4,  title="Kijun MOD Divider")

jurik_phase = input(title="* Jurik (JMA) Only - Phase", type=input.integer, defval=3)
jurik_power = input(title="* Jurik (JMA) Only - Power", type=input.integer, defval=1)
volatility_lookback = input(10, title="* Volatility Adjusted (VAMA) Only - Volatility lookback length")
//                  MF
beta = input(0.8,minval=0,maxval=1,step=0.1,  title="Modular Filter, General Filter Only - Beta")
feedback = input(false, title="Modular Filter Only - Feedback")
z = input(0.5,title="Modular Filter Only - Feedback Weighting",step=0.1, minval=0, maxval=1)
//EDSMA
ssfLength = input(title="EDSMA - Super Smoother Filter Length", type=input.integer, minval=1, defval=20)
ssfPoles = input(title="EDSMA - Super Smoother Filter Poles", type=input.integer, defval=2, options=[2, 3])

//----
//                  EDSMA
get2PoleSSF(src, length) =>
    PI = 2 * asin(1)
    arg = sqrt(2) * PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(arg)
    c2 = b1
    c3 = -pow(a1, 2)
    c1 = 1 - c2 - c3
    
    ssf = 0.0
    ssf := c1 * src + c2 * nz(ssf[1]) + c3 * nz(ssf[2])

get3PoleSSF(src, length) =>
    PI = 2 * asin(1)

    arg = PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(1.738 * arg)
    c1 = pow(a1, 2)

    coef2 = b1 + c1
    coef3 = -(c1 + b1 * c1)
    coef4 = pow(c1, 2)
    coef1 = 1 - coef2 - coef3 - coef4

    ssf = 0.0
    ssf := coef1 * src + coef2 * nz(ssf[1]) + coef3 * nz(ssf[2]) + coef4 * nz(ssf[3])

//          MA Main function
ma(type, src, len) =>
    float result = 0
    if type=="TMA"
        result := sma(sma(src, ceil(len / 2)), floor(len / 2) + 1)
    if type=="MF"
        ts=0.,b=0.,c=0.,os=0.
        //----
        alpha = 2/(len+1)
        a = feedback ? z*src + (1-z)*nz(ts[1],src) : src
        //----
        b := a > alpha*a+(1-alpha)*nz(b[1],a) ? a : alpha*a+(1-alpha)*nz(b[1],a)
        c := a < alpha*a+(1-alpha)*nz(c[1],a) ? a : alpha*a+(1-alpha)*nz(c[1],a)
        os := a == b ? 1 : a == c ? 0 : os[1]
        //----
        upper = beta*b+(1-beta)*c
        lower = beta*c+(1-beta)*b 
        ts := os*upper+(1-os)*lower
        result := ts
    if type=="LRC"
        result := linreg(src, len, 0)
    if type=="SMA" // Simple
        result := sma(src, len)
    if type=="EMA" // Exponential
        result := ema(src, len)
    if type=="DEMA" // Double Exponential
        e = ema(src, len)
        result := 2 * e - ema(e, len)
    if type=="TEMA" // Triple Exponential
        e = ema(src, len)
        result := 3 * (e - ema(e, len)) + ema(ema(e, len), len)
    if type=="WMA" // Weighted
        result := wma(src, len)
    if type=="VAMA" // Volatility Adjusted
        /// Copyright © 2019 to present, Joris Duyck (JD)
        mid=ema(src,len)
        dev=src-mid
        vol_up=highest(dev,volatility_lookback)
        vol_down=lowest(dev,volatility_lookback)
        result := mid+avg(vol_up,vol_down)
    if type=="HMA" // Hull
        result := wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))
    if type=="JMA" // Jurik
        /// Copyright © 2018 Alex Orekhov (everget)
        /// Copyright © 2017 Jurik Research and Consulting.
        phaseRatio = jurik_phase < -100 ? 0.5 : jurik_phase > 100 ? 2.5 : jurik_phase / 100 + 1.5
        beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
        alpha = pow(beta, jurik_power)
        jma = 0.0
        e0 = 0.0
        e0 := (1 - alpha) * src + alpha * nz(e0[1])
        e1 = 0.0
        e1 := (src - e0) * (1 - beta) + beta * nz(e1[1])
        e2 = 0.0
        e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
        jma := e2 + nz(jma[1])
        result := jma
    if type=="Kijun v2"
        kijun = avg(lowest(len), highest(len))//, (open + close)/2)
        conversionLine = avg(lowest(len/kidiv), highest(len/kidiv))
        delta = (kijun + conversionLine)/2
        result :=delta
    if type=="McGinley"
        mg = 0.0
        mg := na(mg[1]) ? ema(src, len) : mg[1] + (src - mg[1]) / (len * pow(src/mg[1], 4))
        result :=mg
    if type=="EDSMA"
    
        zeros = src - nz(src[2])
        avgZeros = (zeros + zeros[1]) / 2
        
        // Ehlers Super Smoother Filter 
        ssf = ssfPoles == 2
             ? get2PoleSSF(avgZeros, ssfLength)
             : get3PoleSSF(avgZeros, ssfLength)
        
        // Rescale filter in terms of Standard Deviations
        stdev = stdev(ssf, len)
        scaledFilter = stdev != 0
             ? ssf / stdev
             : 0
        
        alpha = 5 * abs(scaledFilter) / len
        
        edsma = 0.0
        edsma := alpha * src + (1 - alpha) * nz(edsma[1])
        result :=  edsma
    result
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


//  MA DEFINITION
slowMA = ma(slowMAtype, haMAslow , slowMAlength)
//fastMA = ma(fastMAtype, slowMA , fastMAlength)
fastMA = ma(fastMAtype, haMAfast , fastMAlength)
upMA = ma(upMAtype, haMAup , upMAlength)
closeMA = ma('SMA', src , 2)

//  Strategy Conditions
L1 = crossover(fastMA,slowMA)
L2 = close > upMA
S1 = crossunder(fastMA,slowMA)
S2 = close < upMA
longcondition = upMAcond ? L1 and L2 : L1
shortcondition = upMAcond ? S1 or S2 : S1

//  Plots
color_fill_uptrend = color.new(#4caf50, 80)
color_fill_downtrend = color.new(#c2185b, 80)
plot(slowMA, title='Slow MA', color=color.olive, linewidth=2)
plot(fastMA, title='Fast MA', color=color.teal, linewidth=2)
cls=plot(closeMA, title='Source Line', color=na, linewidth=1)
up = plot(upMA, title='Uptrend Conditional MA', color=color.purple, linewidth=2)
fill(up,cls, color = close > upMA ? color_fill_uptrend : color_fill_downtrend )

//plotshape(longcondition, style = shape.triangleup, color = color.green, location = location.belowbar, text = "Long", size = size.small)
//plotshape(shortcondition, style = shape.triangledown, color = color.red, location = location.abovebar, text = "Short", size = size.small)


strategy.entry(id="long", long = true, when = longcondition and window())
strategy.close("long", when = shortcondition and window())

//if (longcondition)
//    strategy.entry("BUY", strategy.long, when = window())

//if (shortcondition)
//    strategy.entry("SELL", strategy.short, when = window())