Strategy · Pine Script v6 · On the chart

Buy the Dip Futures 1000x

by PETERSAMUELOPS12· code credited to Gotrade

A long-only dip-buying strategy for leveraged futures.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code419
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update5 months ago25 May 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

419 lines of Pine Script v6 from pinescript/futures_trading.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

futures_trading.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Gotrade

//@version=6
strategy("Buy the Dip – Futures 1000x", overlay=true, fill_orders_on_standard_ohlc=true,
         default_qty_type=strategy.fixed, default_qty_value=1,
         initial_capital=1000000, margin_long=0.1,
         commission_type=strategy.commission.percent, commission_value=0.04)

// ═══════════════════════════════════════════════════════════════════════════════
// INPUTS
// ═══════════════════════════════════════════════════════════════════════════════
grp0 = "Portfolio"
portfolioSize = input.float(10000, "Portfolio Size (chart currency)", minval=1, group=grp0)

grp1 = "Signal A — Uptrend Dip"
useAutoCrash      = input.bool(true,  "Auto-adjust crash % to asset volatility",   group=grp1,
                        tooltip="ON: measures the asset's own historical max dip and enters at a fraction of it. Adapts automatically to SPX (small dips) vs IHSG (large dips) vs BTC (huge dips). OFF: uses the fixed % below.")
autoCrashRatio    = input.float(0.5,  "Entry at X fraction of historical max dip", minval=0.1, maxval=1.0, step=0.05, group=grp1,
                        tooltip="0.5 = enter when current dip reaches 50% of the deepest dip ever seen over the lookback window. 0.3 = earlier entry, 0.7 = wait for deeper dip.")
autoCrashLookback = input.int(100,    "History window to measure max dip (bars)",  minval=10,             group=grp1,
                        tooltip="Rolling window to measure the asset's typical max dip. 100 bars on 1D = ~5 months of recent conditions. Keep SHORT (50-150) so a once-in-a-decade crash (like COVID) doesn't permanently inflate the threshold for years afterward. Longer windows = threshold anchored to historical extremes.")
crashPct          = input.float(7.0,  "Manual crash % (when auto is OFF)",          minval=1.0, step=0.5, group=grp1,
                        tooltip="Used only when auto-adjust is disabled. SPX≈7%, UK100≈4%, IHSG≈20%, BTC≈30%.")
lookback          = input.int(20,     "Lookback bars for recent high",              minval=5,             group=grp1)
useTrendFilter  = input.bool(true, "Only enter when price > Trend MA",   group=grp1,
                    tooltip="Buy dips only in uptrending markets.")
trendMAPeriod   = input.int(100,  "Trend MA period",                     minval=10,            group=grp1)
trendMABuffer   = input.float(2.0, "Min % above trend MA to enter",      minval=0.0, step=0.5, group=grp1,
                    tooltip="Require price to be at least X% above the trend MA before entering. Prevents buying right at the boundary where the trend exit would immediately fire. 2% = meaningful clearance.")

grp1d = "Bear Market Regime Filter"
useBearFilter  = input.bool(true, "Enable bear market regime detection",            group=grp1d,
                    tooltip="Blocks ALL entries when market is confirmed in a bear regime.")
bearMAPeriod   = input.int(200,   "Bear regime MA period (200-SMA recommended)",   minval=20, group=grp1d,
                    tooltip="200-bar SMA is the standard long-term trend divider.")
bearConsecBars = input.int(10,    "Bars below bear MA to confirm bear regime",     minval=1,  group=grp1d,
                    tooltip="10 consecutive bars below 200-SMA = confirmed bear. Prevents false triggers on brief dips.")
bearExitBars   = input.int(5,     "Bars above bear MA to exit bear regime",        minval=1,  group=grp1d,
                    tooltip="5 consecutive bars back above 200-SMA to clear bear status. Asymmetric — slow to enter bear, quick to exit.")

grp1b = "Signal B — EMA Oversold Dip"
useEmaDip     = input.bool(true,  "Enable: buy when price X% below EMA", group=grp1b,
                    tooltip="Mean-reversion entry. Catches oversold bounces below a key EMA.")
emaDipPeriod  = input.int(50,     "EMA period",                          minval=5,             group=grp1b,
                    tooltip="50-bar EMA is a common mean-reversion reference.")
