拓冰建站拓冰建站
首页 / 资讯中心 / 正文

NautilusTrader Rust 如何编写能提交订单的 Strategy?

NautilusTrader Rust 如何编写能提交订单的 Strategy【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader在 NautilusTrader 中Strategy 是在 Actor 基础上扩展出来的组件它除了接收行情数据还能通过Strategytrait 的方法向交易场所提交、修改和撤销订单。本文的任务是写一个纯 Rust 的最小 Strategy——订阅QuoteTick报价在每笔报价到达时构建一个市价单并调用submit_order提交——然后把它挂到回测引擎上跑通确认订单链路可用。适用前提Rust 工具链满足最低版本 MSRV1.98.1Nautilus 各 crate 已发布到 crates.io当前文档给出的版本线为0.63全程不需要 Python 运行时。Rust API 处于活跃开发中方法签名和 trait 要求可能随版本变化以你所依赖的版本文档为准。准备条件添加 crate 依赖Nautilus 的 crate 位于仓库的crates/目录外部项目通过 crates.io 引用。在Cargo.toml中加入[dependencies] nautilus-backtest 0.63 nautilus-common 0.63 nautilus-execution 0.63 nautilus-model { version 0.63, features [test-support] } nautilus-trading { version 0.63, features [examples] } anyhow 1 log 0.4两个 feature flag 的作用来自 Rust 概念指南 的 Feature flags 表test-supportnautilus-model提供测试 fixture、builder、spec 和默认值示例中的模拟合约 stub 依赖它。examplesnautilus-trading启用示例策略EmaCross、GridMarketMaker后面验证环节会用到。如果做加密市场需要在nautilus-model上额外开启high-precision默认 9 位精度加密场所价格小数位更多时文档要求开启。如果希望跟踪最新开发分支需把所有 Nautilus 依赖指向同一个 git 源避免 crates.io 与 git 版本之间出现类型不匹配本文主路径使用 crates.io 版本。定义 Strategy 结构体持有StrategyCoreStrategy 结构体必须持有一个StrategyCore字段用于运行期接线。常规策略逻辑不直接使用该字段而是通过self上的 facade 方法访问运行时use nautilus_common::actor::DataActor; use nautilus_model::{ data::QuoteTick, enums::OrderSide, identifiers::{InstrumentId, StrategyId}, types::Quantity, }; use nautilus_trading::{nautilus_strategy, strategy::{Strategy, StrategyConfig, StrategyCore}}; pub struct MyStrategy { core: StrategyCore, instrument_id: InstrumentId, trade_size: Quantity, }构造函数中StrategyConfig接收两个关键字段strategy_id和order_id_tag。tag 会追加到本策略发出的所有 client order ID 上用于在多个策略交易同一标的时避免 ID 冲突。文档对 tag 有一个硬性限制tag 不能包含连字符因为运行时会从 strategy ID 最后一段以连字符分隔的部分把它读回来。StrategyCore::new遇到非法 tag 会 panic希望以错误方式处理时改用StrategyCore::new_checked。impl MyStrategy { pub fn new(instrument_id: InstrumentId) - Self { let config StrategyConfig { strategy_id: Some(StrategyId::from(MY_STRAT-001)), order_id_tag: Some(001.to_string()), ..Default::default() }; Self { core: StrategyCore::new(config), instrument_id, trade_size: Quantity::from(1.0), } } }用nautilus_strategy!宏接线并实现Debugnautilus_strategy!宏生成注册和Strategytrait 实现所需的 native runtime 接线默认委托给名为core的字段字段名不同时传第二个参数。宏还额外提供config()方法返回传给StrategyCore::new的StrategyConfig。运行期注册依赖 blanket 的Actor和Component实现它们要求 native 接线宏负责和Debug自己实现或 derivenautilus_strategy!(MyStrategy); impl std::fmt::Debug for MyStrategy { fn fmt(self, f: mut std::fmt::Formatter_) - std::fmt::Result { f.debug_struct(MyStrategy).finish() } }注意宏不会让 Strategy 或其StrategyCore自动 deref 到运行时内部core字段不要直接当 API 用。实现DataActor并调用submit_order提交订单数据部分与 Actor 完全一致在on_start里订阅在 handler 里响应。提交订单的关键就两步——self.order()构建订单self.submit_order发出impl DataActor for MyStrategy { fn on_start(mut self) - anyhow::Result() { self.subscribe_quotes(self.instrument_id, None, None); Ok(()) } fn on_quote(mut self, quote: QuoteTick) - anyhow::Result() { let order self.order().market( self.instrument_id, OrderSide::Buy, self.trade_size, None, None, None, None, None, None, None, ); self.submit_order(order, None, None, None)?; Ok(()) } }self.order()返回的OrderApi可构建的订单类型包括market、limit、stop_market、stop_limit、market_to_limit、market_if_touched、limit_if_touched、trailing_stop_market、trailing_stop_limit、bracket、create_list另有generate_client_order_id与generate_order_list_id。submit_order通过宏生成的Strategytrait 实现挂在self上。仓库内的完整示例 EmaCross 展示了带注释的市价单提交写法enter()方法里self.order().market(...)的参数依次为time_in_force、reduce_only、quote_quantity、exec_algorithm_id、exec_algorithm_params、tags、client_order_id随后调用self.submit_order(order, None, None, None)。nautilus_strategy!(EmaCross)与Debug实现的位置、形态与上文一致可直接对照。覆盖订单事件钩子观察提交结果Strategytrait 的订单事件 handler如on_order_rejected、on_order_filled、on_order_canceled通过宏的第二个参数块传入。宏自动生成内部管道DataActorhandler 保持在单独的impl DataActor块中nautilus_strategy!(MyStrategy, { fn on_order_rejected(mut self, event: OrderRejected) { log::warn!(Order rejected: {}, event.reason); } });这是文档给出的直接观察订单结果的手段订单被拒时会输出拒绝原因日志。Strategytrait 提供的完整订单管理 facade 如下方法作用submit_order向场所提交新订单submit_order_list提交一组条件订单modify_order修改价格、数量或触发价modify_orders批量修改同一标的的多个订单cancel_order撤销指定订单cancel_orders按过滤条件撤销一组订单cancel_all_orders撤销某标的的全部订单close_position用市价单平掉一个仓位close_all_positions平掉全部未平仓位挂到回测引擎上运行验证策略写好后用低层级BacktestEngine注册并运行即可验证整条订单链路。流程创建引擎 →add_venue加模拟场所 →add_instrument加合约并add_data加载数据 →add_strategy注册策略 →runuse nautilus_backtest::{config::{BacktestEngineConfig, SimulatedVenueConfig}, engine::BacktestEngine}; use nautilus_model::{ enums::{AccountType, BookType, OmsType}, identifiers::Venue, instruments::{Instrument, InstrumentAny, stubs::audusd_sim}, types::Money, }; let mut engine BacktestEngine::new(BacktestEngineConfig::default())?; engine.add_venue( SimulatedVenueConfig::builder() .venue(Venue::from(SIM)) .oms_type(OmsType::Hedging) .account_type(AccountType::Margin) .book_type(BookType::L1_MBP) .starting_balances(vec![Money::from(1_000_000 USD)]) .build()?, )?; let instrument InstrumentAny::CurrencyPair(audusd_sim()); let instrument_id instrument.id(); engine.add_instrument(instrument)?; engine.add_data(quotes, None, true, true)?; // quotes 为你的行情数据加载结果 engine.add_strategy(MyStrategy::new(instrument_id))?; engine.run(None, None, None, false)?;SimulatedVenueConfig使用 builder 模式只有必填字段需要设置其余回退到文档化默认值build()会校验配置并返回结果需要传播或 unwrap。运行不报错即说明策略注册、数据分发和订单提交链路走通订单层面的反馈如拒单原因通过上文的on_order_rejected日志观察。不想自己写 main 时可以跑仓库现成的示例验证环境与订单链路EmaCross本身就是一个会提交市价单的 Strategycargo run -p nautilus-backtest --features examples --example engine-ema-cross对应源码在 engine_ema_cross.rs它用合成 AUD/USD 报价在SIM场所上回测EmaCrossengine.run(None, None, None, false)?后以Ok(())正常退出。高层BacktestNode路径从 Parquet catalog 流式读数据需nautilus-backtest的streamingfeature运行命令为cargo run -p nautilus-backtest --features examples,streaming --example node-ema-cross源码见 node_ema_cross.rs。两条路径的详细步骤见 Run a Backtest (Rust)。限制与下一步常规策略代码不要导入DataActorNative、StrategyNative也不要直接调用core()、strategy_core_mut()、order_factory()这类 native handle——它们暴露的是借用态运行时状态只在引擎、注册、PyO3、testkit 或明确追求低延迟的 native 代码中使用适用矩阵见 Rust 概念指南 的 Native traits 一节。Rust 编写的 Strategy 除了回测还可以挂到LiveNode对接真实场所LiveNode路径下用node.add_strategy(strategy)?; node.run().await?;注册运行各 adapter 提供自己的工厂与配置类型完整流程见 Run Live Trading (Rust)。从 Python 侧注册内置示例策略的add_builtin_strategy路径仅用于 bundled 示例自定义 native 策略应走纯 Rust 路径。需要更复杂行为多档挂单、补单、仓位对冲时可参考仓库内置的 GridMarketMaker 与 EmaCross 两个完整示例以及 Strategies 概念指南。【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门