Strategy · Pine Script v6 · On the chart

SR+Trend v6 APT

by MuhammadMuhamid

A long-only strategy preset tuned for one crypto pair, using multi-timeframe pivot support and resistance with tighter touch zones and shorter retest windows than the other versions.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code1,151
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update12 days ago17 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

1,151 lines of Pine Script v6 from untitled folder/SR_Uptrend_Strategy2.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

SR_Uptrend_Strategy2.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Combined strategy: SR+Trend v2 — MTF pivot S/R + filters (MA MTF, VWMA, SuperTrend, IMBA, LinReg, HTF ADX, MTF RSI/MACD) + MA exit + trailing
//
// --- 3Commas Signal bot (TradingView Strategy) ---
// 1) 3Commas → Signal bot → Alert type "TradingView Strategy" → copy webhook + JSON "secret" + "bot_uuid".
// 2) Webhook URL (Signal bots only): https://api.3commas.io/signal_bots/webhooks
// 3) TradingView alert: prefer "Order fills only" (not "… and alert()") when Signal delivery = 3Commas.
// 4) Properties → "Recalculate after order is filled": ON vs OFF uses a different backtest timeline (P&L can swing wildly — not a bug).
//    Keep the same setting you used while tuning. Exits below are NOT gated on bar close so recalc + stops still work.
// 5) Alert "Message": paste JSON from 3commas_alert_message_template.json (replace secret + bot_uuid only).
//    Keep {{timenow}}, {{close}}, {{strategy.order.action}}, etc. exactly — TradingView substitutes them.
// 6) Chart exchange + symbol must match your Signal bot pair (e.g. BINANCE:APTUSDT).
// Official spec: https://help.3commas.io/en/articles/9374557-signal-bot-json-file-for-strategy-type
// Set "Signal delivery" below to "3Commas Signal Bot" so Pine does NOT send custom FastAPI alert() JSON.
//@version=6
// SR_Uptrend_Strategy2.pine — APTUSDT Growth preset (Apr 2026 tuning). Original: SR_Uptrend_Strategy.pine
// Defaults target: more trades, higher net P&L, soft-exit gate, continuation longs, HH+RSI filters.
strategy("SR+Trend v6 APT", shorttitle="SR+Trend v6 APT", overlay = true,
     max_labels_count = 500, max_lines_count = 300,
     initial_capital = 1000, default_qty_type = strategy.cash, default_qty_value = 930,
     commission_type = strategy.commission.percent, commission_value = 0.05,
     slippage = 2, pyramiding = 0,
     calc_on_every_tick = false, calc_on_order_fills = false)

//------------------------------------------------------------------------------
// Groups
//------------------------------------------------------------------------------
string G_GEN      = "1 General"
string G_SR       = "2 Support / Resistance (MTF pivots)"
string G_TR_MA    = "3 Trend — Moving averages (MTF)"
string G_TR_ST    = "4 Trend — SuperTrend"
string G_TR_IMBA  = "5 Trend — IMBA-style channel"
string G_TR_LR    = "6 Trend — Linear regression"
string G_TR_VW    = "6b Trend — VWMA (optional)"
string G_TR_ADX   = "6c Trend — HTF ADX (optional)"
string G_TR_RSI   = "6d Trend — RSI (optional, MTF)"
string G_TR_MACD  = "6e Trend — MACD (optional, MTF)"
string G_TR_LOCAL = "3b Trend — Local EMA stack (micro)"
string G_TR_VOL   = "6f Volume filter (optional)"
string G_TR_HH    = "6g Higher-high structure (optional)"
string G_ENT_LONG = "7 Entries — Long (support)"
string G_ENT_SHRT = "8 Entries — Short (resistance)"
string G_EXIT     = "9 Risk — SL / TP / Trailing"
string G_VIS      = "10 Visualization"

//------------------------------------------------------------------------------
// General
//------------------------------------------------------------------------------
useBarConfirm = input.bool(true, "Signals on confirmed bar only", group = G_GEN,
     tooltip = "OFF = entry conditions can go true every tick → same-bar stop/re-entry loops + many 3Commas webhooks. Keep ON for live.")

// Gates new entries only — reduces realtime re-entry loops; does not delay exits.
ordersOnConfirmedBar = input.bool(true, "New entries: bar close only (3Commas)", group = G_GEN,
     tooltip = "When ON, only strategy.entry waits for barstate.isconfirmed. Exits are not delayed (Recalculate + stops work normally).")

cooldownBarsAfterExit = input.int(0, "Min bars after exit before new entry", minval = 0, maxval = 50, group = G_GEN,
     tooltip = "After a flat bar following a trade, wait this many extra bars before a new entry. 0 = off.")

signal_delivery = input.string("3Commas Signal Bot", "Signal delivery",
     options = ["3Commas Signal Bot", "Custom webhook bot", "Off"],
     group = G_GEN,
     tooltip = "3Commas: add a TradingView alert manually with 3Commas JSON + webhook (see header comment). Custom: FastAPI bot JSON via Pine alert().")

// --- Custom FastAPI webhook only (ignored for 3Commas) ---
string ALERT_SECRET = input.string("REPLACE_ME", "[Custom bot] secret → WEBHOOK_SECRET", group = G_GEN, display = display.none)
float alert_buy_usdt = input.float(800.0, "[Custom bot] BUY quote USDT", minval = 1, step = 1, group = G_GEN, display = display.none)
float alert_sell_base = input.float(0.001, "[Custom bot] SELL base qty", minval = 0.00000001, step = 0.001, group = G_GEN, display = display.none)
string alert_symbol = input.string("APTUSDT", "[Custom bot] symbol", group = G_GEN, display = display.none)

use_custom_webhook = signal_delivery == "Custom webhook bot"

//------------------------------------------------------------------------------
// SR — pivot-based MTF (per-TF pivot length)
//------------------------------------------------------------------------------
touchBandMode = input.string("ATR", "Touch zone mode", options = ["ATR", "Ticks"], group = G_SR)
touchAtrMult  = input.float(0.45, "Touch zone × ATR", step = 0.05, minval = 0.05, group = G_SR, inline = "tz")
touchTicks    = input.int(5, "or ticks", minval = 1, group = G_SR, inline = "tz")

srStrengthMin = input.int(1, "Minimum pivot touches", minval = 1, maxval = 10, group = G_SR,
     tooltip = "Count pivots on \"Strength TF\" that lie near an MTF S/R level.")
strengthTf = input.timeframe("15", "Strength: pivot-touch TF", group = G_SR,
     tooltip = "Pivots on this timeframe are compared to S/R levels for the touch-strength filter.")
strengthPivotLen = input.int(12, "Strength TF pivot length", minval = 3, maxval = 50, group = G_SR)

tf5_en = input.bool(true, "Use 5m S/R", group = G_SR, inline = "tf5")
pivLen5 = input.int(22, "", minval = 3, maxval = 50, group = G_SR, inline = "tf5")

tf15_en = input.bool(true, "Use 15m S/R", group = G_SR, inline = "tf15")
pivLen15 = input.int(18, "", minval = 3, maxval = 50, group = G_SR, inline = "tf15")

tf60_en = input.bool(true, "Use 1h S/R", group = G_SR, inline = "tf60")
pivLen60 = input.int(22, "", minval = 3, maxval = 50, group = G_SR, inline = "tf60")

tf240_en = input.bool(true, "Use 4h S/R", group = G_SR, inline = "tf240")
pivLen240 = input.int(8, "", minval = 3, maxval = 50, group = G_SR, inline = "tf240")

retestConfirmBars = input.int(5, "Bars after support touch to confirm entry", minval = 1, maxval = 30, group = G_SR,
     tooltip = "After price touches any MTF support, entry may fire on this bar or within the next N bars when trend filters align.")
priorAboveLb = input.int(2, "Pullback: prior bars close above support", minval = 1, maxval = 20, group = G_SR,
     tooltip = "Touch counts as a retest only if price was already above that support level on recent bars (pullback from above).")
blockBreakReclaim = input.bool(true, "Block pierce-and-reclaim entries", group = G_SR,
     tooltip = "OFF allows same-bar reclaim. ON blocks bars that pierce below support then close back above it (failed-break reclaim).")
reclaimPierceAtr = input.float(0.40, "Pierce below support (× ATR) = reclaim block", step = 0.05, minval = 0, group = G_SR)

useResFlipSup = input.bool(true, "Broken MTF resistance → support (retest longs)", group = G_SR,
     tooltip = "After a confirmed close above a pivot resistance level, treat that price as support on pullbacks until price closes clearly back below it or the pivot steps to a new level.")
flipConfirmOnClose = input.bool(false, "Flip on confirmed bar only", group = G_SR)
flipBreakBufAtr = input.float(0.05, "Flip when close above res (+ × ATR)", step = 0.05, minval = 0, group = G_SR)
flipInvalidBufAtr = input.float(0.2, "Unflip when close below res (− × ATR)", step = 0.05, minval = 0.01, group = G_SR)

//------------------------------------------------------------------------------
// MA MTF trend
//------------------------------------------------------------------------------
useMaTrend    = input.bool(true, "Require MA uptrend / downtrend", group = G_TR_MA)
maType        = input.string("SMA", "MA type (TF1–TF3)", options = ["SMA", "EMA", "WMA", "RMA", "VWMA"], group = G_TR_MA,
     tooltip = "VWMA uses volume on each MTF bar inside request.security.")
maBlockWhenNa = input.bool(false, "MA: block entries while MTF MA is na", group = G_TR_MA,
     tooltip = "OFF (default): if an enabled MTF MA is still na (warming up), that MA is ignored so 4h×200 does not freeze the whole backtest. ON: require a valid MA value.")
plotMaLines   = input.bool(true, "Plot MTF MA lines (TF1–TF3)", group = G_TR_MA)
requireMaSlope = input.bool(true, "Require enabled MAs to be rising (slope)", group = G_TR_MA,
     tooltip = "Each enabled MTF MA must be higher than N bars ago. Blocks flat or topping macro trends where close > MA but MA is not actually rising.")
maSlopeLb      = input.int(3, "MA slope lookback (chart bars)", minval = 1, maxval = 50, group = G_TR_MA,
     tooltip = "Compare MA now vs. this many chart bars ago. 3–5 bars on 5m = 15–25 minutes of slope verification.")

