From 41c60bf967828902cce6aae11815af7082cad8da Mon Sep 17 00:00:00 2001 From: root Date: Sat, 18 Oct 2025 20:22:38 +0200 Subject: [PATCH] v6: add optional RSI confirmation gate to v5 (SuperTrend + RSI combo); README updated --- Bullmania_Money_Line_v6.pine | 140 +++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 142 insertions(+) create mode 100644 Bullmania_Money_Line_v6.pine diff --git a/Bullmania_Money_Line_v6.pine b/Bullmania_Money_Line_v6.pine new file mode 100644 index 0000000..7287711 --- /dev/null +++ b/Bullmania_Money_Line_v6.pine @@ -0,0 +1,140 @@ +//@version=5 +indicator("Bullmania Money Line v6 (SuperTrend + RSI)", overlay=true) + +// Parameter Mode +paramMode = input.string("Profiles by timeframe", "Parameter Mode", options=["Single", "Profiles by timeframe"], tooltip="Choose whether to use one global set of parameters or timeframe-specific profiles.") + +// Single (global) parameters +atrPeriodSingle = input.int(10, "ATR Period (Single mode)", minval=1, group="Single Mode") +multiplierSingle = input.float(3.0, "Multiplier (Single mode)", minval=0.1, step=0.1, group="Single Mode") + +// Profile override when using profiles +profileOverride = input.string("Auto", "Profile Override", options=["Auto", "Minutes", "Hours", "Daily", "Weekly/Monthly"], tooltip="When in 'Profiles by timeframe' mode, choose a fixed profile or let it auto-detect from the chart timeframe.", group="Profiles") + +// Timeframe profile parameters +// Minutes (<= 59m) +atr_m = input.int(12, "ATR Period (Minutes)", minval=1, group="Profiles — Minutes") +mult_m = input.float(3.3, "Multiplier (Minutes)", minval=0.1, step=0.1, group="Profiles — Minutes") + +// Hours (>=1h and <1d) +atr_h = input.int(10, "ATR Period (Hours)", minval=1, group="Profiles — Hours") +mult_h = input.float(3.0, "Multiplier (Hours)", minval=0.1, step=0.1, group="Profiles — Hours") + +// Daily (>=1d and <1w) +atr_d = input.int(10, "ATR Period (Daily)", minval=1, group="Profiles — Daily") +mult_d = input.float(2.8, "Multiplier (Daily)", minval=0.1, step=0.1, group="Profiles — Daily") + +// Weekly/Monthly (>=1w) +atr_w = input.int(7, "ATR Period (Weekly/Monthly)", minval=1, group="Profiles — Weekly/Monthly") +mult_w = input.float(2.5, "Multiplier (Weekly/Monthly)", minval=0.1, step=0.1, group="Profiles — Weekly/Monthly") + +// Optional RSI confirmation +useRsi = input.bool(false, "Use RSI confirmation", inline="rsi") +rsiLen = input.int(14, "RSI Length", minval=1, inline="rsi") +rsiOverbought = input.int(70, "RSI Overbought", minval=1, maxval=100, inline="rsi") +rsiOversold = input.int(30, "RSI Oversold", minval=1, maxval=100, inline="rsi") + +// Optional MACD confirmation +useMacd = input.bool(false, "Use MACD confirmation", inline="macd") +macdSrc = input.source(close, "MACD Source", inline="macd") +macdFastLen = input.int(12, "Fast", minval=1, inline="macdLens") +macdSlowLen = input.int(26, "Slow", minval=1, inline="macdLens") +macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens") + +// Determine effective parameters based on selected mode/profile +var string activeProfile = "" +resSec = timeframe.in_seconds(timeframe.period) +isMinutes = resSec < 3600 +isHours = resSec >= 3600 and resSec < 86400 +isDaily = resSec >= 86400 and resSec < 604800 +isWeeklyOrMore = resSec >= 604800 + +// Resolve profile bucket +string profileBucket = "Single" +if paramMode == "Single" + profileBucket := "Single" +else + if profileOverride == "Minutes" + profileBucket := "Minutes" + else if profileOverride == "Hours" + profileBucket := "Hours" + else if profileOverride == "Daily" + profileBucket := "Daily" + else if profileOverride == "Weekly/Monthly" + profileBucket := "Weekly/Monthly" + else + profileBucket := isMinutes ? "Minutes" : isHours ? "Hours" : isDaily ? "Daily" : "Weekly/Monthly" + +atrPeriod = profileBucket == "Single" ? atrPeriodSingle : profileBucket == "Minutes" ? atr_m : profileBucket == "Hours" ? atr_h : profileBucket == "Daily" ? atr_d : atr_w +multiplier = profileBucket == "Single" ? multiplierSingle : profileBucket == "Minutes" ? mult_m : profileBucket == "Hours" ? mult_h : profileBucket == "Daily" ? mult_d : mult_w +activeProfile := profileBucket + +// Core Money Line logic (unchanged from v1) +atr = ta.atr(atrPeriod) +src = (high + low) / 2 + +up = src - (multiplier * atr) +dn = src + (multiplier * atr) + +var float up1 = na +var float dn1 = na + +up1 := nz(up1[1], up) +dn1 := nz(dn1[1], dn) + +up1 := close[1] > up1 ? math.max(up, up1) : up +dn1 := close[1] < dn1 ? math.min(dn, dn1) : dn + +var int trend = 1 +var float tsl = na + +tsl := nz(tsl[1], up1) + +if trend == 1 + tsl := math.max(up1, tsl) + trend := close < tsl ? -1 : 1 +else + tsl := math.min(dn1, tsl) + trend := close > tsl ? 1 : -1 + +supertrend = tsl + +// Plot the Money Line +upTrend = trend == 1 ? supertrend : na +downTrend = trend == -1 ? supertrend : na + +plot(upTrend, "Up Trend", color=color.new(color.green, 0), style=plot.style_linebr, linewidth=2) +plot(downTrend, "Down Trend", color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2) + +// Show active profile on chart as a label (once per bar close) +showProfileLabel = input.bool(true, "Show active profile label", group="Profiles") +var label profLbl = na +if barstate.islast and showProfileLabel + if not na(profLbl) + label.delete(profLbl) + profLbl := label.new(bar_index, close, text="Profile: " + activeProfile + " | ATR=" + str.tostring(atrPeriod) + " Mult=" + str.tostring(multiplier), yloc=yloc.price, style=label.style_label_upper_left, textcolor=color.white, color=color.new(color.blue, 20)) + +// RSI confirmation logic +rsi = ta.rsi(close, rsiLen) +longRsiOk = not useRsi or rsi < rsiOverbought +shortRsiOk = not useRsi or rsi > rsiOversold + +// MACD confirmation logic +[macdLine, macdSignal, macdHist] = ta.macd(macdSrc, macdFastLen, macdSlowLen, macdSigLen) +longMacdOk = not useMacd or (macdLine > macdSignal) +shortMacdOk = not useMacd or (macdLine < macdSignal) + +// Combined confirmation +longOk = longRsiOk and longMacdOk +shortOk = shortRsiOk and shortMacdOk + +// Plot buy/sell signals (gated by optional RSI and MACD) +buyFlip = trend == 1 and trend[1] == -1 +sellFlip = trend == -1 and trend[1] == 1 + +plotshape(buyFlip and longOk, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.circle, size=size.small) +plotshape(sellFlip and shortOk, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.circle, size=size.small) + +// Fill area between price and Money Line +fill(plot(close, display=display.none), plot(upTrend, display=display.none), color=color.new(color.green, 90)) +fill(plot(close, display=display.none), plot(downTrend, display=display.none), color=color.new(color.red, 90)) \ No newline at end of file diff --git a/README.md b/README.md index 39e6a7f..fe39455 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ This repo contains multiple versions; v4 is the stable baseline and `v4+` adds o - `Bullmania_Money_Line_v4.pine` — v1 + optional noise reduction (confirmation bars, ATR buffer). Tagged `v4.0.0`. - `Bullmania_Money_Line_v4_plus.pine` — v4-compatible but with optional filters and quality-of-life features (Pine v6). - `Bullmania_Money_Line_v5.pine` — v1 + optional MACD confirmation gate and optional timeframe profiles (Single mode or auto profile by chart TF). +- `Bullmania_Money_Line_v6.pine` — v5 + optional RSI confirmation gate (SuperTrend + RSI combo). ## How it works (all versions) - Money Line is derived from a mid-price `(high + low) / 2` and `ATR(atrPeriod)` scaled by `multiplier`. @@ -177,6 +178,7 @@ Keep Multiplier roughly stable and fine-tune by small increments; HA candles all 5) Open Inputs to adjust parameters. ## Changelog +- v6 — v5 + optional RSI confirmation gate (buy requires RSI < overbought; sell requires RSI > oversold). Combines with MACD if enabled. - v5 — v1 + optional MACD gate (buy dot requires MACD line > signal; sell dot requires MACD line < signal). Adds optional timeframe profiles: choose "Single" or "Profiles by timeframe". Profiles buckets: Minutes, Hours, Daily, Weekly/Monthly with independent ATR Period and Multiplier. Defaults keep v1 behavior. - v4+ — Pine v6 variant with optional ADX/MTF/session/cooldown, calc source toggle, EMA trend filter, anti-chop (CHOP, retest, min body), gated markers, and per-timeframe profiles. - v4.0.0 — Adds Flip confirmation bars and Flip buffer (×ATR). Defaults keep v1 behavior. Tag: `v4.0.0`.