Ir al contenido
← Todos los ejemplos

Ejemplo 17

Trade pages

read a run's closed trades page by page (`trades_page`), the

Categoría
Host: necesita los datos y el motor de la terminal
Permisos
market.readbacktest.run
Antes de ejecutarlo
a published BTCUSDT dataset on this machine
Qué hace
runs one backtest on TTT's engine (one job, waited for)
Cómo ejecutarlo
in TTT, open "T0 Lang", open this file, grant market.read and
Lenguaje
>=0.1.1, <0.2.0
Host
>=0.1.3, <0.2.0
Necesita
market >=0.1.1, <0.2.0features >=0.1.0, <0.2.0backtest >=0.1.3, <0.2.0

Código

// Purpose: read a run's closed trades page by page (`trades_page`), the
// way to read a run too large for one `trades` call, and check the pages
// add up to the whole.
// Category: host
// Permissions: market.read, backtest.run
// Preconditions: a published BTCUSDT dataset on this machine
// Side effects: runs one backtest on TTT's engine (one job, waited for)
// Run: in TTT, open "T0 Lang", open this file, grant market.read and
// backtest.run, Run.

lang ">=0.1.1, <0.2.0";
host "ttt" ">=0.1.3, <0.2.0";
requires "market" ">=0.1.1, <0.2.0";
requires "features" ">=0.1.0, <0.2.0";
requires "backtest" ">=0.1.3, <0.2.0";

strategy flip(window: Int, size: Quantity) version "1.0.0" {
    let average = features.sma(window);
    let px = features.price(features.Source.Trades);
    rule enter when cross_above(px, average) && exposure_is(Exposure.Flat)
        => order(Side.Buy, Intent.Open, OrderType.Market, Sizing.Fixed(size));
    rule exit when cross_below(px, average) && exposure_is(Exposure.Open)
        => order(Side.Sell, Intent.Close, OrderType.Market, Sizing.Fixed(size));
    flatten_on_stop;
}

fn main() -> Result<Unit, Error> {
    let ds = market.datasets("BTCUSDT")?.first().expect("no published BTCUSDT dataset on this machine");
    let report = backtest.run(backtest.Spec {
        strategy: flip(2, qty(0.01)),
        dataset: ds,
        start: None,
        end: None,
        starting_balance: money(10000, USDT),
        execution: backtest.Execution {
            maker_fee: bps(2),
            taker_fee: bps(5),
            slippage: backtest.Slippage.None,
            latency: 0ms,
            market_fill: backtest.MarketFill.NextPrint,
            limit_fill: backtest.LimitFill.TradeThrough,
        },
    })?;
    let mut read = 0;
    let mut pages = 0;
    let mut from = 0;
    let mut more = true;
    while more {
        let page = backtest.trades_page(report.run_id, from, 1)?;
        read = read + page.trades.len();
        pages = pages + 1;
        match page.next {
            Some(next) => {
                from = next;
            }
            None => {
                more = false;
            }
        }
    }
    let all = backtest.trades(report.run_id)?;
    print(to_string(read) + " trades in " + to_string(pages) + " page(s); trades() has " + to_string(all.len()));
    print(if read == all.len() { "the pages add up to the whole" } else { "the pages DO NOT add up" });
    match backtest.trades_page(report.run_id, 0, 0) {
        Ok(_) => print("unexpected: an empty page was accepted"),
        Err(e) => print("refused as it should be: " + e.code),
    }
    return Ok(());
}