Стратегия следования тренду с скользящими средними и супертенденцией

Автор:Чао Чжан, Дата: 2023-10-20 16:50:01
Тэги:

img

Обзор

Эта стратегия сочетает в себе индикаторы скользящей средней и индикатор SuperTrend для реализации стратегии следования тренду с отслеживанием стоп-лосса.

Логика стратегии

Стратегия использует две скользящие средние FRAMA для торговых сигналов и индикатор SuperTrend для фильтрации.

Конкретно, когда быстрая линия пересекает медленную линию, генерируется сигнал покупки. Когда быстрая линия пересекает медленную линию, генерируется сигнал продажи. Чтобы избежать ложных перерывов, стратегия добавляет фильтр, требующий выравнивания индикатора SuperTrend. Торги принимаются только тогда, когда SuperTrend согласен с направлением сигнала.

Для управления позициями стратегия использует изменение направления SuperTrend в качестве сигнала остановки потери.

После достижения определенной цели прибыли, последующий стоп-лосс может быть использован для блокировки прибыли.

Анализ преимуществ

  • Использует скользящие средние для определения направления тренда, способный отфильтровывать рыночный шум и точно оценивать тенденции
  • Сочетание с фильтром SuperTrend позволяет избежать ошибочных сделок от ложных прорывов
  • Изменение направления SuperTrend действует как точка остановки потери, что позволяет быстро остановить потерю и эффективно контролировать риск.
  • Опциональный стоп-лосс может максимизировать прибыль

Анализ рисков

  • В качестве стратегии, основанной на тенденциях, она уязвима к колебаниям на различных рынках.
  • Движущиеся средние имеют отстающий эффект, могут привести к преждевременному или позднему вхождению
  • Неправильные параметры SuperTrend могут привести к слишком агрессивному или слишком консервативному стоп-лосс
  • При включении остановки задержки ширина задержки должна быть правильно настроена, чтобы избежать чрезмерной потери остановки

Эти риски могут быть уменьшены путем корректировки параметров скользящей средней, оптимизации настроек SuperTrend и соответствующего использования стоп-лосса.

Руководство по оптимизации

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

  1. Оптимизировать параметры скользящей средней для поиска наилучшей комбинации параметров

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

  1. Настроить параметры SuperTrend

Для оптимизации эффекта стоп-лосса можно протестировать различные периоды ATR и множители.

  1. Добавить другие индикаторные фильтры

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

  1. Оптимизировать параметры остановки

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

  1. Комбинировать с другими стратегиями стоп-лосса

Могут быть испытаны комбинации с фиксированной остановкой, остановкой волатильности, адаптивной остановкой.

Заключение

Стратегия объединяет анализ тренда скользящих средних и управление остановками SuperTrends в полноценную стратегию с последующим остановкой потери.


/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-13 00:00:00
period: 30m
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © 03.freeman

//@version=4
// strategy("FRAMA strategy", overlay=true,precision=6, initial_capital=1000,calc_on_every_tick=true, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=10000, currency=currency.EUR)
ma_src = input(title="MA FRAMA Source", type=input.source, defval=close)
ma_frama_len = input(title="MA FRAMA Length", type=input.integer, defval=12)
res = input(title="Resolution", type=input.resolution, defval="1W")
frama_FC = input(defval=1,minval=1, title="* Fractal Adjusted (FRAMA) Only - FC")
frama_SC = input(defval=200,minval=1, title="* Fractal Adjusted (FRAMA) Only - SC")
High = security(syminfo.tickerid, res, high)
Low = security(syminfo.tickerid, res, low)
source = security(syminfo.tickerid, res, ma_src)
enterRule = input(false,title = "Use supertrend for enter")
exitRule = input(false,title = "Use supertrend for exit")