ma1_en = input.bool(true, "TF1", group = G_TR_MA, inline = "m1")
ma1_tf = input.timeframe("1", "", group = G_TR_MA, inline = "m1")
ma1_len = input.int(200, "", group = G_TR_MA, inline = "m1")

ma2_en = input.bool(false, "TF2", group = G_TR_MA, inline = "m2")
ma2_tf = input.timeframe("240", "", group = G_TR_MA, inline = "m2")
ma2_len = input.int(100, "", group = G_TR_MA, inline = "m2")

ma3_en = input.bool(true, "TF3", group = G_TR_MA, inline = "m3")
ma3_tf = input.timeframe("60", "", group = G_TR_MA, inline = "m3")
ma3_len = input.int(400, "", group = G_TR_MA, inline = "m3")

//------------------------------------------------------------------------------
// Local EMA stack (micro trend — 5m or chart TF)
//------------------------------------------------------------------------------
useLocalTrend    = input.bool(false, "Require local EMA trend alignment", group = G_TR_LOCAL,
     tooltip = "Fast EMA > slow EMA on the chosen TF confirms local directional bias. Use 5m to block entries when the 5m structure is down inside an HTF uptrend — the most common cause of false longs on 5m alts.")
localTrendTf     = input.timeframe("5", "Local EMA timeframe", group = G_TR_LOCAL,
     tooltip = "Set to your chart TF or one step above. 5m is ideal when executing on a 5m chart.")
localEmaFast     = input.int(21, "Fast EMA period", minval = 2, maxval = 200, group = G_TR_LOCAL)
localEmaSlow     = input.int(34, "Slow EMA period", minval = 2, maxval = 500, group = G_TR_LOCAL)
requireAboveFast = input.bool(false, "Also require close above fast EMA (long)", group = G_TR_LOCAL,
     tooltip = "For longs: close must also be above the fast EMA, not just EMA cross alignment. Adds momentum confirmation.")
plotLocalEma     = input.bool(false, "Plot local EMA lines", group = G_TR_LOCAL)

//------------------------------------------------------------------------------
// SuperTrend (optional HTF — computed on chosen TF, aligned to chart)
//------------------------------------------------------------------------------
useSuperTrend = input.bool(true, "Require SuperTrend alignment", group = G_TR_ST)
stTf          = input.timeframe("5", "SuperTrend timeframe", group = G_TR_ST,
     tooltip = "Must match your chart interval text when you want chart-TF SuperTrend (e.g. 15 on 15m). Use 60 / 240 for slower HTF filter while scalping on lower TF. MTF band uses hl2.")
stAtrLen      = input.int(15, "ATR period", minval = 1, group = G_TR_ST)
stMult        = input.float(2.5, "Multiplier", step = 0.1, minval = 0.1, group = G_TR_ST)
stSrc         = input.source(hl2, "Source (same TF as chart only)", group = G_TR_ST,
     tooltip = "Used only when SuperTrend timeframe equals your chart timeframe. HTF SuperTrend always uses hl2 on that TF.")

//------------------------------------------------------------------------------
// IMBA-style channel (fib band regime)
//------------------------------------------------------------------------------
useImba       = input.bool(false, "Require IMBA-style uptrend / downtrend", group = G_TR_IMBA)
imbaSens      = input.float(18.0, "Sensitivity (channel length)", step = 0.1, minval = 1, group = G_TR_IMBA)
imbaTf        = input.timeframe("60", "Channel timeframe", group = G_TR_IMBA,
     tooltip = "Fib channel is computed on this HTF. Set to the same string as your chart (e.g. 15, 60, 240) when you want it aligned with the chart resolution.")
imbaMode      = input.string("Regime", "IMBA mode", options = ["Regime", "Signal edge"], group = G_TR_IMBA,
     tooltip = "Regime: price vs mid-line & fib 236/786. Signal edge: uses internal long/short flip like original.")

//------------------------------------------------------------------------------
// LinReg filter (optional HTF smoothed OHLC)
//------------------------------------------------------------------------------
useLinReg     = input.bool(true, "Use LinReg candle filter", group = G_TR_LR)
lrTf          = input.timeframe("1", "LinReg timeframe", group = G_TR_LR,
     tooltip = "LinReg-smoothed OHLC on this TF, aligned to chart. Match chart TF string for native resolution.")
lrLen         = input.int(6, "LinReg length", minval = 2, group = G_TR_LR)
sigLen        = input.int(11, "Signal line length (chart TF)", minval = 1, group = G_TR_LR,
     tooltip = "SMA/EMA of LinReg close runs on chart bars after HTF alignment.")
sigUseSma     = input.bool(false, "Signal = SMA (off = EMA)", group = G_TR_LR)

//------------------------------------------------------------------------------
// Optional VWMA trend (separate from TF1–TF3 MA type)
//------------------------------------------------------------------------------
useVwmaTrend  = input.bool(true, "Require close above VWMA (HTF)", group = G_TR_VW)
vwmaTf        = input.timeframe("240", "VWMA timeframe", group = G_TR_VW)
vwmaLen       = input.int(200, "VWMA length", minval = 1, group = G_TR_VW)
plotVwmaLine  = input.bool(true, "Plot VWMA line", group = G_TR_VW)

//------------------------------------------------------------------------------
// Optional HTF ADX trend (classic +DI vs −DI with ADX floor)
//------------------------------------------------------------------------------
useAdxTrend   = input.bool(false, "Require ADX trend alignment", group = G_TR_ADX,
     tooltip = "Longs: +DI > −DI and ADX ≥ min. Shorts: −DI > +DI and ADX ≥ min. Computed on the ADX timeframe.")
adxTf         = input.timeframe("240", "ADX timeframe", group = G_TR_ADX)
adxLen        = input.int(14, "DI length", minval = 1, group = G_TR_ADX)
adxSmooth     = input.int(14, "ADX smoothing", minval = 1, group = G_TR_ADX)
adxMin        = input.float(18.0, "Min ADX for trend", step = 0.5, minval = 1, group = G_TR_ADX)

//------------------------------------------------------------------------------
// RSI (MTF) — Wilder RSI matches TradingView ta.rsi(); source is evaluated on the RSI timeframe
//------------------------------------------------------------------------------
useRsiFilter  = input.bool(true, "Require RSI filter", group = G_TR_RSI)
rsiTf         = input.timeframe("60", "RSI timeframe", group = G_TR_RSI)
rsiLen        = input.int(14, "RSI length", minval = 1, group = G_TR_RSI)
rsiSrcMode    = input.string("close", "Source on MTF", options = ["close", "open", "high", "low", "hl2", "hlc3", "ohlc4"], group = G_TR_RSI)
rsiLongMax    = input.float(75.0, "Long: max RSI (block overbought)", step = 1, minval = 1, maxval = 99, group = G_TR_RSI)
rsiLongMin    = input.float(42.0, "Long: min RSI (0 = off)", step = 1, minval = 0, maxval = 99, group = G_TR_RSI,
     tooltip = "Above 0: also block longs when RSI is below this (e.g. 40 = require some momentum).")
rsiShortMin   = input.float(30.0, "Short: min RSI (block oversold)", step = 1, minval = 1, maxval = 99, group = G_TR_RSI)
rsiShortMax   = input.float(100.0, "Short: max RSI (100 = off)", step = 1, minval = 1, maxval = 100, group = G_TR_RSI)

//------------------------------------------------------------------------------
// MACD (MTF) — same oscillator/signal MA choices as TV MACD script
//------------------------------------------------------------------------------
useMacdFilter = input.bool(false, "Require MACD filter", group = G_TR_MACD)
macdTf        = input.timeframe("60", "MACD timeframe", group = G_TR_MACD)
macdFast      = input.int(12, "Fast length", minval = 1, group = G_TR_MACD)
macdSlow      = input.int(26, "Slow length", minval = 1, group = G_TR_MACD)
macdSig       = input.int(9, "Signal length", minval = 1, group = G_TR_MACD)
macdOscType   = input.string("EMA", "Oscillator MA type", options = ["EMA", "SMA"], group = G_TR_MACD)
macdSigType   = input.string("EMA", "Signal MA type", options = ["EMA", "SMA"], group = G_TR_MACD)
macdRule      = input.string("Line vs signal", "MACD rule", options = ["Line vs signal", "Histogram vs 0"], group = G_TR_MACD,
     tooltip = "Line vs signal: longs need MACD > signal. Histogram: longs need histogram > 0.")

//------------------------------------------------------------------------------
// Volume filter (optional)
//------------------------------------------------------------------------------
useVolumeFilter  = input.bool(false, "Require above-average volume on entry", group = G_TR_VOL,
     tooltip = "Entry bar volume must be ≥ multiplier × SMA of volume. Filters low-conviction S/R touches on the chart timeframe.")
volMaLen         = input.int(20, "Volume SMA length", minval = 5, group = G_TR_VOL)
volMultMin       = input.float(1.2, "Min volume (× SMA)", step = 0.1, minval = 0.1, group = G_TR_VOL,
     tooltip = "1.0 = at-least-average volume; 1.5 = 50% above average. Start at 1.0 then raise if too many low-volume false entries pass.")

//------------------------------------------------------------------------------
// Higher-high structure filter (optional)
//------------------------------------------------------------------------------
useHhStructure   = input.bool(true, "Require higher-high structure (HTF longs)", group = G_TR_HH,
     tooltip = "Last confirmed pivot high on the chosen TF must be above the prior pivot high. Validates real HTF uptrend structure — blocks longs inside ranges that pass macro MA filters but are not making higher highs.")
hhTf             = input.timeframe("15", "Higher-high timeframe", group = G_TR_HH,
     tooltip = "15m or 1h recommended when executing on 5m. Higher TF = fewer but more significant structure checks.")
hhPivotLen       = input.int(7, "Pivot length (HH TF)", minval = 3, maxval = 30, group = G_TR_HH)

//------------------------------------------------------------------------------
// Long entries
//------------------------------------------------------------------------------
long_en       = input.bool(true, "Enable longs at support retest", group = G_ENT_LONG)
requireBounce = input.bool(false, "Legacy: same-bar close above touched level", group = G_ENT_LONG,
     tooltip = "OFF (recommended): use support retest window + trend filters. ON: also require close above the touched level on the entry bar.")
