Writing a Custom Strategy
1. Create the file
Add crates/strategy/src/my_strategy.rs and implement the Strategy trait:
#![allow(unused)]
fn main() {
use std::sync::Arc;
use mercury_core::{BookUpdate, Fill, Signal, Trade};
use crate::Strategy;
pub struct MyStrategy {
// your state here
}
impl MyStrategy {
pub fn new() -> Self {
Self {}
}
}
impl Strategy for MyStrategy {
fn name(&self) -> &'static str { "my_strategy" }
fn on_book(&mut self, book: &Arc<BookUpdate>) -> Vec<Signal> {
// compute signals from the order book
vec![]
}
fn on_trade(&mut self, _trade: &Trade) -> Vec<Signal> {
vec![]
}
fn on_fill(&mut self, _fill: &Fill) {
// update inventory / reinforce learning
}
fn reset(&mut self) {
// clear all state
*self = Self::new();
}
}
}
2. Export from the crate
In crates/strategy/src/lib.rs:
#![allow(unused)]
fn main() {
pub mod my_strategy;
pub use my_strategy::MyStrategy;
}
3. Register the CLI flag
In crates/cli/src/run.rs, add a match arm for the new strategy name:
#![allow(unused)]
fn main() {
"my_strategy" => Box::new(MyStrategy::new()),
}
4. Run it
cargo run --bin mercury -- run --symbol BTCUSDT --paper --strategy my_strategy
Tips
- Keep
on_bookfast — it is called on every tick. Avoid allocations on the hot path. - Use
rust_decimal::Decimalfor all price/quantity arithmetic. - Initialise warm-up state in
reset()so backtests start clean. - Use
on_fillto track inventory rather than counting signals, since orders may be partially filled or rejected.