ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

NautilusTrader 模拟订单(Emulated Orders)实战指南:用 OrderEmulator 在任意交易场所启用条件单

NautilusTrader 模拟订单(Emulated Orders)实战指南:用 OrderEmulator 在任意交易场所启用条件单 NautilusTrader 模拟订单Emulated Orders实战指南用 OrderEmulator 在任意交易场所启用条件单【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader本篇指南围绕 NautilusTrader 的OrderEmulator模拟订单引擎展开讲解如何借助本地行情监控在交易场所不支持原生条件单的情况下依然使用STOP_LIMIT、TRAILING_STOP_MARKET、LIMIT_IF_TOUCHED等高级订单类型。读完本文你将掌握emulation_trigger三种触发模式的选型、模拟订单从提交到释放的完整生命周期、Cache 查询 API以及重启恢复与最佳实践并能在策略中直接落地可运行的模拟订单代码。什么是模拟订单模拟订单Emulated Order是 NautilusTrader 提供的一种本地订单机制当你的交易场所venue本身不支持某种订单类型时OrderEmulator会在本地替你模拟这张订单的存在与触发逻辑。OrderEmulator持续监控由emulation_trigger选定的行情数据。当本地订单满足释放条件release condition时模拟器将其转换为一张MARKET或LIMIT订单并让这张新订单走标准的风险检查与执行通道RiskEngine → ExecutionEngine → ExecutionClient。例如一张模拟的STOP_LIMIT订单在止损价格被触发后会变成一张真实的LIMIT订单提交给场所。核心实现位于 emulator.rsOrderEmulator结构体内维护了matching_cores按InstrumentId索引的本地撮合核心OrderMatchingCore用于判断触发条件subscribed_quotes/subscribed_trades当前已订阅的 Quote 与 Trade 行情集合manager负责缓存原始SubmitOrder命令并管理订单状态转换的OrderManagerpending_messages命令/事件缓冲队列用于避免重入问题。提交一张模拟订单在订单构造函数或OrderFactory方法上设置emulation_trigger即可将订单交由本地模拟器处理。本地模拟器只接受以下三种取值触发类型TriggerType使用的行情数据DEFAULT报价Quotes本地行为等同于BID_ASK。BID_ASK最优买一/卖一Best bid and ask quotes。LAST_PRICE成交Trades。将emulation_trigger保留为None则关闭本地模拟订单直接走常规提交通道RiskEngine → ExecutionEngine。需要特别注意的是TriggerType枚举本身还包含其他取值。从 enums.rs 可以看到完整定义Default、LastPrice、MarkPrice、IndexPrice、BidAsk、DoubleLast、DoubleBidAsk、LastOrBidAsk、MidPoint。其中MarkPrice、IndexPrice等描述了部分交易场所支持的触发方法但本地OrderEmulator不会接受它们作为emulation_trigger的值——emulator.rs的handle_submit_order中明确断言仅接受TriggerType::Default | BidAsk | LastPrice其余取值会记录错误并直接取消订单见 emulator.rs。触发类型的选择直接决定模拟订单的行为方式对于止损单stop orders模拟器将触发价与所选行情数据进行比较对于移动止损单trailing-stop orders模拟器根据该行情数据持续更新移动触发价对于模拟的LIMIT订单模拟器将限价与所选行情比较价格被触及时释放一张MARKET订单。在策略中提交模拟订单的完整示例在 Python 侧emulation_trigger是各订单构造器的标准参数。从 limit.rs 等 Python 绑定可见LimitOrder、StopMarketOrder、StopLimitOrder、MarketIfTouchedOrder、LimitIfTouchedOrder、TrailingStopMarketOrder、TrailingStopLimitOrder的构造函数均接受emulation_trigger与trigger_instrument_id参数。结合 strategies.md 中的官方示例一张基于最新成交价触发的模拟LIMIT买单可以这样提交from nautilus_trader.model import LimitOrder from nautilus_trader.model import OrderSide from nautilus_trader.model import TriggerType def buy(self) - None: order: LimitOrder self.order_factory.limit( instrument_idself.instrument_id, order_sideOrderSide.BUY, quantityself.instrument.make_qty(self.trade_size), priceself.instrument.make_price(5000.00), emulation_triggerTriggerType.LAST_PRICE, ) self.submit_order(order)命令路由规则SubmitOrder/SubmitOrderList命令的第一站取决于订单属性见 strategies.md指定了emulation_trigger→ 命令首先发送给OrderEmulator指定了exec_algorithm_id且无emulation_trigger→ 命令首先发送给对应的ExecutionAlgorithm否则 → 命令首先发送给RiskEngine。另外模拟订单与执行算法可以叠加使用订单先进入OrderEmulator释放后才被路由到ExecutionAlgorithm。这一行为在emulator.rs的释放逻辑中有直接体现——释放时若订单带有exec_algorithm_id则命令被发送至算法端否则发送至执行端见 emulator.rs。技术细节所有受支持的模拟订单类型在所有环境上下文回测 backtest、沙箱 sandbox、实盘 live中都由同一个OrderEmulator组件统一管理。这意味着你在回测中验证过的模拟订单逻辑可以在实盘中以相同语义运行。从架构组件看OrderEmulator由四个核心文件组成位于 order_emulatoremulator.rs主体逻辑负责订单持有、行情处理、触发与释放config.rsOrderEmulatorConfig配置目前仅含debug: bool开启额外调试日志其余字段取默认值handlers.rsOrderEmulatorExecuteHandler接收交易命令与OrderEmulatorOnEventHandler接收订单事件adapter.rsOrderEmulatorAdapter负责将组件挂接到消息总线。关于数量限制NautilusTrader 并不为模拟订单配置固定的数量上限。实际可用上限由可用内存与行情处理成本决定——每个被模拟的订单都会在本地匹配核心中驻留、并可能触发相应的行情订阅因此大规模模拟订单集会带来可预期的内存与 CPU 开销。模拟订单的生命周期一张模拟订单按以下阶段推进Strategy通过submit_order提交订单RiskEngine执行交易前检查pre-trade checks可能拒绝该订单OrderEmulator在本地持有并监控该订单匹配的行情更新将其转换为MARKET或LIMIT订单并释放释放后的订单在提交场所前再次经过RiskEngine检查。在消息流层面OrderEmulator::execute统一分派SubmitOrder、SubmitOrderList、ModifyOrder、BatchModifyOrders、CancelOrder、CancelAllOrders等交易命令见 emulator.rs并消费QuoteTick、TradeTick、OrderBookDeltas三类行情事件来驱动触发判定。需要强调的两点语义模拟订单照常通过标准风险控制。策略可以修改或取消它们cancel-all全部撤单请求也会包含它们模拟订单在转换时保留其 client order ID因此后续缓存查询仍使用同一 ID策略侧的状态关联不会断裂。持有的模拟订单Held当OrderEmulator持有一张订单时会发生以下事情与handle_submit_order的实现一一对应见 emulator.rs缓存原始SubmitOrder命令manager.cache_submit_order_command保存命令供释放时原样重放在本地匹配核心中处理订单为触发标的物trigger_instrument_id默认等于订单自身instrument_id支持合成标的物 synthetic instrument获取或创建OrderMatchingCore订单以RestingOrder形式驻留订阅所需行情若不存在匹配的订阅BID_ASK/DEFAULT触发类型会订阅报价subscribe_quotes_for_instrumentLAST_PRICE触发类型会订阅成交subscribe_trades_for_instrument订阅通过DataCommand::Subscribe下发到数据引擎见 emulator.rs接受策略修改与市场驱动更新在释放或取消之前ModifyOrder改价、改触发价、改数量与移动止损的价格更新都会被受理。进入持有状态时若订单仍处于Initialized状态模拟器会生成OrderEmulated事件并写入缓存、发布到策略事件主题events.order.strategy_id将订单状态推进为Emulated。释放的模拟订单Released当行情满足模拟订单的触发条件时释放过程执行以下动作见 fill_market_order 与 fill_limit_order通过另一个OrderInitialized事件将订单转换为MARKET或LIMIT订单将订单的emulation_trigger置为None使各组件不再将其视为模拟订单将转换后的订单与缓存的原始SubmitOrder命令重新送回RiskEngine若风险引擎未拒绝则由ExecutionEngine路由到对应的ExecutionClient。在行情驱动层面on_quote_tick/on_trade_tick/on_order_book_deltas会将最新买一/卖一/最新成交价写入匹配核心随后iterate_orders依次迭代买单侧与卖单侧先处理买单侧以保证 OCO/OUO 等跨侧条件单在两侧之间正确变更状态产出MatchAction::FillLimit模拟 LIMIT 触价转市价单或MatchAction::TriggerStop止损触发动作并分派见 emulator.rs。若触发时对应侧尚无可用行情如买单需要卖一价订单不会被释放而是保留在队列中等待下一次行情更新重试validate_release逻辑见 emulator.rs。释放时会生成OrderReleased事件携带released_price释放时的参考价并发布给策略与风险引擎。可被模拟的订单类型原始模拟订单类型与释放后类型的关系如下用于模拟的订单类型是否可模拟释放后的类型MARKET-N/AMARKET_TO_LIMIT-N/ALIMIT✓MARKETSTOP_MARKET✓MARKETSTOP_LIMIT✓LIMITMARKET_IF_TOUCHED✓MARKETLIMIT_IF_TOUCHED✓LIMITTRAILING_STOP_MARKET✓MARKETTRAILING_STOP_LIMIT✓LIMIT该映射在源码中有直接对应trigger_stop_order中StopLimit/LimitIfTouched/TrailingStopLimit走fill_limit_order释放为 LIMIT而StopMarket/MarketIfTouched/TrailingStopMarket走fill_market_order释放为 MARKET见 emulator.rs普通LIMIT订单在fill_limit_order中被直接转市价单释放。MARKET与MARKET_TO_LIMIT本身是即时执行的订单类型不具备先持有、后触发的语义因此不可模拟。对于移动止损单update_trailing_stop_order会在每次行情更新后基于买一/卖一/最新价调用trailing_stop_calculate重算触发价在activation_price被触及前订单保持惰性持有状态is_order_activated判定见 emulator.rs。查询模拟状态可以通过 Cache 或订单对象本身查询模拟状态。通过 Cache 查询Cache提供以下方法实现位于 cache/mod.rsself.cache.orders_emulated(...)返回所有匹配过滤条件的模拟订单。过滤参数包括venue、instrument_id、strategy_id、account_id、side全部可选见 cache/mod.rsself.cache.is_order_emulated(...)按单个 client order ID 判断该订单是否处于模拟状态见 cache/mod.rsself.cache.orders_emulated_count(...)返回匹配过滤条件的模拟订单数量见 cache/mod.rs。更详细的签名与行为可参考 API 参考文档cache 部分或直接阅读上述缓存源码。直接查询订单对象使用order.is_emulated可直接查询订单对象。返回False意味着订单已被释放或从未被模拟。⚠️警告切勿在本地长期持有模拟订单的引用。当模拟订单被释放时订单对象会发生转换类型可能从STOP_LIMIT变为LIMIT你持有的旧引用将失效。请改用Cache查询。持久化与恢复模拟订单的跨重启恢复由OrderEmulator::on_start完成见 emulator.rs启动时模拟器从配置的缓存数据库cache database中读取恢复出来的模拟订单orders_emulated查询仅对状态仍为Initialized或Emulated的订单执行恢复已脱离模拟状态的订单被跳过若订单存在父订单如括号单/条件单的附属订单会先检查父订单是否已关闭、持仓是否已平仓并处理OTO一触即发条件单的延迟激活逻辑对每个待恢复订单基于其OrderInitialized事件重建SubmitOrder命令重新进入handle_submit_order流程从而恢复行情订阅与本地匹配核心中的驻留状态。这套机制保证模拟订单的状态触发价、数量、关联关系在进程重启后得以延续。最佳实践在实际使用模拟订单时建议遵循以下三条原则通过Cache查询订单而非保存本地订单引用释放会转换订单对象持有旧引用会导致状态失真注意订单类型在释放时发生变更策略中的条件分支、日志与风控逻辑应基于释放前类型 释放后类型的组合进行判断同时处理初始与释放时两次风险检查的拒绝模拟订单在持有前和释放后各经过一次RiskEngine检查任何一次被拒都应妥善处理释放时被拒意味着转换后的订单不会到达场所。相关指南订单总览订单概念、执行指令与订单工厂OrderFactory。高级订单订单列表order lists、条件类型contingency types与括号订单bracket orders。策略在策略中进行订单管理与提交。【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表