Nautilus Trader 缓存机制完全指南:Cache 架构、配置与实战调用
2026/9/12 2:58:09 网站建设 项目流程

Nautilus Trader 缓存机制完全指南:Cache 架构、配置与实战调用

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

本文是 Nautilus Trader 事件驱动交易引擎中Cache组件的权威技术指南。Cache是整个系统面向交易状态的中央内存存储,为策略(Strategy)与 Actor 提供行情数据(订单簿、报价、成交、K 线)与执行对象(订单、持仓、账户、合约)的统一查询入口,并支持通过 Redis/Postgres 作为持久化恢复后端。读完本文,你将掌握 Cache 的写入时序原理、CacheConfig全部参数语义与合法范围、数据库恢复的两种接入方式,以及覆盖行情查询、状态查询、清理与自定义数据共享的完整 Python/Rust 调用范式。

一、Cache 的定位与核心职责

从 crates/common/src/cache/mod.rs 的模块注释可以看出,Cache是一个"用于市场数据与执行数据的进程内缓存,可选持久化后端支持"的内存组件,其对外暴露了三类职责:

  • 存储有界行情历史:维护当前订单簿,以及报价(QuoteTick)、成交(TradeTick)、K 线(Bar)等市场数据的受限长度历史序列;
  • 跟踪执行状态对象:跟踪订单(Order)、持仓(Position)、账户(Account)、合约(Instrument)与币种(Currency),直到被显式清理(purge)或系统重置(reset);
  • 共享自定义数据:在应用自定义的字符串键下共享调用方自行序列化的原始字节,并在配置了数据库后端时持久化这些条目。

在架构上,Cache 不是独立的进程,而是被DataEngine(数据引擎)与ExecutionEngine(执行引擎)共同持有的状态仓库。策略与 Actor 通过只读句柄访问它,写入权则归属引擎——这一点从源码中CacheView(面向适配器的只读视图)与CacheApi(面向用户的查询 API)的分离可以印证:crates/common/src/cache/mod.rs 中CacheView的注释明确指出"适配器侧代码接收的是该类型而非可变缓存句柄,从而确保缓存写入始终由数据与执行引擎所有"。

二、缓存如何工作:事件流写入时序

引擎在事件流经系统时把内置数据写入Cache。实盘适配器(Live Adapter)是异步地向引擎馈送事件的,因此缓存内容变化发生在引擎处理事件的时刻,而不是适配器首次收到数据的时刻

对于报价、成交与 K 线,DataEngine会先尝试写入Cache,再向订阅者发布。写入成功后,当策略回调(如on_quote(...))运行时,最新值已经可读。订单簿增量(deltas)与深度快照则直接发布,由BookUpdater订阅单独维护当前簿状态:

这一"先写缓存、后派发回调"的时序保证了策略在事件回调内读取到的总是包含该事件的最新状态,是 Nautilus 事件驱动确定性模型的关键一环。完整的分步追踪可参阅 数据流:一次报价 tick 的生命周期。

2.1 策略内访问缓存的基本示例

在策略内部,通过self.cache访问共享缓存:

def on_bar(self, bar: Bar) -> None: # Read recent bars from the cache. last_bar = self.cache.bar(self.bar_type, index=0) # Same bar after a successful cache write. previous_bar = self.cache.bar(self.bar_type, index=1) third_last_bar = self.cache.bar(self.bar_type, index=2) # Read current position state. if self.last_position_opened_id is not None: position = self.cache.position(self.last_position_opened_id) if position is not None and position.is_open: open_quantity = position.quantity # Read open orders for the instrument. open_orders = self.cache.orders_open(instrument_id=self.instrument_id)

注意index=0代表最近一条数据——有界行情序列全部采用反向索引(reverse indexing),这也是下文所有行情访问 API 的统一约定。

三、配置 Cache:CacheConfig 参数详解

使用CacheConfig类配置 Cache 的行为与容量,并根据 环境上下文 传给BacktestEngine(回测)或LiveNode(实盘)。容量设置在两种环境中完全一致:

from nautilus_trader.config import BacktestEngineConfig from nautilus_trader.config import CacheConfig from nautilus_trader.config import LiveNodeConfig # For backtesting engine_config = BacktestEngineConfig( cache=CacheConfig( tick_capacity=10_000, # Store last 10,000 ticks per instrument bar_capacity=5_000, # Store last 5,000 bars per bar type ), ) # For live trading node_config = LiveNodeConfig( cache=CacheConfig( tick_capacity=10_000, bar_capacity=5_000, ), )

