
Bạn có biết không? Chiến lược này giống như một “trend radar” cực kỳ nhạy cảm! Nó không giống như một chiến lược theo đuổi mù quáng, mà giống như một người lướt sóng kiên nhẫn, chờ đợi cho làn sóng hoàn hảo nhất xuất hiện.
RSI động cơ 🚀
Hệ thống lọc EMA kép 📈
Một ngày một nguyên tắc 📅
Hãy tập trung vào việc thực hiện tối đa một giao dịch mỗi ngày, tránh những sai lầm thường xuyên. Điều này giống như một thợ săn giỏi sẽ không bắn mười con thỏ trong một ngày, mà sẽ tập trung vào việc bắn con chim béo nhất.
ATR dừng động 🛡️
Các trường hợp sử dụng tốt nhất:
Lưu ý:
Ý nghĩa của chiến lược này là “chờ gió đến”, không phải mọi ngày đều có cơ hội giao dịch hoàn hảo, nhưng một khi nó xuất hiện, tỷ lệ thành công sẽ rất cao!
/*backtest
start: 2025-07-01 00:00:00
end: 2025-10-08 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT","balance":500000}]
*/
//@version=6
strategy("FirstStrike Long 200 Daily Trend Rider [KedArc Quant]",
overlay=true,
initial_capital=100000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=10,
commission_type=strategy.commission.percent,
commission_value=0.01,
pyramiding=0,
calc_on_every_tick=false,
process_orders_on_close=true)
//@author [KedArc Quant]
//@created on 02-Sep-2025
// ========= Inputs =========
groupRSI = "RSI / Trigger"
rsiLen = input.int(14, "RSI Length", minval=2, tooltip="Period for RSI calculation.", group=groupRSI)
rsiTrigger = input.int(50, "Trigger Level (RSI >= this)", minval=1, maxval=99, tooltip="RSI must cross/sustain above this for entry.", group=groupRSI)
triggerMode = input.string("Any bar >= trigger", "Trigger mode", options=["Cross only", "Cross+Grace", "Cross+Grace+Sustain", "Any bar >= trigger"], tooltip="Modes for RSI trigger: 'Cross only' for precise, 'Any bar' for opportunistic.", group=groupRSI)
graceBars = input.int(30, "Grace window (bars) after cross", minval=0, maxval=500, tooltip="Bars after RSI cross where entry is still allowed if RSI >= trigger.", group=groupRSI)
sustainBars = input.int(3, "Sustain bars (RSI >= trigger)", minval=1, maxval=100, tooltip="Consecutive bars RSI must stay >= trigger for sustain mode.", group=groupRSI)
requireDip = input.bool(false, "Require RSI dip below Rearm before any entry?", tooltip="If true, needs RSI < Rearm level post-reset before entry.", group=groupRSI)
rsiRearm = input.int(45, "Rearm level (if requireDip=true)", minval=1, maxval=99, tooltip="RSI level below which a dip 'rearms' eligibility.", group=groupRSI)
groupEMA = "Trend / Filters"
emaFastLen = input.int(20, "EMA (fast) confirmation", minval=1, tooltip="Short EMA for price action filter (close > EMA).", group=groupEMA)
emaTrend = input.int(200, "EMA (trend filter)", minval=50, tooltip="Long EMA for overall trend (close > EMA200).", group=groupEMA)
groupTime = "Optional Hour Window"
useSession = input.bool(false, "Restrict by Session?", tooltip="Use TradingView session string for precise market hours.", group=groupTime)
sessionStr = input("0930-1600", "Session (e.g., 0930-1600 for NYSE)", tooltip="Session format: HHMM-HHMM in exchange timezone.", group=groupTime)
useTime = input.bool(false, "Restrict by Hour Range?", tooltip="Fallback to simple hour range if session not used.", group=groupTime)
startHour = input.int(9, "Start Hour", minval=0, maxval=23, group=groupTime)
endHour = input.int(15, "End Hour", minval=0, maxval=23, group=groupTime)
groupVol = "Volume Filter"
useVol = input.bool(false, "Require Volume > SMA?", tooltip="Filter entries to high-volume bars only.", group=groupVol)
volLen = input.int(20, "Volume SMA Length", minval=1, tooltip="SMA period for volume average.", group=groupVol)
groupRisk = "Risk / Exits"
atrLen = input.int(14, "ATR Length", minval=1, tooltip="Period for ATR volatility calculation.", group=groupRisk)
atrMult = input.float(1.5, "ATR Stop Multiplier", step=0.1, tooltip="Multiplier for initial stop-loss distance.", group=groupRisk)
riskRR = input.float(2.0, "Take-Profit R Multiple", step=0.1, tooltip="Risk-reward ratio for fixed TP.", group=groupRisk)
useTrail = input.bool(false, "Use Trailing Stop?", tooltip="Activate trailing stop after entry for trend capture.", group=groupRisk)
trailMult = input.float(2.0, "Trailing ATR Multiplier", step=0.1, tooltip="ATR multiplier for trailing stop distance.", group=groupRisk)
// ========= Calculations =========
hr = hour(time)
inSession = useSession ? time(timeframe.period, sessionStr) != 0 : true
inHours = useSession ? inSession : (useTime ? (hr >= startHour and hr <= endHour) : true)
emaFast = ta.ema(close, emaFastLen)
ema200 = ta.ema(close, emaTrend)
rsi = ta.rsi(close, rsiLen)
atr = ta.atr(atrLen)
volSMA = ta.sma(volume, volLen)
// Trend filters (long-only)
trendOK = close > ema200
priceOK = close > emaFast
volOK = useVol ? volume > volSMA : true
// ----- One-trade-per-day gate -----
newDay = ta.change(time("D"))
var bool tookTradeToday = false
if newDay != 0
tookTradeToday := false
// ----- Rearm (optional pullback requirement) -----
var bool rearmed = not requireDip
if requireDip and rsi < rsiRearm
rearmed := true
if newDay != 0
rearmed := not requireDip // Reset to false if required, else true
// ----- Trigger logic variants -----
crossNow = ta.crossover(rsi, rsiTrigger)
var int lastCrossBarIndex = na
if newDay != 0
lastCrossBarIndex := na
if crossNow
lastCrossBarIndex := bar_index
withinGrace = graceBars > 0 and not na(lastCrossBarIndex) and (bar_index - lastCrossBarIndex) <= graceBars and rsi >= rsiTrigger
// Sustain: RSI has been >= trigger for sustainBars consecutive bars
sinceBelow = ta.barssince(rsi < rsiTrigger)
sustainOK = not na(sinceBelow) and sinceBelow >= sustainBars
anyBarOK = rsi >= rsiTrigger
bool triggerOK = switch triggerMode
"Cross only" => crossNow
"Cross+Grace" => (crossNow or withinGrace)
"Cross+Grace+Sustain" => ((crossNow or withinGrace) and sustainOK) // AND for post-cross sustain
"Any bar >= trigger" => anyBarOK
// Final entry condition (one long per day)
longCond = inHours and trendOK and priceOK and rearmed and triggerOK and volOK and not tookTradeToday and strategy.position_size == 0
// ========= Orders =========
if longCond
strategy.entry("Long", strategy.long)
tookTradeToday := true
rearmed := false
label.new(bar_index, low, "LONG\nRSI:" + str.tostring(rsi, "#.#"), color=color.green, style=label.style_label_up, size=size.small)
if strategy.position_size > 0
avg = strategy.position_avg_price
stopPrice = avg - atrMult * atr
riskPS = avg - stopPrice
limitPx = avg + riskRR * riskPS
strategy.exit("TP/SL", from_entry="Long", stop=stopPrice, limit=limitPx)
if useTrail
trailStop = close - trailMult * atr // Simple close-based trail
strategy.exit("Trail", from_entry="Long", trail_price=trailStop, trail_offset=0)
// ========= Visuals (minimal) =========
plot(ema200, "EMA 200 (Trend)", color=color.new(color.blue, 0), linewidth=2)
plot(emaFast, "EMA Fast", color=color.new(color.orange, 0))
plot(strategy.position_size != 0 ? strategy.position_avg_price : na, "Entry Px", color=color.new(color.green, 0), style=plot.style_linebr)
bgcolor(longCond ? color.new(color.green, 90) : na, title="Entry Signal")
alertcondition(longCond, title="FirstStrike Long Entry", message="Long entry triggered at {{close}}")