emaDipPct     = input.float(5.0,  "Trigger when price X% below EMA",    minval=0.1, step=0.5, group=grp1b,
                    tooltip="5% below EMA = oversold. Lower = more signals, higher = only extreme dips.")
emaDipTrend   = input.bool(true,  "Require uptrend for EMA dip too",    group=grp1b,
                    tooltip="ON (default): EMA dip entries also require price above trend MA. Turn off only to catch recoveries in corrections — dangerous in prolonged bear markets.")

grp1e = "Signal C — MACD Crossover Dip"
useMacdDip        = input.bool(true,  "Enable MACD crossover breakout entry",             group=grp1e,
                        tooltip="On bullish MACD crossover, wait for price to rise X% above crossover price before entering. If price drops X% below instead, invalidate and wait for next crossover.")
macdFast          = input.int(12,    "MACD fast EMA",                                      minval=2,            group=grp1e)
macdSlow          = input.int(26,    "MACD slow EMA",                                      minval=2,            group=grp1e)
macdSignal        = input.int(9,     "MACD signal EMA",                                    minval=2,            group=grp1e)
macdEntryPct      = input.float(10.0,"Enter when price rises X% above crossover price",    minval=0.5, step=0.5, group=grp1e,
                        tooltip="10% = enter only after price confirms momentum by rising 10% above the MACD bullish crossover price.")
macdInvalidatePct = input.float(10.0,"Invalidate if price drops X% below crossover price", minval=0.5, step=0.5, group=grp1e,
                        tooltip="10% = if price falls 10% below the crossover price before reaching the entry target, cancel the setup and wait for the next crossover.")
macdDipTrend      = input.bool(true, "Require uptrend for MACD entry too",                  group=grp1e,
                        tooltip="ON: MACD entries also require price above the trend MA buffer.")

grp1c = "Pyramiding"
maxPyramid = input.int(3, "Max entries per open trade", minval=1, group=grp1c,
                tooltip="Signal A, Signal B, Signal C, and Compounding all share this counter. Resets when position closes.")

grp2 = "Risk Management"
useEquityPct     = input.bool(true,  "Size position as % of equity (recommended)",    group=grp2,
                      tooltip="ON: margin = X% of current equity — positions scale down after losses. OFF: fixed margin amount.")
marginEquityPct  = input.float(0.2,  "Margin as % of equity per trade",               minval=0.01, step=0.01, group=grp2)
marginAmt        = input.float(2000, "Fixed margin per trade (when % mode is OFF)",   minval=1,   group=grp2)
leverage         = input.int(1000,   "Leverage (x)",                                  minval=1, maxval=1000, group=grp2)
trailPct         = input.float(5.0,  "Trailing stop % from peak",                     minval=0.1, step=0.1, group=grp2)
trailActivatePct = input.float(8.0,  "Activate trail only after X% profit",           minval=0.1, step=0.1, group=grp2,
                      tooltip="Must be > trailPct. Guarantees trail stop is above entry when it first activates.")
portfolioStopPct = input.float(50.0, "Emergency close when loss ≥ X% of peak equity", minval=1.0, maxval=100.0, step=1.0, group=grp2,
                      tooltip="Now references peak equity, not fixed initial capital. Scales up as you make profits.")
equityDDFilter   = input.bool(true,  "Halt new entries when equity drawdown > X% from peak", group=grp2,
                      tooltip="Circuit breaker: stops all new entries if equity has fallen more than X% from its all-time high. Does NOT close existing positions.")
equityDDPct      = input.float(20.0, "Max equity drawdown % from peak before halting", minval=1.0, maxval=99.0, step=1.0, group=grp2,
                      tooltip="20% = halt entries if equity is 20%+ below its peak. Prevents averaging down into a collapsing position.")
useTrendExit     = input.bool(true,  "Exit on trend MA crossunder",                   group=grp2,
                      tooltip="Closes full position when price crosses below the trend MA. Acts as a regime-change exit.")
useEMAExit       = input.bool(false, "Exit on EMA dip MA crossunder",                 group=grp2,
                      tooltip="Faster exit using the 50-EMA. More responsive but more whipsaws.")

grp3 = "Compounding"
compoundRatio = input.float(100.0, "Compound when profit ≥ X% of portfolio", minval=1.0, step=1.0, group=grp3,
                    tooltip="Fires an extra pyramid entry at each profit tier. Counts toward pyramid limit.")