lrLongRule    = input.string("Green candle", "LinReg long rule", options = ["Green candle", "Close > signal", "Both"], group = G_ENT_LONG)

// Continuation / momentum long when price never pulls back to HTF support (breakout-style)
useContLong = input.bool(true, "Also enable continuation longs", group = G_ENT_LONG,
     tooltip = "Long when price breaks prior N-bar high with trend filters, without needing an S/R touch.")
contBreakLb = input.int(8, "Continuation: prior high lookback", minval = 2, maxval = 100, group = G_ENT_LONG)
contRequireGreen = input.bool(true, "Continuation: require green candle", group = G_ENT_LONG)
contRelaxStrength = input.bool(true, "Continuation: skip pivot-touch strength filter", group = G_ENT_LONG)
contExtraTpR      = input.float(1.5, "Continuation: extra TP when mode = R multiple", minval = 0, step = 0.25, group = G_ENT_LONG,
     tooltip = "Adds this many R multiples to take-profit when entry is continuation-only (touch path unchanged). Ignored if TP mode is not Risk multiple (R).")

//------------------------------------------------------------------------------
// Short entries
//------------------------------------------------------------------------------
short_en      = input.bool(false, "Enable shorts at resistance", group = G_ENT_SHRT,
     tooltip = "OFF = no short entries (you will still see exit markers for closed longs if enabled below).")
lrShortRule   = input.string("Red candle", "LinReg short rule", options = ["Red candle", "Close < signal", "Both"], group = G_ENT_SHRT)

//------------------------------------------------------------------------------
// Exits
//------------------------------------------------------------------------------
atrLenExit    = input.int(7, "ATR length (risk)", minval = 1, group = G_EXIT)

slMode        = input.string("Below structure & ATR", "Stop loss mode",
     options = ["ATR multiple", "Percent", "Below structure & ATR", "Swing low lookback"], group = G_EXIT)
slAtrMult     = input.float(0.65, "SL × ATR (from entry)", step = 0.1, minval = 0.1, group = G_EXIT)
slPct         = input.float(1.4, "SL percent (if Percent mode)", step = 0.05, minval = 0.05, group = G_EXIT)
slSwingLb     = input.int(25, "Swing low lookback bars", minval = 2, group = G_EXIT)
structBuff    = input.float(1.35, "Structure buffer × ATR under level", step = 0.05, group = G_EXIT)

tpMode        = input.string("Risk multiple (R)", "Take profit mode",
     options = ["Risk multiple (R)", "ATR multiple", "Percent"], group = G_EXIT)
tpR           = input.float(2.25, "TP as R multiple", step = 0.25, minval = 0.25, group = G_EXIT)
tpAtrMult     = input.float(12.0, "TP × ATR from entry", step = 0.25, minval = 0.25, group = G_EXIT)
tpPct         = input.float(1.5, "TP percent", step = 0.05, minval = 0.05, group = G_EXIT)

useTrail      = input.bool(true, "Trailing stop after TP trigger", group = G_EXIT)
trailTriggerR = input.float(1.0, "Activate trail after +R unrealized", step = 0.25, minval = 0.25, group = G_EXIT)
trailAtrMult  = input.float(1.5, "Trail distance × ATR", step = 0.1, minval = 0.1, group = G_EXIT)
trailStyle    = input.string("ATR from close (ratchet)", "Trailing style",
     options = ["ATR from close (ratchet)", "Chandelier (swing ± ATR)"],
     group = G_EXIT,
     tooltip = "Ratchet: stop follows close − ATR (default). Chandelier: stop = highest high since trail armed − ATR (longs); often fewer premature exits in trends.")

minSlDistAtr  = input.float(0.20, "Floor: min SL distance from entry (× ATR)", step = 0.05, minval = 0.05, group = G_EXIT,
     tooltip = "If structure/swing SL is tighter than this, widen to here — avoids instant stop-outs on noise.")
minRForSoftExit = input.float(1.0, "Soft exit gate: min unrealized R (0 = off)", step = 0.25, minval = 0, group = G_EXIT,
     tooltip = "Regime and micro exits (4h MA cross, SuperTrend, TF1 MA, LinReg) are suppressed until unrealized profit reaches this R multiple. Set 0.5–1.0 to prevent green-then-red exits during early trade development.")

// --- Confirmed HTF resistance break → optional open-ended exit + stronger trail ---
useHtfBreakTrail = input.bool(true, "HTF res break: cancel TP limit + trail runner", group = G_EXIT,
     tooltip = "While long, when price confirms a close above the chosen HTF pivot resistance, drop the fixed TP and use the breakout trailing settings so momentum can extend.")
htfResTf = input.timeframe("60", "HTF resistance timeframe", group = G_EXIT)
htfResPivotLen = input.int(9, "HTF pivot length (resistance)", minval = 3, maxval = 50, group = G_EXIT)
htfBreakConfirmMode = input.string("HTF candle close", "Resistance break confirmation",
     options = ["HTF candle close", "Chart close (aligned level)"],
     group = G_EXIT,
     tooltip = "HTF candle: pivot high & buffer evaluated on that timeframe with its bar close. Chart: uses the same pivot level aligned to the chart; confirmation uses chart bar close.")
htfBreakBufAtr = input.float(0.20, "Break buffer × ATR above resistance", step = 0.05, minval = 0, group = G_EXIT,
     tooltip = "Require close above resistance by this × ATR (chart ATR for chart mode; HTF ATR inside HTF mode).")

htfTrailImmediate = input.bool(true, "After break: arm trailing immediately", group = G_EXIT,
     tooltip = "If OFF, breakout trail still waits for +R using “After break: trail arms after +R”.")
htfTrailTriggerR = input.float(0.25, "After break: trail arms after +R (if not immediate)", step = 0.25, minval = 0, group = G_EXIT)
htfTrailAtrMult = input.float(0.85, "After break: trail distance × ATR", step = 0.1, minval = 0.1, group = G_EXIT,
     tooltip = "Usually slightly wider than normal trail so volatility does not stop you out during extension.")
htfResetTrailAnchorOnBreak = input.bool(true, "After break: reset trail anchor", group = G_EXIT,
     tooltip = "On first confirmed break bar, clear the trail anchor so the stop stair-steps from current price.")

// --- Exit position when MTF candle confirms close through MA (in addition to bracket SL) ---
useExitLongMa  = input.bool(true, "Exit long: MTF close crosses below MA", group = G_EXIT,
     tooltip = "Closes the long when a new candle on the exit timeframe confirms a close below the MA on that same timeframe.")
useExitShortMa = input.bool(false, "Exit short: MTF close crosses above MA", group = G_EXIT)
exitMaTf       = input.timeframe("240", "Exit MA timeframe", group = G_EXIT)
exitMaLen      = input.int(100, "Exit MA length", minval = 1, group = G_EXIT)
exitMaType     = input.string("SMA", "Exit MA type", options = ["SMA", "EMA", "WMA", "RMA", "VWMA"], group = G_EXIT)
plotExitMa     = input.bool(false, "Plot exit MA (aligned to chart)", group = G_EXIT)

// --- Close long when price loses key trend lines (confirmed bar) ---
useExitBelowSt   = input.bool(true, "Exit long: close below SuperTrend line", group = G_EXIT,
     tooltip = "Uses the aligned SuperTrend support line (up band in bull regime).")
useExitBelowMa1  = input.bool(false, "Exit long: close below TF1 MA", group = G_EXIT,
     tooltip = "Default TF1 = 1m × 200 when configured that way.")
useExitBelowLinReg = input.bool(false, "Exit long: close below LinReg close", group = G_EXIT,
     tooltip = "LinReg-smoothed close on the LinReg timeframe, aligned to chart.")

//------------------------------------------------------------------------------
// Visualization
//------------------------------------------------------------------------------
showSrPlots   = input.bool(true, "Plot MTF support/resistance lines", group = G_VIS)
showMarkers   = input.bool(true, "Plot Buy/Sell markers", group = G_VIS)
showHtfBreak = input.bool(true, "Marker when HTF break runner arms", group = G_VIS)
showFlipSup   = input.bool(true, "Plot levels acting as flipped support", group = G_VIS,
     tooltip = "Pivot highs that have broken above are drawn while treated as support (until invalidated).")
showImbaMid   = input.bool(true, "Plot IMBA mid-line (chart TF)", group = G_VIS)
showStBand    = input.bool(false, "Plot SuperTrend band", group = G_VIS)
showExitPnL   = input.bool(true, "Label P/L % when a trade closes", group = G_VIS,
     tooltip = "Shows approximate return for the last closed trade at the bar it closes.")
showCumPnL    = input.bool(true, "Show cumulative net P/L % (table, last bar)", group = G_VIS)

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
f_ma(string t, series float src, int length) =>
    float maS = ta.sma(src, length)
    float maE = ta.ema(src, length)
    float maW = ta.wma(src, length)
    float maR = ta.rma(src, length)
    float maV = ta.vwma(src, length)
    t == "SMA" ? maS : t == "EMA" ? maE : t == "WMA" ? maW : t == "VWMA" ? maV : maR

// MTF MA — series aligned to chart (always evaluate f_ma inside security for consistent history)
f_ma_mtf(string tf, float lenF, bool en) =>
    float mSec = request.security(syminfo.tickerid, tf,
         f_ma(maType, close, int(lenF)), barmerge.gaps_off, barmerge.lookahead_off)
    en and lenF > 0 ? mSec : na

// MTF VWMA aligned to chart (volume-weighted on that TF)
f_vwma_mtf(string tf, int lenV, bool en) =>
    float v = request.security(syminfo.tickerid, tf, ta.vwma(close, lenV), barmerge.gaps_off, barmerge.lookahead_off)
    en and lenV > 0 ? v : na

// ADX / DMI on HTF — call only inside request.security (float so na() is valid for "no HTF data")
// +1 bull, -1 bear, 0 neither (weak / flat DMI)
f_adx_trend_score() =>
    [dip, dim, adxv] = ta.dmi(adxLen, adxSmooth)
    dip > dim and adxv >= adxMin ? 1.0 : dim > dip and adxv >= adxMin ? -1.0 : 0.0

