본문으로 건너뛰기
← 모든 예제

예제 78

Tunable ema cross

an EMA crossover whose parameters say which of them an optimizer may move, with decorators (ADR-0015). It buys when the fast EMA of the closed bars crosses above the slow one and sells when it crosses

분류
Host: 터미널의 데이터와 엔진 필요
권한
orders.submit
실행하기 전에
a chart in hand on the live market or a replay whose instrument the live feed serves (closed bars)
하는 일
asks the terminal to run the strategy; once running it places orders on the account the person chose.
실행 방법
Insert strategy in the Backtests window (backtest and optimize); Add script on a replay or the live market.
언어
>=0.2.0, <0.3.0
호스트
>=0.1.17, <0.2.0
필요한 것
features >=0.1.8, <0.2.0trade >=0.1.0, <0.2.0

소스

// Purpose: an EMA crossover whose parameters say which of them an optimizer may move, with decorators (ADR-0015). It buys when the fast EMA of the closed bars crosses above the slow one and sells when it crosses
// back; the *rule* is fixed, the numbers are not. `@param(min:, max:, step:, …)` before a parameter gives the range it is searched in and the grid it moves on; `above: fast` keeps `slow` above `fast` in every
// configuration tried; `size` has no decorator, so it is a fixed value the optimizer never touches. The value `main` passes (9, 21) is where the terminal's Parameters panel starts; a decorator never changes what
// the strategy does, so this runs exactly as `ema_cross(9, 21, qty(0.01))` without them.
// In the Backtests window: add the strategy, open its Parameters, tick Optimize on `fast` and `slow`, and use the Optimize tab to search them on a dataset.
// HONEST NOTE: an EMA crossover has no known edge after fees on a short timeframe; this is a template for the mechanism, not a signal. Every backtest of the search replays the tape, so a search takes a while:
// keep the window short and the budget small, and read the best result as the most flattering one.
// Category: host
// Permissions: orders.submit
// Preconditions: a chart in hand on the live market or a replay whose instrument the live feed serves (closed bars)
// Side effects: asks the terminal to run the strategy; once running it places orders on the account the person chose.
// Run: Insert strategy in the Backtests window (backtest and optimize); Add script on a replay or the live market.

lang ">=0.2.0, <0.3.0";
host "ttt" ">=0.1.17, <0.2.0";
requires "features" ">=0.1.8, <0.2.0";
requires "trade" ">=0.1.0, <0.2.0";

strategy ema_cross(
    @param(label: "Fast EMA", min: 3, max: 30, step: 1, group: "Signal", hint: "Bars of the fast average.") fast: Int,
    @param(label: "Slow EMA", min: 20, max: 200, step: 5, above: fast, group: "Signal", hint: "Bars of the slow average; always above the fast one.") slow: Int,
    size: Quantity,
) version "1.0.0" {
    let fast_ma = features.ema(fast);
    let slow_ma = features.ema(slow);

    rule enter when cross_above(fast_ma, slow_ma) && exposure_is(Exposure.Flat)
        => order(Side.Buy, Intent.Open, OrderType.Market, Sizing.Fixed(size));
    rule exit when cross_below(fast_ma, slow_ma) && exposure_is(Exposure.Open)
        => order(Side.Sell, Intent.Close, OrderType.Market, Sizing.Fixed(size));
    flatten_on_stop;
}

fn main() -> Result<Unit, Error> {
    // 9 over 21 bars, a hundredth of a coin.
    let run = trade.run(ema_cross(9, 21, qty(0.01)))?;
    print(run.name + " on " + run.target + ": " + run.state);
    return Ok(());
}