Skip to content

Instance Builder

The InstanceBuilder configures and compiles a Pine script into an executable Instance.

Basic Usage

rust
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:

  1. Main chart K-lines — consumed by Instance::run() to drive bar-by-bar execution
  2. request.security() data — MTF and cross-symbol candlestick streams

Vec<Candlestick> implements DataProvider directly, so you can pass bars without any wrapper:

rust
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:

rust
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

MethodDescription
with_pathFile path shown in error messages
with_localeLocale for number/date formatting
with_input_valueOverride a script input by ID
with_input_sessionsFilter which trade sessions are processed
with_background_colorCustom chart background color
with_last_infoLast bar index and timestamp
with_execution_limitsLoop iteration and security call limits
with_library_loaderCustom loader for import statements
with_output_modeSeries graph output mode (Chart or Stream)

Script Metadata

with_path — Set a file path for the script (used in error messages):

rust
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:

rust
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:

rust
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:

rust
// 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:

rust
use openpine_vm::InputSessions;

let instance = Instance::builder(provider, source, timeframe, "NASDAQ:AAPL")
    .with_input_sessions(InputSessions::REGULAR | InputSessions::EXTENDED)
    .build().await?;
FlagDescription
InputSessions::REGULARRegular trading hours
InputSessions::EXTENDEDExtended/pre-market/after-hours
InputSessions::OVERNIGHTOvernight sessions
InputSessions::ALLAll sessions

Display & Environment

with_background_color — Set a custom background color:

rust
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):

rust
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:

rust
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:

rust
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.

ModeBehavior
OutputMode::Chart (default)Series graph data is written to instance.chart()
OutputMode::StreamSeries graph data is emitted as DrawEvent in the event stream
rust
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:

rust
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

rust
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

Released under the MIT License.