Skip to main content

optimise

Function optimise 

Source
pub fn optimise<'a>(
    create_strategy: impl Fn() -> Box<dyn Strategy + 'a> + 'a,
    backtest: &'a Backtest,
    bars: &'a [Bar],
    lower: &'a [Bar],
    inputs: &'a [(String, Vec<InputValue>)],
) -> impl Iterator<Item = Result<StrategyTrial, &'static str>> + 'a
Expand description

Runs one fresh strategy per combination of inputs, on the same backtest and bars.

create_strategy must return an independent strategy with the same initial configuration and state each time. For a configured, cloneable strategy, pass || Box::new(strategy.clone()) to leave the original unchanged; a super::StrategyFactory can supply boxed strategies. Returned strategies may borrow host data for the iterator’s lifetime.

No strategy is created or run until next. Each next runs one complete backtest and computes its report’s performance. Consume a few trials per frame, or create and consume the iterator on a worker thread. Dropping it stops the remaining trials.

Values run in the supplied order, with the last input varying fastest. No inputs means one unmodified trial; any input with no values means no trials. Duplicate ids yield Err("duplicate strategy input"). A rejected assignment yields the strategy’s exact Strategy::set_input error without running that trial. Either error ends the iterator. lower has the same meaning as in Backtest::run; pass &[] for chart bars alone.

§Panics

As with Backtest::run, a trial panics if the starting capital is not finite.

use egui_charts::model::Timeframe;
use egui_charts::strategies::{Backtest, StrategyFactory, optimise};
use egui_charts::studies::InputValue;

let factory = StrategyFactory::new();
let backtest = Backtest::new("Consecutive Up/Down", "TEST", Timeframe::Min1, 10_000.0);
let grid = [("length".into(), vec![InputValue::Length(2), InputValue::Length(3)])];
// Supply the host's chart bars and optional finer bars in place of the empty slices.
let mut trials = optimise(
    || factory.create("Consecutive Up/Down").unwrap(), &backtest, &[], &[], &grid,
);
assert_eq!(trials.next().unwrap().unwrap().inputs[0].1, InputValue::Length(2));
assert_eq!(trials.next().unwrap().unwrap().inputs[0].1, InputValue::Length(3));
assert!(trials.next().is_none());