124 lines
3.6 KiB
Rust
124 lines
3.6 KiB
Rust
|
|
//! Benchmark for RaptorBT backtesting performance.
|
||
|
|
|
||
|
|
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
||
|
|
use raptorbt::core::types::{BacktestConfig, CompiledSignals, Direction, OhlcvData};
|
||
|
|
use raptorbt::indicators::trend::{ema, sma};
|
||
|
|
use raptorbt::portfolio::engine::PortfolioEngine;
|
||
|
|
|
||
|
|
/// Generate sample OHLCV data.
|
||
|
|
fn generate_sample_data(n: usize) -> OhlcvData {
|
||
|
|
let mut open = vec![100.0; n];
|
||
|
|
let mut high = vec![101.0; n];
|
||
|
|
let mut low = vec![99.0; n];
|
||
|
|
let mut close = vec![100.0; n];
|
||
|
|
|
||
|
|
// Create a trending pattern
|
||
|
|
for i in 1..n {
|
||
|
|
let change = (i as f64 * 0.1).sin() * 2.0;
|
||
|
|
close[i] = close[i - 1] + change;
|
||
|
|
open[i] = close[i - 1];
|
||
|
|
high[i] = close[i].max(open[i]) + 1.0;
|
||
|
|
low[i] = close[i].min(open[i]) - 1.0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OhlcvData {
|
||
|
|
timestamps: (0..n as i64).collect(),
|
||
|
|
open,
|
||
|
|
high,
|
||
|
|
low,
|
||
|
|
close,
|
||
|
|
volume: vec![1000.0; n],
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Generate sample trading signals based on SMA crossover.
|
||
|
|
fn generate_sample_signals(
|
||
|
|
close: &[f64],
|
||
|
|
fast_period: usize,
|
||
|
|
slow_period: usize,
|
||
|
|
) -> CompiledSignals {
|
||
|
|
let n = close.len();
|
||
|
|
let fast_sma = sma(close, fast_period).unwrap_or_else(|_| vec![0.0; n]);
|
||
|
|
let slow_sma = sma(close, slow_period).unwrap_or_else(|_| vec![0.0; n]);
|
||
|
|
|
||
|
|
let mut entries = vec![false; n];
|
||
|
|
let mut exits = vec![false; n];
|
||
|
|
|
||
|
|
for i in 1..n {
|
||
|
|
// Entry: fast crosses above slow
|
||
|
|
if fast_sma[i] > slow_sma[i] && fast_sma[i - 1] <= slow_sma[i - 1] {
|
||
|
|
entries[i] = true;
|
||
|
|
}
|
||
|
|
// Exit: fast crosses below slow
|
||
|
|
if fast_sma[i] < slow_sma[i] && fast_sma[i - 1] >= slow_sma[i - 1] {
|
||
|
|
exits[i] = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
CompiledSignals {
|
||
|
|
symbol: "BENCH".to_string(),
|
||
|
|
entries,
|
||
|
|
exits,
|
||
|
|
position_sizes: None,
|
||
|
|
direction: Direction::Long,
|
||
|
|
weight: 1.0,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fn bench_single_backtest(c: &mut Criterion) {
|
||
|
|
let mut group = c.benchmark_group("single_backtest");
|
||
|
|
|
||
|
|
for size in [1000, 5000, 10000, 50000].iter() {
|
||
|
|
group.bench_with_input(BenchmarkId::new("bars", size), size, |b, &size| {
|
||
|
|
let ohlcv = generate_sample_data(size);
|
||
|
|
let signals = generate_sample_signals(&ohlcv.close, 10, 30);
|
||
|
|
let config = BacktestConfig::default();
|
||
|
|
let engine = PortfolioEngine::new(config);
|
||
|
|
|
||
|
|
b.iter(|| {
|
||
|
|
let result = engine.run_single(black_box(&ohlcv), black_box(&signals));
|
||
|
|
black_box(result)
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
group.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
fn bench_sma(c: &mut Criterion) {
|
||
|
|
let mut group = c.benchmark_group("sma");
|
||
|
|
|
||
|
|
for size in [1000, 5000, 10000, 50000].iter() {
|
||
|
|
group.bench_with_input(BenchmarkId::new("data_size", size), size, |b, &size| {
|
||
|
|
let ohlcv = generate_sample_data(size);
|
||
|
|
|
||
|
|
b.iter(|| {
|
||
|
|
let result = sma(black_box(&ohlcv.close), black_box(20));
|
||
|
|
black_box(result)
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
group.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
fn bench_ema(c: &mut Criterion) {
|
||
|
|
let mut group = c.benchmark_group("ema");
|
||
|
|
|
||
|
|
for size in [1000, 5000, 10000, 50000].iter() {
|
||
|
|
group.bench_with_input(BenchmarkId::new("data_size", size), size, |b, &size| {
|
||
|
|
let ohlcv = generate_sample_data(size);
|
||
|
|
|
||
|
|
b.iter(|| {
|
||
|
|
let result = ema(black_box(&ohlcv.close), black_box(20));
|
||
|
|
black_box(result)
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
group.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
criterion_group!(benches, bench_single_backtest, bench_sma, bench_ema);
|
||
|
|
criterion_main!(benches);
|