grp4 = "Volatility Filter"
useVolFilter   = input.bool(true,  "Enable ATR volatility filter",                   group=grp4,
                    tooltip="Skips entries or reduces leverage when market volatility is abnormally high.")
atrPeriod      = input.int(14,     "ATR period",                                     minval=5,            group=grp4)
atrHighPct     = input.float(3.0,  "ATR% threshold: skip entries above this",        minval=0.1, step=0.1, group=grp4,
                    tooltip="ATR% = ATR / close × 100. If above this %, skip all new entries.")
atrModPct      = input.float(1.5,  "ATR% threshold: reduce leverage below this",     minval=0.1, step=0.1, group=grp4,
                    tooltip="Between this and the skip threshold, leverage scales down proportionally.")
volLeverageMin = input.int(100,    "Minimum leverage in elevated-vol regime",        minval=1, maxval=1000, group=grp4,
                    tooltip="Floor for leverage when vol is between the two thresholds.")

// ═══════════════════════════════════════════════════════════════════════════════
// DERIVED CALCULATIONS
// ═══════════════════════════════════════════════════════════════════════════════
// Clamp equity to a small positive floor so margin never goes negative or zero
safeEquity      = math.max(strategy.equity, strategy.initial_capital * 0.001)
effectiveMargin = useEquityPct ? safeEquity * marginEquityPct / 100 : marginAmt

// ── ATR Volatility Filter ──────────────────────────────────────────────────────
atrValue     = ta.atr(atrPeriod)
atrPct       = atrValue / math.max(close, 0.000001) * 100.0
volTooHigh   = useVolFilter and atrPct >= atrHighPct
volElevated  = useVolFilter and atrPct >= atrModPct and not volTooHigh
// Scale leverage down linearly between atrModPct and atrHighPct
volLeverageRatio  = volElevated ?
     math.max(float(volLeverageMin), leverage * (1.0 - (atrPct - atrModPct) / math.max(atrHighPct - atrModPct, 0.001))) :
     float(leverage)
effectiveLeverage = volTooHigh ? float(volLeverageMin) : volLeverageRatio

notionalSize  = effectiveMargin * effectiveLeverage
qtyContracts  = notionalSize / math.max(close, 0.000001)

// ═══════════════════════════════════════════════════════════════════════════════
// TREND MA + BEAR MARKET REGIME DETECTION
// ═══════════════════════════════════════════════════════════════════════════════
trendMA   = ta.sma(close, trendMAPeriod)
inUptrend = close > trendMA
// Entry requires price to be trendMABuffer% above the trend MA, not just barely above it.
// This creates a buffer so the trend exit (crossunder) doesn't fire immediately after entry.
trendMAThreshold = trendMA * (1 + trendMABuffer / 100)
entryAllowed     = not useTrendFilter or close > trendMAThreshold

// 200-SMA bear regime: confirmed after bearConsecBars consecutive bars below
bearMA = ta.sma(close, bearMAPeriod)
var int barsBelow200 = 0
var int barsAbove200 = 0
if close < bearMA
    barsBelow200 := barsBelow200 + 1
    barsAbove200 := 0
else
    barsAbove200 := barsAbove200 + 1
    barsBelow200 := 0

var bool inBearRegime = false
if barsBelow200 >= bearConsecBars
    inBearRegime := true
if barsAbove200 >= bearExitBars
    inBearRegime := false

bearBlock = useBearFilter and inBearRegime

// ═══════════════════════════════════════════════════════════════════════════════
// SIGNALS
// ═══════════════════════════════════════════════════════════════════════════════
// Signal A: Uptrend Dip
recentHigh   = ta.highest(high, lookback)
crashPct_cur = (recentHigh - close) / recentHigh * 100.0

// Auto-crash: rolling max dip over a SHORT recent window (100 bars default).
// Short window = adapts to current volatility regime, not permanently anchored
// to once-in-a-decade events like COVID. After COVID's 25% dip, a 500-bar
// window keeps effectiveCrashPct=12.5% for ~2 years, starving the strategy
// of signals. A 100-bar window recovers once the extreme rolls out (~5 months).
histMaxDip        = ta.highest(crashPct_cur, autoCrashLookback)
// Smooth with an EMA of the rolling max to prevent abrupt threshold jumps
// when a new extreme enters or exits the window.
var float smoothedMax = na
smoothedMax      := na(smoothedMax) ? histMaxDip : 0.95 * smoothedMax + 0.05 * histMaxDip
effectiveCrashPct = useAutoCrash ? smoothedMax * autoCrashRatio : crashPct

