Стратегия следования за трендом, основанная на среднем истинном диапазоне


Дата создания: 2024-01-05 16:28:48 Последнее изменение: 2024-01-05 16:28:48
Копировать: 0 Количество просмотров: 612
1
Подписаться
1617
Подписчики

Стратегия следования за трендом, основанная на среднем истинном диапазоне

Обзор

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

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

Стратегия использует три основных параметра: период, умножение множителя и точка входа/выхода. По умолчанию ATR 14 циклов и умножение в 4 раза.

Эта стратегия сначала рассчитывает средние цены на многоголовые цены (buyavg) и средние цены на пустые цены (sellavg), а затем сравнивает цены и их отношение к этим двум средним ценам, чтобы определить направление текущей тенденции. Если цена выше средней цены на пустые цены, то она считается многоголовой; если цена ниже средней цены на многоголовые цены, то она считается пустой.

Кроме того, эта стратегия в сочетании с ATR устанавливает следящий стоп (Trailing Stop Loss). Конкретный метод заключается в следующем: с 14-циклической взвешенной движущейся средней величиной ATR, умноженной на множитель (например, по умолчанию 4) как стоп-дистанцию. Таким образом, стоп-дистанция может быть скорректирована в зависимости от степени волатильности рынка.

Когда сбой вызывается, стратегия уравняет прибыль.

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

  1. На основе тенденций, чтобы быть успешным и получать прибыль.
  2. Использование ATR для динамической корректировки стоп-дистанции позволяет эффективно контролировать риск
  3. Расчет точек купли-продажи прост и понятен

Риски и противодействие

  1. Если тенденция изменится, возможны большие убытки
    • Соответствующая корректировка ATR-циклов и умножения, оптимизация стоп-дистанции
  2. В результате землетрясения WILL понесла несколько небольших потерь.
    • Увеличение фильтрации, чтобы избежать рыночных потрясений
  3. Неправильная настройка параметров может привести к неэффективности стратегии
    • Тестирование оптимизации многокомбинатных параметров, чтобы найти оптимальные параметры

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

  1. Добавление других показателей, позволяющих оценить фильтрующие сигналы и избежать выхода на поле в условиях шока
  2. Оптимизация ATR-циклов и множительных параметров, чтобы сделать стоп-дистанцию более рациональной
  3. Добавление контроля за открытием позиций, изменение размеров позиций в зависимости от рыночных условий

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

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