:::tip 默认情况下,Cache为每个合约的 tick 序列保留最多 10,000 条值,为每个 bar 类型保留 10,000 根 K 线。这两者是相互独立的限额,不是合并后的总量。每个容量应取值于[1, 1_000_000]。当策略需要更长的内存回看窗口且内存开销可接受时,可以调大它们。 :::

3.1 全部配置项

CacheConfig支持以下参数(Rust 侧完整形态,与 Python 侧一一对应):

use nautilus_common::{cache::CacheConfig, enums::SerializationEncoding}; let config = CacheConfig { encoding: SerializationEncoding::MsgPack, timestamps_as_iso8601: false, buffer_interval_ms: None, bulk_read_batch_size: None, use_trader_prefix: true, use_instance_id: false, flush_on_start: false, drop_instruments_on_reset: true, tick_capacity: 10_000, bar_capacity: 10_000, persist_account_events: true, save_market_data: false, };

各参数语义、默认值与约束如下表(依据 crates/common/src/cache/config.rs 源码):

参数默认值说明
encodingJson数据库操作的序列化编码(Json/MsgPack),控制所用序列化器类型
timestamps_as_iso8601false时间戳是否以 ISO 8601 字符串形式持久化
buffer_interval_msNone管道化/批处理事务之间的缓冲间隔(毫秒)。设为Some(ms)后写操作按批次落库
bulk_read_batch_sizeNone批量读操作(如 Redis MGET)的批次大小,设置后按该大小分块读取
use_trader_prefixtrue键是否使用trader-前缀
use_instance_idfalse键是否使用 trader 的实例 ID
flush_on_startfalse启动时是否清空数据库
drop_instruments_on_resettrue重置时是否从缓存内存中丢弃合约数据
tick_capacity10_000内部 tick 双端队列最大长度,范围[1, 1_000_000]
bar_capacity10_000内部 bar 双端队列最大长度,范围[1, 1_000_000]
persist_account_eventstrue账户事件是否持久化到后端数据库
save_market_datafalse市场数据是否持久化到磁盘

3.2 容量校验的源码实现

容量的合法性并非运行期才暴露,而是在构造与反序列化阶段就严格校验。源码 crates/common/src/cache/config.rs 定义了常量MAX_CACHE_DATA_CAPACITY = 1_000_000,并通过check_cache_data_capacity调用check_in_range_inclusive_usize(capacity, 1, MAX_CACHE_DATA_CAPACITY, parameter)校验;validate()方法对tick_capacitybar_capacity逐一检查,越界时返回形如must be in range [1, 1000000], was 0ConfigError::Range错误。其单元测试覆盖了零值、超上限、usize::MAX等非法输入在new()中 panic、在 builder 与 JSON 反序列化中报错的行为,同时验证了默认容量为 10,000。

:::note 每个 bar 类型维护各自的容量。例如同时使用 1 分钟与 5 分钟 K 线时,各自最多存储bar_capacity根。当bar_capacity达到上限,Cache自动淘汰最旧的数据——这是通过BoundedVecDeque(有界双端队列,见 crates/common/src/cache/bounded.rs)实现的。 :::

四、数据库配置:重启后的状态恢复

配置数据库后端后,Cache可以在重启后恢复已成功持久化、且受支持的缓存记录。可恢复的记录包括:通用数据、币种、合约、合约收盘(instrument closes)、账户、订单与持仓。启动时不会恢复有界的市场数据历史,也不会恢复正在运行的进程

只要配置了数据库后端,合约收盘(Instrument Closes)就会持久化。save_market_data不约束它,因为合约收盘是恢复快照(recovery snapshot)而非有界市场数据历史。

CacheConfig控制缓存行为本身;连接设置则属于具体后端配置,例如RedisCacheConfigPostgresCacheConfig

需要特别强调:后端是恢复机制,不是完整事件归档,也不是同步的分布式缓存。每个节点拥有各自的内存缓存;让多个节点指向同一数据库命名空间并不能使这些缓存保持一致。

4.1 Rust 原生接入:CacheDatabaseFactory

Rust 原生调用方构造具体数据库配置,并通过CacheDatabaseFactorytrait 构造适配器传入系统 builder。crates/common/src/cache/database.rs 中该 trait 的核心方法是async fn create(&self, trader_id, instance_id, config) -> Box<dyn CacheDatabaseAdapter>,返回的是与具体存储无关的CacheDatabaseAdapter传输面(提供closeflushload_allload_currenciesload_instruments等方法):

