Skip to content

安全与执行限制

将 OpenPine 嵌入宿主应用程序时,用户提供的 Pine 脚本会在 VM 内执行。VM 提供可配置的限制,以保护宿主进程不受失控脚本的影响。

为何需要限制

Pine 脚本可以包含循环(forwhilefor..in),其迭代次数可能根据用户输入或数据任意增加。若无限制,恶意或有缺陷的脚本可能导致宿主进程无限期挂起。OpenPine 的执行限制按 Bar 检查,因此开销可预测。

配置限制

在调用 build() 前,将 ExecutionLimits 传入 InstanceBuilder::with_execution_limits

rust
use openpine_vm::{ExecutionLimits, Instance, TimeFrame};

let limits = ExecutionLimits::default()
    .with_max_loop_iterations_per_bar(1_000_000);

let mut instance = Instance::builder(source, TimeFrame::days(1), "NASDAQ:AAPL")
    .with_execution_limits(limits)
    .build().await?;

超出限制时,VM 会抛出运行时错误(Error::Exception),处理方式与其他运行时异常相同。

可用限制

max_loop_iterations_per_bar

属性
默认值500,000
作用域所有 forwhilefor..in 循环在每个 Bar 内共享同一预算
重置时机每根 K 线执行开始时计数器重置
禁用方式设置为 u64::MAX 可关闭限制

同一 Bar 内所有循环类型共享同一预算。例如,脚本中两个嵌套 for 循环各迭代 1,000 次,则共消耗 1,000,000 次迭代——超过默认预算 500,000。

rust
// 为计算密集型脚本提高限制
let limits = ExecutionLimits::default()
    .with_max_loop_iterations_per_bar(2_000_000);

// 完全禁用限制(不建议用于不受信任的脚本)
let limits = ExecutionLimits::default()
    .with_max_loop_iterations_per_bar(u64::MAX);

max_security_depth

属性
默认值3
作用域request.security() 调用的最大嵌套深度
禁用方式设置为 0 可完全禁止 request.security()

控制 request.security() 的最大嵌套层数。深度为 1 表示 security 表达式内部不得再调用 request.security()。默认值 3 与 TradingView 行为一致。

rust
// 仅允许一层 request.security()(不允许嵌套)
let limits = ExecutionLimits::default()
    .with_max_security_depth(1);

// 完全禁止 request.security()
let limits = ExecutionLimits::default()
    .with_max_security_depth(0);

max_security_calls

属性
默认值40
作用域所有 request.security() 调用点中,唯一 (symbol, timeframe) 组合的最大数量
禁用方式设置为 0 可完全禁止 request.security()

每个不同的 (symbol, timeframe) 组合会创建一个独立的数据流。共享同一组合的多个调用点只计一次。默认值 40 与 TradingView 行为一致。

rust
// 在资源受限的环境中收紧限制
let limits = ExecutionLimits::default()
    .with_max_security_calls(10);

处理超限错误

超限错误以 Error::Exception 的形式抛出,与 runtime.error() 及其他运行时错误类型相同:

rust
match instance.run_to_end("NASDAQ:AAPL", TimeFrame::days(1)).await {
    Err(openpine_vm::Error::Exception(e)) => {
        eprintln!("脚本错误:{}", e.display());
    }
    _ => {}
}

有关处理运行时错误的完整说明,请参阅错误处理

建议

  • 不受信任的脚本:保持默认限制或将其调低。如无需使用 request.security(),可将 max_security_depth 设为 10
  • 已知脚本:仅在确认脚本确实需要更多资源时才提高限制。
  • 服务端执行:建议在独立线程中运行每个 Instance,并配合操作系统级别的超时作为二次保障。循环限制仅防止过多迭代,不能防范其他耗时计算来源。

下一步

基于 MIT 许可证发布。