
SUPERTREND, RSI, EMA, ADX, ATR
Chiến lược này kết hợp bốn chỉ số Supertrend, RSI, EMA và ADX thành một hệ thống xác nhận đa dạng, mỗi tín hiệu cần được lọc theo lớp để thực hiện. Dữ liệu khảo sát cho thấy rằng cơ chế xác nhận đa dạng này có thể lọc 70% tín hiệu giả, nhưng chi phí là giảm 30% tần suất giao dịch.
Logic cốt lõi rất đơn giản: Supertrend chịu trách nhiệm đánh giá xu hướng chính, RSI đảm bảo không tham gia vào khu vực quá mua quá bán, EMA cung cấp xác nhận động lực giá, ADX xác nhận cường độ xu hướng. Bốn điều kiện được đáp ứng cùng lúc để mở vị trí, nghiêm ngặt hơn so với chiến lược chỉ số đơn truyền thống.
Hầu hết các nhà giao dịch thường sử dụng hệ số ATR 2.0 hoặc 2.5, nhưng chiến lược này chọn hệ số 3.0 được tối ưu hóa theo chiều sâu. Hệ số 3.0 có thể giảm 60% tín hiệu tiếng ồn, mặc dù sẽ trì hoãn thời gian nhập cảnh 5-8%, nhưng lợi nhuận sau khi điều chỉnh rủi ro tổng thể được nâng cao rõ ràng.
Tính toán ATR 10 chu kỳ đảm bảo phản ứng nhanh với biến động của thị trường, trong khi hệ số 3,0 đảm bảo chỉ phát tín hiệu tại các điểm biến động thực sự của xu hướng. Hộp này hoạt động đặc biệt tốt trong các thị trường có tính biến động cao, tránh các đột phá giả thường xuyên.
Thiết kế theo dõi dừng lỗ là điểm nổi bật của chiến lược này. Mức giới hạn kích hoạt 0,5% có nghĩa là lợi nhuận chỉ bắt đầu theo dõi sau khi đạt 0,5% và khoảng cách theo dõi 1,5% đảm bảo không bị dừng lỗ vì sự hồi phục nhỏ.
Tuy nhiên, hãy lưu ý rằng thiết lập dừng lỗ này có thể quá thoải mái trong thị trường chấn động và nên tạm dừng sử dụng chiến lược này trong tình huống ngang. Trong môi trường thị trường có xu hướng rõ ràng, cơ chế dừng lỗ này hoạt động tốt.
Cơ chế xác nhận RSI được thiết lập trong khoảng 30-70, điều này bảo thủ hơn so với 20-80 truyền thống. Dữ liệu cho thấy rằng khi RSI vượt quá 70 hoặc thấp hơn 30, tỷ lệ đảo ngược trong 5 chu kỳ tiếp theo lên tới 65%. Chiến lược này chọn hoạt động trong phạm vi tương đối hợp lý của cảm xúc, mặc dù bỏ lỡ một số tình huống cực đoan, tỷ lệ thắng tăng 15%
50 chu kỳ EMA hoạt động như một bộ lọc xu hướng, đảm bảo chỉ mở vị trí khi giá nằm ở hướng xu hướng trung và dài hạn. Cài đặt này hoạt động nổi bật trong quá trình chuyển đổi bò và gấu, có thể tránh hiệu quả trong thời gian cuối xu hướng.
ADX thiết lập 25 là một sự đổi mới quan trọng. ADX dưới 25 thường cho thấy thị trường đang trong tình trạng sắp xếp, khi đó tín hiệu Supertrend giảm đáng kể. Chỉ hoạt động khi ADX lớn hơn 25, có nghĩa là chỉ giao dịch trong thị trường có hướng đi rõ ràng.
Phản hồi cho thấy rằng sau khi thêm bộ lọc ADX, sự rút lui tối đa của chiến lược giảm 40%, mặc dù số lần giao dịch giảm 25%, nhưng lợi nhuận trung bình của một giao dịch tăng 20%. Đây là suy nghĩ giao dịch “ít hơn và tinh tế” điển hình.
Chiến lược hỗ trợ tính toán Supertrend trên các khung thời gian khác nhau, giải quyết các hạn chế của một khung thời gian duy nhất. Bạn có thể giao dịch trên biểu đồ 15 phút, nhưng sử dụng tín hiệu Supertrend trên biểu đồ 1 giờ, do đó duy trì sự linh hoạt trong hoạt động và tránh nhiễu nhiễu ngắn.
Ứng dụng thực tế được đề xuất: giao dịch đường ngắn sử dụng Supertrend với khung thời gian cao cấp, giao dịch đường giữa sử dụng khung thời gian hai cấp cao. Điều này có thể cải thiện đáng kể chất lượng tín hiệu.
Chiến lược này hoạt động tốt trong các thị trường có xu hướng, nhưng không hoạt động tốt trong các trường hợp sau:
Các trường hợp sử dụng thích hợp nhất: giao dịch xu hướng trong ngày của các cặp tiền tệ chính, giao dịch theo chu kỳ của chỉ số cổ phiếu, giao dịch ngắn và trung bình của tiền điện tử.
Bất kỳ chiến lược định lượng nào cũng có nguy cơ thất bại, và chiến lược này cũng không ngoại lệ. Mặc dù cơ chế xác nhận nhiều lần giúp tăng tỷ lệ thắng, nhưng nó cũng có thể thất bại khi cấu trúc thị trường thay đổi cơ bản.
Hãy nhớ rằng: Không có chiến lược nào đảm bảo lợi nhuận, và thị trường luôn có những rủi ro không thể đoán trước được.
/*backtest
start: 2025-01-05 00:00:00
end: 2026-01-03 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_OKX","currency":"ETH_USDT","balance":500000}]
*/
//@version=6
strategy("Multi-Timeframe Supertrend Strategy with Confirmations V1",
overlay=true,
default_qty_value=10)
// === INPUTS ===
// Strategy Direction
enableLong = input.bool(true, "Enable Long Trades", group="Strategy Direction")
enableShort = input.bool(true, "Enable Short Trades", group="Strategy Direction")
// Supertrend Settings
supertrendTf = input.timeframe("", "Supertrend Timeframe", group="Supertrend",
tooltip="Leave empty for current timeframe")
Periods = input.int(10, "ATR Period", minval=1, group="Supertrend")
Multiplier = input.float(3.0, "ATR Multiplier", minval=0.1, step=0.1, group="Supertrend")
changeATR = input.bool(true, "Change ATR Calculation Method ?", group="Supertrend")
// Confirmation Indicators
useRsi = input.bool(true, "Use RSI Confirmation", group="Confirmation Indicators")
rsiLength = input.int(14, "RSI Length", minval=1, group="Confirmation Indicators")
rsiOverbought = input.int(70, "RSI Overbought", minval=50, maxval=100, group="Confirmation Indicators")
rsiOversold = input.int(30, "RSI Oversold", minval=0, maxval=50, group="Confirmation Indicators")
useEma = input.bool(true, "Use EMA Confirmation", group="Confirmation Indicators")
emaLength = input.int(50, "EMA Length", minval=1, group="Confirmation Indicators")
useAdx = input.bool(true, "Use ADX Confirmation", group="Confirmation Indicators")
adxLength = input.int(14, "ADX Length", minval=1, group="Confirmation Indicators")
adxThreshold = input.int(25, "ADX Threshold", minval=10, group="Confirmation Indicators")
// Risk Management
trailPercent = input.float(1.5, "Trailing Stop %", minval=0.1, maxval=50, group="Risk Management") / 100
trailActivation = input.float(0.5, "Trail Activation %", minval=0.1, maxval=50, group="Risk Management") / 100
// === CALCULATIONS ===
// Function to calculate Supertrend on any timeframe using your exact code structure
supertrend_calc(tf) =>
// Request price data from specified timeframe
[srcHigh, srcLow, srcClose, srcOpen] = request.security(syminfo.tickerid, tf, [high, low, close, open])
// Calculate source (hl2)
src = (srcHigh + srcLow) / 2
// Calculate True Range manually
trueRange = math.max(srcHigh - srcLow, math.max(math.abs(srcHigh - srcClose[1]), math.abs(srcLow - srcClose[1])))
// Calculate ATR
atr2 = ta.sma(trueRange, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
// Calculate Supertrend bands
up = src - (Multiplier * atr)
up1 = nz(up[1], up)
up := srcClose[1] > up1 ? math.max(up, up1) : up
dn = src + (Multiplier * atr)
dn1 = nz(dn[1], dn)
dn := srcClose[1] < dn1 ? math.min(dn, dn1) : dn
// Determine trend
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and srcClose > dn1 ? 1 : trend == 1 and srcClose < up1 ? -1 : trend
[trend, up, dn]
// Get Supertrend values from selected timeframe
[supertrendTrend, supertrendUp, supertrendDn] = supertrend_calc(supertrendTf)
// RSI Calculation
rsiValue = ta.rsi(close, rsiLength)
rsiBullish = rsiValue < rsiOverbought
rsiBearish = rsiValue > rsiOversold
// EMA Calculation
emaValue = ta.ema(close, emaLength)
emaBullish = close > emaValue
emaBearish = close < emaValue
// ADX Calculation
[dip, din, adxValue] = ta.dmi(adxLength, adxLength)
adxBullish = adxValue >= adxThreshold and dip > din
adxBearish = adxValue >= adxThreshold and din > dip
// === ENTRY CONDITIONS ===
// Detect Supertrend flips using the multi-timeframe trend
bullishFlip = supertrendTrend == 1 and supertrendTrend[1] == -1
bearishFlip = supertrendTrend == -1 and supertrendTrend[1] == 1
// Combined confirmations
longConfirmations = true
shortConfirmations = true
if useRsi
longConfirmations := longConfirmations and rsiBullish
shortConfirmations := shortConfirmations and rsiBearish
if useEma
longConfirmations := longConfirmations and emaBullish
shortConfirmations := shortConfirmations and emaBearish
if useAdx
longConfirmations := longConfirmations and adxBullish
shortConfirmations := shortConfirmations and adxBearish
// Final entry conditions
enterLong = enableLong and bullishFlip and longConfirmations
enterShort = enableShort and bearishFlip and shortConfirmations
// === EXIT CONDITIONS ===
// Exit on opposite Supertrend signal
// Long exit: when Supertrend flips from green (1) to red (-1)
exitLongOnSignal = supertrendTrend == -1 and supertrendTrend[1] == 1
// Short exit: when Supertrend flips from red (-1) to green (1)
exitShortOnSignal = supertrendTrend == 1 and supertrendTrend[1] == -1
// === TRAILING STOP CALCULATION ===
// Variables to track trailing stops
var float longTrailPrice = na
var float longStopPrice = na
var float shortTrailPrice = na
var float shortStopPrice = na
// Variables for exit conditions
bool exitLongOnTrail = false
bool exitShortOnTrail = false
// Reset trailing stops when not in position
if strategy.position_size == 0
longTrailPrice := na
longStopPrice := na
shortTrailPrice := na
shortStopPrice := na
// Long position trailing stop logic
if strategy.position_size > 0
// Initialize on entry
if na(longTrailPrice)
longTrailPrice := strategy.position_avg_price
longStopPrice := strategy.position_avg_price * (1 - trailActivation)
// Update highest price since entry
if close > longTrailPrice
longTrailPrice := close
longStopPrice := close * (1 - trailActivation)
// Move stop up if price has moved favorably
if close >= longStopPrice * (1 + trailPercent)
// Calculate new stop price based on the trail percentage
longStopPrice := longTrailPrice * (1 - trailPercent)
// Check exit condition
exitLongOnTrail := close <= longStopPrice
// Short position trailing stop logic
if strategy.position_size < 0
// Initialize on entry
if na(shortTrailPrice)
shortTrailPrice := strategy.position_avg_price
shortStopPrice := strategy.position_avg_price * (1 + trailActivation)
// Update lowest price since entry
if close < shortTrailPrice
shortTrailPrice := close
shortStopPrice := close * (1 + trailActivation)
// Move stop down if price has moved favorably
if close <= shortStopPrice * (1 - trailPercent)
// Calculate new stop price based on the trail percentage
shortStopPrice := shortTrailPrice * (1 + trailPercent)
// Check exit condition
exitShortOnTrail := close >= shortStopPrice
// === STRATEGY EXECUTION ===
// Entry Orders
if enterLong
strategy.entry("Long", strategy.long, comment="Bullish Flip")
if enterShort
strategy.entry("Short", strategy.short, comment="Bearish Flip")
// Exit on trailing stop (if hit)
if strategy.position_size > 0 and exitLongOnTrail
strategy.close("Long", comment="Trailing Stop")
longTrailPrice := na
longStopPrice := na
if strategy.position_size < 0 and exitShortOnTrail
strategy.close("Short", comment="Trailing Stop")
shortTrailPrice := na
shortStopPrice := na
// Exit on opposite Supertrend signal (if trailing stop hasn't already triggered)
if strategy.position_size > 0 and exitLongOnSignal
strategy.close("Long", comment="Supertrend Flip Exit")
longTrailPrice := na
longStopPrice := na
if strategy.position_size < 0 and exitShortOnSignal
strategy.close("Short", comment="Supertrend Flip Exit")
shortTrailPrice := na
shortStopPrice := na
//==================== 图表绘制 ====================
//绘制Supertrend原始翻转信号(小圆点,未经确认过滤)
plotshape(bullishFlip, "Supertrend Flip Up", shape.circle,
location.belowbar, color=color.new(color.green, 50), size=size.tiny)
plotshape(bearishFlip, "Supertrend Flip Down", shape.circle,
location.abovebar, color=color.new(color.red, 50), size=size.tiny)
//绘制策略实际入场信号(通过确认条件过滤后的信号)
plotshape(enterLong, "Long Entry", shape.labelup, location.belowbar,
color=color.green, textcolor=color.white, size=size.small, text="Long")
plotshape(enterShort, "Short Entry", shape.labeldown, location.abovebar,
color=color.red, textcolor=color.white, size=size.small, text="Short")
//绘制出场信号
plotshape(exitLongOnSignal and strategy.position_size[1] > 0, "Long Exit Signal", shape.xcross,
location.abovebar, color=color.new(color.orange, 0), size=size.small)
plotshape(exitShortOnSignal and strategy.position_size[1] < 0, "Short Exit Signal", shape.xcross,
location.belowbar, color=color.new(color.orange, 0), size=size.small)
//绘制追踪止损线
plot(strategy.position_size > 0 ? longStopPrice : na, "Trailing Stop Long",
color=color.orange, style=plot.style_linebr, linewidth=2)
plot(strategy.position_size < 0 ? shortStopPrice : na, "Trailing Stop Short",
color=color.orange, style=plot.style_linebr, linewidth=2)
//==================== 警报设置 ====================
alertcondition(bullishFlip, "SuperTrend Buy", "SuperTrend Buy on {ticker}!")
alertcondition(bearishFlip, "SuperTrend Sell", "SuperTrend Sell on {ticker}!")
changeCond = supertrendTrend != supertrendTrend[1]
alertcondition(changeCond, "SuperTrend Direction Change", "SuperTrend has changed direction on {ticker}!")