diff --git a/Bullmania_Money_Line_Strategy.pine b/Bullmania_Money_Line_Strategy.pine new file mode 100644 index 0000000..a768bd6 --- /dev/null +++ b/Bullmania_Money_Line_Strategy.pine @@ -0,0 +1,105 @@ +//@version=5 +strategy("Bullmania Money Line Strategy", overlay=true, pyramiding=0, + initial_capital=input.float(10000, "Initial Capital"), + commission_type=strategy.commission.percent, + commission_value=input.float(0.10, "Commission %"), + slippage=input.int(0, "Slippage (ticks)")) + +// Parameters (match indicator defaults) +atrPeriod = input.int(10, "ATR Period", minval=1) +multiplier = input.float(3.0, "Multiplier", minval=0.1, step=0.1) +smoothLen = input.int(0, "Smoothing EMA Length (0 = off)", minval=0) + +// Risk settings +riskPct = input.float(1.0, "Risk % per trade", minval=0.1, step=0.1) +stopBufferTicks = input.int(1, "Stop buffer (ticks)", minval=0) +takeProfitRR = input.float(0.0, "Take Profit R multiple (0 = off)", minval=0, step=0.1) +exitOnFlip = input.bool(true, "Exit on opposite flip") + +// Money Line (same logic as indicator) +atr = ta.atr(atrPeriod) +srcBase = (high + low) / 2 +src = smoothLen > 0 ? ta.ema(srcBase, smoothLen) : srcBase + +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 + +// Signals +rawBuy = trend == 1 and trend[1] == -1 +rawSell = trend == -1 and trend[1] == 1 + +// Plot for visual check +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) +plotshape(rawBuy, title="Raw Buy", location=location.belowbar, color=color.new(color.green, 0), style=shape.circle, size=size.tiny) +plotshape(rawSell, title="Raw Sell", location=location.abovebar, color=color.new(color.red, 0), style=shape.circle, size=size.tiny) + +// Helper +mt = syminfo.mintick + +// Long entries +longStop = supertrend - mt * stopBufferTicks +longRisk = strategy.equity * (riskPct / 100.0) +longRDist = close - longStop +longQty = longRDist > 0 ? (longRisk / longRDist) : 0 + +if rawBuy and strategy.position_size <= 0 and longQty > 0 + strategy.entry("Long", strategy.long, qty=longQty) + +if strategy.position_size > 0 + // Update trailing exit on each bar + longStop := supertrend - mt * stopBufferTicks + tpLong = na + if takeProfitRR > 0 + entry = strategy.position_avg_price + sd = entry - longStop + tpLong := entry + takeProfitRR * sd + strategy.exit("XL", from_entry="Long", stop=longStop, limit=tpLong) + if exitOnFlip and rawSell + strategy.close("Long") + +// Short entries +shortStop = supertrend + mt * stopBufferTicks +shortRisk = strategy.equity * (riskPct / 100.0) +shortRDist = shortStop - close +shortQty = shortRDist > 0 ? (shortRisk / shortRDist) : 0 + +if rawSell and strategy.position_size >= 0 and shortQty > 0 + strategy.entry("Short", strategy.short, qty=shortQty) + +if strategy.position_size < 0 + // Update trailing exit on each bar + shortStop := supertrend + mt * stopBufferTicks + tpShort = na + if takeProfitRR > 0 + entry = strategy.position_avg_price + sd = shortStop - entry + tpShort := entry - takeProfitRR * sd + strategy.exit("XS", from_entry="Short", stop=shortStop, limit=tpShort) + if exitOnFlip and rawBuy + strategy.close("Short")