use nautilus_common::{ cache::{CacheConfig, database::CacheDatabaseFactory}, enums::SerializationEncoding, }; use nautilus_infrastructure::redis::cache::RedisCacheConfig; let config = CacheConfig { encoding: SerializationEncoding::MsgPack, timestamps_as_iso8601: true, buffer_interval_ms: Some(100), ..Default::default() }; let database = RedisCacheConfig { host: Some("localhost".to_string()), port: Some(6379), connection_timeout: 2, response_timeout: 2, ..Default::default() }; let cache_database = database .create(trader_id, instance_id, config.clone()) .await?;

对于 Rust 原生实盘节点,在启动前挂载适配器:

let node_config = LiveNodeConfig { trader_id, ..Default::default() }; let mut node = LiveNode::build("LiveNode".to_string(), Some(node_config))?; node.set_cache_database(cache_database)?; node.run().await?;

在默认的LiveExecutionEngineConfig.load_cache = true下,节点会在连接客户端、对账执行状态之前恢复已持久化的缓存状态并重建派生索引。设置CacheConfig.flush_on_start = true则改为先清空后端。

RedisCacheConfig(crates/infrastructure/src/redis/cache.rs)完整支持host(默认127.0.0.1)、port(默认6379)、usernamepasswordssl(是否启用 SSL 连接)、connection_timeout(连接等待秒数)、response_timeout(响应等待秒数)、number_of_retries(带指数退避的重试次数)、exponent_basemax_delay(重试间最大延迟秒数)与factor(重试延迟乘数)。注意其文档要求Redis 6.2 或更高版本才能正确运行。

4.2 Python 接入:with_cache_database_factory

Python 侧将同样的数据库配置传给LiveNodeBuilder.with_cache_database_factory。节点在启动时才构造并持有适配器,因此连接只在节点运行时打开

from nautilus_trader.common import Environment from nautilus_trader.infrastructure import RedisCacheConfig from nautilus_trader.live import LiveNode from nautilus_trader.model import TraderId node = ( LiveNode.builder("LiveNode", TraderId("TRADER-001"), Environment.LIVE) .with_cache_database_factory(RedisCacheConfig(host="localhost", port=6379)) .build() ) try: node.run() finally: node.dispose()

改传PostgresCacheConfig即可用 Postgres 作为缓存后端。PostgresCacheConfig(crates/infrastructure/src/sql/cache.rs)支持hostportusernamepassworddatabase,缺失字段会从 Postgres 环境变量再解析到内置默认值。需要留意:Postgres 不支持 Actor 或策略状态持久化,因此不要与load_state/save_state组合使用。两个配置类都来自nautilus_trader.infrastructure

:::warning 务必 dispose 节点。dispose()会关闭后端,从而刷新在设置了CacheConfig.buffer_interval_ms时仍滞留在缓冲区中的写入。如果从run()直接返回,这些写入可能被丢弃。 :::

五、使用缓存:市场数据访问

Cache提供订单簿、报价、成交、K 线及其他市场数据访问。有界行情序列使用反向索引,最近一条位于索引 0

5.1 K 线访问

# Get all cached bars for a bar type. bars = self.cache.bars(bar_type) # Returns list[Bar] or None. # Get the most recent bar. latest_bar = self.cache.bar(bar_type) # Returns Bar or None. # Get a historical bar by index (0 = most recent). second_last_bar = self.cache.bar(bar_type, index=1) # Returns Bar or None. # Check whether bars exist and get the count. bar_count = self.cache.bar_count(bar_type) has_bars = self.cache.has_bars(bar_type)

5.2 报价 tick

# Get quotes. quotes = self.cache.quotes(instrument_id) # Returns list[QuoteTick] or None. latest_quote = self.cache.quote(instrument_id) # Returns QuoteTick or None. second_last_quote = self.cache.quote(instrument_id, index=1) # Returns QuoteTick or None. # Check quote availability. quote_count = self.cache.quote_count(instrument_id) has_quotes = self.cache.has_quote_ticks(instrument_id)

5.3 成交 tick

# Get trades. trades = self.cache.trades(instrument_id) # Returns list[TradeTick] or None. latest_trade = self.cache.trade(instrument_id) # Returns TradeTick or None. second_last_trade = self.cache.trade(instrument_id, index=1) # Returns TradeTick or None. # Check trade availability. trade_count = self.cache.trade_count(instrument_id) has_trades = self.cache.has_trade_ticks(instrument_id)

