
Anda tahu, strategi ini adalah seperti “radar trend” yang sangat sensitif. Ia bukan seperti strategi mengejar tanpa melihat, tetapi seperti seorang peselancar yang sabar menunggu gelombang yang sempurna untuk muncul.
RSI Engine 🚀
Sistem penapisan dua EMA 📈
Prinsip Satu Hari 📅
Buat satu transaksi sahaja sehari, dan elakkan percubaan yang kerap. Ia seperti pemburu yang baik tidak akan membunuh 10 ekor lembu dalam sehari, tetapi fokus untuk membunuh yang paling gemuk.
Kerosakan ATR dinamik 🛡️
Senario kegunaan terbaik:
Perhatian:
Strategi ini adalah strategi “wait and see” (tunggu dan lihat), kerana peluang perdagangan yang sempurna tidak akan muncul setiap hari, tetapi apabila ia muncul, ia akan berjaya!
/*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}}")