跳转到内容

标的池模型

标的池模型是模块化的品种选择器。它通过 UniverseResult 返回品种代码:

aq-engine/src/core/universe/mod.rs
pub trait UniverseModel {
fn version(&self) -> &str;
fn run(&mut self, ctx: &mut dyn StrategyContext) -> UniverseResult;
}

AQE 会合并 Strategy::universe(ctx) 和所有已注册标的池模型返回的品种代码,最终标的池是去重后的并集。因此,你可以在内联代码中保留静态标的池,再由一个或多个模型根据自选列表、筛选条件、账户规则或日期相关逻辑补充品种。

state.add_universe_model(
UniverseModelBuilder::new(Box::new(MyUniverseModel::new()))
.can_fail(false)
.build(),
);
use aq_engine::core::strategy::StrategyContext;
use aq_engine::core::universe::{UniverseModel, UniverseResult};
use std::collections::HashSet;
pub struct CryptoMajors;
impl CryptoMajors {
pub fn new() -> Self {
Self
}
}
impl UniverseModel for CryptoMajors {
fn version(&self) -> &str {
"1.0"
}
fn run(&mut self, _ctx: &mut dyn StrategyContext) -> UniverseResult {
let symbols = ["BTCUSD", "ETHUSD"]
.into_iter()
.map(str::to_string)
.collect::<HashSet<_>>();
UniverseResult::passed(symbols, self.name().to_string())
}
}

内联生命周期代码仍然有效:

  • 将简单的启动注册放在 Strategy::on_start 中
  • 将简单的各资产初始化配置放在 Strategy::init 中
  • 从 Strategy::universe 返回固定的品种代码集合
  • 将一次性清理放在 Strategy::on_teardown 中

当品种选择具有清晰的模块边界、需要构造函数配置,或需要在策略之间复用时,建议使用标的池模型。