sigA = ta.crossover(crashPct_cur, effectiveCrashPct) and entryAllowed

// Signal B: EMA Oversold Dip
emaDipMA    = ta.ema(close, emaDipPeriod)
emaBelowPct = (emaDipMA - close) / emaDipMA * 100.0   // positive = price below EMA
sigB        = useEmaDip and ta.crossover(emaBelowPct, emaDipPct) and
              (not emaDipTrend or entryAllowed)

// Signal C: MACD Crossover Breakout
// Logic: bullish MACD cross → record crossover price → enter if +X% above it.
//        If price falls -X% below crossover before reaching target → invalidate.
//        Bearish MACD cross → always invalidate (no trading in downward momentum).

// Step 1 — compute MACD
macdLine      = ta.ema(close, macdFast) - ta.ema(close, macdSlow)
signalLine    = ta.ema(macdLine, macdSignal)
macdBullCross = ta.crossover(macdLine, signalLine)   // momentum turns bullish
macdBearCross = ta.crossunder(macdLine, signalLine)  // momentum turns bearish → no trade

// Step 2 — track the price at the latest bullish crossover
var float macdCrossPrice = na
if macdBullCross
    macdCrossPrice := close        // new setup: record crossover price
if macdBearCross
    macdCrossPrice := na           // bearish cross: cancel any pending setup

// Step 3 — invalidate if price drops too far below crossover (failed breakout)
macdDropFromCross = not na(macdCrossPrice) ? (macdCrossPrice - close) / macdCrossPrice * 100.0 : 0.0
if not na(macdCrossPrice) and macdDropFromCross >= macdInvalidatePct
    macdCrossPrice := na           // -10% from crossover = fake breakout, wait for next

// Step 4 — measure rise from crossover price
macdRisePct = not na(macdCrossPrice) ? (close - macdCrossPrice) / macdCrossPrice * 100.0 : 0.0

// Step 5 — fire when price first crosses +entryPct% above crossover
sigC = useMacdDip and not na(macdCrossPrice) and
       ta.crossover(macdRisePct, macdEntryPct) and
       (not macdDipTrend or entryAllowed)

// ═══════════════════════════════════════════════════════════════════════════════
// POSITION STATE
// ═══════════════════════════════════════════════════════════════════════════════
inPos    = strategy.position_size > 0
avgEntry = strategy.position_avg_price
liqPrice = avgEntry > 0 ? avgEntry * (1 - 1.0 / leverage) : na

// Track pyramid count — reset to 0 when flat
var int pyramidCount = 0
if not inPos
    pyramidCount := 0
pyramidAllowed = pyramidCount < maxPyramid

// ═══════════════════════════════════════════════════════════════════════════════
// TRAILING STOP
// ═══════════════════════════════════════════════════════════════════════════════
var float peakSinceEntry = na
if inPos
    peakSinceEntry := math.max(nz(peakSinceEntry, close), high)
else
    peakSinceEntry := na

rawTrailStop   = not na(peakSinceEntry) ? peakSinceEntry * (1 - trailPct / 100) : na
// Floor at entry: once trail activates, worst case is breakeven
trailStopPrice = (not na(rawTrailStop) and avgEntry > 0) ? math.max(avgEntry, rawTrailStop) : na
trailActive    = inPos and not na(peakSinceEntry) and
                 peakSinceEntry >= avgEntry * (1 + trailActivatePct / 100)

// ═══════════════════════════════════════════════════════════════════════════════
// EQUITY PEAK TRACKER, CIRCUIT BREAKER, ENTRY GATE
// ═══════════════════════════════════════════════════════════════════════════════
var float equityPeak = strategy.initial_capital
// Reset equity peak when bear regime ends — fresh reference for each new bull cycle.
// Without this, the circuit breaker locks permanently after a crash (equity can't
// recover to the pre-crash peak while no trades are being placed).
bearRegimeJustEnded = not inBearRegime and inBearRegime[1]
if bearRegimeJustEnded
    equityPeak := strategy.equity
equityPeak := math.max(equityPeak, strategy.equity)

