88 行
3.3 KiB
Text
88 行
3.3 KiB
Text
|
|
//@version=5
|
||
|
|
strategy("LuxAlgo-Style Scalper [GPT-5]",
|
||
|
|
overlay=true,
|
||
|
|
margin_long=100,
|
||
|
|
margin_short=100,
|
||
|
|
default_qty_type=strategy.percent_of_equity,
|
||
|
|
default_qty_value=1,
|
||
|
|
pyramiding=10,
|
||
|
|
process_orders_on_close=true)
|
||
|
|
|
||
|
|
// === INPUTS ===
|
||
|
|
smaPeriod = input.int(21, "SMA Period")
|
||
|
|
stochLen = input.int(14, "Stoch RSI Length")
|
||
|
|
stochSmoothK = input.int(3, "Stoch RSI %K Smoothing")
|
||
|
|
stochSmoothD = input.int(3, "Stoch RSI %D Smoothing")
|
||
|
|
overbought = input.int(80, "Overbought level")
|
||
|
|
oversold = input.int(20, "Oversold level")
|
||
|
|
pivotLen = input.int(5, "Swing detection sensitivity")
|
||
|
|
tp_pips = input.float(10, "Take Profit (pips)", step=0.1)
|
||
|
|
sl_pips = input.float(20, "Stop Loss (pips)", step=0.1)
|
||
|
|
allowHedge = input.bool(true, "Allow Buy & Sell at same time?")
|
||
|
|
useSMAFilter = input.bool(true, "Use SMA Direction Filter?")
|
||
|
|
|
||
|
|
// === CALCULATIONS ===
|
||
|
|
|
||
|
|
// 21 SMA
|
||
|
|
sma21 = ta.sma(close, smaPeriod)
|
||
|
|
plot(sma21, color=color.orange, title="21 SMA")
|
||
|
|
|
||
|
|
// Stochastic RSI
|
||
|
|
rsi = ta.rsi(close, stochLen)
|
||
|
|
k = ta.sma(ta.stoch(rsi, rsi, rsi, stochLen), stochSmoothK)
|
||
|
|
d = ta.sma(k, stochSmoothD)
|
||
|
|
|
||
|
|
isOverbought = (k > overbought and d > overbought)
|
||
|
|
isOversold = (k < oversold and d < oversold)
|
||
|
|
|
||
|
|
// LuxAlgo-style swing highs/lows (replicated)
|
||
|
|
swingHigh = ta.pivothigh(high, pivotLen, pivotLen)
|
||
|
|
swingLow = ta.pivotlow(low, pivotLen, pivotLen)
|
||
|
|
|
||
|
|
plotshape(not na(swingHigh), title="Swing High", style=shape.triangledown, color=color.red, size=size.tiny, location=location.abovebar)
|
||
|
|
plotshape(not na(swingLow), title="Swing Low", style=shape.triangleup, color=color.green, size=size.tiny, location=location.belowbar)
|
||
|
|
|
||
|
|
// Get last swing type: 1 = low, -1 = high
|
||
|
|
var int lastSwing = 0
|
||
|
|
if not na(swingHigh)
|
||
|
|
lastSwing := -1
|
||
|
|
if not na(swingLow)
|
||
|
|
|
||
|
|
lastSwing := 1
|
||
|
|
|
||
|
|
// Price direction
|
||
|
|
priceAbove = close > sma21
|
||
|
|
priceBelow = close < sma21
|
||
|
|
|
||
|
|
// pip conversion
|
||
|
|
pip = syminfo.mintick * 10
|
||
|
|
tp = tp_pips * pip
|
||
|
|
sl = sl_pips * pip
|
||
|
|
|
||
|
|
// === TRADING LOGIC ===
|
||
|
|
|
||
|
|
// BUY when StochRSI oversold + recent swing low + (above SMA)
|
||
|
|
if isOversold and (lastSwing == 1) and (not useSMAFilter or priceAbove)
|
||
|
|
strategy.entry("Buy", strategy.long)
|
||
|
|
strategy.exit("Buy Exit", "Buy", limit=close + tp, stop=close - sl)
|
||
|
|
alert("BUY signal — StochRSI oversold + Swing Low + Above SMA", alert.freq_once_per_bar)
|
||
|
|
|
||
|
|
// SELL when StochRSI overbought + recent swing high + (below SMA)
|
||
|
|
if isOverbought and (lastSwing == -1) and (not useSMAFilter or priceBelow)
|
||
|
|
strategy.entry("Sell", strategy.short)
|
||
|
|
strategy.exit("Sell Exit", "Sell", limit=close - tp, stop=close + sl)
|
||
|
|
alert("SELL signal — StochRSI overbought + Swing High + Below SMA", alert.freq_once_per_bar)
|
||
|
|
|
||
|
|
// Optional hedging (neutral zone)
|
||
|
|
if allowHedge and not (isOversold or isOverbought)
|
||
|
|
if (not useSMAFilter or priceAbove)
|
||
|
|
strategy.entry("Buy-Hedge", strategy.long)
|
||
|
|
strategy.exit("Buy-Hedge Exit", "Buy-Hedge", limit=close + tp, stop=close - sl)
|
||
|
|
if (not useSMAFilter or priceBelow)
|
||
|
|
strategy.entry("Sell-Hedge", strategy.short)
|
||
|
|
strategy.exit("Sell-Hedge Exit", "Sell-Hedge", limit=close - tp, stop=close + sl)
|
||
|
|
|
||
|
|
// === VISUALS ===
|
||
|
|
hline(overbought, "Overbought", color=color.red, linestyle=hline.style_dotted)
|
||
|
|
hline(oversold, "Oversold", color=color.green, linestyle=hline.style_dotted)
|
||
|
|
bgcolor(isOversold ? color.new(color.green,85) : isOverbought ? color.new(color.red,85) : na)
|