Skip to main content

navi_vm/
lib.rs

1#![deny(private_interfaces, unreachable_pub)]
2#![warn(missing_docs)]
3#![recursion_limit = "512"]
4
5//! Navi virtual machine.
6//!
7//! This crate provides the runtime used to execute compiled Navi programs.
8//! It includes the execution engine, built-in types, and the data structures
9//! used to collect script outputs (e.g. plots and other visuals).
10//!
11//! # Key types
12//!
13//! | Type | Description |
14//! |------|-------------|
15//! | [`Instance`] | A running script. Owns the compiled program and all VM state. |
16//! | [`InstanceBuilder`] | Compiles an Navi source string into an [`Instance`]. |
17//! | [`Candlestick`] | One OHLCV bar. |
18//! | [`CandlestickItem`] | Stream item yielded by `DataProvider::candlesticks` (`Confirmed`, `Realtime`, or `HistoryEnd`). |
19//! | [`DataProvider`] | Supplies candlestick data and symbol metadata to the VM. Implemented for `Vec<Candlestick>`. |
20//! | [`SymbolInfo`] | Symbol metadata (`syminfo.*` built-ins). |
21//! | [`TimeFrame`] | Bar interval (e.g. `TimeFrame::days(1)`). |
22//! | [`visuals::Chart`] | Accumulates all visual outputs (plots, lines, labels, …). |
23//! | [`script_info::ScriptInfo`] | Script metadata extracted at compile time (type, inputs, alerts). |
24//! | [`Error`] | Top-level error type covering both compilation and runtime failures. |
25//!
26//! The compiled [`Program`](navi_program::Program) is embedded
27//! inside `Instance` and is not directly manipulated at this layer.
28//!
29//! # Basic usage
30//!
31//! ```rust,ignore
32//! use navi_vm::{Candlestick, Instance, TimeFrame, TradeSession};
33//!
34//! let source = r#"
35//!     indicator("SMA", overlay=true)
36//!     plot(ta.sma(close, 20))
37//! "#;
38//!
39//! // 1. Collect historical bars (Vec<Candlestick> implements DataProvider).
40//! let bars: Vec<Candlestick> = historical_bars;
41//!
42//! // 2. Compile the script into a runnable Instance.
43//! let instance = Instance::builder(bars, source, TimeFrame::days(1), "NASDAQ:AAPL")
44//!     .build()
45//!     .await?
46//!     .run_to_end("NASDAQ:AAPL", TimeFrame::days(1))
47//!     .await?;
48//!
49//! // 3. Read visual outputs.
50//! let chart = instance.chart();
51//! for (_id, series_graph) in chart.series_graphs() {
52//!     if let Some(plot) = series_graph.as_plot() {
53//!         println!("{:?}: {} values", plot.title, plot.series.len());
54//!     }
55//! }
56//! # Ok::<(), navi_vm::Error>(())
57//! ```
58//!
59//! # Execution model
60//!
61//! Navi executes **bar by bar**. [`Instance::run`] feeds each bar
62//! from the [`DataProvider`] stream:
63//!
64//! - [`CandlestickItem::Bar`] before `HistoryEnd` — treated as a confirmed bar;
65//!   `barstate.ishistory` is `true`.
66//! - [`CandlestickItem::Bar`] after `HistoryEnd` — treated as a realtime bar;
67//!   may be updated multiple times (same timestamp = tick update). A new
68//!   timestamp triggers automatic confirmation of the previous bar. When the
69//!   stream ends on a realtime bar, it is confirmed automatically.
70//! - [`CandlestickItem::HistoryEnd`] emits an [`Event::HistoryEnd`] event.
71//!
72//! # Overriding inputs
73//!
74//! Script inputs declared with `input.*()` can be overridden at build time:
75//!
76//! ```rust,ignore
77//! let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
78//!     .with_input_value(0, 50_i64)   // override first input (e.g. "Length") to 50
79//!     .build()
80//!     .await?;
81//! ```
82//!
83//! Use [`script_info()`] to inspect available inputs and their
84//! types before building.
85//!
86//! # Strategy scripts
87//!
88//! Strategy scripts (`strategy(…)`) are handled identically to indicators at
89//! the API level. After feeding all bars, call [`Instance::strategy_report`]
90//! to retrieve the backtest summary.
91//!
92//! # Snapshots
93//!
94//! See the [`snapshot`] module for how to checkpoint and restore VM state,
95//! which is useful for avoiding full historical replays on server restarts.
96
97rust_i18n::i18n!("locales");
98
99pub(crate) mod aux_series;
100mod compactor;
101mod context;
102mod currency;
103pub(crate) mod data_provider;
104mod error;
105mod events;
106mod execution_limits;
107mod executor;
108pub(crate) mod gc_serde;
109mod instance;
110mod instance_builder;
111#[cfg(feature = "jit")]
112pub(crate) mod jit;
113mod market_ext;
114mod native_funcs;
115pub use native_funcs::NativeFuncs;
116/// Unified candlestick + script event stream for chart providers.
117#[cfg(feature = "chart_stream")]
118pub mod chart_stream;
119pub(crate) mod objects;
120mod output_mode;
121mod plot_row_stream;
122mod raw_value;
123mod rollback;
124mod run_handle;
125mod runtime_error_messages;
126/// Metadata extracted from a compiled script (inputs, script type, alerts).
127pub mod script_info;
128pub(crate) mod security;
129mod series;
130/// Save and restore VM instance state.
131pub mod snapshot;
132mod state;
133mod str_format;
134mod strategy;
135mod ticker_expr;
136mod time;
137pub use compactor::*;
138pub use currency::Currency;
139pub use data_provider::{DataProvider, DataProviderError, HistoryProvider, PartialSymbolInfo};
140pub use events::*;
141pub use execution_limits::*;
142pub use instance::*;
143pub use instance_builder::{
144    InputSessions, InstanceBuilder, InstanceBuilderFromProgram, StrategyConfigOverride,
145    script_info, script_info_from_project,
146};
147/// Module/project loader, including the source [`loader::Dialect`].
148pub use navi_compiler::loader;
149pub use navi_program::Program;
150pub use navi_types::{
151    AuxDataItem, AuxDataPoint, BacktraceFrame, BarState, Candlestick, CandlestickItem,
152    DividendsField, EarningsField, Error, InvalidSymbolError, Market, RuntimeError, SplitsField,
153    Symbol, SymbolInfo, SymbolType, SyminfoFields, Tick, TickItem, TradeSession,
154    UnknownMarketError, VolumeType,
155};
156/// Types describing visual outputs (plots, lines, labels, etc.).
157pub use navi_visuals as visuals;
158pub use navi_visuals::DrawEvent;
159pub use output_mode::OutputMode;
160pub use plot_row_stream::PlotRowStream;
161pub use run_handle::RunHandle;
162pub use series::*;
163pub use strategy::*;
164pub use time::*;
165
166/// Returns the version of the `navi-vm` crate (e.g. `"0.2.0"`).
167pub fn version() -> &'static str {
168    env!("CARGO_PKG_VERSION")
169}