millionchart
فارسی

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)