← 모든 예제
예제 10
Parameter sweep
A small parameter sweep: the same strategy at three window lengths, all
- 분류
- Host: 터미널의 데이터와 엔진 필요
- 권한
- market.readbacktest.run
- 언어
>=0.1.1, <0.2.0- 호스트
>=0.1.1, <0.2.0- 필요한 것
- market >=0.1.1, <0.2.0features >=0.1.0, <0.2.0backtest >=0.1.1, <0.2.0
소스
// Category: host // Permissions: market.read, backtest.run // A small parameter sweep: the same strategy at three window lengths, all // submitted at once (each is its own job on TTT's engine), then compared // on net result. Every run uses the same explicit execution costs. // // Grant in the T0 Lang window: market.read, backtest.run. lang ">=0.1.1, <0.2.0"; host "ttt" ">=0.1.1, <0.2.0"; requires "market" ">=0.1.1, <0.2.0"; requires "features" ">=0.1.0, <0.2.0"; requires "backtest" ">=0.1.1, <0.2.0"; strategy ema_cross(fast: Int, slow: Int, size: Quantity) version "1.0.0" { let fast_ema = features.ema(fast); let slow_ema = features.ema(slow); rule enter when cross_above(fast_ema, slow_ema) && exposure_is(Exposure.Flat) => order(Side.Buy, Intent.Open, OrderType.Market, Sizing.Fixed(size)); rule exit when cross_below(fast_ema, slow_ema) && exposure_is(Exposure.Open) => order(Side.Sell, Intent.Close, OrderType.Market, Sizing.Fixed(size)); flatten_on_stop; } fn costs() -> backtest.Execution { return backtest.Execution { maker_fee: bps(2), taker_fee: bps(5), slippage: backtest.Slippage.Fraction(bps(1)), latency: 50ms, market_fill: backtest.MarketFill.NextPrint, limit_fill: backtest.LimitFill.TradeThrough, }; } fn main() -> Result<Unit, Error> { let ds = market.datasets("BTCUSDT")?.first().expect("no published BTCUSDT dataset on this machine"); let slows = [21, 50, 100]; let mut jobs: List<backtest.Job> = []; for slow in slows { let job = backtest.submit(backtest.Spec { strategy: ema_cross(9, slow, qty(0.01)), dataset: ds, start: None, end: None, starting_balance: money(10000, USDT), execution: costs(), })?; jobs.push(job); } let mut best: Option<Money> = None; let mut best_slow = 0; let mut i = 0; while i < jobs.len() { let report = backtest.wait(jobs[i])?; let net = report.realized_pnl; print("slow " + to_string(slows[i]) + ": " + to_string(report.status) + ", " + to_string(report.trades) + " trades, net " + to_string(net)); let better = match best { Some(b) => net > b, None => true, }; if better { best = Some(net); best_slow = slows[i]; } i = i + 1; } print("best slow window: " + to_string(best_slow) + " (one dataset, one period: not evidence of an edge)"); return Ok(()); }