5.4 订单簿

# Get the current order book. book = self.cache.order_book(instrument_id) # Returns OrderBook or None. # Check whether an order book exists. has_book = self.cache.has_order_book(instrument_id) # Get the number of applied book updates. update_count = self.cache.book_update_count(instrument_id)

5.5 价格访问

from nautilus_trader.model import PriceType # Get the current price by type. Returns Price or None. price = self.cache.price( instrument_id=instrument_id, price_type=PriceType.MID, # Options: BID, ASK, MID, LAST )

5.6 Bar 类型查询

from nautilus_trader.model import AggregationSource, PriceType # Get all available bar types for an instrument. Returns list[BarType]. bar_types = self.cache.bar_types( instrument_id=instrument_id, price_type=PriceType.LAST, # Options: BID, ASK, MID, LAST aggregation_source=AggregationSource.EXTERNAL, )

5.7 综合示例:一个市场数据策略

from nautilus_trader.model import Bar, BarType from nautilus_trader.trading import Strategy class MarketDataStrategy(Strategy): def on_start(self) -> None: # Subscribe to 1-minute bars. self.bar_type = BarType.from_str(f"{self.instrument_id}-1-MINUTE-LAST-EXTERNAL") self.subscribe_bars(self.bar_type) def on_bar(self, bar: Bar) -> None: bars = (self.cache.bars(self.bar_type) or [])[:3] if len(bars) < 3: return # Access the latest three bars for analysis. current_bar = bars[0] prev_bar = bars[1] prev_prev_bar = bars[2] # Read the latest quote and trade. latest_quote = self.cache.quote(self.instrument_id) latest_trade = self.cache.trade(self.instrument_id) if latest_quote is not None: current_spread = latest_quote.ask_price - latest_quote.bid_price self.log.info(f"Current spread: {current_spread}")

六、使用缓存:交易对象访问

Cache还提供订单、持仓、账户与合约等交易对象的访问。

6.1 订单:按条件查询

可按 venue、策略、合约、账户或订单方向过滤查询订单。

# Get a specific order by its client order ID order = self.cache.order(ClientOrderId("O-123")) # Get all orders in the system orders = self.cache.orders() # Get orders filtered by specific criteria orders_for_venue = self.cache.orders(venue=venue) # All orders for a specific venue orders_for_strategy = self.cache.orders( strategy_id=strategy_id ) # All orders for a specific strategy orders_for_instrument = self.cache.orders( instrument_id=instrument_id ) # All orders for an instrument

6.2 订单:状态查询

# Get orders by their current state open_orders = self.cache.orders_open() # Orders currently active at the venue closed_orders = self.cache.orders_closed() # Orders that have completed their lifecycle emulated_orders = self.cache.orders_emulated() # Orders being simulated locally by the system inflight_orders = ( self.cache.orders_inflight() ) # Orders submitted (or modified) to venue, but not yet confirmed local_active_orders = ( self.cache.orders_active_local() ) # Orders still managed locally (initialized, emulated, or released) # Check specific order states exists = self.cache.order_exists( client_order_id ) # Checks if an order with the given ID exists in the cache is_open = self.cache.is_order_open(client_order_id) # Checks if an order is currently open is_closed = self.cache.is_order_closed(client_order_id) # Checks if an order is closed is_emulated = self.cache.is_order_emulated( client_order_id ) # Checks if an order is being simulated locally is_inflight = self.cache.is_order_inflight( client_order_id ) # Checks if an order is submitted or modified, but not yet confirmed is_active_local = self.cache.is_order_active_local( client_order_id ) # Checks if an order is still managed locally

6.3 订单:统计

# Get counts of orders in different states open_count = self.cache.orders_open_count() # Number of open orders closed_count = self.cache.orders_closed_count() # Number of closed orders emulated_count = self.cache.orders_emulated_count() # Number of emulated orders inflight_count = self.cache.orders_inflight_count() # Number of inflight orders local_active_count = ( self.cache.orders_active_local_count() ) # Number of locally active orders (initialized, emulated, or released) total_count = self.cache.orders_total_count() # Total number of orders in the system # Get filtered order counts buy_orders_count = self.cache.orders_open_count( side=OrderSide.BUY ) # Number of currently open BUY orders venue_orders_count = self.cache.orders_total_count( venue=venue ) # Total number of orders for a given venue

