use ahash::AHashMap;
use nautilus_backtest::{config::BacktestEngineConfig, engine::BacktestEngine};
use nautilus_execution::models::{fee::FeeModelAny, fill::FillModelAny};
use nautilus_model::{
data::{Data, QuoteTick},
enums::{AccountType, BookType, OmsType},
identifiers::{InstrumentId, Venue},
instruments::{Instrument, InstrumentAny, stubs::audusd_sim},
types::{Money, Price, Quantity},
};
use nautilus_trading::examples::strategies::EmaCross;
fn quote(instrument_id: InstrumentId, bid: &str, ask: &str, ts: u64) -> Data {
Data::Quote(QuoteTick::new(
instrument_id,
Price::from(bid),
Price::from(ask),
Quantity::from("100000"),
Quantity::from("100000"),
ts.into(),
ts.into(),
))
}
fn generate_quotes(instrument_id: InstrumentId) -> Vec<Data> {
let spread = 0.00020;
let base_ts: u64 = 1_735_689_600_000_000_000; let interval: u64 = 1_000_000_000;
let mut quotes = Vec::new();
let mut tick: u64 = 0;
let mut add = |mid: f64| {
let bid = format!("{mid:.5}");
let ask = format!("{:.5}", mid + spread);
quotes.push(quote(instrument_id, &bid, &ask, base_ts + tick * interval));
tick += 1;
};
for _ in 0..25 {
add(0.65000);
}
let cycles = 6;
for cycle in 0..cycles {
let base = 0.65000 + (cycle as f64 * 0.00100);
for i in 0..40 {
add(base + (i as f64 * 0.00050));
}
for i in 0..80 {
let peak = base + 39.0 * 0.00050;
add(peak - (i as f64 * 0.00050));
}
}
quotes
}
fn main() -> anyhow::Result<()> {
let mut engine = BacktestEngine::new(BacktestEngineConfig::default())?;
engine.add_venue(
Venue::from("SIM"),
OmsType::Hedging,
AccountType::Margin,
BookType::L1_MBP,
vec![Money::from("1_000_000 USD")],
None, None, AHashMap::new(), None, vec![], FillModelAny::default(),
FeeModelAny::default(),
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, )?;
let instrument = InstrumentAny::CurrencyPair(audusd_sim());
let instrument_id = instrument.id();
engine.add_instrument(&instrument)?;
engine.add_strategy(EmaCross::new(
instrument_id,
Quantity::from("100000"),
10,
20,
))?;
let quotes = generate_quotes(instrument_id);
engine.add_data(quotes, None, true, true);
engine.run(None, None, None, false)?;
Ok(())
}