Add Bullmania Money Line Strategy: risk-based position sizing, TSL at Money Line, optional TP and flip exits
This commit is contained in:
105
Bullmania_Money_Line_Strategy.pine
Normal file
105
Bullmania_Money_Line_Strategy.pine
Normal file
@@ -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")
|
||||
Reference in New Issue
Block a user