6.4 持仓

Cache保留持仓直到被清理或重置,并提供多种查询方式。

# Get a specific position by its ID position = self.cache.position(PositionId("P-123")) # Get positions by their state all_positions = self.cache.positions() # All positions in the system open_positions = self.cache.positions_open() # All currently open positions closed_positions = self.cache.positions_closed() # All closed positions # Get positions filtered by various criteria venue_positions = self.cache.positions(venue=venue) # Positions for a specific venue instrument_positions = self.cache.positions( instrument_id=instrument_id ) # Positions for a specific instrument strategy_positions = self.cache.positions( strategy_id=strategy_id ) # Positions for a specific strategy long_positions = self.cache.positions(side=PositionSide.LONG) # All long positions

持仓状态与关系查询:

# Check position states exists = self.cache.position_exists(position_id) # Checks if a position with the given ID exists is_open = self.cache.is_position_open(position_id) # Checks if a position is open is_closed = self.cache.is_position_closed(position_id) # Checks if a position is closed # Get position and order relationships orders = self.cache.orders_for_position(position_id) # All orders related to a specific position position = self.cache.position_for_order( client_order_id ) # Find the position associated with a specific order

持仓统计:

# Get position counts in different states open_count = self.cache.positions_open_count() # Number of currently open positions closed_count = self.cache.positions_closed_count() # Number of closed positions total_count = self.cache.positions_total_count() # Number of positions in the system # Get filtered position counts long_positions_count = self.cache.positions_open_count( side=PositionSide.LONG ) # Number of open long positions instrument_positions_count = self.cache.positions_total_count( instrument_id=instrument_id ) # Number of positions for a given instrument

6.5 账户

# Access account information account = self.cache.account(account_id) # Retrieve account by ID account = self.cache.account_for_venue(venue) # Retrieve account for a specific venue account_id = self.cache.account_id(venue) # Retrieve account ID for a venue

6.6 合约

# Get instrument information instrument = self.cache.instrument(instrument_id) # Retrieve a specific instrument by its ID all_instruments = self.cache.instruments() # Retrieve all instruments in the cache # Get instruments for a venue. venue_instruments = self.cache.instruments(venue=venue) # Instruments for a specific venue # Get instrument identifiers instrument_ids = self.cache.instrument_ids() # Get all instrument IDs venue_instrument_ids = self.cache.instrument_ids( venue=venue ) # Get instrument IDs for a specific venue

性能提示:从 crates/common/src/cache/mod.rs 中CacheApi的文档注释看,单点读取返回拥有所有权的快照,因此 Actor 代码不会在活跃Cache上持有借用(Ref);批量集合读取返回所有匹配值的拥有快照,并有意命名为批量读。在热点路径上,当不需要完整快照时,优先使用计数(*_count)、ID(*_ids)或has_*方法。

七、清理缓存数据

长时间运行的会话会不断累积已关闭订单、已关闭持仓、账户事件与不再使用的合约。Cache提供定向与批量两种清理方法,使策略与实盘交易引擎无需重启系统即可将内存控制在有界范围内。

7.1 定向清理(Targeted Purges)

用于删除单个实体。实体仍处于活跃状态时会拒绝清理

  • cache.purge_order(client_order_id):移除该订单及其所有以订单为键的索引条目。跳过未关闭(open)的订单。
  • cache.purge_position(position_id):移除该持仓、其快照及以持仓为键的索引条目。跳过未关闭的持仓。
  • cache.purge_instrument(instrument_id):移除该合约及其瞬态的逐合约映射(订单簿、报价、成交、标记/指数/资金费率价格、合约状态与收盘、greeks,以及引用该合约的 K 线)。当存在任何关联订单处于非终态(即尚未到达 closed 状态,包括 initialized、submitted、accepted、emulated、released 与 inflight)或任何关联持仓未关闭时,跳过清理。

:::warningpurge_instrument面向拥有自身生命周期逻辑、能自主判断合约何时不再需要的 Actor 与策略。清理一个其他组件仍在依赖的合约会导致合约查找缺失并丢失市场数据历史。活跃订阅归属数据引擎,若不再需要更新,请先取消订阅再清理。 :::

7.2 批量清理(Bulk Purges)