// RSI on the TF where this runs (for request.security)
f_rsi_tf() =>
    float srcR = switch rsiSrcMode
        "open" => open
        "high" => high
        "low" => low
        "hl2" => hl2
        "hlc3" => hlc3
        "ohlc4" => ohlc4
        => close
    ta.rsi(srcR, rsiLen)

// MACD bundle on the TF where this runs
macdOscMaTf(float src, int length, string typ) =>
    float e = ta.ema(src, length)
    float s = ta.sma(src, length)
    typ == "EMA" ? e : s

// Single-float MACD pieces for request.security (avoids tuple-destructure compile issues)
f_macd_md_only() =>
    float mf = macdOscMaTf(close, macdFast, macdOscType)
    float ms = macdOscMaTf(close, macdSlow, macdOscType)
    mf - ms

f_macd_sig_only() =>
    float mf = macdOscMaTf(close, macdFast, macdOscType)
    float ms = macdOscMaTf(close, macdSlow, macdOscType)
    float md = mf - ms
    macdOscMaTf(md, macdSig, macdSigType)

f_macd_hist_only() =>
    float mf = macdOscMaTf(close, macdFast, macdOscType)
    float ms = macdOscMaTf(close, macdSlow, macdOscType)
    float md = mf - ms
    float sg = macdOscMaTf(md, macdSig, macdSigType)
    md - sg

// MTF: confirmed candle closed through MA (evaluated on exitMaTf)
f_exit_ma_long_cross() =>
    float m = f_ma(exitMaType, close, exitMaLen)
    bool cu = ta.crossunder(close, m)
    bool bc = barstate.isconfirmed
    bc and cu

f_exit_ma_short_cross() =>
    float m = f_ma(exitMaType, close, exitMaLen)
    bool co = ta.crossover(close, m)
    bool bc = barstate.isconfirmed
    bc and co

// Latest confirmed pivot low / high on a timeframe (lookahead_off)
f_last_pivot_low(string tf, int len_) =>
    request.security(syminfo.tickerid, tf,
         ta.valuewhen(not na(ta.pivotlow(len_, len_)), ta.pivotlow(len_, len_), 0),
         barmerge.gaps_off, barmerge.lookahead_off)

f_last_pivot_high(string tf, int len_) =>
    request.security(syminfo.tickerid, tf,
         ta.valuewhen(not na(ta.pivothigh(len_, len_)), ta.pivothigh(len_, len_), 0),
         barmerge.gaps_off, barmerge.lookahead_off)

// Last two confirmed pivot highs on a timeframe (for higher-high structure filter)
f_hhph_last(int len_) =>
    ta.valuewhen(not na(ta.pivothigh(len_, len_)), ta.pivothigh(len_, len_), 0)

f_hhph_prior(int len_) =>
    ta.valuewhen(not na(ta.pivothigh(len_, len_)), ta.pivothigh(len_, len_), 1)

// SuperTrend bands + trend on the TF where this expression runs (for request.security)
f_super_trend_htf() =>
    atr_ = ta.atr(stAtrLen)
    src = hl2
    up = src - stMult * atr_
    up1 = nz(up[1], up)
    up := close[1] > up1 ? math.max(up, up1) : up
    dn = src + stMult * atr_
    dn1 = nz(dn[1], dn)
    dn := close[1] < dn1 ? math.min(dn, dn1) : dn
    tr = 1
    tr := nz(tr[1], 1)
    tr := tr == -1 and close > dn1 ? 1 : tr == 1 and close < up1 ? -1 : tr
    [up, dn, tr]

// LinReg OHLC bundle on the TF where this runs
f_linreg_ohlc(int lenLR) =>
    [ta.linreg(open, lenLR, 0), ta.linreg(high, lenLR, 0), ta.linreg(low, lenLR, 0), ta.linreg(close, lenLR, 0)]

// Latest pivot on strength TF (for touch-strength filter)
f_strength_pl(int len_) =>
    ta.valuewhen(not na(ta.pivotlow(len_, len_)), ta.pivotlow(len_, len_), 0)

f_strength_ph(int len_) =>
    ta.valuewhen(not na(ta.pivothigh(len_, len_)), ta.pivothigh(len_, len_), 0)

// Confirmed close above latest pivot high on the timeframe where this runs (for HTF break detection)
f_htf_close_above_resistance(int pivLen, float bufAtr) =>
    float lv = ta.valuewhen(not na(ta.pivothigh(pivLen, pivLen)), ta.pivothigh(pivLen, pivLen), 0)
    float atrh = ta.atr(atrLenExit)
    not na(lv) and barstate.isconfirmed and close > lv + bufAtr * atrh

// IMBA channel on optional TF
f_imba_channel(float sens, string tf) =>
    int period = int(sens * 10)
    period := math.max(period, 3)
    float hi = request.security(syminfo.tickerid, tf, ta.highest(high, period), barmerge.gaps_off, barmerge.lookahead_off)
    float lo = request.security(syminfo.tickerid, tf, ta.lowest(low, period), barmerge.gaps_off, barmerge.lookahead_off)
    float range_ = hi - lo
    float fib236 = hi - range_ * 0.236
    float fib786 = hi - range_ * 0.786
    float mid = hi - range_ * 0.5
    [hi, lo, fib236, fib786, mid]

//------------------------------------------------------------------------------
// Core series
//------------------------------------------------------------------------------
atr = ta.atr(atrLenExit)
tickSize = syminfo.mintick

float htfExitResLvl = useHtfBreakTrail ? f_last_pivot_high(htfResTf, htfResPivotLen) : na
bool htfResBreakHtfBar = request.security(syminfo.tickerid, htfResTf, f_htf_close_above_resistance(htfResPivotLen, htfBreakBufAtr), barmerge.gaps_off, barmerge.lookahead_off)
bool rawBreakHtfBar = useHtfBreakTrail and htfBreakConfirmMode == "HTF candle close" and htfResBreakHtfBar
bool rawBreakChartBar = useHtfBreakTrail and htfBreakConfirmMode == "Chart close (aligned level)" and not na(htfExitResLvl) and barstate.isconfirmed and close > htfExitResLvl + htfBreakBufAtr * atr
bool rawHtfResBreakNow = rawBreakHtfBar or rawBreakChartBar

float band = touchBandMode == "ATR" ? atr * touchAtrMult : touchTicks * tickSize

float sup5 = tf5_en ? f_last_pivot_low("5", pivLen5) : na
float sup15 = tf15_en ? f_last_pivot_low("15", pivLen15) : na
float sup60 = tf60_en ? f_last_pivot_low("60", pivLen60) : na
float sup240 = tf240_en ? f_last_pivot_low("240", pivLen240) : na

float res5 = tf5_en ? f_last_pivot_high("5", pivLen5) : na
float res15 = tf15_en ? f_last_pivot_high("15", pivLen15) : na
float res60 = tf60_en ? f_last_pivot_high("60", pivLen60) : na
float res240 = tf240_en ? f_last_pivot_high("240", pivLen240) : na

touchedSupport(lvl) =>
    not na(lvl) and low <= lvl + band

touchedResistance(lvl) =>
    not na(lvl) and high >= lvl - band

// Pierce below support then close back above — user wants to avoid this as entry
breakReclaimBar(lvl) =>
    not na(lvl) and low < lvl - reclaimPierceAtr * atr and close > lvl

// Pullback retest: price was above support, wick/tags the zone (not a deep reclaim candle)
retestSupportBar(lvl) =>
    if na(lvl)
        false
    else
        bool inZone = low <= lvl + band
        bool fromAbove = ta.lowest(close[1], priorAboveLb) > lvl
        bool reclaimOk = not blockBreakReclaim or not breakReclaimBar(lvl)
        inZone and fromAbove and reclaimOk

bounceLong(lvl) =>
    not requireBounce or (not na(lvl) and close > lvl)

bounceShort(lvl) =>
    not requireBounce or (not na(lvl) and close < lvl)

// --- Resistance → support flip (per TF pivot high) ---
var bool flipR5 = false
var bool flipR15 = false
var bool flipR60 = false
var bool flipR240 = false

if useResFlipSup
    float brkFlip = flipBreakBufAtr * atr
    float invFlip = flipInvalidBufAtr * atr
    bool okFlipBar = not flipConfirmOnClose or barstate.isconfirmed

    if barstate.isconfirmed
        if tf5_en and not na(res5) and not na(res5[1]) and res5 != res5[1]
            flipR5 := false
        if tf15_en and not na(res15) and not na(res15[1]) and res15 != res15[1]
            flipR15 := false
        if tf60_en and not na(res60) and not na(res60[1]) and res60 != res60[1]
            flipR60 := false
        if tf240_en and not na(res240) and not na(res240[1]) and res240 != res240[1]
            flipR240 := false

    if okFlipBar and tf5_en and not na(res5)
        if close > res5 + brkFlip
            flipR5 := true
        if flipR5 and close < res5 - invFlip
            flipR5 := false
    if okFlipBar and tf15_en and not na(res15)
        if close > res15 + brkFlip
            flipR15 := true
        if flipR15 and close < res15 - invFlip
            flipR15 := false
    if okFlipBar and tf60_en and not na(res60)
        if close > res60 + brkFlip
            flipR60 := true
        if flipR60 and close < res60 - invFlip
            flipR60 := false
    if okFlipBar and tf240_en and not na(res240)
        if close > res240 + brkFlip
            flipR240 := true
        if flipR240 and close < res240 - invFlip
            flipR240 := false

// Pullback to broken resistance (now acting as support)
touchFlipRetest(bool tfEn, bool flipped, float resLvl) =>
    useResFlipSup and tfEn and flipped and retestSupportBar(resLvl)

// Valid retest touch on any enabled MTF support (pullback from above, not break-reclaim)
bool retest5 = tf5_en and retestSupportBar(sup5)
bool retest15 = tf15_en and retestSupportBar(sup15)
bool retest60 = tf60_en and retestSupportBar(sup60)
bool retest240 = tf240_en and retestSupportBar(sup240)
bool retestFlip5 = touchFlipRetest(tf5_en, flipR5, res5)
bool retestFlip15 = touchFlipRetest(tf15_en, flipR15, res15)
bool retestFlip60 = touchFlipRetest(tf60_en, flipR60, res60)
bool retestFlip240 = touchFlipRetest(tf240_en, flipR240, res240)
bool retestLongNow = retest5 or retest15 or retest60 or retest240 or retestFlip5 or retestFlip15 or retestFlip60 or retestFlip240

