
Vous savez, cette stratégie est comme un radar de tendance ultra-sensible. Ce n’est pas une stratégie de suivi aveugle, mais plutôt comme un surfeur patient qui attend la vague la plus parfaite. La logique de base est très simple: le RSI dépasse la ligne 50 + le prix est à l’EMA200 = la tendance arrive, poussez !
Moteur de puissance RSI 🚀
Système de filtrage à double EMA 📈
Le principe de la journée unique 📅
C’est comme un bon chasseur qui ne tue pas dix canards par jour, mais se concentre sur le plus gros.
Arrêt de la dynamique ATR 🛡️
Meilleur scénario:
À noter:
L’essence de cette stratégie est d’attendre que le vent se lève, il n’y a pas de bonnes opportunités de trading tous les jours, mais une fois qu’elles se présentent, le taux de réussite est élevé !
/*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}}")