equityDrawdownPct = (equityPeak - strategy.equity) / equityPeak * 100.0
circuitBreakerOn  = equityDDFilter and equityDrawdownPct >= equityDDPct

// Consolidated entry gate: all three protections must clear
entryGate = not circuitBreakerOn and not bearBlock and not volTooHigh

// Emergency stop amount references PEAK equity (not fixed initial_capital)
portfolioStopAmt = equityPeak * portfolioStopPct / 100

// ═══════════════════════════════════════════════════════════════════════════════
// COMPOUNDING LOGIC
// ═══════════════════════════════════════════════════════════════════════════════
compoundLevel = strategy.initial_capital * compoundRatio / 100.0
profitTier    = inPos ? math.floor(strategy.openprofit / compoundLevel) : 0
compoundFire  = inPos and profitTier > math.floor(strategy.openprofit[1] / compoundLevel)

// ═══════════════════════════════════════════════════════════════════════════════
// ORDERS
// ═══════════════════════════════════════════════════════════════════════════════
// Signal A: uptrend dip
if sigA and pyramidAllowed and entryGate
    pyramidCount += 1
    strategy.entry("A-Dip #" + str.tostring(pyramidCount), strategy.long, qty=qtyContracts,
                   comment="A: " + str.tostring(math.round(crashPct_cur, 1)) + "% dip")

// Signal B: EMA oversold dip
if sigB and pyramidAllowed and not sigA and entryGate
    pyramidCount += 1
    strategy.entry("B-EMA #" + str.tostring(pyramidCount), strategy.long, qty=qtyContracts,
                   comment="B: -" + str.tostring(math.round(emaBelowPct, 1)) + "% EMA")

// Signal C: MACD crossover breakout
if sigC and pyramidAllowed and not sigA and not sigB and entryGate
    pyramidCount += 1
    strategy.entry("C-MACD #" + str.tostring(pyramidCount), strategy.long, qty=qtyContracts,
                   comment="C: +" + str.tostring(math.round(macdRisePct, 1)) + "% MACD xo@" + str.tostring(math.round(macdCrossPrice, 2)))

// Compound on profit — now counts toward pyramid limit
if compoundFire and pyramidAllowed and entryGate
    pyramidCount += 1
    strategy.entry("Compound x" + str.tostring(profitTier), strategy.long, qty=qtyContracts,
                   comment="COMPOUND tier " + str.tostring(profitTier) + " [" + str.tostring(pyramidCount) + "/" + str.tostring(maxPyramid) + "]")

// Exit: trailing stop
if trailActive and close <= trailStopPrice
    strategy.close_all(comment="TRAIL EXIT")

// Emergency exit: loss >= X% of peak equity
if inPos and strategy.openprofit <= -portfolioStopAmt
    strategy.close_all(comment="EMRG STOP " + str.tostring(portfolioStopPct) + "%")

// Exit: trend MA crossunder (regime change exit)
trendCrossunder = ta.crossunder(close, trendMA)
if useTrendExit and inPos and trendCrossunder
    strategy.close_all(comment="TREND EXIT MA" + str.tostring(trendMAPeriod))

// Exit: EMA dip MA crossunder (faster exit, optional)
emaCrossunder = ta.crossunder(close, emaDipMA)
if useEMAExit and inPos and emaCrossunder
    strategy.close_all(comment="EMA EXIT MA" + str.tostring(emaDipPeriod))

// ═══════════════════════════════════════════════════════════════════════════════
// PLOTS
// ═══════════════════════════════════════════════════════════════════════════════
plot(trendMA,                         "Trend MA",      color=color.new(color.blue,   30), linewidth=2)
plot(bearMA,                          "Bear MA (200)", color=color.new(color.red,    20), linewidth=2)
plot(emaDipMA,                        "EMA Dip MA",    color=color.new(color.orange, 30), linewidth=1)
plot(recentHigh,                      "Recent High",   color=color.new(color.red,    50), linewidth=1)
plot(inPos ? trailStopPrice : na,     "Trailing Stop", color=color.new(color.yellow,  0), linewidth=2, style=plot.style_linebr)
plot(inPos ? peakSinceEntry : na,     "Peak",          color=color.new(color.green,  50), linewidth=1, style=plot.style_linebr)
plot(inPos ? liqPrice       : na,     "Liq Price",     color=color.new(color.red,     0), linewidth=1, style=plot.style_linebr)

