Changes: - moneyline_v11_2_indicator.pinescript: Alert format now includes SCORE:100 - parse_signal_enhanced.json: Added indicatorScore parsing (SCORE:X regex) - execute/route.ts: Added hasIndicatorScore bypass (score >= 90 bypasses quality check) - Money_Machine.json: Both Execute Trade nodes now pass indicatorScore to API Rationale: v11.2 indicator filters already optimized (2.544 PF, +51.80% return). Bot-side quality scoring was blocking proven profitable signals (e.g., quality 75). Now indicator passes SCORE:100, bot respects it and executes immediately. This completes the signal chain: Indicator (SCORE:100) → n8n parser (indicatorScore) → workflow → bot endpoint (bypass)
116 lines
5.3 KiB
Plaintext
116 lines
5.3 KiB
Plaintext
//@version=6
|
|
strategy("Breaker v1 SIMPLE", overlay=true, pyramiding=0, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
|
|
|
|
// =============================================================================
|
|
// SIMPLIFIED BREAKER - Removed squeeze/release complexity
|
|
// Core idea: BB breakout + EMA trend + minimal filters
|
|
// =============================================================================
|
|
|
|
// === TREND (proven in Money Line) ===
|
|
emaFastLen = input.int(50, "EMA Fast", minval=1, group="Trend")
|
|
emaSlowLen = input.int(200, "EMA Slow", minval=1, group="Trend")
|
|
|
|
// === BOLLINGER BANDS ===
|
|
bbLen = input.int(20, "BB Length", minval=5, group="BB")
|
|
bbMult = input.float(2.0, "BB Mult", minval=0.5, step=0.1, group="BB")
|
|
|
|
// === MINIMAL FILTERS ===
|
|
adxLen = input.int(14, "ADX Length", minval=5, group="Filters")
|
|
adxMin = input.int(15, "ADX Min", minval=0, maxval=50, group="Filters")
|
|
rsiLen = input.int(14, "RSI Length", minval=2, group="Filters")
|
|
rsiLongMin = input.float(55, "RSI Long Min", minval=0, maxval=100, group="Filters")
|
|
rsiLongMax = input.float(72, "RSI Long Max", minval=0, maxval=100, group="Filters")
|
|
rsiShortMin = input.float(28, "RSI Short Min", minval=0, maxval=100, group="Filters")
|
|
rsiShortMax = input.float(45, "RSI Short Max", minval=0, maxval=100, group="Filters")
|
|
cooldownBars = input.int(3, "Cooldown Bars", minval=0, group="Filters")
|
|
|
|
// === EXITS ===
|
|
tpPct = input.float(1.0, "TP %", minval=0.1, maxval=10, step=0.1, group="Exits")
|
|
slPct = input.float(0.5, "SL %", minval=0.1, maxval=10, step=0.1, group="Exits")
|
|
|
|
// =============================================================================
|
|
// CALCULATIONS
|
|
// =============================================================================
|
|
|
|
// EMAs
|
|
emaFast = ta.ema(close, emaFastLen)
|
|
emaSlow = ta.ema(close, emaSlowLen)
|
|
trendLong = emaFast > emaSlow
|
|
trendShort = emaFast < emaSlow
|
|
|
|
// Bollinger Bands
|
|
basis = ta.sma(close, bbLen)
|
|
dev = bbMult * ta.stdev(close, bbLen)
|
|
upper = basis + dev
|
|
lower = basis - dev
|
|
|
|
// BB breakout (simple close above/below)
|
|
bbBreakLong = close > upper
|
|
bbBreakShort = close < lower
|
|
|
|
// Indicators
|
|
rsi = ta.rsi(close, rsiLen)
|
|
[_, _, adxVal] = ta.dmi(adxLen, adxLen)
|
|
|
|
// Filter checks
|
|
adxOk = adxVal >= adxMin
|
|
rsiLongOk = rsi >= rsiLongMin and rsi <= rsiLongMax
|
|
rsiShortOk = rsi >= rsiShortMin and rsi <= rsiShortMax
|
|
|
|
// Cooldown
|
|
var int lastBar = 0
|
|
cooldownOk = bar_index - lastBar > cooldownBars
|
|
|
|
// =============================================================================
|
|
// SIGNALS - Simple: Trend + BB breakout + RSI + ADX
|
|
// =============================================================================
|
|
|
|
longSignal = trendLong and bbBreakLong and adxOk and rsiLongOk and cooldownOk
|
|
shortSignal = trendShort and bbBreakShort and adxOk and rsiShortOk and cooldownOk
|
|
|
|
// =============================================================================
|
|
// ENTRIES & EXITS
|
|
// =============================================================================
|
|
|
|
if longSignal
|
|
strategy.entry("Long", strategy.long)
|
|
lastBar := bar_index
|
|
|
|
if shortSignal
|
|
strategy.entry("Short", strategy.short)
|
|
lastBar := bar_index
|
|
|
|
// Exits
|
|
if strategy.position_size > 0
|
|
strategy.exit("L Exit", "Long", stop=strategy.position_avg_price * (1 - slPct/100), limit=strategy.position_avg_price * (1 + tpPct/100))
|
|
if strategy.position_size < 0
|
|
strategy.exit("S Exit", "Short", stop=strategy.position_avg_price * (1 + slPct/100), limit=strategy.position_avg_price * (1 - tpPct/100))
|
|
|
|
// =============================================================================
|
|
// PLOTS
|
|
// =============================================================================
|
|
|
|
plot(emaFast, "EMA 50", color=color.green, linewidth=1)
|
|
plot(emaSlow, "EMA 200", color=color.red, linewidth=1)
|
|
plot(upper, "BB Upper", color=color.teal)
|
|
plot(lower, "BB Lower", color=color.teal)
|
|
|
|
plotshape(longSignal, "Buy", location=location.belowbar, color=color.lime, style=shape.triangleup, size=size.small)
|
|
plotshape(shortSignal, "Sell", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)
|
|
|
|
// Debug table
|
|
var table dbg = table.new(position.top_right, 2, 6, bgcolor=color.new(color.black, 80))
|
|
if barstate.islast
|
|
table.cell(dbg, 0, 0, "Trend", text_color=color.white)
|
|
table.cell(dbg, 1, 0, trendLong ? "LONG ✓" : trendShort ? "SHORT ✓" : "FLAT", text_color=trendLong ? color.lime : trendShort ? color.red : color.gray)
|
|
table.cell(dbg, 0, 1, "BB Break", text_color=color.white)
|
|
table.cell(dbg, 1, 1, bbBreakLong ? "UP ✓" : bbBreakShort ? "DN ✓" : "none", text_color=bbBreakLong ? color.lime : bbBreakShort ? color.red : color.gray)
|
|
table.cell(dbg, 0, 2, "ADX", text_color=color.white)
|
|
table.cell(dbg, 1, 2, str.tostring(adxVal, "#.#") + (adxOk ? " ✓" : " ✗"), text_color=adxOk ? color.lime : color.red)
|
|
table.cell(dbg, 0, 3, "RSI", text_color=color.white)
|
|
table.cell(dbg, 1, 3, str.tostring(rsi, "#.#"), text_color=rsiLongOk or rsiShortOk ? color.lime : color.orange)
|
|
table.cell(dbg, 0, 4, "Cooldown", text_color=color.white)
|
|
table.cell(dbg, 1, 4, cooldownOk ? "OK ✓" : "wait", text_color=cooldownOk ? color.lime : color.orange)
|
|
table.cell(dbg, 0, 5, "Signal", text_color=color.white)
|
|
table.cell(dbg, 1, 5, longSignal ? "BUY!" : shortSignal ? "SELL!" : "—", text_color=longSignal ? color.lime : shortSignal ? color.red : color.gray)
|