Chiến lược theo dõi xu hướng dựa trên ATR

Tác giả:ChaoZhang, Ngày: 2024-01-05 16:28:48
Tags:

img

Tổng quan

Đây là một chiến lược theo dõi xu hướng dựa trên Average True Range (ATR). Nó sử dụng ATR để tính toán giá trị chỉ số và xác định hướng xu hướng giá. Chiến lược cũng cung cấp một cơ chế dừng lỗ để kiểm soát rủi ro.

Chiến lược logic

Chiến lược này sử dụng ba thông số chính: Thời gian, nhân và Điểm vào / Ra. Các thông số mặc định là 14 thời gian ATR và nhân 4.

Chiến lược đầu tiên tính giá trung bình dài (buyvg) và giá trung bình ngắn (sellavg), sau đó so sánh mối quan hệ giá giữa hai mức trung bình này để xác định hướng xu hướng hiện tại.

Ngoài ra, chiến lược này kết hợp ATR để thiết lập một mức dừng lỗ. Cụ thể, nó sử dụng trung bình động cân nặng 14 giai đoạn của ATR nhân với một nhân (bên mặc định 4) làm khoảng cách dừng lỗ. Điều này cho phép khoảng cách dừng lỗ được điều chỉnh dựa trên biến động của thị trường.

Khi stop loss được kích hoạt, chiến lược sẽ đóng vị trí để khóa lợi nhuận.

Ưu điểm

  1. Dựa trên đánh giá xu hướng, nó có thể theo xu hướng liên tục để kiếm lợi nhuận
  2. Sử dụng ATR để điều chỉnh năng động khoảng cách dừng mất mát, kiểm soát hiệu quả rủi ro
  3. Đơn giản và trực tiếp để tính điểm vào và ra, dễ hiểu và thực hiện

Rủi ro và giải pháp

  1. Có thể gặp lỗ lớn khi thay đổi xu hướng
    • Điều chỉnh thời gian ATR và nhân hợp lý để tối ưu hóa khoảng cách dừng mất mát
  2. Sẽ tạo ra nhiều lỗ nhỏ trong các thị trường khác nhau
    • Thêm các điều kiện lọc để tránh các thị trường khác nhau
  3. Cài đặt tham số không chính xác có thể làm suy giảm hiệu suất chiến lược
    • Thực hiện tối ưu hóa đa tham số để tìm tối ưu

Hướng dẫn tối ưu hóa

  1. Thêm các chỉ số khác để lọc để tránh mở các vị trí trên các thị trường khác nhau
  2. Tối ưu hóa thời gian ATR và các thông số nhân để làm cho khoảng cách dừng hợp lý hơn
  3. Thêm điều khiển kích thước vị trí dựa trên điều kiện thị trường

Kết luận

Nói chung đây là một chiến lược theo dõi xu hướng đơn giản và thực tế. Nó chỉ cần một vài tham số để thực hiện, và sử dụng ATR để điều chỉnh động các điểm dừng để kiểm soát rủi ro hiệu quả. Khi kết hợp với các chỉ số hỗ trợ khác để lọc, nó có thể được tối ưu hóa hơn nữa. Nói chung, chiến lược này phù hợp với những người muốn tìm hiểu về các chiến lược theo dõi xu hướng, và cũng có thể được sử dụng như một thành phần cơ bản cho các chiến lược tiên tiến hơn.


/*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])

Thêm nữa