ma(src, len) =>
    float result = 0
    int len1 = len/2
    e = 2.7182818284590452353602874713527
    w = log(2/(frama_SC+1)) / log(e) // Natural logarithm (ln(2/(SC+1))) workaround
    H1 = highest(High,len1)
    L1 = lowest(Low,len1)
    N1 = (H1-L1)/len1
    H2_ = highest(High,len1)
    H2 = H2_[len1]
    L2_ = lowest(Low,len1)
    L2 = L2_[len1]
    N2 = (H2-L2)/len1
    H3 = highest(High,len)
    L3 = lowest(Low,len)
    N3 = (H3-L3)/len
    dimen1 = (log(N1+N2)-log(N3))/log(2)
    dimen = iff(N1>0 and N2>0 and N3>0,dimen1,nz(dimen1[1]))
    alpha1 = exp(w*(dimen-1))
    oldalpha = alpha1>1?1:(alpha1<0.01?0.01:alpha1)
    oldN = (2-oldalpha)/oldalpha
    N = (((frama_SC-frama_FC)*(oldN-1))/(frama_SC-1))+frama_FC
    alpha_ = 2/(N+1)
    alpha = alpha_<2/(frama_SC+1)?2/(frama_SC+1):(alpha_>1?1:alpha_)
    frama = 0.0
    frama :=(1-alpha)*nz(frama[1]) + alpha*src
    result := frama
    result

frama = ma(sma(source,1),ma_frama_len)
signal = ma(frama,ma_frama_len)
plot(frama, color=color.red)
plot(signal, color=color.green)


longCondition = crossover(frama,signal)
shortCondition = crossunder(frama,signal)

Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)


Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))

TrendUp = 0.0
TrendDown = 0.0
Trend = 0.0
Tsl = 0.0
TrendUp :=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown :=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn

Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl := Trend==1? TrendUp: TrendDown

linecolor = Trend == 1 ? color.green : color.red

//plot(Tsl, color = linecolor , style =  plot.style_line , linewidth = 2,title = "SuperTrend")

plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,color.green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, color.red,0,0)

plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)


//  Strategy: (Thanks to JayRogers)
// === STRATEGY RELATED INPUTS ===
//tradeInvert     = input(defval = false, title = "Invert Trade Direction?")
// the risk management inputs
inpTakeProfit   = input(defval = 0, title = "Take Profit Points", minval = 0)
inpStopLoss     = input(defval = 0, title = "Stop Loss Points", minval = 0)
inpTrailStop    = input(defval = 0, title = "Trailing Stop Loss Points", minval = 0)
inpTrailOffset  = input(defval = 0, title = "Trailing Stop Loss Offset Points", minval = 0)

// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = inpTakeProfit  >= 1 ? inpTakeProfit  : na
useStopLoss     = inpStopLoss    >= 1 ? inpStopLoss    : na
useTrailStop    = inpTrailStop   >= 1 ? inpTrailStop   : na
useTrailOffset  = inpTrailOffset >= 1 ? inpTrailOffset : na

// === STRATEGY - LONG POSITION EXECUTION ===
enterLong() => enterRule? (longCondition and Trend ==1):longCondition                                             // functions can be used to wrap up and work out complex conditions
exitLong() => exitRule and Trend == -1

strategy.entry(id = "Buy", long = true, when = enterLong() )             // use function or simple condition to decide when to get in
strategy.close(id = "Buy", when = exitLong() )                         // ...and when to get out

// === STRATEGY - SHORT POSITION EXECUTION ===
enterShort() => enterRule? (shortCondition and Trend ==-1):shortCondition
exitShort() => exitRule and Trend == 1

strategy.entry(id = "Sell", long = false, when = enterShort())
strategy.close(id = "Sell", when = exitShort() )

// === STRATEGY RISK MANAGEMENT EXECUTION ===
// finally, make use of all the earlier values we got prepped
strategy.exit("Exit Buy", from_entry = "Buy", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Sell", from_entry = "Sell", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)

// === Backtesting Dates === thanks to Trost

testPeriodSwitch = input(false, "Custom Backtesting Dates")
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testStopHour = input(23, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
isPeriod = true
// === /END

if not isPeriod
    strategy.cancel_all()
    strategy.close_all()

Больше