touchLong = (tf5_en and touchedSupport(sup5)) or touchedSupport(sup15) or touchedSupport(sup60) or touchedSupport(sup240) or touchFlipRetest(tf5_en, flipR5, res5) or touchFlipRetest(tf15_en, flipR15, res15) or touchFlipRetest(tf60_en, flipR60, res60) or touchFlipRetest(tf240_en, flipR240, res240)

touchShort = (tf5_en and touchedResistance(res5) and not (useResFlipSup and flipR5)) or (tf15_en and touchedResistance(res15) and not (useResFlipSup and flipR15)) or (tf60_en and touchedResistance(res60) and not (useResFlipSup and flipR60)) or (tf240_en and touchedResistance(res240) and not (useResFlipSup and flipR240))

// Prefer higher timeframe level when multiple zones touched same bar
float nearestTouchSup = na
if touchedSupport(sup240) or touchFlipRetest(tf240_en, flipR240, res240)
    nearestTouchSup := touchedSupport(sup240) ? sup240 : res240
else if touchedSupport(sup60) or touchFlipRetest(tf60_en, flipR60, res60)
    nearestTouchSup := touchedSupport(sup60) ? sup60 : res60
else if touchedSupport(sup15) or touchFlipRetest(tf15_en, flipR15, res15)
    nearestTouchSup := touchedSupport(sup15) ? sup15 : res15
else if tf5_en and (touchedSupport(sup5) or touchFlipRetest(tf5_en, flipR5, res5))
    nearestTouchSup := touchedSupport(sup5) ? sup5 : res5

// Retest latch: after a valid pullback touch, allow entry when trend filters confirm (same bar or next N bars)
var int lastRetestBar = na
var float lastRetestLvl = na
if retestLongNow
    lastRetestBar := bar_index
    lastRetestLvl := retest240 ? sup240 : retest60 ? sup60 : retest15 ? sup15 : retest5 ? sup5 : retestFlip240 ? res240 : retestFlip60 ? res60 : retestFlip15 ? res15 : retestFlip5 ? res5 : na

int barsSinceRetest = na(lastRetestBar) ? 999999 : bar_index - lastRetestBar
bool recentRetestWindow = not na(lastRetestBar) and barsSinceRetest >= 0 and barsSinceRetest <= retestConfirmBars
bool retestLvlOk = not requireBounce or na(lastRetestLvl) or close > lastRetestLvl
bool retestEntryOk = recentRetestWindow and retestLvlOk and not (blockBreakReclaim and not na(lastRetestLvl) and breakReclaimBar(lastRetestLvl))

float nearestTouchRes = na
if tf240_en and touchedResistance(res240) and not (useResFlipSup and flipR240)
    nearestTouchRes := res240
else if tf60_en and touchedResistance(res60) and not (useResFlipSup and flipR60)
    nearestTouchRes := res60
else if tf15_en and touchedResistance(res15) and not (useResFlipSup and flipR15)
    nearestTouchRes := res15
else if tf5_en and touchedResistance(res5) and not (useResFlipSup and flipR5)
    nearestTouchRes := res5

//------------------------------------------------------------------------------
// Pivot taps near MTF level — pivots from chosen strength timeframe
//------------------------------------------------------------------------------
float lastPL_str = request.security(syminfo.tickerid, strengthTf, f_strength_pl(strengthPivotLen), barmerge.gaps_off, barmerge.lookahead_off)
float lastPH_str = request.security(syminfo.tickerid, strengthTf, f_strength_ph(strengthPivotLen), barmerge.gaps_off, barmerge.lookahead_off)

tapsNearLong(lvl) =>
    not na(lvl) and not na(lastPL_str) and math.abs(lastPL_str - lvl) <= band * 3 ? 1 : 0

tapsNearShort(lvl) =>
    not na(lvl) and not na(lastPH_str) and math.abs(lastPH_str - lvl) <= band * 3 ? 1 : 0

int strengthSumLong = (tf5_en ? tapsNearLong(sup5) : 0) + (tf15_en ? tapsNearLong(sup15) : 0) + (tf60_en ? tapsNearLong(sup60) : 0) + (tf240_en ? tapsNearLong(sup240) : 0)

int strengthFlipLong = (tf5_en and flipR5 ? tapsNearLong(res5) : 0) + (tf15_en and flipR15 ? tapsNearLong(res15) : 0) + (tf60_en and flipR60 ? tapsNearLong(res60) : 0) + (tf240_en and flipR240 ? tapsNearLong(res240) : 0)

int strengthSumShort = (tf5_en and not flipR5 ? tapsNearShort(res5) : 0) + (tf15_en and not flipR15 ? tapsNearShort(res15) : 0) + (tf60_en and not flipR60 ? tapsNearShort(res60) : 0) + (tf240_en and not flipR240 ? tapsNearShort(res240) : 0)

bool strengthOkLong = srStrengthMin <= 1 or strengthSumLong + strengthFlipLong >= srStrengthMin

bool strengthOkShort = srStrengthMin <= 1 or strengthSumShort >= srStrengthMin

float priorHighCont = ta.highest(high[1], contBreakLb)
bool deepSupTouch = touchedSupport(sup15) or touchedSupport(sup60) or touchedSupport(sup240)

//------------------------------------------------------------------------------
// MA trend (+ optional VWMA + HTF ADX)
//------------------------------------------------------------------------------
float ma1 = f_ma_mtf(ma1_tf, ma1_len, ma1_en)
float ma2 = f_ma_mtf(ma2_tf, ma2_len, ma2_en)
float ma3 = f_ma_mtf(ma3_tf, ma3_len, ma3_en)
float vwTrend = f_vwma_mtf(vwmaTf, vwmaLen, useVwmaTrend)

float adxTrendHt = request.security(syminfo.tickerid, adxTf, f_adx_trend_score(), barmerge.gaps_off, barmerge.lookahead_off)

// When MTF MA is na: ignore that MA unless "block when na" is ON (fixes 4h×200 freezing tester on short history / future ranges)
maPassLong(bool en, float m) =>
    not en ? true :
     maBlockWhenNa and na(m) ? false :
     not maBlockWhenNa and na(m) ? true :
     close > m

maPassShort(bool en, float m) =>
    not en ? true :
     maBlockWhenNa and na(m) ? false :
     not maBlockWhenNa and na(m) ? true :
     close < m

bool maUp =
     maPassLong(ma1_en, ma1) and
     maPassLong(ma2_en, ma2) and
     maPassLong(ma3_en, ma3)

bool maDn =
     maPassShort(ma1_en, ma1) and
     maPassShort(ma2_en, ma2) and
     maPassShort(ma3_en, ma3)

bool vwOkLong  = maPassLong(useVwmaTrend, vwTrend)
bool vwOkShort = maPassShort(useVwmaTrend, vwTrend)

bool adxLongOk  = not useAdxTrend or (na(adxTrendHt) ? not maBlockWhenNa : adxTrendHt > 0)
bool adxShortOk = not useAdxTrend or (na(adxTrendHt) ? not maBlockWhenNa : adxTrendHt < 0)

float rsiMtf = useRsiFilter ? request.security(syminfo.tickerid, rsiTf, f_rsi_tf(), barmerge.gaps_off, barmerge.lookahead_off) : na
float macdMtf = useMacdFilter ? request.security(syminfo.tickerid, macdTf, f_macd_md_only(), barmerge.gaps_off, barmerge.lookahead_off) : na
float macdSigMtf = useMacdFilter ? request.security(syminfo.tickerid, macdTf, f_macd_sig_only(), barmerge.gaps_off, barmerge.lookahead_off) : na
float macdHistMtf = useMacdFilter ? request.security(syminfo.tickerid, macdTf, f_macd_hist_only(), barmerge.gaps_off, barmerge.lookahead_off) : na

bool rsiOkLong =
     not useRsiFilter ? true :
     na(rsiMtf) ? not maBlockWhenNa :
     rsiMtf <= rsiLongMax and (rsiLongMin <= 0 or rsiMtf >= rsiLongMin)

bool rsiOkShort =
     not useRsiFilter ? true :
     na(rsiMtf) ? not maBlockWhenNa :
     rsiMtf >= rsiShortMin and rsiMtf <= rsiShortMax

bool macdOkLong =
     not useMacdFilter ? true :
     na(macdMtf) ? not maBlockWhenNa :
     macdRule == "Line vs signal" ? macdMtf > macdSigMtf : macdHistMtf > 0

bool macdOkShort =
     not useMacdFilter ? true :
     na(macdMtf) ? not maBlockWhenNa :
     macdRule == "Line vs signal" ? macdMtf < macdSigMtf : macdHistMtf < 0

float exitMaAligned = (useExitLongMa or useExitShortMa or plotExitMa) ? request.security(syminfo.tickerid, exitMaTf, f_ma(exitMaType, close, exitMaLen), barmerge.gaps_off, barmerge.lookahead_off) : na
bool exitLongMaTrigger  = useExitLongMa and request.security(syminfo.tickerid, exitMaTf, f_exit_ma_long_cross(), barmerge.gaps_off, barmerge.lookahead_off)
bool exitShortMaTrigger = useExitShortMa and request.security(syminfo.tickerid, exitMaTf, f_exit_ma_short_cross(), barmerge.gaps_off, barmerge.lookahead_off)

//------------------------------------------------------------------------------
// SuperTrend — chart TF (custom source) vs other TF via request.security (hl2)
//------------------------------------------------------------------------------
bool stIsChartTf = timeframe.in_seconds(timeframe.period) == timeframe.in_seconds(stTf)

float stAtr_c = ta.atr(stAtrLen)
float stUp_c = stSrc - stMult * stAtr_c
float stUp1_c = nz(stUp_c[1], stUp_c)
stUp_c := close[1] > stUp1_c ? math.max(stUp_c, stUp1_c) : stUp_c
float stDn_c = stSrc + stMult * stAtr_c
float stDn1_c = nz(stDn_c[1], stDn_c)
stDn_c := close[1] < stDn1_c ? math.min(stDn_c, stDn1_c) : stDn_c
var int stTrend_c = 1
stTrend_c := nz(stTrend_c[1], 1)
stTrend_c := stTrend_c == -1 and close > stDn1_c ? 1 : stTrend_c == 1 and close < stUp1_c ? -1 : stTrend_c