// Background zones
bgcolor(useTrendFilter and not inUptrend ? color.new(color.red, 92) : na,  title="Downtrend Zone")
bgcolor(inBearRegime                     ? color.new(color.red, 80) : na,  title="Bear Regime")
bgcolor(circuitBreakerOn                 ? color.new(color.purple, 85) : na, title="Circuit Breaker Active")
bgcolor(volTooHigh                       ? color.new(color.orange, 85) : na, title="High Volatility Zone")

// Entry / exit signals
plotshape(sigA and pyramidAllowed and entryGate,                           "Signal A",         shape.triangleup,   location.belowbar, color.green,  size=size.normal)
plotshape(sigB and pyramidAllowed and not sigA and entryGate,              "Signal B (EMA)",   shape.triangleup,   location.belowbar, color.orange, size=size.small)
plotshape(sigC and pyramidAllowed and not sigA and not sigB and entryGate, "Signal C (MACD)",  shape.triangleup,   location.belowbar, color.aqua,   size=size.small)
plotshape(macdBullCross,                                                   "MACD Bull Cross",  shape.circle,       location.belowbar, color.teal,   size=size.tiny)
plotshape(sigA and not pyramidAllowed,                                     "A blocked (max)",  shape.xcross,       location.belowbar, color.gray,   size=size.tiny)
plotshape(compoundFire and not pyramidAllowed,                "Compound blocked", shape.xcross,       location.abovebar, color.gray,   size=size.tiny)
plotshape(compoundFire and pyramidAllowed and entryGate,      "Compound",         shape.diamond,      location.abovebar, color.aqua,   size=size.small)
plotshape(useTrendExit and inPos and trendCrossunder,         "Trend Exit",       shape.triangledown, location.abovebar, color.red,    size=size.normal)

// ═══════════════════════════════════════════════════════════════════════════════
// DASHBOARD
// ═══════════════════════════════════════════════════════════════════════════════
var table dash = table.new(position.top_right, 2, 16,
     bgcolor=color.new(color.black, 55), border_width=1, border_color=color.new(color.gray, 50))

