本文へ移動
← すべてのサンプル

サンプル 17

Trade pages

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

カテゴリ
Host:ターミナルのデータとエンジンが必要
権限
market.readbacktest.run
実行する前に
a published BTCUSDT dataset on this machine
何をするか
runs one backtest on TTT's engine (one job, waited for)
実行方法
in TTT, open "T0 Lang", open this file, grant market.read and
言語
>=0.1.1, <0.2.0
ホスト
>=0.1.3, <0.2.0
必要なもの
market >=0.1.1, <0.2.0features >=0.1.0, <0.2.0backtest >=0.1.3, <0.2.0

ソース

// 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(());
}