[stUp_h, stDn_h, stTrend_h] = request.security(syminfo.tickerid, stTf, f_super_trend_htf(), barmerge.gaps_off, barmerge.lookahead_off)

float stUp = stIsChartTf ? stUp_c : stUp_h
float stDn = stIsChartTf ? stDn_c : stDn_h
int stTrendVal = stIsChartTf ? stTrend_c : int(stTrend_h)

bool stBull = stTrendVal == 1
bool stBear = stTrendVal == -1

//------------------------------------------------------------------------------
// IMBA
//------------------------------------------------------------------------------
[imHi, imLo, fib236, fib786, imMid] = f_imba_channel(imbaSens, imbaTf)

var bool is_long_trend = false
var bool is_short_trend = false
bool can_long_imba = close >= imMid and close >= fib236 and not is_long_trend
bool can_short_imba = close <= imMid and close <= fib786 and not is_short_trend

if can_long_imba
    is_long_trend := true
    is_short_trend := false
else if can_short_imba
    is_short_trend := true
    is_long_trend := false

bool imbaRegimeLong = close >= imMid and close >= fib236
bool imbaRegimeShort = close <= imMid and close <= fib786

bool imbaOkLong = not useImba ? true : imbaMode == "Regime" ? imbaRegimeLong : is_long_trend
bool imbaOkShort = not useImba ? true : imbaMode == "Regime" ? imbaRegimeShort : is_short_trend

//------------------------------------------------------------------------------
// LinReg filter (optional TF via request.security)
//------------------------------------------------------------------------------
[lrO, lrH, lrL, lrC] = request.security(syminfo.tickerid, lrTf, f_linreg_ohlc(lrLen), barmerge.gaps_off, barmerge.lookahead_off)
float bopen = useLinReg ? lrO : open
float bhigh = useLinReg ? lrH : high
float blow = useLinReg ? lrL : low
float bclose = useLinReg ? lrC : close

float sigSma = ta.sma(bclose, sigLen)
float sigEma = ta.ema(bclose, sigLen)
float sig = sigUseSma ? sigSma : sigEma

bool lrGreen = bopen < bclose
bool lrRed = bopen > bclose

bool lrLongOk =
     not useLinReg ? true :
     lrLongRule == "Green candle" ? lrGreen :
     lrLongRule == "Close > signal" ? bclose > sig :
     lrGreen and bclose > sig

bool lrShortOk =
     not useLinReg ? true :
     lrShortRule == "Red candle" ? lrRed :
     lrShortRule == "Close < signal" ? bclose < sig :
     lrRed and bclose < sig

// MA slope filter — each enabled MA must be higher than N bars ago (actually rising)
bool ma1SlopeOk   = not requireMaSlope or not ma1_en or na(ma1) or na(ma1[maSlopeLb]) or ma1 > ma1[maSlopeLb]
bool ma2SlopeOk   = not requireMaSlope or not ma2_en or na(ma2) or na(ma2[maSlopeLb]) or ma2 > ma2[maSlopeLb]
bool ma3SlopeOk   = not requireMaSlope or not ma3_en or na(ma3) or na(ma3[maSlopeLb]) or ma3 > ma3[maSlopeLb]
bool ma1SlopeDnOk = not requireMaSlope or not ma1_en or na(ma1) or na(ma1[maSlopeLb]) or ma1 < ma1[maSlopeLb]
bool ma2SlopeDnOk = not requireMaSlope or not ma2_en or na(ma2) or na(ma2[maSlopeLb]) or ma2 < ma2[maSlopeLb]
bool ma3SlopeDnOk = not requireMaSlope or not ma3_en or na(ma3) or na(ma3[maSlopeLb]) or ma3 < ma3[maSlopeLb]
bool maSlopeOkLong  = ma1SlopeOk  and ma2SlopeOk  and ma3SlopeOk
bool maSlopeOkShort = ma1SlopeDnOk and ma2SlopeDnOk and ma3SlopeDnOk

// Local EMA stack (micro trend — 5m or chart TF)
float localFastEma   = useLocalTrend ? request.security(syminfo.tickerid, localTrendTf, ta.ema(close, localEmaFast), barmerge.gaps_off, barmerge.lookahead_off) : na
float localSlowEma   = useLocalTrend ? request.security(syminfo.tickerid, localTrendTf, ta.ema(close, localEmaSlow), barmerge.gaps_off, barmerge.lookahead_off) : na
bool localTrendOkLong  = not useLocalTrend or (not na(localFastEma) and not na(localSlowEma) and localFastEma > localSlowEma and (not requireAboveFast or close > localFastEma))
bool localTrendOkShort = not useLocalTrend or (not na(localFastEma) and not na(localSlowEma) and localFastEma < localSlowEma and (not requireAboveFast or close < localFastEma))

// Volume filter — chart-TF bar volume vs. SMA
float volMaSeries = useVolumeFilter ? ta.sma(volume, volMaLen) : na
bool volOkLong    = not useVolumeFilter or (not na(volMaSeries) and volMaSeries > 0 and volume >= volMultMin * volMaSeries)
bool volOkShort   = not useVolumeFilter or (not na(volMaSeries) and volMaSeries > 0 and volume >= volMultMin * volMaSeries)

// Higher-high structure — last HTF pivot high must be above prior pivot high
float hhLastPH  = useHhStructure ? request.security(syminfo.tickerid, hhTf, f_hhph_last(hhPivotLen),  barmerge.gaps_off, barmerge.lookahead_off) : na
float hhPriorPH = useHhStructure ? request.security(syminfo.tickerid, hhTf, f_hhph_prior(hhPivotLen), barmerge.gaps_off, barmerge.lookahead_off) : na
bool hhOkLong   = not useHhStructure or (not na(hhLastPH) and not na(hhPriorPH) and hhLastPH > hhPriorPH)

//------------------------------------------------------------------------------
// Filters assembly
//------------------------------------------------------------------------------
bool filtLong =
     (not useMaTrend or maUp) and
     maSlopeOkLong and
     (not useSuperTrend or stBull) and
     imbaOkLong and lrLongOk and vwOkLong and adxLongOk and rsiOkLong and macdOkLong and
     localTrendOkLong and volOkLong and hhOkLong

bool filtShort =
     (not useMaTrend or maDn) and
     maSlopeOkShort and
     (not useSuperTrend or stBear) and
     imbaOkShort and lrShortOk and vwOkShort and adxShortOk and rsiOkShort and macdOkShort and
     localTrendOkShort and volOkShort

bool touchPathLong = long_en and retestEntryOk and filtLong and strengthOkLong
bool contPathLong = useContLong and long_en and filtLong and not deepSupTouch and close > priorHighCont and (not contRequireGreen or close > open) and (contRelaxStrength ? true : strengthOkLong)
bool isContEntry = contPathLong and not touchPathLong

confirmed = not useBarConfirm or barstate.isconfirmed

//------------------------------------------------------------------------------
// Stops / targets from entry reference (computed at signal bar)
//------------------------------------------------------------------------------
float swingLow = ta.lowest(low, slSwingLb)

calcLongStop(float entry, float lvl) =>
    float slAtr = entry - slAtrMult * atr
    float slPct_ = entry * (1 - slPct / 100)
    float slStruct = na(lvl) ? slAtr : lvl - structBuff * atr
    float slSwing = swingLow
    float sl = slAtr
    switch slMode
        "ATR multiple" => sl := slAtr
        "Percent" => sl := slPct_
        "Below structure & ATR" => sl := math.min(slAtr, math.min(slStruct, slSwing))
        => sl := math.min(slAtr, slSwing)
    float floor = entry - minSlDistAtr * atr
    math.min(sl, floor)

calcShortStop(float entry, float lvl) =>
    float slAtr = entry + slAtrMult * atr
    float slPct_ = entry * (1 + slPct / 100)
    float slStruct = na(lvl) ? slAtr : lvl + structBuff * atr
    float slSwing = ta.highest(high, slSwingLb)
    float sl = slAtr
    switch slMode
        "ATR multiple" => sl := slAtr
        "Percent" => sl := slPct_
        "Below structure & ATR" => sl := math.max(slAtr, math.max(slStruct, slSwing))
        => sl := math.max(slAtr, slSwing)
    float ceil = entry + minSlDistAtr * atr
    math.max(sl, ceil)

calcLongTp(float entry, float stop_, float rMultOverride = na) =>
    float risk = entry - stop_
    float rUse = na(rMultOverride) ? tpR : rMultOverride
    switch tpMode
        "Risk multiple (R)" => entry + risk * rUse
        "ATR multiple" => entry + tpAtrMult * atr
        => entry * (1 + tpPct / 100)

calcShortTp(float entry, float stop_) =>
    float risk = stop_ - entry
    switch tpMode
        "Risk multiple (R)" => entry - risk * tpR
        "ATR multiple" => entry - tpAtrMult * atr
        => entry * (1 - tpPct / 100)

var float savedLongStop = na
var float savedLongTp = na
var float savedShortStop = na
var float savedShortTp = na
var float trailAnchorLong = na
var float trailAnchorShort = na
var bool trailActiveLong = false
var bool trailActiveShort = false
var bool longHtfBreakMode = false
var float trailSwingHiLong = na
var float trailSwingLoShort = na

// Exit bar index after any close → cooldown against same-bar / next-tick re-entry loops
var int lastExitToFlatBar = na
if strategy.position_size == 0 and strategy.position_size[1] != 0
    lastExitToFlatBar := bar_index

int barsSinceExitFlat = na(lastExitToFlatBar) ? 999999 : bar_index - lastExitToFlatBar
bool cooldownExitOk = cooldownBarsAfterExit <= 0 or na(lastExitToFlatBar) or barsSinceExitFlat > cooldownBarsAfterExit

bool entryBarOk = not ordersOnConfirmedBar or barstate.isconfirmed

bool rawLongSetup = confirmed and strategy.position_size == 0 and (touchPathLong or contPathLong)
bool rawShortSetup = short_en and confirmed and strategy.position_size == 0 and touchShort and filtShort and bounceShort(nearestTouchRes) and strengthOkShort