按年龄清扫旧条目。它们接收当前时间戳与以秒计的缓冲(buffer)或回看(lookback)窗口。

  • cache.purge_closed_orders(ts_now, buffer_secs):清理关闭时间早于buffer_secs的已关闭订单。
  • cache.purge_closed_positions(ts_now, buffer_secs):清理关闭时间早于buffer_secs的已关闭持仓。
  • cache.purge_account_events(ts_now, lookback_secs):清理早于lookback_secs的账户状态事件。传0清理全部事件。

7.3 实盘中的自动清理

LiveExecutionEngineConfig通过定时器调度上述批量清理。所有清理间隔默认均为None,即禁用对应循环。设置间隔即启用循环,并通过 buffer/lookback 控制最近多少条目的数据保持受保护。以下示例使用实盘配置指南推荐的首选初始值:

from nautilus_trader.config import LiveExecutionEngineConfig exec_engine = LiveExecutionEngineConfig( purge_closed_orders_interval_mins=15, purge_closed_orders_buffer_mins=60, purge_closed_positions_interval_mins=15, purge_closed_positions_buffer_mins=60, purge_account_events_interval_mins=15, purge_account_events_lookback_mins=60, )

更短的间隔意味着更频繁地执行清理,更短的 buffer/lookback 则移除更新的数据。应根据内存上限以及对账/分析所需的近期执行上下文,为每个参数单独选择取值。完整参数参考见 配置实盘交易:内存管理。

:::note 合约清理没有自动循环,因为何时丢弃合约取决于策略状态而非时间。请在拥有该合约生命周期的 Actor 或策略中调用cache.purge_instrument。 :::

八、自定义数据:跨组件共享

Cache在应用自定义的字符串键下存储原始字节。添加前先序列化值,取出后反序列化。Actor 与策略可借此共享少量应用数据。

8.1 基本存取

# Store serialized data. self.cache.add(key="my_key", value=b"some binary data") # Retrieve serialized data. stored_data = self.cache.get("my_key") # Returns bytes or None.

:::warningCache不是通用数据库。大数据集或复杂查询请使用专门的存储。 :::

九、最佳实践与常见问题

9.1 Cache 与 Portfolio 的分工

CachePortfolio用途不同:

Cache

  • 保留执行对象、选定对象历史与有界近期市场数据,直到清理或重置;
  • 立即应用本地状态变更,例如提交前初始化订单;
  • 在引擎处理外部事件时应用之,例如订单成交。

Portfolio

  • 聚合持仓、敞口与账户信息;
  • 基于缓存状态与市场价格计算当前组合价值。
from nautilus_trader.model import PositionChanged from nautilus_trader.trading import Strategy class MyStrategy(Strategy): def on_position_changed(self, event: PositionChanged) -> None: # Read the fills retained by the cached position. position = self.cache.position(event.position_id) fills = position.events() if position is not None else [] # Read current aggregate exposure from the portfolio. current_exposure = self.portfolio.net_exposure(event.instrument_id)

9.2 Cache 与策略变量(strategy variables)的选择

用缓存条目存共享、序列化的数据,用策略变量存本地工作状态。

Cache 存储

  • 对共享系统缓存的所有 Actor 与策略可用;
  • 配置了数据库后端且写入完成时可持久化通用字节条目;
  • 单个策略重置后依然可用,但缓存或执行引擎重置会清空内存条目。

策略变量

  • 将类型化的、策略专属的计算与中间值封装在内部;
  • 不会向其他组件暴露,也不会自动持久化。

Actor 与策略状态在进程重启间的持久化使用独立的on_save/on_load钩子配合受支持的后端,详见实盘指南的 缓存数据库配置 一节。

共享数据在加入缓存前必须序列化:

import json from nautilus_trader.trading import Strategy class MyStrategy(Strategy): def on_start(self) -> None: shared_data = { "last_reset": self.clock.timestamp_ns(), "trading_enabled": True, } self.cache.add("shared_strategy_info", json.dumps(shared_data).encode())

另一策略可按如下方式取回:

import json from nautilus_trader.trading import Strategy class AnotherStrategy(Strategy): def on_start(self) -> None: data_bytes = self.cache.get("shared_strategy_info") if data_bytes is not None: shared_data = json.loads(data_bytes) self.log.info(f"Shared data retrieved: {shared_data}")

十、延伸阅读

  • 数据(Data):Cache 中存储的数据类型。
  • 策略(Strategies):策略如何通过 Cache 访问行情与状态。
  • 报告(Reports):基于缓存数据生成报告。
  • 配置实盘交易:缓存数据库配置与自动清理参数的完整参考。
  • 架构总览:环境上下文与数据流的完整链路。

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询