if barstate.islast
    pnlCol     = strategy.openprofit >= 0 ? color.lime : color.red
    netCol     = strategy.netprofit  >= 0 ? color.lime : color.red
    trendColor = inUptrend ? color.lime : color.red
    na_str     = "–"

    table.cell(dash, 0, 0, "Buy-the-Dip 1000x", text_color=color.white,
               text_size=size.small, bgcolor=color.new(color.navy, 30))
    table.cell(dash, 1, 0, "",                   text_color=color.white,
               text_size=size.small, bgcolor=color.new(color.navy, 30))

    table.cell(dash, 0, 1, "Trend",           text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 1, (inUptrend ? "▲ UPTREND" : "▼ DOWNTREND") + " | MA" + str.tostring(trendMAPeriod) + "=" + str.tostring(math.round(trendMA, 0)),
               text_color=trendColor, text_size=size.small)

    table.cell(dash, 0, 2, "Sig A (dip)",     text_color=color.silver, text_size=size.small)
    autoLabel = useAutoCrash ? (" auto=" + str.tostring(math.round(effectiveCrashPct, 1)) + "% [ref=" + str.tostring(math.round(smoothedMax, 1)) + "%×" + str.tostring(autoCrashRatio) + "]") : ""
    table.cell(dash, 1, 2, str.tostring(math.round(effectiveCrashPct, 1)) + "% from " + str.tostring(lookback) + "-bar high" + autoLabel + (entryAllowed ? " ✓" : " ✗"),
               text_color=color.green, text_size=size.small)

    table.cell(dash, 0, 3, "Sig B (EMA)",     text_color=color.silver, text_size=size.small)
    emaStatus = useEmaDip ? (str.tostring(emaDipPct) + "% below EMA" + str.tostring(emaDipPeriod) + " | now " + str.tostring(math.round(emaBelowPct, 1)) + "%") : "disabled"
    table.cell(dash, 1, 3, emaStatus,
               text_color=emaBelowPct >= emaDipPct ? color.orange : color.silver, text_size=size.small)

    table.cell(dash, 0, 4, "Pyramid",         text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 4, str.tostring(pyramidCount) + " / " + str.tostring(maxPyramid) + " entries",
               text_color=pyramidAllowed ? color.lime : color.red, text_size=size.small)

    table.cell(dash, 0, 5, "Margin / trade",  text_color=color.silver, text_size=size.small)
    modeStr = useEquityPct ? (str.tostring(marginEquityPct) + "% eq=") : "fixed="
    table.cell(dash, 1, 5, modeStr + str.tostring(math.round(effectiveMargin, 0)) + " × " + str.tostring(math.round(effectiveLeverage, 0)) + "x",
               text_color=color.yellow, text_size=size.small)

    trailWarning = trailActivatePct <= trailPct ? " ⚠" : " ✓"
    table.cell(dash, 0, 6, "Trail Stop",      text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 6, str.tostring(trailPct) + "% / activate +" + str.tostring(trailActivatePct) + "%" + trailWarning,
               text_color=trailActivatePct > trailPct ? color.yellow : color.red, text_size=size.small)

    table.cell(dash, 0, 7, "Trail Price",     text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 7, inPos ? (trailActive ? str.tostring(math.round(trailStopPrice, 2)) : "waiting +" + str.tostring(trailActivatePct) + "%") : na_str,
               text_color=trailActive ? color.yellow : color.gray, text_size=size.small)

    table.cell(dash, 0, 8, "Peak",            text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 8, inPos ? str.tostring(math.round(peakSinceEntry, 2)) : na_str,
               text_color=color.lime, text_size=size.small)

    table.cell(dash, 0, 9, "Emrg Stop",       text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 9, "-" + str.tostring(math.round(portfolioStopAmt, 0)) + " (" + str.tostring(portfolioStopPct) + "% of peak)",
               text_color=color.orange, text_size=size.small)

    table.cell(dash, 0, 10, "Open P&L",       text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 10, str.tostring(math.round(strategy.openprofit, 2)),
               text_color=pnlCol, text_size=size.small)

    table.cell(dash, 0, 11, "Net Profit",     text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 11, str.tostring(math.round(strategy.netprofit, 2)),
               text_color=netCol, text_size=size.small)

    table.cell(dash, 0, 12, "Equity Peak",    text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 12, str.tostring(math.round(equityPeak, 0)) + " | DD: " + str.tostring(math.round(equityDrawdownPct, 1)) + "%",
               text_color=equityDrawdownPct > equityDDPct * 0.75 ? color.red : color.lime, text_size=size.small)

    table.cell(dash, 0, 13, "Circuit Breaker", text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 13, circuitBreakerOn ? "⛔ HALTED" : "✓ ACTIVE",
               text_color=circuitBreakerOn ? color.red : color.lime, text_size=size.small)

    table.cell(dash, 0, 14, "Bear Regime",    text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 14, inBearRegime ? ("🐻 BEAR " + str.tostring(barsBelow200) + " bars") : ("✓ BULL " + str.tostring(barsAbove200) + " bars"),
               text_color=inBearRegime ? color.red : color.lime, text_size=size.small)

    table.cell(dash, 0, 15, "Volatility",     text_color=color.silver, text_size=size.small)
    table.cell(dash, 1, 15, "ATR%=" + str.tostring(math.round(atrPct, 2)) + (volTooHigh ? " ⛔ SKIP" : volElevated ? " ⚠ ×" + str.tostring(math.round(effectiveLeverage, 0)) : " ✓ OK"),
               text_color=volTooHigh ? color.red : volElevated ? color.orange : color.lime, text_size=size.small)

Overview

Entries fire when price falls a set share of its recent high, with the depth optionally scaled to the asset's own historical maximum dip, when price sits below an EMA by a set percentage, or after a MACD crossover breakout. Trend and bear-regime filters can block entries. It allows up to three entries per trade, uses very high leverage and exits with a trailing stop from the peak, with no fixed stop.

Details

Published by

PETERSAMUELOPS12 on GitHub

Code credit

Gotrade, as written in the script's header

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Mean reversion

Markets

Any symbol

Timeframes

H4 and above

Risk Notes

  • The strategy can add several entries in the same direction
  • The strategy enters trades without a stop loss

Settings

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