bool longSignal = rawLongSetup and cooldownExitOk and entryBarOk
bool shortSignal = rawShortSetup and cooldownExitOk and entryBarOk

var float lastPubLongStop = na
var float lastPubLongTp = na
var float lastPubShortStop = na
var float lastPubShortTp = na

if longSignal
    longHtfBreakMode := false
    float lvlStop = isContEntry ? na : (na(lastRetestLvl) ? nearestTouchSup : lastRetestLvl)
    lastRetestBar := na
    float sl = calcLongStop(close, lvlStop)
    float rAdj = isContEntry and tpMode == "Risk multiple (R)" ? tpR + contExtraTpR : na
    float tp = calcLongTp(close, sl, rAdj)
    savedLongStop := sl
    savedLongTp := tp
    trailAnchorLong := na
    trailActiveLong := false
    trailSwingHiLong := na
    lastPubLongStop := na
    lastPubLongTp := na
    strategy.entry("Long", strategy.long)

if shortSignal
    float sl = calcShortStop(close, nearestTouchRes)
    float tp = calcShortTp(close, sl)
    savedShortStop := sl
    savedShortTp := tp
    trailAnchorShort := na
    trailActiveShort := false
    trailSwingLoShort := na
    lastPubShortStop := na
    lastPubShortTp := na
    strategy.entry("Short", strategy.short)

float stLineLong = stBull ? stUp : stDn
bool exitBelowStNow = useExitBelowSt and not na(stLineLong) and close < stLineLong
bool exitBelowMa1Now = useExitBelowMa1 and ma1_en and not na(ma1) and close < ma1
bool exitBelowLrNow = useExitBelowLinReg and useLinReg and close < bclose
// Soft exit R gate — suppress regime/micro exits until trade reaches minimum unrealized R
float longUnrealR   = strategy.position_size > 0 and not na(savedLongStop) and strategy.position_avg_price > savedLongStop ? (close - strategy.position_avg_price) / (strategy.position_avg_price - savedLongStop) : 0.0
bool softExitRGateOk = minRForSoftExit <= 0 or longUnrealR >= minRForSoftExit
bool exitLongSignalNow = strategy.position_size > 0 and confirmed and softExitRGateOk and (exitLongMaTrigger or exitBelowStNow or exitBelowMa1Now or exitBelowLrNow)
bool maCloseLongNow = exitLongSignalNow
bool maCloseShortNow = strategy.position_size < 0 and exitShortMaTrigger
if maCloseLongNow
    string exitWhy = exitLongMaTrigger ? "MTF MA exit" : exitBelowStNow ? "Below ST" : exitBelowMa1Now ? "Below TF1 MA" : "Below LinReg"
    strategy.close("Long", comment = exitWhy)
if maCloseShortNow
    strategy.close("Short", comment = "MTF MA exit")

// Long: latch HTF resistance breakout → runner trail + optional TP removal
if strategy.position_size > 0 and rawHtfResBreakNow
    bool firstHtfBreak = not longHtfBreakMode
    longHtfBreakMode := true
    if firstHtfBreak and htfResetTrailAnchorOnBreak
        trailAnchorLong := na
        trailSwingHiLong := na

// Bracket: update 3Commas / exchange only when stop or TP meaningfully changes (avoids per-tick order spam)
tickEps = syminfo.mintick * 2
if strategy.position_size > 0 and not na(savedLongStop) and not na(savedLongTp) and not maCloseLongNow
    float limitTpLong = longHtfBreakMode ? na : savedLongTp
    float risk = strategy.position_avg_price - savedLongStop
    bool trailLongEff = useTrail or longHtfBreakMode
    float trTrigEff = longHtfBreakMode ? htfTrailTriggerR : trailTriggerR
    float trMultEff = longHtfBreakMode ? htfTrailAtrMult : trailAtrMult
    bool armTrailProfit = risk > 0 and high >= strategy.position_avg_price + risk * trTrigEff
    bool armTrailBreak = longHtfBreakMode and htfTrailImmediate
    if trailLongEff and (armTrailBreak or armTrailProfit)
        trailActiveLong := true
    float trailLvl = na
    if trailActiveLong and trailLongEff
        if trailStyle == "Chandelier (swing ± ATR)"
            trailSwingHiLong := na(trailSwingHiLong) ? high : math.max(trailSwingHiLong, high)
            trailLvl := trailSwingHiLong - trMultEff * atr
        else
            trailLvl := na(trailAnchorLong) ? close - trMultEff * atr : math.max(trailAnchorLong, close - trMultEff * atr)
            trailAnchorLong := trailLvl
    float stopUse = trailActiveLong and not na(trailLvl) ? math.max(savedLongStop, trailLvl) : savedLongStop
    bool tpLegChanged = not (na(limitTpLong) and na(lastPubLongTp)) and (na(limitTpLong) or na(lastPubLongTp) or math.abs(limitTpLong - lastPubLongTp) >= tickEps)
    bool longBracketChanged = na(lastPubLongStop) or math.abs(stopUse - lastPubLongStop) >= tickEps or tpLegChanged
    if longBracketChanged
        strategy.exit("Long X", from_entry = "Long", stop = stopUse, limit = limitTpLong)
        lastPubLongStop := stopUse
        lastPubLongTp := limitTpLong

if strategy.position_size < 0 and not na(savedShortStop) and not na(savedShortTp) and not maCloseShortNow
    float risk = savedShortStop - strategy.position_avg_price
    if useTrail and risk > 0 and low <= strategy.position_avg_price - risk * trailTriggerR
        trailActiveShort := true
    float trailLvl = na
    if trailActiveShort and useTrail
        if trailStyle == "Chandelier (swing ± ATR)"
            trailSwingLoShort := na(trailSwingLoShort) ? low : math.min(trailSwingLoShort, low)
            trailLvl := trailSwingLoShort + trailAtrMult * atr
        else
            trailLvl := na(trailAnchorShort) ? close + trailAtrMult * atr : math.min(trailAnchorShort, close + trailAtrMult * atr)
            trailAnchorShort := trailLvl
    float stopUse = trailActiveShort and not na(trailLvl) ? math.min(savedShortStop, trailLvl) : savedShortStop
    bool shortBracketChanged = na(lastPubShortStop) or math.abs(stopUse - lastPubShortStop) >= tickEps or na(lastPubShortTp) or math.abs(savedShortTp - lastPubShortTp) >= tickEps
    if shortBracketChanged
        strategy.exit("Short X", from_entry = "Short", stop = stopUse, limit = savedShortTp)
        lastPubShortStop := stopUse
        lastPubShortTp := savedShortTp

// Reset saved stops only when flat AND not opening a position this bar.
// On the entry bar, position_size is still 0 — clearing here removes SL/TP before any exit order runs,
// so the position stays open forever and no second trade can occur.
flat = strategy.position_size == 0
if flat and not longSignal and not shortSignal
    savedLongStop := na
    savedLongTp := na
    savedShortStop := na
    savedShortTp := na
    trailAnchorLong := na
    trailAnchorShort := na
    trailActiveLong := false
    trailActiveShort := false
    trailSwingHiLong := na
    trailSwingLoShort := na
    longHtfBreakMode := false
    lastPubLongStop := na
    lastPubLongTp := na
    lastPubShortStop := na
    lastPubShortTp := na

//------------------------------------------------------------------------------
// Plotting
//------------------------------------------------------------------------------
plot(showSrPlots and tf5_en ? sup5 : na, "Support 5m", color = color.new(color.aqua, 40), linewidth = 1, style = plot.style_linebr)
plot(showSrPlots ? sup15 : na, "Support 15m", color = color.new(color.teal, 30), linewidth = 1, style = plot.style_linebr)
plot(showSrPlots ? sup60 : na, "Support 1h", color = color.new(color.green, 30), linewidth = 2, style = plot.style_linebr)
plot(showSrPlots ? sup240 : na, "Support 4h", color = color.new(color.lime, 30), linewidth = 2, style = plot.style_linebr)

plot(showSrPlots and tf5_en and not (showFlipSup and flipR5) ? res5 : na, "Resistance 5m", color = color.new(color.yellow, 50), linewidth = 1, style = plot.style_linebr)
plot(showSrPlots and tf15_en and not (showFlipSup and flipR15) ? res15 : na, "Resistance 15m", color = color.new(color.orange, 30), linewidth = 1, style = plot.style_linebr)
plot(showSrPlots and tf60_en and not (showFlipSup and flipR60) ? res60 : na, "Resistance 1h", color = color.new(color.red, 30), linewidth = 2, style = plot.style_linebr)
plot(showSrPlots and tf240_en and not (showFlipSup and flipR240) ? res240 : na, "Resistance 4h", color = color.new(color.maroon, 30), linewidth = 2, style = plot.style_linebr)

plot(showSrPlots and showFlipSup and tf5_en and flipR5 ? res5 : na, "5m broken res → sup", color = color.new(color.lime, 0), linewidth = 2, style = plot.style_linebr)
plot(showSrPlots and showFlipSup and tf15_en and flipR15 ? res15 : na, "15m broken res → sup", color = color.new(color.lime, 0), linewidth = 2, style = plot.style_linebr)
plot(showSrPlots and showFlipSup and tf60_en and flipR60 ? res60 : na, "1h broken res → sup", color = color.new(color.aqua, 0), linewidth = 2, style = plot.style_linebr)
plot(showSrPlots and showFlipSup and tf240_en and flipR240 ? res240 : na, "4h broken res → sup", color = color.new(color.teal, 0), linewidth = 2, style = plot.style_linebr)

plot(showImbaMid ? imMid : na, "IMBA mid", color = strategy.position_size > 0 ? color.green : strategy.position_size < 0 ? color.red : color.gray, linewidth = 2)

plot(showStBand ? (stTrendVal == 1 ? stUp : na) : na, "ST up band", color = color.new(color.green, 40), linewidth = 2)
plot(showStBand ? (stTrendVal == -1 ? stDn : na) : na, "ST dn band", color = color.new(color.red, 40), linewidth = 2)

