
Đừng để tên gọi lừa dối, K-algo trail hoàn toàn không phải là một chiến lược theo dõi ATR đơn giản. Hệ thống này kết hợp một cách khéo léo ba hệ thống kỹ thuật SuperTrend, Gann chín và Heikin Ashi để tạo thành một khung nhận dạng xu hướng ba chiều.
Sự đổi mới cốt lõi của chiến lược này nằm trong biểu đồ Heikin Ashi xử lý bằng phẳng EMA 11 chu kỳ kép. Heikin Ashi truyền thống dễ tạo ra tín hiệu giả, nhưng sau hai vòng EMA, chất lượng tín hiệu được cải thiện đáng kể.
Thiết lập dừng lỗ trực tiếp sử dụng đường SuperTrend, đây là giải pháp dừng động hợp lý nhất. Thậm chí thú vị hơn là thiết kế dừng ba lớp: khoảng cách rủi ro gấp 1,7 lần, 2,5 lần và 3,0 lần. Việc dừng dần dần này đảm bảo lợi nhuận cơ bản và để lại nhiều không gian cho tình hình xu hướng.
Tính toán Gann Square of 9 trong mã có vẻ đơn giản, nhưng thực tế có tác dụng rất lớn. Bằng cách tính toán gốc vuông của giá hiện tại, các vị trí kháng cự hỗ trợ lên xuống cung cấp các điểm giá bổ sung cho chiến lược. Mặc dù logic chủ chiến lược không sử dụng trực tiếp các vị trí này, nhưng chúng cung cấp một tài liệu tham khảo quan trọng cho việc điều chỉnh và đánh giá rủi ro bằng tay.
Chiến lược này hoạt động tốt nhất trong thị trường xu hướng một chiều, đặc biệt là các loại biến động cao như tiền điện tử và tương lai chỉ số cổ phiếu. Tuy nhiên, phải rõ ràng: Trong tình trạng biến động ngang, các vụ phá vỡ giả thường xuyên sẽ dẫn đến tổn thất nhỏ liên tục.
Bất kỳ chiến lược định lượng nào cũng có nguy cơ thua lỗ, và chiến lược này cũng không ngoại lệ. Mặc dù dữ liệu đánh giá lại cho thấy lợi nhuận sau khi điều chỉnh rủi ro hoạt động tốt, nhưng giao dịch thực tế vẫn có thể phải đối mặt với tổn thất liên tục.
/*backtest
start: 2025-06-11 00:00:00
end: 2025-08-25 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy('K-algo trail', overlay=true)
// ===== INPUTS =====
Periods = input(title='ATR Period', defval=10)
src = input(hl2, title='Source')
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3)
changeATR = input(title='Change ATR Calculation Method ?', defval=true)
showsignals = input(title='Show Buy/Sell Signals ?', defval=true)
// ===== ATR & SUPER TREND (K-TREND) CALCULATION =====
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
// Plot SuperTrend
upPlot = plot(trend == 1 ? up : na, title='Up Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.green, 0))
buySignal = trend == 1 and trend[1] == -1
plotshape(buySignal ? up : na, title='UpTrend Begins', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.green, 0))
dnPlot = plot(trend == 1 ? na : dn, title='Down Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.red, 0))
sellSignal = trend == -1 and trend[1] == 1
plotshape(sellSignal ? dn : na, title='DownTrend Begins', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.red, 0))
// ===== GANN SQUARE OF 9 =====
normalise_squareRootCurrentClose = math.floor(math.sqrt(close))
upperGannLevel_1 = (normalise_squareRootCurrentClose + 1) * (normalise_squareRootCurrentClose + 1)
upperGannLevel_2 = (normalise_squareRootCurrentClose + 2) * (normalise_squareRootCurrentClose + 2)
zeroGannLevel = normalise_squareRootCurrentClose * normalise_squareRootCurrentClose
lowerGannLevel_1 = (normalise_squareRootCurrentClose - 1) * (normalise_squareRootCurrentClose - 1)
lowerGannLevel_2 = (normalise_squareRootCurrentClose - 2) * (normalise_squareRootCurrentClose - 2)
// ===== SMOOTHED HEIKIN ASHI CALCULATION =====
ma1_len = input.int(title='MA1', defval=11, minval=1, maxval=100, step=1)
ma2_len = input.int(title='MA2', defval=11, minval=1, maxval=100, step=1)
// First Smoothing (11,11)
o = ta.ema(open, ma1_len)
c = ta.ema(close, ma1_len)
h = ta.ema(high, ma1_len)
l = ta.ema(low, ma1_len)
ha_t = ticker.heikinashi(syminfo.tickerid)
ha_o = request.security(ha_t, timeframe.period, o)
ha_c = request.security(ha_t, timeframe.period, c)
ha_h = request.security(ha_t, timeframe.period, h)
ha_l = request.security(ha_t, timeframe.period, l)
o2 = ta.ema(ha_o, ma2_len)
c2 = ta.ema(ha_c, ma2_len)
h2 = ta.ema(ha_h, ma2_len)
l2 = ta.ema(ha_l, ma2_len)
ha_col = o2 > c2 ? color.orange : color.blue
plotcandle(o2, h2, l2, c2, title='Heikin Ashi Smoothed', color=ha_col, wickcolor=#00000000)
// ===== STRATEGY LOGIC =====
// Final Combined Long Condition
longCondition = (o2 < c2 and trend == 1) and barstate.isconfirmed
// Final Combined Short Condition
shortCondition = (o2 > c2 and trend == -1) and barstate.isconfirmed
// ===== STRATEGY EXECUTION =====
if longCondition
SL = math.round(up, 2)
range_1 = math.abs(close - SL)
TARGET1 = close + range_1 * 1.7
TARGET2 = close + range_1 * 2.5
TARGET3 = close + range_1 * 3.0
strategy.entry('BUY', strategy.long)
strategy.exit('BUY T1', 'BUY', qty=1, limit=TARGET1)
strategy.exit('BUY T2', 'BUY', qty=1, limit=TARGET2)
strategy.exit('BUY T3', 'BUY', qty=1, limit=TARGET3)
strategy.exit('BUY SL', 'BUY', stop=SL)
if shortCondition
SL = math.round(dn, 2)
range_2 = math.abs(close - SL)
TARGET1 = close - range_2 * 1.7
TARGET2 = close - range_2 * 2.5
TARGET3 = close - range_2 * 3.0
strategy.entry('SELL', strategy.short)
strategy.exit('SELL T1', 'SELL', qty=1, limit=TARGET1)
strategy.exit('SELL T2', 'SELL', qty=1, limit=TARGET2)
strategy.exit('SELL T3', 'SELL', qty=1, limit=TARGET3)
strategy.exit('SELL SL', 'SELL', stop=SL)
// Plot entry signals
plotshape(longCondition ? close : na, title='Buy', text='BUY', location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.new(color.green, 0), textcolor=color.new(color.white, 0))
plotshape(shortCondition ? close : na, title='Sell', text='SELL', location=location.abovebar, style=shape.labeldown, size=size.tiny, color=color.new(color.red, 0), textcolor=color.new(color.white, 0))