#[non_exhaustive]pub struct Backtest {
pub name: String,
pub symbol: String,
pub timeframe: Timeframe,
pub settings: BacktestSettings,
/* private fields */
}Expand description
Runs a Strategy over bars and reports the result as a StrategyReport.
The strategy decides on each bar once it closes. Its orders fill no earlier than the next
bar, along that bar’s price path: from the open to the extreme nearer the open (the high when
both are as near within a few ulps), then to the other extreme, then to the close. A market
order fills at the open. A limit, stop or stop-limit order fills where the path reaches it, at
its limit or stop price, or at the open when the bar opened beyond it; a triggered stop-limit
order works on as a limit order from its stop. Orders the path reaches at the same point fill
in the order they were first placed. An exit with a take profit and a stop loss fills whichever
the path reaches first. With settings.fill_on_close, market orders fill at the
close of the bar they were placed on instead.
Each entry is a trade, closed by exits and opposite entries first in first out; each partial exit is its own trade with its share of the entry. A trade’s label names its entry and exit orders, such as “Long / Take profit”, or the entry alone while open. Profit is the price difference times the quantity, less its allocated fees. Without a start time, the equity curve holds the initial capital one interval before the first bar, then the account value at each bar’s close, stamped with the bar’s time. With a start time it begins there and subsequent marks use chart-bar closing times. Fills use the times of their chart or finer bars. Close fills on trade-based bars use the last source time, which stays fixed as bars arrive.
Bars are oldest first, in strictly increasing time order. A bar without finite prices, or whose high and low do not contain its open and close, fills no orders and has no equity value. Settings apply sizing, pyramiding, costs and margin at each execution; a margin deficit closes the position along the path. Optional finer bars determine fills within each chart bar.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.name: StringWhat the report calls the run.
symbol: StringThe instrument the bars are of.
timeframe: TimeframeThe bar interval.
settings: BacktestSettingsAccount and execution assumptions, also recorded in the report’s properties.
Implementations§
Source§impl Backtest
impl Backtest
Sourcepub fn report(&self) -> Option<&StrategyReport>
pub fn report(&self) -> Option<&StrategyReport>
The current live report, available after the first Self::update.
With tick recalculation, trades include forming-bar fills; equity marks are closed bars.
Self::run remains an independent historical calculation and does not change this state.
Sourcepub fn update(
&mut self,
strategy: &mut dyn Strategy,
bars: &[Bar],
lower: &[Bar],
) -> Vec<StrategyFill>
pub fn update( &mut self, strategy: &mut dyn Strategy, bars: &[Bar], lower: &[Bar], ) -> Vec<StrategyFill>
Continues a live strategy on bars, oldest first, with the last bar still forming.
Pass the same strategy instance and the full retained history on each call. The first
call processes the closed history and returns its fills; discard that batch when priming
a run that should alert only on subsequent fills. lower has the meaning it has in run.
With settings.recalculate_on_every_update off, only newly closed bars execute, exactly
as in run over bars without its last bar. With it on, an observed forming bar walks
from its open to its close, then from its previous close to each new close, and decides
again with that forming bar included in the context. Its fills and orders are retained
when the bar closes; unseen intrabar extremes are never replayed over observed ticks.
Identical snapshots do nothing. Fill callbacks still exclude the unfinished bar.
A correction before the previous forming bar, removed history, changed settings or inputs
rebuilds from the start using Strategy::prepare to reset decision state. Replayed fills
before the previous forming bar are not returned again. An observed forming bar can be
revised freely without a rebuild. Start a new Backtest for a different strategy instance.
§Panics
Panics if starting capital is not finite or bar timestamps are not strictly increasing.
Source§impl Backtest
impl Backtest
Sourcepub fn new(
name: impl Into<String>,
symbol: impl Into<String>,
timeframe: Timeframe,
initial_capital: f64,
) -> Self
pub fn new( name: impl Into<String>, symbol: impl Into<String>, timeframe: Timeframe, initial_capital: f64, ) -> Self
A backtest that fills market orders at the next bar’s open.
Sourcepub fn run(
&self,
strategy: &mut dyn Strategy,
bars: &[Bar],
lower: &[Bar],
) -> StrategyReport
pub fn run( &self, strategy: &mut dyn Strategy, bars: &[Bar], lower: &[Bar], ) -> StrategyReport
Runs strategy over bars and reports its trades, equity and assumptions.
lower supplies finer bars of the same symbol. Valid bars are walked in time order inside
each chart bar; a chart bar without any falls back to its own path. Decisions and equity
remain on the chart interval. Pass &[] to use chart bars alone.
With a start time, prepare still receives all bars, but chart bars opening before it
cannot trade. Equity starts at the requested time and subsequent points use chart-bar
closes, so the starting value and first close have distinct timestamps. A final execution
bar without a known end labels its equity mark one nanosecond after its last source time.
§Panics
Panics if the starting capital is not finite.
Sourcepub async fn run_async(
&self,
strategy: &mut dyn Strategy,
bars: &[Bar],
lower: &[Bar],
) -> StrategyReport
pub async fn run_async( &self, strategy: &mut dyn Strategy, bars: &[Bar], lower: &[Bar], ) -> StrategyReport
Runs the same fills as Self::run, yielding between batches of 256 chart or finer bars.
Poll from an executor or once per frame. Dropping the future cancels the run. Strategy preparation and individual callbacks remain synchronous, so hosts should keep them bounded.
§Panics
Panics if the starting capital is not finite.
Trait Implementations§
impl StructuralPartialEq for Backtest
Auto Trait Implementations§
impl Freeze for Backtest
impl RefUnwindSafe for Backtest
impl Send for Backtest
impl Sync for Backtest
impl Unpin for Backtest
impl UnsafeUnpin for Backtest
impl UnwindSafe for Backtest
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more