plot(plotMaLines and ma1_en ? ma1 : na, "MA TF1", color = color.new(color.orange, 0), linewidth = 2)
plot(plotMaLines and ma2_en ? ma2 : na, "MA TF2", color = color.new(color.white, 15), linewidth = 2)
plot(plotMaLines and ma3_en ? ma3 : na, "MA TF3", color = color.new(color.fuchsia, 0), linewidth = 2)
plot(plotVwmaLine and useVwmaTrend ? vwTrend : na, "VWMA (trend)", color = color.new(color.yellow, 0), linewidth = 2)
plot(plotLocalEma and useLocalTrend ? localFastEma : na, "Local EMA Fast", color = color.new(color.blue, 20), linewidth = 1)
plot(plotLocalEma and useLocalTrend ? localSlowEma : na, "Local EMA Slow", color = color.new(color.navy, 30), linewidth = 1)
plot(plotExitMa and (useExitLongMa or useExitShortMa) ? exitMaAligned : na, "Exit MA (MTF)", color = color.new(color.purple, 0), linewidth = 2)

plotshape(showMarkers and longSignal and isContEntry ? low : na, title = "Cont long", style = shape.labelup, location = location.absolute,
     color = color.new(color.teal, 0), textcolor = color.white, text = "Cont", size = size.small)

plotshape(showMarkers and longSignal and not isContEntry ? low : na, title = "Buy long", style = shape.labelup, location = location.absolute,
     color = color.new(color.green, 0), textcolor = color.white, text = "Buy", size = size.small)

plotshape(showMarkers and shortSignal ? high : na, title = "Sell", style = shape.labeldown, location = location.absolute,
     color = color.new(color.red, 0), textcolor = color.white, text = "Sell", size = size.small)

// Closed-trade P/L % label (uses last closed trade on this bar)
int ctClosed = strategy.closedtrades
if showExitPnL and ctClosed > nz(ctClosed[1])
    int ti = ctClosed - 1
    float esz = strategy.closedtrades.size(ti)
    float ep = strategy.closedtrades.entry_price(ti)
    float xp = strategy.closedtrades.exit_price(ti)
    float pctx = na
    if ep != 0 and esz != 0
        pctx := esz > 0 ? (xp - ep) / ep * 100.0 : (ep - xp) / ep * 100.0
    string tTxt = na(pctx) ? "—" : (pctx >= 0 ? "+" : "") + str.tostring(pctx, "#.##") + "%"
    color tCol = na(pctx) ? color.gray : pctx >= 0 ? color.new(color.green, 0) : color.new(color.red, 0)
    float yAt = esz > 0 ? high : low
    label.new(bar_index, yAt, tTxt, xloc = xloc.bar_index, style = esz > 0 ? label.style_label_down : label.style_label_up,
         color = tCol, textcolor = color.white, size = size.small)

var table tblCum = na
if showCumPnL
    if na(tblCum)
        tblCum := table.new(position.top_right, 2, 2, border_width = 1, frame_color = color.new(color.gray, 50), frame_width = 1)
    if barstate.islastconfirmedhistory
        float netPct = strategy.initial_capital != 0 ? 100.0 * strategy.netprofit / strategy.initial_capital : na
        table.cell(tblCum, 0, 0, "Net P/L %", text_color = color.white, bgcolor = color.new(color.black, 75))
        table.cell(tblCum, 1, 0, str.tostring(netPct, "#.##") + "%", text_color = color.white, bgcolor = color.new(color.black, 75))
        table.cell(tblCum, 0, 1, "Closed trades", text_color = color.white, bgcolor = color.new(color.black, 75))
        table.cell(tblCum, 1, 1, str.tostring(strategy.closedtrades), text_color = color.white, bgcolor = color.new(color.black, 75))

plotshape(showHtfBreak and strategy.position_size > 0 and longHtfBreakMode and not longHtfBreakMode[1] ? high : na,
     title = "HTF break runner", style = shape.diamond, location = location.absolute,
     color = color.new(color.purple, 0), size = size.tiny)

//------------------------------------------------------------------------------
// Alerts — Custom FastAPI bot (https://bot.alphawebstudioz.com)
//------------------------------------------------------------------------------
if use_custom_webhook and (ALERT_SECRET == "REPLACE_ME" or str.length(ALERT_SECRET) < 32)
    runtime.error("Set [Custom bot] secret to your full bot webhook secret")

f_bot_json_buy() =>
    "{\"secret\":\"" + ALERT_SECRET + "\",\"action\":\"buy\",\"symbol\":\"" + syminfo.ticker +
     "\",\"quote_order_qty\":" + str.tostring(alert_buy_usdt) +
     ",\"dedupe_key\":\"L-" + str.tostring(bar_index) + "-" + str.tostring(time) + "\"}"

f_bot_json_sell_exit() =>
    "{\"secret\":\"" + ALERT_SECRET + "\",\"action\":\"sell\",\"symbol\":\"" + syminfo.ticker +
     "\",\"dedupe_key\":\"X-" + str.tostring(bar_index) + "-" + str.tostring(time) + "\"}"

if use_custom_webhook and longSignal
    alert(f_bot_json_buy(), alert.freq_once_per_bar_close)

if use_custom_webhook and shortSignal
    alert(
         "{\"secret\":\"" + ALERT_SECRET + "\",\"action\":\"sell\",\"symbol\":\"" + syminfo.ticker +
          "\",\"quantity\":" + str.tostring(alert_sell_base) +
          ",\"dedupe_key\":\"S-" + str.tostring(bar_index) + "-" + str.tostring(time) + "\"}",
         alert.freq_once_per_bar_close)

bool longJustClosed = strategy.position_size == 0 and strategy.position_size[1] > 0
if use_custom_webhook and longJustClosed
    alert(f_bot_json_sell_exit(), alert.freq_once_per_bar_close)

Overview

SR+Trend v6 APT can flip broken resistance into support and supports optional moving average, SuperTrend, channel, regression, VWMA, ADX, RSI, MACD, volume and higher-high filters. Exits combine stop loss, take profit, trailing and moving average exits. Orders fill on bar close with fixed cash sizing.

Details

Published by

MuhammadMuhamid on GitHub

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Support & resistance, Trend

Markets

Crypto

Timeframes

M15-H1

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Signals on confirmed bar onlybooltrueuseBarConfirm
New entries: bar close only (3Commas)booltrueordersOnConfirmedBar
Min bars after exit before new entryint0cooldownBarsAfterExit
Signal deliverystring3Commas Signal Botsignal_delivery
[Custom bot] secret → WEBHOOK_SECRETstringREPLACE_MEALERT_SECRET
[Custom bot] BUY quote USDTfloat800.0alert_buy_usdt
[Custom bot] SELL base qtyfloat0.001alert_sell_base
[Custom bot] symbolstringAPTUSDTalert_symbol
Touch zone modestringATRtouchBandMode
Touch zone × ATRfloat0.45touchAtrMult
or ticksint5touchTicks
Minimum pivot touchesint1srStrengthMin
Show all 40 settings
SettingTypeDefaultVariable
Strength: pivot-touch TFtimeframe15strengthTf
Strength TF pivot lengthint12strengthPivotLen
Use 5m S/Rbooltruetf5_en
pivLen5int22pivLen5
Use 15m S/Rbooltruetf15_en
pivLen15int18pivLen15
Use 1h S/Rbooltruetf60_en
pivLen60int22pivLen60
Use 4h S/Rbooltruetf240_en
pivLen240int8pivLen240
Bars after support touch to confirm entryint5retestConfirmBars
Pullback: prior bars close above supportint2priorAboveLb
Block pierce-and-reclaim entriesbooltrueblockBreakReclaim
Pierce below support (× ATR) = reclaim blockfloat0.40reclaimPierceAtr
Broken MTF resistance → support (retest longs)booltrueuseResFlipSup
Flip on confirmed bar onlyboolfalseflipConfirmOnClose
Flip when close above res (+ × ATR)float0.05flipBreakBufAtr
Unflip when close below res (− × ATR)float0.2flipInvalidBufAtr
Require MA uptrend / downtrendbooltrueuseMaTrend
MA type (TF1–TF3)stringSMAmaType
MA: block entries while MTF MA is naboolfalsemaBlockWhenNa
Plot MTF MA lines (TF1–TF3)booltrueplotMaLines
Require enabled MAs to be rising (slope)booltruerequireMaSlope
MA slope lookback (chart bars)int3maSlopeLb
TF1booltruema1_en
ma1_tftimeframe1ma1_tf
ma1_lenint200ma1_len
TF2boolfalsema2_en
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This trend-following strategy executes a classic Donchian channel breakout system designed to cross-validate backtest results against external framework benchmarks. It triggers a long entry when the closing price breaks above the highest high of the prior entr

Strategy v6 BreakoutTrend
Updated yesterday · AGPL-3.0 GitHub repository of Forven S01509 - Simple Donchian 20/10 Breakout

Omar Edited WF

by Alorse
330 stars

Omar Edited WF is a trading strategy overlay built around Williams Fractals and multiple Exponential Moving Averages. It detects high and low fractal pivot points over configurable lookback periods alongside three adjustable EMA trendlines. Long entries are ma

Strategy v5 TrendMoving averages
Updated 2 months ago · None stated GitHub repository of Omar Edited WF
257 stars

This strategy calculates dynamic support and resistance levels using pivot highs and lows alongside a custom smoothed trend filter and a 3-period EMA. It identifies entry opportunities when price breaks out relative to the trend filter and short-term EMA cross

Strategy v5 TrendSupport & resistance Repaints
Updated 6 weeks ago · None stated GitHub repository of 30s - ES 1m Strategy Candle Bar
106 stars

This overlay strategy plots a two-timeframe Ichimoku setup on the price chart, with Tenkan, Kijun, Chikou, and Kumo from a base higher timeframe and an optional highest-timeframe cloud. It allows two entries in the same direction and uses ATR-based trailing st

Strategy v4 TrendVolatility & bands
Updated 2 years ago · GPL-3.0 GitHub repository of 2Tier Ichimoku Pyramiding [Takazudo]
104 stars

This strategy combines three Exponential Moving Averages with Williams Fractals to execute trend-following or mean-reverting trades. It analyzes price structure using short, medium, and long-term EMAs along with fractal highs and lows. Entries trigger when fra

Strategy v5 TrendMoving averages
Updated 3 years ago · MIT GitHub repository of 3MA and Fractals Strategy

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers