diff --git a/Bullmania_Money_Line_v7.pine b/Bullmania_Money_Line_v7.pine index 99653cc..fbaff9f 100644 --- a/Bullmania_Money_Line_v7.pine +++ b/Bullmania_Money_Line_v7.pine @@ -39,11 +39,13 @@ macdSlowLen = input.int(26, "Slow", minval=1, inline="macdLens") macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens") // RSI gate (designed for 15m by default) -useRsi = input.bool(true, "Use RSI gate", group="RSI Gate", tooltip="Require RSI to be oversold for longs and overbought for shorts.") +useRsi = input.bool(true, "Use RSI gate", group="RSI Gate", tooltip="Gate signals with RSI conditions from a selectable timeframe.") rsiTf = input.timeframe("15", "RSI timeframe", group="RSI Gate") rsiLen = input.int(14, "RSI Length", minval=1, group="RSI Gate") rsiOverbought = input.int(70, "RSI Overbought", minval=1, maxval=100, group="RSI Gate") rsiOversold = input.int(30, "RSI Oversold", minval=1, maxval=100, group="RSI Gate") +rsiGateMode = input.string("Cross within lookback", "RSI gate mode", options=["In zone now","Cross within lookback","In zone within lookback"], group="RSI Gate", tooltip="How RSI should validate: require being in OB/OS now, a recent cross out of the zone, or having touched the zone within a lookback window.") +rsiLookback = input.int(3, "RSI lookback bars", minval=0, maxval=20, group="RSI Gate", tooltip="Bars to look back for a cross/touch. 0 = only this bar.") // Entry filters (optional, same behavior as v5) groupFilters = "Entry filters" @@ -132,8 +134,19 @@ if barstate.islast and showProfileLabel // RSI from selected timeframe (use regular close for RSI by default) rsiTfVal = request.security(syminfo.tickerid, rsiTf, ta.rsi(close, rsiLen), lookahead=barmerge.lookahead_off) -longRsiOk = not useRsi or (rsiTfVal <= rsiOversold) -shortRsiOk = not useRsi or (rsiTfVal >= rsiOverbought) + +// Build RSI conditions per selected mode +rsiLongNow = rsiTfVal <= rsiOversold +rsiShortNow = rsiTfVal >= rsiOverbought +rsiCrossUp = ta.crossover(rsiTfVal, rsiOversold) // crossed up from below Oversold +rsiCrossDown = ta.crossunder(rsiTfVal, rsiOverbought) // crossed down from above Overbought +rsiLongRecent = rsiLookback == 0 ? rsiLongNow : (ta.lowest(rsiTfVal, rsiLookback + 1) <= rsiOversold) +rsiShortRecent = rsiLookback == 0 ? rsiShortNow : (ta.highest(rsiTfVal, rsiLookback + 1) >= rsiOverbought) +rsiCrossUpRecent = rsiLookback == 0 ? rsiCrossUp : (ta.barssince(rsiCrossUp) <= rsiLookback) +rsiCrossDownRecent = rsiLookback == 0 ? rsiCrossDown : (ta.barssince(rsiCrossDown) <= rsiLookback) + +longRsiOk = not useRsi or (rsiGateMode == "In zone now" ? rsiLongNow : rsiGateMode == "Cross within lookback" ? rsiCrossUpRecent : rsiLongRecent) +shortRsiOk = not useRsi or (rsiGateMode == "In zone now" ? rsiShortNow : rsiGateMode == "Cross within lookback" ? rsiCrossDownRecent : rsiShortRecent) // MACD confirmation logic [macdLine, macdSignal, macdHist] = ta.macd(macdSrc, macdFastLen, macdSlowLen, macdSigLen)