Исходный код стратегии
/*backtest
start: 2022-12-29 00:00:00
end: 2024-01-04 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Trend Strategy by zdmre', shorttitle='Trend Strategy', overlay=true, pyramiding=0, currency=currency.USD, default_qty_type=strategy.percent_of_equity, initial_capital=10000, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.005)
show_STOPLOSSprice = input(true, title='Show TrailingSTOP Prices')
src = input(close, title='Source')
out2 = ta.ema(src, 20)

buyavg = (close + high) / 2.02 - high * (1 - open / close) * (1 - low * open / (high * close))
sellavg = ((low + close) / 1.99 + low * (1 - low / open) * (1 - low * open / (close * high)) / 1.1 + out2 )/ 2

// === INPUT BACKTEST RANGE ===
fromMonth = input.int(defval=1, title='From Month', minval=1, maxval=12)
fromDay = input.int(defval=1, title='From Day', minval=1, maxval=31)
fromYear = input.int(defval=2021, title='From Year', minval=1970)
thruMonth = input.int(defval=1, title='Thru Month', minval=1, maxval=12)
thruDay = input.int(defval=1, title='Thru Day', minval=1, maxval=31)
thruYear = input.int(defval=2100, title='Thru Year', minval=1970)

// === INPUT SHOW PLOT ===
showDate = input(defval=true, title='Show Date Range')

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


// === TRAILING STOP LOSS === //

ATR_Period = input(14)
ATR_Mult = input(4.0)
var float ATR_TrailSL = na
var int pos = na
atr = ta.rma (ta.tr(true), 14)
xATR = ta.atr(ATR_Period)
nLoss = ATR_Mult * xATR

iff_1 = close > nz(ATR_TrailSL[1], 0) ? close - nLoss : close + nLoss
iff_2 = close < nz(ATR_TrailSL[1], 0) and close[1] < nz(ATR_TrailSL[1], 0) ? math.min(nz(ATR_TrailSL[1]), close + nLoss) : iff_1
ATR_TrailSL := close > nz(ATR_TrailSL[1], 0) and close[1] > nz(ATR_TrailSL[1], 0) ? math.max(nz(ATR_TrailSL[1]), close - nLoss) : iff_2

iff_3 = close[1] > nz(ATR_TrailSL[1], 0) and close < nz(ATR_TrailSL[1], 0) ? -1 : nz(pos[1], 0)
pos := close[1] < nz(ATR_TrailSL[1], 0) and close > nz(ATR_TrailSL[1], 0) ? 1 : iff_3

atr_color = pos == -1 ? color.green : pos == 1 ? color.red : color.aqua
atrtrend = plot(ATR_TrailSL, 'Trailing StopLoss', atr_color, linewidth=2)

// ===  Stop Loss === //
slGroup = 'Stop Loss'
useSL = input.bool(false, title='╔══════   Enable   ══════╗', group=slGroup, tooltip='If you are using this strategy for Scalping or Futures market, we do not recommend using Stop Loss.')
SLbased = input.string(title='Based on', defval='Percent', options=['ATR', 'Percent'], group=slGroup, tooltip='ATR: Average True Range\nPercent: eg. 5%.')
multiATR = input.float(10.0, title='ATR   Mult', group=slGroup, inline='atr')
lengthATR = input.int(14, title='Length', group=slGroup, inline='atr')
SLPercent = input.float(5, title='Percent', group=slGroup) * 0.01
Shortposenter = input.bool(false, title='ShortPosition')

longStop = 0.0
shortStop = 0.0

if SLbased == 'ATR'
    longStop := ta.valuewhen(pos == 1, low, 0) - ta.valuewhen(pos == 1, ta.rma(ta.tr(true), lengthATR), 0) * multiATR
    longStopPrev = nz(longStop[1], longStop)
    longStop := close[1] > longStopPrev ? math.max(longStop, longStopPrev) : longStop

    shortStop := ta.valuewhen(pos == -1, ta.rma(ta.tr(true), lengthATR), 0) * multiATR + ta.valuewhen(pos == -1, high, 0)
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := close[1] > shortStopPrev ? math.max(shortStop, shortStopPrev) : shortStop
    shortStop
if SLbased == 'Percent'
    longStop := strategy.position_avg_price * (1 - SLPercent)
    shortStop := strategy.position_avg_price * (1 + SLPercent)
    shortStop
exitLong  = pos == -1 

// === PlotColor === //
buySignal = pos == 1 and pos[1] == -1
plotshape(buySignal, title="Long", location=location.belowbar, style=shape.labelup, size=size.normal, color=color.new(color.green,50), text='Buy', textcolor=color.white)
exitSignal = pos == -1 and pos[1] == 1
plotshape(exitSignal, title="Exit", location=location.abovebar, style=shape.labeldown, size=size.normal, color=color.new(color.red,50), text='Exit', textcolor=color.white)

hPlot = plot(ohlc4, title="", style=plot.style_circles, linewidth=0, editable = false)
longFill = (pos == 1 ? color.new(color.green,80) : na) 
shortFill = (pos == -1 ? color.new(color.red,80) : na)
fill(hPlot, atrtrend,color=longFill)
fill(hPlot,atrtrend, color=shortFill)

// === Strategy === //
strategy.entry('Long', strategy.long,limit = buyavg, when=window() and pos == 1,comment="Entry: "+str.tostring(buyavg))
strategy.close('Long', when=window() and exitLong , comment='Exit: '+str.tostring(sellavg) )

if Shortposenter
    strategy.entry('Short', strategy.short, when=window() and pos== -1,comment="Entry: "+str.tostring(close))
    strategy.close('Short', when=window() and pos == 1 , comment='Exit: ')

if useSL
    strategy.exit('Stop Loss', 'Long', stop=longStop)
    
// === Show StopLoss Price === //
if show_STOPLOSSprice
    if pos == -1
        label ShortStop = label.new(bar_index, na, 'SL: ' + str.tostring(ATR_TrailSL), color=color.green, textcolor=color.white, style=label.style_none, yloc=yloc.abovebar, size=size.small)
        label.delete(ShortStop[1])

    if pos == 1
        label LongStop = label.new(bar_index, na, 'SL: ' + str.tostring(ATR_TrailSL), color=color.red, textcolor=color.white, style=label.style_none, yloc=yloc.belowbar, size=size.small)
        label.delete(LongStop[1])