Orders, strategies and alerts
Strategies that place orders on the synthetic bars, with exits and risk rules, and an alert call (alerts on scripts are off in this release).
A strategy is an indicator that also places orders. The tester fills them on the bars of the chart under the rules of the setup block. The data here is generated, so these programs show how to write a strategy, not how a strategy performs.
Cross alert#
An alert condition on a crossing, with a name and a message.
Cuprel
// An alert condition: the settings panel lists it, and the alert fires on the bar where the fast average crosses above the slow one.
indicator "Cross alert"
edition = 1
display = price
input fast_length: int = 9, name = "Fast length", min = 1
input slow_length: int = 21, name = "Slow length", min = 2
let fast = tech.sma(close, fast_length)
let slow = tech.sma(close, slow_length)
plot(fast, name = "Fast", color = color.green)
plot(slow, name = "Slow", color = color.red)
alert.when(
tech.crosses_above(fast, slow),
name = "Fast above slow",
message = "The fast average crossed above the slow one",
)Moving average crossover strategy#
Enter and close on a crossing; the first strategy.
Cuprel
// A crossover strategy: buy when the fast average crosses above the slow one, sell the position when it crosses back.
// The tester fills the orders on the synthetic data; costs are set in the setup block.
strategy "Moving average crossover"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
input fast_length: int = 10, name = "Fast length", min = 1
input slow_length: int = 30, name = "Slow length", min = 2
let fast = tech.ema(close, fast_length)
let slow = tech.ema(close, slow_length)
if tech.crosses_above(fast, slow)
orders.enter("Long", side.long)
if tech.crosses_below(fast, slow)
orders.close("Long")
plot(fast, name = "Fast", color = color.green)
plot(slow, name = "Slow", color = color.red)RSI reversion strategy#
Enter after the RSI crosses below a level, leave when it recovers.
Cuprel
// Mean reversion: enter long when the RSI falls below the oversold level, leave when it recovers above the middle.
strategy "RSI reversion"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
input length: int = 14, name = "RSI length", min = 2
input oversold: float = 30, name = "Oversold"
input exit_level: float = 55, name = "Exit level"
let value = tech.rsi(close, length)
if tech.crosses_below(value, oversold)
orders.enter("Long", side.long)
if value > exit_level
orders.close("Long")
plot(close, name = "Close", color = color.gray)Donchian breakout strategy#
A stop entry above a channel and a stop exit below a shorter one.
Cuprel
// A channel breakout: a stop order one tick above the highest high of the last `length` bars, an exit under the lowest low of a shorter window.
strategy "Donchian breakout"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
input entry_length: int = 20, name = "Entry length", min = 2
input exit_length: int = 10, name = "Exit length", min = 2
let entry_level = tech.highest(high, entry_length)[1]
let exit_level = tech.lowest(low, exit_length)[1]
if bar.is_closed
orders.enter("Breakout", side.long, stop = entry_level, expires = 1)
orders.exit("Leave", "Breakout", stop = exit_level)
plot(entry_level, name = "Entry level", color = color.green)
plot(exit_level, name = "Exit level", color = color.red)ATR stop and target#
A protective stop and a target measured in ATR multiples.
Cuprel
// A position with a protective stop and a target measured in multiples of the Average True Range at the time of entry.
strategy "ATR stop and target"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
input length: int = 14, name = "ATR length", min = 2
input stop_mult: float = 2.0, name = "Stop multiple", min = 0.5, step = 0.5
input target_mult: float = 3.0, name = "Target multiple", min = 0.5, step = 0.5
let range = tech.atr(length)
let trend_up = tech.ema(close, 20) > tech.ema(close, 50)
if tech.crosses_above(close, tech.ema(close, 20)) and trend_up and trades.open_count == 0
orders.enter("Long", side.long)
orders.exit(
"Long exit",
"Long",
stop = close - stop_mult * range,
limit = close + target_mult * range,
)
plot(tech.ema(close, 20), name = "EMA 20", color = color.orange)Risk guards#
Daily order and drawdown limits that stop new entries.
Cuprel
// Rules that stop trading when a limit is reached: no more than two entries a day, no new entries after three losing days in a row.
strategy "Risk guards"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
input length: int = 20, name = "Length", min = 2
risk.max_daily_orders(2)
risk.max_losing_days(3)
let basis = tech.sma(close, length)
if tech.crosses_above(close, basis)
orders.enter("Long", side.long)
if tech.crosses_below(close, basis)
orders.close("Long")
plot(basis, name = "Basis", color = color.orange)