Instance Builder
The InstanceBuilder configures and compiles a Pine script into an executable Instance.
Basic Usage
use openpine_vm::{Instance, TimeFrame};
let mut instance = Instance::builder(bars, source, TimeFrame::days(1), "NASDAQ:AAPL")
.build().await?;
instance.run_to_end("NASDAQ:AAPL", TimeFrame::days(1)).await?;Data Providers
The first argument to Instance::builder() is a DataProvider. It serves two roles:
- Main chart K-lines — consumed by
Instance::run()to drive bar-by-bar execution request.security()data — MTF and cross-symbol candlestick streams
Vec<Candlestick> implements DataProvider directly, so you can pass bars without any wrapper:
let mut instance = Instance::builder(bars, source, timeframe, "NASDAQ:AAPL")
.build().await?;
instance.run_to_end("NASDAQ:AAPL", timeframe).await?;For multi-symbol or live data, implement DataProvider:
let mut instance = Instance::builder(MyProvider::new(), source, timeframe, "NASDAQ:AAPL")
.build().await?;
instance.run_to_end("NASDAQ:AAPL", timeframe).await?;The symbol string is the last argument; symbol metadata is resolved automatically by the provider.
Builder Methods
| Method | Description |
|---|---|
with_path | File path shown in error messages |
with_locale | Locale for number/date formatting |
with_input_value | Override a script input by ID |
with_input_sessions | Filter which trade sessions are processed |
with_background_color | Custom chart background color |
with_last_info | Last bar index and timestamp |
with_execution_limits | Loop iteration and security call limits |
with_library_loader | Custom loader for import statements |
with_output_mode | Series graph output mode (Chart or Stream) |
Script Metadata
with_path — Set a file path for the script (used in error messages):
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_path("my_indicator.pine")
.build().await?;with_locale — Set the locale for number and date formatting:
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_locale("zh")
.build().await?;Input Configuration
with_input_value — Override default input values by ID. Input IDs are assigned sequentially starting from 0, in the order input.*() calls appear in the script.
To discover input IDs at runtime, call the standalone script_info() function — inputs is a Vec<Input> in declaration order, so the index equals the ID:
use openpine_vm::script_info;
let info = script_info(source)?;
for (id, input) in info.inputs.iter().enumerate() {
println!("id={id} input={input:?}");
}Then override by ID:
// Pine script:
// length = input.int(14, "RSI Length") // input id 0
// src = input.source(close, "Source") // input id 1
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_input_value(0, 21) // Override RSI Length to 21
.build().await?;with_input_sessions — Control which trade sessions are processed:
use openpine_vm::InputSessions;
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_input_sessions(InputSessions::REGULAR | InputSessions::EXTENDED)
.build().await?;| Flag | Description |
|---|---|
InputSessions::REGULAR | Regular trading hours |
InputSessions::EXTENDED | Extended/pre-market/after-hours |
InputSessions::OVERNIGHT | Overnight sessions |
InputSessions::ALL | All sessions |
Display & Environment
with_background_color — Set a custom background color:
use openpine_vm::ast::Color;
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_background_color(Color::new(255, 255, 255, 255))
.build().await?;with_last_info — Provide information about the last available bar (useful for barstate.islast):
use openpine_vm::LastInfo;
let last = LastInfo::new(499, 1700000000000);
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_last_info(last)
.build().await?;Execution Limits
with_execution_limits — Configure runtime limits to protect against runaway scripts:
use openpine_vm::ExecutionLimits;
let limits = ExecutionLimits::default()
.with_max_loop_iterations_per_bar(1_000_000);
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_execution_limits(limits)
.build().await?;When not called, the default limit of 500,000 loop iterations per bar is used. See Security & Execution Limits for details.
with_library_loader — Add a custom library loader for import statements:
use openpine_vm::loader::LibraryLoader;
struct MyLoader;
impl LibraryLoader for MyLoader {
// ... implement loading logic
}
let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
.with_library_loader(MyLoader)
.build().await?;Output Mode
with_output_mode — Controls how plot() data is produced during execution.
| Mode | Behavior |
|---|---|
OutputMode::Chart (default) | Series graph data is written to instance.chart() |
OutputMode::Stream | Series graph data is emitted as DrawEvent in the event stream |
use openpine_vm::{Instance, OutputMode, TimeFrame};
let mut instance = Instance::builder(provider, source, TimeFrame::days(1), "NASDAQ:AAPL")
.with_output_mode(OutputMode::Stream)
.build().await?;See Executing Scripts for usage examples.
Inspecting Script Info
Use the standalone script_info() function to inspect a script's metadata without creating an executable instance. It requires only the source code — no data provider, symbol, or timeframe:
use openpine_vm::script_info;
let info = script_info(source)?;
println!("Script type: {:?}", info.script_type);
println!("Is overlay: {}", info.overlay());
println!("Inputs: {} total", info.inputs.len());
for input in &info.inputs {
// Inspect input definitions
}Chaining Everything Together
use openpine_vm::{Instance, OutputMode, TimeFrame};
let mut instance = Instance::builder(bars, source, TimeFrame::minutes(5), "NASDAQ:AAPL")
.with_path("strategy.pine")
.with_locale("en")
.with_input_value(0, 20) // Override first input
.with_input_value(1, 2.5) // Override second input
.with_input_sessions(InputSessions::REGULAR)
.with_last_info(LastInfo::new(999, last_time))
.with_output_mode(OutputMode::Stream)
.build().await?;
instance.run_to_end("NASDAQ:AAPL", TimeFrame::minutes(5)).await?;Next Steps
- Executing Scripts — feed data and run
- Reading Outputs — inspect results