SettingTypeDefaultVariable
Portfolio Size (chart currency)float10000portfolioSize
Auto-adjust crash % to asset volatilitybooltrueuseAutoCrash
Entry at X fraction of historical max dipfloat0.5autoCrashRatio
History window to measure max dip (bars)int100autoCrashLookback
Manual crash % (when auto is OFF)float7.0crashPct
Lookback bars for recent highint20lookback
Only enter when price > Trend MAbooltrueuseTrendFilter
Trend MA periodint100trendMAPeriod
Min % above trend MA to enterfloat2.0trendMABuffer
Enable bear market regime detectionbooltrueuseBearFilter
Bear regime MA period (200-SMA recommended)int200bearMAPeriod
Bars below bear MA to confirm bear regimeint10bearConsecBars
Show all 40 settings
SettingTypeDefaultVariable
Bars above bear MA to exit bear regimeint5bearExitBars
Enable: buy when price X% below EMAbooltrueuseEmaDip
EMA periodint50emaDipPeriod
Trigger when price X% below EMAfloat5.0emaDipPct
Require uptrend for EMA dip toobooltrueemaDipTrend
Enable MACD crossover breakout entrybooltrueuseMacdDip
MACD fast EMAint12macdFast
MACD slow EMAint26macdSlow
MACD signal EMAint9macdSignal
Enter when price rises X% above crossover pricefloat10.0macdEntryPct
Invalidate if price drops X% below crossover pricefloat10.0macdInvalidatePct
Require uptrend for MACD entry toobooltruemacdDipTrend
Max entries per open tradeint3maxPyramid
Size position as % of equity (recommended)booltrueuseEquityPct
Margin as % of equity per tradefloat0.2marginEquityPct
Fixed margin per trade (when % mode is OFF)float2000marginAmt
Leverage (x)int1000leverage
Trailing stop % from peakfloat5.0trailPct
Activate trail only after X% profitfloat8.0trailActivatePct
Emergency close when loss ≥ X% of peak equityfloat50.0portfolioStopPct
Halt new entries when equity drawdown > X% from peakbooltrueequityDDFilter
Max equity drawdown % from peak before haltingfloat20.0equityDDPct
Exit on trend MA crossunderbooltrueuseTrendExit
Exit on EMA dip MA crossunderboolfalseuseEMAExit
Compound when profit ≥ X% of portfoliofloat100.0compoundRatio
Enable ATR volatility filterbooltrueuseVolFilter
ATR periodint14atrPeriod
ATR% threshold: skip entries above thisfloat3.0atrHighPct
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

330 stars

Alert BB + RSI [Alorse] is a multi-symbol mean-reversion strategy designed for cryptocurrency trading. It evaluates Bollinger Bands and the Relative Strength Index (RSI) across up to 20 user-defined ticker symbols simultaneously. The strategy enters long posit

Strategy v4 Oscillators & momentumVolatility & bands
Updated 2 months ago · None stated GitHub repository of Alert BB + RSI [Alorse]
285 stars

Mean Reversion Strategy is an overlay strategy that identifies pullbacks using a long-term EMA, RSI, and candlestick patterns. It generates long signals when a bullish engulfing candle forms below the EMA while RSI is oversold, and short signals when a bearish

Strategy v4 Mean reversionCandlestick patterns
Updated 3 years ago · None stated GitHub repository of Mean Reversion Strategy

STRG One Bar Pursuit

by harryguiacorn
219 stars

The STRG One Bar Pursuit strategy identifies single-bar momentum reversals by monitoring shifts between bullish and bearish candlesticks starting from the year 2024. It enters a long position when a bullish candle follows a bearish candle and enters a short po

Strategy v5 Candlestick patternsMean reversion
Updated 1 year ago · None stated GitHub repository of STRG One Bar Pursuit

This strategy draws on the price chart and combines Stochastic RSI, the Money Flow Index, and an exponential moving average to open long or short trades. Longs use the lower oscillator thresholds and shorts use the upper ones, with direction limited to longs,

Strategy v5 Oscillators & momentumMoving averages Repaints
Updated 2 years ago · GPL-3.0 GitHub repository of 3 Indicator Strategy (StochRSI, MFI & EMA) With Safety Orders

Bollinger Bands Strategy

by cklose2000
105 stars

This strategy generates buy and sell signals based on Bollinger Band crossovers combined with a simple moving average trend filter. It enters a long position when price crosses above the lower band while trading above the SMA filter line, and enters a short po

Strategy v5 Volatility & bandsMoving averages
Updated 1 year ago · None stated GitHub repository of Bollinger Bands 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