openpine-vm 概述
openpine-vm 是编译和执行 Pine Script 程序的 Rust crate。它提供了以 Instance 类型为中心的高级 API。
添加依赖
toml
[dependencies]
openpine-vm = { git = "https://github.com/longbridge/openpine.git" }核心概念
执行模型
OpenPine 使用逐 K 线执行模型。你每次喂入一根 K 线的数据,VM 为每根 K 线执行整个脚本。这与 Pine Script 在 TradingView 上的工作方式一致。
Candlestick 1 → Execute → Outputs updated
Candlestick 2 → Execute → Outputs updated
Candlestick 3 → Execute → Outputs updated
...核心类型
| 类型 | 描述 |
|---|---|
Instance | 已编译的可执行脚本实例 |
InstanceBuilder | 用于配置和编译脚本的构建器 |
Candlestick | 喂入 VM 的 OHLCV K 线数据 |
TimeFrame | 图表时间周期(1D、5m、1W 等) |
SymbolInfo | 交易标的元数据——由 DataProvider 自动提供,无需手动构造 |
DataProvider | 异步 trait,为 request.security() 提供 K 线数据和标的信息 |
CandlestickItem | 由 DataProvider::candlesticks yield 的枚举:Confirmed(candle)、Realtime(candle) 或 HistoryEnd |
Chart | 视觉输出集合(绘图、标签、线条等) |
Event | 执行期间发出的日志和警报事件 |
ScriptInfo | 已编译脚本的元数据(类型、输入、警报) |
Error | 编译或运行时错误 |
最小示例
rust
use openpine_vm::{Instance, TimeFrame};
#[tokio::main]
async fn main() -> Result<(), openpine_vm::Error> {
// 1. 定义 Pine 脚本
let source = r#"
//@version=6
indicator("SMA Crossover")
fast = ta.sma(close, 5)
slow = ta.sma(close, 20)
plot(fast, "Fast SMA", color.blue)
plot(slow, "Slow SMA", color.red)
plotshape(ta.crossover(fast, slow), style=shape.triangleup)
"#;
// 2. 构建实例,直接传入 K 线数据
let timeframe = TimeFrame::days(1);
let symbol = "NASDAQ:AAPL";
let bars = load_candles(); // 你的数据源——Vec<Candlestick>
let mut instance = Instance::builder(bars, source, timeframe, symbol)
.build().await?;
// 3. 检查编译警告
for warning in instance.warnings() {
eprintln!("Warning: {}", warning.display_as_warning());
}
// 4. 运行脚本——从 provider 读取所有 K 线
instance.run_to_end(symbol, timeframe).await?;
// 5. 读取输出
for (_id, graph) in instance.chart().series_graphs() {
if let Some(plot) = graph.as_plot() {
let title = plot.title.as_deref().unwrap_or("unnamed");
println!("Plot '{}': {} bars", title, plot.series.len());
}
}
Ok(())
}执行模型
Instance::run() 消费 DataProvider 的 K 线流,驱动整个执行循环:
DataProvider::candlesticks() 流
Confirmed(_) -> 已收盘的 K 线(bar_index 递增,barstate.isconfirmed = true)
Realtime(_) -> 正在形成的 K 线(可回滚,流结束时自动确认)
HistoryEnd -> 标记历史数据已全部推送完毕instance.run() 返回事件 Stream。使用 run_to_end() 消费所有事件后访问图表,或直接消费流进行逐 K 线事件处理。