25. Example Custom Strategy
//@version=5
strategy("Perpbot Example Strategy",
overlay=true,
initial_capital=1000,
pyramiding=0,
default_qty_type=strategy.cash,
default_qty_value=1000,
calc_on_every_tick=true,
process_orders_on_close=false)
// ────────────────────────────────────────────────────────────────
// SECTION 1 – USER AREA (SAFE TO EDIT)
// You can change indicator settings AND the 4 conditions below.
// DO NOT change any alert_message text ("long", "short", "close").
// ────────────────────────────────────────────────────────────────
// Basic indicators (you can tweak these inputs)
rsiLen = input.int(14, "RSI Length")
bbLen = input.int(20, "BB Length")
bbStd = input.float(2, "BB Std Dev", step = 0.1)
rsi = ta.rsi(close, rsiLen)
[bbU, bbM, bbL] = ta.bb(close, bbLen, bbStd)
// === ENTRY CONDITIONS (EDIT THESE IF YOU WANT) ===
// Example long: oversold + near lower band
longEntryCondition = (rsi < 30) and (close < bbL)
// Example short: overbought + near upper band
shortEntryCondition = (rsi > 70) and (close > bbU)
// === EXIT CONDITIONS (EDIT THESE IF YOU WANT) ===
// Example long exit: RSI back above 50 OR price above middle band
longExitCondition = (rsi > 50) or (close > bbM)
// Example short exit: RSI back below 50 OR price below middle band
shortExitCondition = (rsi < 50) or (close < bbM)
// Visuals (optional, safe to edit or remove)
plotshape(longEntryCondition, title="Long Entry", location=location.belowbar,
color=color.new(color.green, 0), style=shape.triangleup, size=size.tiny)
plotshape(shortEntryCondition, title="Short Entry", location=location.abovebar,
color=color.new(color.red, 0), style=shape.triangledown, size=size.tiny)
// ────────────────────────────────────────────────────────────────
// SECTION 2 – PERPBOT INTEGRATION (DO NOT TOUCH)
// DO NOT change:
// • alert_message values ("long", "short", "close")
// • strategy.entry / strategy.close_all ids or types
// Perpbot expects EXACTLY these commands.
// ────────────────────────────────────────────────────────────────
var bool inLong = false
var bool inShort = false
var bool didClose = false // ensures only one command per bar
// Reset per bar
didClose := false
// 1) EXIT LOGIC → send "close" when your exit condition hits
if inLong and longExitCondition
strategy.close_all(comment = "Long Exit", alert_message = "close")
inLong := false
inShort := false
didClose := true
if not didClose and inShort and shortExitCondition
strategy.close_all(comment = "Short Exit", alert_message = "close")
inLong := false
inShort := false
didClose := true
// 2) ENTRY / FLIP LOGIC → send "long" or "short"
// Note: if we flip (short → long or long → short) we ONLY send the
// new direction command. Perpbot handles the flip on its side.
if not didClose
// LONG ENTRY – sends "long" to Perpbot
if longEntryCondition and not inLong
strategy.entry(id = "Long", direction = strategy.long, alert_message = "long")
inLong := true
inShort := false
// SHORT ENTRY – sends "short" to Perpbot
if shortEntryCondition and not inShort
strategy.entry(id = "Short", direction = strategy.short, alert_message = "short")
inShort := true
inLong := false
// 3) Safety: reset flags if strategy is flat (for any reason)
if strategy.position_size == 0
inLong := false
inShort := falseLast updated