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 := false

Last updated