移除回测兼容语义残留

This commit is contained in:
boris
2026-06-26 13:39:21 +08:00
parent 7f40cfdab0
commit 380c34aa66
15 changed files with 265 additions and 300 deletions
+22 -22
View File
@@ -170,7 +170,7 @@ pub struct BrokerSimulator<C, R> {
inactive_limit: bool, inactive_limit: bool,
liquidity_limit: bool, liquidity_limit: bool,
strict_value_budget: bool, strict_value_budget: bool,
aiquant_rqalpha_execution_rules: bool, aiquant_execution_rules: bool,
same_day_buy_close_mark_at_fill: bool, same_day_buy_close_mark_at_fill: bool,
intraday_execution_start_time: Option<NaiveTime>, intraday_execution_start_time: Option<NaiveTime>,
runtime_intraday_start_time: Cell<Option<NaiveTime>>, runtime_intraday_start_time: Cell<Option<NaiveTime>>,
@@ -193,7 +193,7 @@ impl<C, R> BrokerSimulator<C, R> {
inactive_limit: true, inactive_limit: true,
liquidity_limit: true, liquidity_limit: true,
strict_value_budget: false, strict_value_budget: false,
aiquant_rqalpha_execution_rules: false, aiquant_execution_rules: false,
same_day_buy_close_mark_at_fill: false, same_day_buy_close_mark_at_fill: false,
intraday_execution_start_time: None, intraday_execution_start_time: None,
runtime_intraday_start_time: Cell::new(None), runtime_intraday_start_time: Cell::new(None),
@@ -220,7 +220,7 @@ impl<C, R> BrokerSimulator<C, R> {
inactive_limit: true, inactive_limit: true,
liquidity_limit: true, liquidity_limit: true,
strict_value_budget: false, strict_value_budget: false,
aiquant_rqalpha_execution_rules: false, aiquant_execution_rules: false,
same_day_buy_close_mark_at_fill: false, same_day_buy_close_mark_at_fill: false,
intraday_execution_start_time: None, intraday_execution_start_time: None,
runtime_intraday_start_time: Cell::new(None), runtime_intraday_start_time: Cell::new(None),
@@ -250,8 +250,8 @@ impl<C, R> BrokerSimulator<C, R> {
self self
} }
pub fn with_aiquant_rqalpha_execution_rules(mut self, enabled: bool) -> Self { pub fn with_aiquant_execution_rules(mut self, enabled: bool) -> Self {
self.aiquant_rqalpha_execution_rules = enabled; self.aiquant_execution_rules = enabled;
self self
} }
@@ -362,7 +362,7 @@ where
symbol: &str, symbol: &str,
snapshot: &crate::data::DailyMarketSnapshot, snapshot: &crate::data::DailyMarketSnapshot,
) -> f64 { ) -> f64 {
if self.aiquant_rqalpha_execution_rules && self.execution_price_field == PriceField::Last { if self.aiquant_execution_rules && self.execution_price_field == PriceField::Last {
let start_cursor = self let start_cursor = self
.runtime_intraday_start_time .runtime_intraday_start_time
.get() .get()
@@ -2088,7 +2088,7 @@ where
candidate: &crate::data::CandidateEligibility, candidate: &crate::data::CandidateEligibility,
instrument: Option<&Instrument>, instrument: Option<&Instrument>,
) -> RuleCheck { ) -> RuleCheck {
let check_price = if self.aiquant_rqalpha_execution_rules { let check_price = if self.aiquant_execution_rules {
self.aiquant_limit_check_price(snapshot, OrderSide::Buy) self.aiquant_limit_check_price(snapshot, OrderSide::Buy)
} else { } else {
ChinaAShareRiskControl::buy_check_price(snapshot, self.execution_price_field) ChinaAShareRiskControl::buy_check_price(snapshot, self.execution_price_field)
@@ -2102,7 +2102,7 @@ where
) { ) {
return RuleCheck::reject(reason); return RuleCheck::reject(reason);
} }
if !self.aiquant_rqalpha_execution_rules { if !self.aiquant_execution_rules {
return self return self
.rules .rules
.can_buy(date, snapshot, candidate, self.execution_price_field); .can_buy(date, snapshot, candidate, self.execution_price_field);
@@ -2120,7 +2120,7 @@ where
instrument: Option<&Instrument>, instrument: Option<&Instrument>,
algo_request: Option<&AlgoExecutionRequest>, algo_request: Option<&AlgoExecutionRequest>,
) -> RuleCheck { ) -> RuleCheck {
let check_price = if self.aiquant_rqalpha_execution_rules { let check_price = if self.aiquant_execution_rules {
self.aiquant_order_limit_check_price( self.aiquant_order_limit_check_price(
date, date,
data, data,
@@ -2141,7 +2141,7 @@ where
) { ) {
return RuleCheck::reject(reason); return RuleCheck::reject(reason);
} }
if !self.aiquant_rqalpha_execution_rules { if !self.aiquant_execution_rules {
return self return self
.rules .rules
.can_buy(date, snapshot, candidate, self.execution_price_field); .can_buy(date, snapshot, candidate, self.execution_price_field);
@@ -2160,10 +2160,10 @@ where
position: &crate::portfolio::Position, position: &crate::portfolio::Position,
algo_request: Option<&AlgoExecutionRequest>, algo_request: Option<&AlgoExecutionRequest>,
) -> RuleCheck { ) -> RuleCheck {
if !self.aiquant_rqalpha_execution_rules && !candidate.allow_sell { if !self.aiquant_execution_rules && !candidate.allow_sell {
return RuleCheck::reject("sell_disabled"); return RuleCheck::reject("sell_disabled");
} }
let check_price = if self.aiquant_rqalpha_execution_rules { let check_price = if self.aiquant_execution_rules {
self.aiquant_order_limit_check_price( self.aiquant_order_limit_check_price(
date, date,
data, data,
@@ -2185,7 +2185,7 @@ where
) { ) {
return RuleCheck::reject(reason); return RuleCheck::reject(reason);
} }
if !self.aiquant_rqalpha_execution_rules { if !self.aiquant_execution_rules {
return self.rules.can_sell( return self.rules.can_sell(
date, date,
snapshot, snapshot,
@@ -2991,7 +2991,7 @@ where
return Ok(()); return Ok(());
} }
let current_value = if self.aiquant_rqalpha_execution_rules { let current_value = if self.aiquant_execution_rules {
let valuation_price = self.target_value_valuation_price(date, data, symbol, snapshot); let valuation_price = self.target_value_valuation_price(date, data, symbol, snapshot);
valuation_price * current_qty as f64 valuation_price * current_qty as f64
} else { } else {
@@ -4805,7 +4805,7 @@ where
return Ok(0); return Ok(0);
} }
if self.inactive_limit && snapshot.tick_volume == 0 { if self.inactive_limit && snapshot.minute_volume == 0 {
return Err("minute no volume".to_string()); return Err("minute no volume".to_string());
} }
@@ -4832,7 +4832,7 @@ where
} }
if self.volume_limit { if self.volume_limit {
let raw_limit = ((snapshot.tick_volume as f64) * self.volume_percent).round() as i64 let raw_limit = ((snapshot.minute_volume as f64) * self.volume_percent).round() as i64
- consumed_turnover as i64; - consumed_turnover as i64;
if raw_limit <= 0 { if raw_limit <= 0 {
return Err("minute volume limit".to_string()); return Err("minute volume limit".to_string());
@@ -5418,7 +5418,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -5512,7 +5512,7 @@ mod tests {
} }
#[test] #[test]
fn target_value_valuation_uses_daily_snapshot_but_value_order_sizing_uses_intraday_tick() { fn target_value_valuation_uses_daily_snapshot_but_value_order_sizing_uses_intraday_minute() {
let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date"); let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");
let broker = BrokerSimulator::new_with_execution_price( let broker = BrokerSimulator::new_with_execution_price(
ChinaAShareCostModel::default(), ChinaAShareCostModel::default(),
@@ -5645,7 +5645,7 @@ mod tests {
.with_intraday_execution_start_time(date.and_hms_opt(10, 40, 0).unwrap().time()) .with_intraday_execution_start_time(date.and_hms_opt(10, 40, 0).unwrap().time())
.with_slippage_model(SlippageModel::PriceRatio(0.002)) .with_slippage_model(SlippageModel::PriceRatio(0.002))
.with_strict_value_budget(true) .with_strict_value_budget(true)
.with_aiquant_rqalpha_execution_rules(true) .with_aiquant_execution_rules(true)
.with_volume_limit(false) .with_volume_limit(false)
.with_liquidity_limit(false) .with_liquidity_limit(false)
.with_inactive_limit(false); .with_inactive_limit(false);
@@ -5663,7 +5663,7 @@ mod tests {
ask1: 5.83, ask1: 5.83,
prev_close: 5.85, prev_close: 5.85,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 262, minute_volume: 262,
bid1_volume: 54, bid1_volume: 54,
ask1_volume: 143, ask1_volume: 143,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -6068,7 +6068,7 @@ mod tests {
ChinaEquityRuleHooks, ChinaEquityRuleHooks,
PriceField::Last, PriceField::Last,
) )
.with_aiquant_rqalpha_execution_rules(true); .with_aiquant_execution_rules(true);
let aiquant_rule = aiquant_broker.buy_rule_check(date, &snapshot, &candidate, None); let aiquant_rule = aiquant_broker.buy_rule_check(date, &snapshot, &candidate, None);
assert!(!aiquant_rule.allowed); assert!(!aiquant_rule.allowed);
assert_eq!(aiquant_rule.reason.as_deref(), Some("buy_disabled")); assert_eq!(aiquant_rule.reason.as_deref(), Some("buy_disabled"));
@@ -6131,7 +6131,7 @@ mod tests {
ChinaEquityRuleHooks, ChinaEquityRuleHooks,
PriceField::Last, PriceField::Last,
) )
.with_aiquant_rqalpha_execution_rules(true) .with_aiquant_execution_rules(true)
.with_intraday_execution_start_time(date.and_hms_opt(10, 18, 0).unwrap().time()) .with_intraday_execution_start_time(date.and_hms_opt(10, 18, 0).unwrap().time())
.with_volume_limit(false) .with_volume_limit(false)
.with_liquidity_limit(false) .with_liquidity_limit(false)
+1 -1
View File
@@ -53,7 +53,7 @@ impl Default for ChinaAShareCostModel {
} }
impl ChinaAShareCostModel { impl ChinaAShareCostModel {
pub fn aiquant_rqalpha_default() -> Self { pub fn aiquant_default() -> Self {
Self { Self {
commission_rate: 0.00025, commission_rate: 0.00025,
stamp_tax_rate_before_change: 0.0005, stamp_tax_rate_before_change: 0.0005,
+13 -10
View File
@@ -106,7 +106,7 @@ pub struct DailyMarketSnapshot {
pub ask1: f64, pub ask1: f64,
pub prev_close: f64, pub prev_close: f64,
pub volume: u64, pub volume: u64,
pub tick_volume: u64, pub minute_volume: u64,
pub bid1_volume: u64, pub bid1_volume: u64,
pub ask1_volume: u64, pub ask1_volume: u64,
pub trading_phase: Option<String>, pub trading_phase: Option<String>,
@@ -519,7 +519,7 @@ struct SymbolPriceSeries {
bid1s: Vec<f64>, bid1s: Vec<f64>,
ask1s: Vec<f64>, ask1s: Vec<f64>,
volumes: Vec<u64>, volumes: Vec<u64>,
tick_volumes: Vec<u64>, minute_volumes: Vec<u64>,
bid1_volumes: Vec<u64>, bid1_volumes: Vec<u64>,
ask1_volumes: Vec<u64>, ask1_volumes: Vec<u64>,
trading_phases: Vec<Option<String>>, trading_phases: Vec<Option<String>>,
@@ -557,7 +557,10 @@ impl SymbolPriceSeries {
let bid1s = sorted.iter().map(|row| row.bid1).collect::<Vec<_>>(); let bid1s = sorted.iter().map(|row| row.bid1).collect::<Vec<_>>();
let ask1s = sorted.iter().map(|row| row.ask1).collect::<Vec<_>>(); let ask1s = sorted.iter().map(|row| row.ask1).collect::<Vec<_>>();
let volumes = sorted.iter().map(|row| row.volume).collect::<Vec<_>>(); let volumes = sorted.iter().map(|row| row.volume).collect::<Vec<_>>();
let tick_volumes = sorted.iter().map(|row| row.tick_volume).collect::<Vec<_>>(); let minute_volumes = sorted
.iter()
.map(|row| row.minute_volume)
.collect::<Vec<_>>();
let bid1_volumes = sorted.iter().map(|row| row.bid1_volume).collect::<Vec<_>>(); let bid1_volumes = sorted.iter().map(|row| row.bid1_volume).collect::<Vec<_>>();
let ask1_volumes = sorted.iter().map(|row| row.ask1_volume).collect::<Vec<_>>(); let ask1_volumes = sorted.iter().map(|row| row.ask1_volume).collect::<Vec<_>>();
let trading_phases = sorted let trading_phases = sorted
@@ -592,7 +595,7 @@ impl SymbolPriceSeries {
bid1s, bid1s,
ask1s, ask1s,
volumes, volumes,
tick_volumes, minute_volumes,
bid1_volumes, bid1_volumes,
ask1_volumes, ask1_volumes,
trading_phases, trading_phases,
@@ -816,7 +819,7 @@ impl SymbolPriceSeries {
ask1: self.ask1s[index], ask1: self.ask1s[index],
prev_close: self.prev_closes[index], prev_close: self.prev_closes[index],
volume: self.volumes[index], volume: self.volumes[index],
tick_volume: self.tick_volumes[index], minute_volume: self.minute_volumes[index],
bid1_volume: self.bid1_volumes[index], bid1_volume: self.bid1_volumes[index],
ask1_volume: self.ask1_volumes[index], ask1_volume: self.ask1_volumes[index],
trading_phase: self.trading_phases[index].clone(), trading_phase: self.trading_phases[index].clone(),
@@ -837,7 +840,7 @@ impl SymbolPriceSeries {
"last" | "last_price" => Some(self.last_prices[index]), "last" | "last_price" => Some(self.last_prices[index]),
"prev_close" | "pre_close" => Some(self.prev_closes[index]), "prev_close" | "pre_close" => Some(self.prev_closes[index]),
"volume" => Some(self.volumes[index] as f64), "volume" => Some(self.volumes[index] as f64),
"tick_volume" => Some(self.tick_volumes[index] as f64), "minute_volume" => Some(self.minute_volumes[index] as f64),
"bid1" => Some(self.bid1s[index]), "bid1" => Some(self.bid1s[index]),
"ask1" => Some(self.ask1s[index]), "ask1" => Some(self.ask1s[index]),
"bid1_volume" => Some(self.bid1_volumes[index] as f64), "bid1_volume" => Some(self.bid1_volumes[index] as f64),
@@ -2695,7 +2698,7 @@ fn read_market(path: &Path) -> Result<Vec<DailyMarketSnapshot>, DataSetError> {
ask1: row.parse_optional_f64(14).unwrap_or(close), ask1: row.parse_optional_f64(14).unwrap_or(close),
prev_close, prev_close,
volume: row.parse_u64(7)?, volume: row.parse_u64(7)?,
tick_volume: row.parse_optional_u64(17).unwrap_or_default(), minute_volume: row.parse_optional_u64(17).unwrap_or_default(),
bid1_volume: row.parse_optional_u64(18).unwrap_or_default(), bid1_volume: row.parse_optional_u64(18).unwrap_or_default(),
ask1_volume: row.parse_optional_u64(19).unwrap_or_default(), ask1_volume: row.parse_optional_u64(19).unwrap_or_default(),
trading_phase: row trading_phase: row
@@ -3727,7 +3730,7 @@ mod tests {
ask1: prev_close, ask1: prev_close,
prev_close, prev_close,
volume, volume,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: None, trading_phase: None,
@@ -3915,7 +3918,7 @@ mod tests {
ask1: prev_close, ask1: prev_close,
prev_close, prev_close,
volume: 100_000, volume: 100_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3995,7 +3998,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+110 -114
View File
@@ -391,7 +391,7 @@ struct StockExpressionState {
free_float_cap_bn: f64, free_float_cap_bn: f64,
pe_ttm: f64, pe_ttm: f64,
volume: f64, volume: f64,
tick_volume: i64, minute_volume: i64,
bid1_volume: i64, bid1_volume: i64,
ask1_volume: i64, ask1_volume: i64,
turnover_ratio: f64, turnover_ratio: f64,
@@ -830,7 +830,6 @@ impl PlatformExprStrategy {
| "volume" | "volume"
| "minute_volume" | "minute_volume"
| "intraday_volume" | "intraday_volume"
| "tick_volume"
| "bid1_volume" | "bid1_volume"
| "ask1_volume" | "ask1_volume"
| "turnover_ratio" | "turnover_ratio"
@@ -1015,7 +1014,7 @@ impl PlatformExprStrategy {
fn cost_model(&self) -> ChinaAShareCostModel { fn cost_model(&self) -> ChinaAShareCostModel {
let mut model = if self.config.aiquant_transaction_cost { let mut model = if self.config.aiquant_transaction_cost {
ChinaAShareCostModel::aiquant_rqalpha_default() ChinaAShareCostModel::aiquant_default()
} else { } else {
ChinaAShareCostModel::default() ChinaAShareCostModel::default()
}; };
@@ -2465,7 +2464,7 @@ impl PlatformExprStrategy {
free_float_cap_bn, free_float_cap_bn,
pe_ttm: factor.pe_ttm, pe_ttm: factor.pe_ttm,
volume: expression_volume, volume: expression_volume,
tick_volume: market.tick_volume as i64, minute_volume: market.minute_volume as i64,
bid1_volume: market.bid1_volume as i64, bid1_volume: market.bid1_volume as i64,
ask1_volume: market.ask1_volume as i64, ask1_volume: market.ask1_volume as i64,
turnover_ratio: factor.turnover_ratio.unwrap_or(0.0), turnover_ratio: factor.turnover_ratio.unwrap_or(0.0),
@@ -2873,9 +2872,8 @@ impl PlatformExprStrategy {
scope.push("free_float_market_cap", stock.free_float_cap); scope.push("free_float_market_cap", stock.free_float_cap);
scope.push("pe_ttm", stock.pe_ttm); scope.push("pe_ttm", stock.pe_ttm);
scope.push("volume", stock.volume); scope.push("volume", stock.volume);
scope.push("minute_volume", stock.tick_volume); scope.push("minute_volume", stock.minute_volume);
scope.push("intraday_volume", stock.tick_volume); scope.push("intraday_volume", stock.minute_volume);
scope.push("tick_volume", stock.tick_volume);
scope.push("bid1_volume", stock.bid1_volume); scope.push("bid1_volume", stock.bid1_volume);
scope.push("ask1_volume", stock.ask1_volume); scope.push("ask1_volume", stock.ask1_volume);
scope.push("turnover", stock.turnover_ratio); scope.push("turnover", stock.turnover_ratio);
@@ -2976,9 +2974,8 @@ impl PlatformExprStrategy {
); );
factors.insert("pe_ttm".into(), Dynamic::from(stock.pe_ttm)); factors.insert("pe_ttm".into(), Dynamic::from(stock.pe_ttm));
factors.insert("volume".into(), Dynamic::from(stock.volume)); factors.insert("volume".into(), Dynamic::from(stock.volume));
factors.insert("minute_volume".into(), Dynamic::from(stock.tick_volume)); factors.insert("minute_volume".into(), Dynamic::from(stock.minute_volume));
factors.insert("intraday_volume".into(), Dynamic::from(stock.tick_volume)); factors.insert("intraday_volume".into(), Dynamic::from(stock.minute_volume));
factors.insert("tick_volume".into(), Dynamic::from(stock.tick_volume));
factors.insert("bid1_volume".into(), Dynamic::from(stock.bid1_volume)); factors.insert("bid1_volume".into(), Dynamic::from(stock.bid1_volume));
factors.insert("ask1_volume".into(), Dynamic::from(stock.ask1_volume)); factors.insert("ask1_volume".into(), Dynamic::from(stock.ask1_volume));
factors.insert("turnover".into(), Dynamic::from(stock.turnover_ratio)); factors.insert("turnover".into(), Dynamic::from(stock.turnover_ratio));
@@ -5978,7 +5975,7 @@ impl PlatformExprStrategy {
"free_float_cap_bn" => Some(stock.free_float_cap_bn), "free_float_cap_bn" => Some(stock.free_float_cap_bn),
"pe_ttm" => Some(stock.pe_ttm), "pe_ttm" => Some(stock.pe_ttm),
"volume" => Some(stock.volume), "volume" => Some(stock.volume),
"minute_volume" | "intraday_volume" | "tick_volume" => Some(stock.tick_volume as f64), "minute_volume" | "intraday_volume" => Some(stock.minute_volume as f64),
"bid1_volume" => Some(stock.bid1_volume as f64), "bid1_volume" => Some(stock.bid1_volume as f64),
"ask1_volume" => Some(stock.ask1_volume as f64), "ask1_volume" => Some(stock.ask1_volume as f64),
"turnover" | "turnover_ratio" => Some(stock.turnover_ratio), "turnover" | "turnover_ratio" => Some(stock.turnover_ratio),
@@ -6320,7 +6317,7 @@ impl PlatformExprStrategy {
for name in Self::extract_identifier_candidates(&expr) { for name in Self::extract_identifier_candidates(&expr) {
match name.as_str() { match name.as_str() {
"last" | "last_price" | "bid1" | "ask1" | "bid1_volume" | "ask1_volume" "last" | "last_price" | "bid1" | "ask1" | "bid1_volume" | "ask1_volume"
| "minute_volume" | "intraday_volume" | "tick_volume" => { | "minute_volume" | "intraday_volume" => {
return StockFilterQuoteUsage::IntradayQuote; return StockFilterQuoteUsage::IntradayQuote;
} }
"at_upper_limit" | "at_lower_limit" => { "at_upper_limit" | "at_lower_limit" => {
@@ -6522,7 +6519,6 @@ impl PlatformExprStrategy {
| "volume" | "volume"
| "minute_volume" | "minute_volume"
| "intraday_volume" | "intraday_volume"
| "tick_volume"
| "bid1_volume" | "bid1_volume"
| "ask1_volume" | "ask1_volume"
| "turnover" | "turnover"
@@ -8279,7 +8275,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.0, prev_close: 9.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: None, trading_phase: None,
@@ -8302,7 +8298,7 @@ mod tests {
ask1: 1_000.0, ask1: 1_000.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: None, trading_phase: None,
@@ -8454,7 +8450,7 @@ mod tests {
ask1: 5.12, ask1: 5.12,
prev_close: 5.00, prev_close: 5.00,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 324, bid1_volume: 324,
ask1_volume: 1_717, ask1_volume: 1_717,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -8595,7 +8591,7 @@ mod tests {
ask1: 6.5369, ask1: 6.5369,
prev_close: 6.72, prev_close: 6.72,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -8741,7 +8737,7 @@ mod tests {
ask1: 11.93, ask1: 11.93,
prev_close: 11.40, prev_close: 11.40,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -8837,7 +8833,7 @@ mod tests {
ask1: 12.00, ask1: 12.00,
prev_close: 11.40, prev_close: 11.40,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -8950,7 +8946,7 @@ mod tests {
ask1: 23.99, ask1: 23.99,
prev_close: 21.81, prev_close: 21.81,
volume: 100_161, volume: 100_161,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9068,7 +9064,7 @@ mod tests {
ask1: 23.99, ask1: 23.99,
prev_close: 21.81, prev_close: 21.81,
volume: 100_161, volume: 100_161,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9182,7 +9178,7 @@ mod tests {
ask1: 23.99, ask1: 23.99,
prev_close: 21.81, prev_close: 21.81,
volume: 100_000, volume: 100_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9205,7 +9201,7 @@ mod tests {
ask1: 23.21, ask1: 23.21,
prev_close: 23.99, prev_close: 23.99,
volume: 200_000, volume: 200_000,
tick_volume: 2_000, minute_volume: 2_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9442,7 +9438,7 @@ mod tests {
ask1: 14.51, ask1: 14.51,
prev_close: 13.30, prev_close: 13.30,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9465,7 +9461,7 @@ mod tests {
ask1: 8.02, ask1: 8.02,
prev_close: 7.95, prev_close: 7.95,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9488,7 +9484,7 @@ mod tests {
ask1: 2905.1, ask1: 2905.1,
prev_close: 2898.0, prev_close: 2898.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9733,7 +9729,7 @@ mod tests {
ask1: 14.63, ask1: 14.63,
prev_close: 13.30, prev_close: 13.30,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9756,7 +9752,7 @@ mod tests {
ask1: 8.02, ask1: 8.02,
prev_close: 7.95, prev_close: 7.95,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9779,7 +9775,7 @@ mod tests {
ask1: 2905.1, ask1: 2905.1,
prev_close: 2898.0, prev_close: 2898.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -9987,7 +9983,7 @@ mod tests {
ask1: 47.42, ask1: 47.42,
prev_close: 47.04, prev_close: 47.04,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10010,7 +10006,7 @@ mod tests {
ask1: 46.75, ask1: 46.75,
prev_close: 47.41, prev_close: 47.41,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10234,7 +10230,7 @@ mod tests {
ask1: 6.06, ask1: 6.06,
prev_close: 5.86, prev_close: 5.86,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10352,7 +10348,7 @@ mod tests {
ask1: 9.21, ask1: 9.21,
prev_close: 10.00, prev_close: 10.00,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10490,7 +10486,7 @@ mod tests {
ask1: last_price, ask1: last_price,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10596,7 +10592,7 @@ mod tests {
ask1: 15.05, ask1: 15.05,
prev_close: 14.53, prev_close: 14.53,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10694,7 +10690,7 @@ mod tests {
ask1: 9.9, ask1: 9.9,
prev_close: 9.7, prev_close: 9.7,
volume: 12_300, volume: 12_300,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("close".to_string()), trading_phase: Some("close".to_string()),
@@ -10717,7 +10713,7 @@ mod tests {
ask1: 19.06, ask1: 19.06,
prev_close: 9.9, prev_close: 9.9,
volume: 45_600, volume: 45_600,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10832,7 +10828,7 @@ mod tests {
ask1: 12.0, ask1: 12.0,
prev_close: 10.0, prev_close: 10.0,
volume: 120_000, volume: 120_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -10956,7 +10952,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 120_000, volume: 120_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11067,7 +11063,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume, volume,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11198,7 +11194,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000, volume: 1_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11316,7 +11312,7 @@ mod tests {
ask1: 10.81, ask1: 10.81,
prev_close: 10.5, prev_close: 10.5,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11430,7 +11426,7 @@ mod tests {
ask1: 0.0, ask1: 0.0,
prev_close: 10.4, prev_close: 10.4,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11543,7 +11539,7 @@ mod tests {
ask1: 10.51, ask1: 10.51,
prev_close: 10.4, prev_close: 10.4,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11680,7 +11676,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11842,7 +11838,7 @@ mod tests {
ask1: 11.0, ask1: 11.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -11998,7 +11994,7 @@ mod tests {
ask1: 11.0, ask1: 11.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12154,7 +12150,7 @@ mod tests {
ask1: 10.8, ask1: 10.8,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12314,7 +12310,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12473,7 +12469,7 @@ mod tests {
ask1: 10.81, ask1: 10.81,
prev_close: 10.5, prev_close: 10.5,
volume: 200_000, volume: 200_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12627,7 +12623,7 @@ mod tests {
ask1: 6.5369, ask1: 6.5369,
prev_close: 6.72, prev_close: 6.72,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12739,7 +12735,7 @@ mod tests {
} }
#[test] #[test]
fn platform_aiquant_stock_expr_uses_scheduled_tick_price_for_limit_check() { fn platform_aiquant_stock_expr_uses_scheduled_minute_price_for_limit_check() {
let date = d(2024, 1, 30); let date = d(2024, 1, 30);
let symbol = "002087.SZ"; let symbol = "002087.SZ";
let data = DataSet::from_components_with_actions_and_quotes( let data = DataSet::from_components_with_actions_and_quotes(
@@ -12766,7 +12762,7 @@ mod tests {
ask1: 1.36, ask1: 1.36,
prev_close: 1.42, prev_close: 1.42,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 7_000, bid1_volume: 7_000,
ask1_volume: 4_000, ask1_volume: 4_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -12886,7 +12882,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13036,7 +13032,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13133,7 +13129,7 @@ mod tests {
ask1: 5.83, ask1: 5.83,
prev_close: 5.85, prev_close: 5.85,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 262, minute_volume: 262,
bid1_volume: 54, bid1_volume: 54,
ask1_volume: 143, ask1_volume: 143,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13259,7 +13255,7 @@ mod tests {
ask1: last_price, ask1: last_price,
prev_close: last_price, prev_close: last_price,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13547,7 +13543,7 @@ mod tests {
ask1: 19.06, ask1: 19.06,
prev_close: 21.17, prev_close: 21.17,
volume: 16_173, volume: 16_173,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13646,7 +13642,7 @@ mod tests {
ask1: 3.63, ask1: 3.63,
prev_close: 3.49, prev_close: 3.49,
volume: 10_000_000, volume: 10_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13761,7 +13757,7 @@ mod tests {
ask1: 20.01, ask1: 20.01,
prev_close: 19.8, prev_close: 19.8,
volume: 10_000_000, volume: 10_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -13863,7 +13859,7 @@ mod tests {
ask1: 8.0, ask1: 8.0,
prev_close: 8.0, prev_close: 8.0,
volume: 0, volume: 0,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("suspended".to_string()), trading_phase: Some("suspended".to_string()),
@@ -14045,7 +14041,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14218,7 +14214,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14241,7 +14237,7 @@ mod tests {
ask1: 4000.2, ask1: 4000.2,
prev_close: 3995.0, prev_close: 3995.0,
volume: 100_000, volume: 100_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 100, bid1_volume: 100,
ask1_volume: 100, ask1_volume: 100,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14423,7 +14419,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14565,7 +14561,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14687,7 +14683,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14710,7 +14706,7 @@ mod tests {
ask1: 100.01, ask1: 100.01,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -14865,7 +14861,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -15004,7 +15000,7 @@ mod tests {
ask1: 10.2 + index as f64, ask1: 10.2 + index as f64,
prev_close: 10.0 + index as f64, prev_close: 10.0 + index as f64,
volume: 100 + index as u64 * 100, volume: 100 + index as u64 * 100,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: None, trading_phase: None,
@@ -15148,7 +15144,7 @@ mod tests {
ask1: 10.0 + index as f64, ask1: 10.0 + index as f64,
prev_close: if index == 0 { 9.8 } else { 9.0 + index as f64 }, prev_close: if index == 0 { 9.8 } else { 9.0 + index as f64 },
volume: 1000 + index as u64 * 100, volume: 1000 + index as u64 * 100,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: None, trading_phase: None,
@@ -15295,7 +15291,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -15430,7 +15426,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -15563,7 +15559,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -15723,7 +15719,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -15856,7 +15852,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16015,7 +16011,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16175,7 +16171,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 11.11, prev_close: 11.11,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16324,7 +16320,7 @@ mod tests {
ask1: 9.51, ask1: 9.51,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16492,7 +16488,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16730,7 +16726,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -16896,7 +16892,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17038,7 +17034,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17219,7 +17215,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17395,7 +17391,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17619,7 +17615,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17769,7 +17765,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -17920,7 +17916,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18161,7 +18157,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18347,7 +18343,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18499,7 +18495,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18638,7 +18634,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18768,7 +18764,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -18903,7 +18899,7 @@ mod tests {
ask1: 0.0, ask1: 0.0,
prev_close: 17.11, prev_close: 17.11,
volume: 0, volume: 0,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("paused".to_string()), trading_phase: Some("paused".to_string()),
@@ -19005,7 +19001,7 @@ mod tests {
ask1: 0.0, ask1: 0.0,
prev_close: 7.63, prev_close: 7.63,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19119,7 +19115,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19291,7 +19287,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19478,7 +19474,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000, volume: 1_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: None, trading_phase: None,
@@ -19613,7 +19609,7 @@ mod tests {
ask1: 10.22, ask1: 10.22,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_500, bid1_volume: 2_500,
ask1_volume: 2_500, ask1_volume: 2_500,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19733,7 +19729,7 @@ mod tests {
ask1: 10.22, ask1: 10.22,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_500, bid1_volume: 2_500,
ask1_volume: 2_500, ask1_volume: 2_500,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19877,7 +19873,7 @@ mod tests {
ask1: 1001.5, ask1: 1001.5,
prev_close: 999.0, prev_close: 999.0,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_500, bid1_volume: 2_500,
ask1_volume: 2_500, ask1_volume: 2_500,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -19984,7 +19980,7 @@ mod tests {
ask1: 1001.5, ask1: 1001.5,
prev_close: 999.0, prev_close: 999.0,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_500, bid1_volume: 2_500,
ask1_volume: 2_500, ask1_volume: 2_500,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20086,7 +20082,7 @@ mod tests {
ask1: 1001.5, ask1: 1001.5,
prev_close: 999.0, prev_close: 999.0,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_500, bid1_volume: 2_500,
ask1_volume: 2_500, ask1_volume: 2_500,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20187,7 +20183,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -20311,7 +20307,7 @@ mod tests {
ask1: 10.0, ask1: 10.0,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -20426,7 +20422,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20549,7 +20545,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20690,7 +20686,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20818,7 +20814,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -20941,7 +20937,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -21058,7 +21054,7 @@ mod tests {
ask1: 10.05, ask1: 10.05,
prev_close: 9.95, prev_close: 9.95,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -21191,7 +21187,7 @@ mod tests {
ask1: 10.05 + index as f64, ask1: 10.05 + index as f64,
prev_close: 9.95 + index as f64, prev_close: 9.95 + index as f64,
volume: 1_000_000 + index as u64 * 100_000, volume: 1_000_000 + index as u64 * 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 1_000, bid1_volume: 1_000,
ask1_volume: 1_000, ask1_volume: 1_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -21348,7 +21344,7 @@ mod tests {
} }
#[test] #[test]
fn selection_quote_plan_filters_daily_part_before_tick_candidates() { fn selection_quote_plan_filters_daily_part_before_minute_candidates() {
let date = d(2025, 1, 3); let date = d(2025, 1, 3);
let symbols = ["000001.SZ", "000002.SZ", "000003.SZ", "000004.SZ"]; let symbols = ["000001.SZ", "000002.SZ", "000003.SZ", "000004.SZ"];
let data = DataSet::from_components( let data = DataSet::from_components(
@@ -21396,7 +21392,7 @@ mod tests {
}, },
prev_close: reference_price, prev_close: reference_price,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -135,7 +135,7 @@ const RESERVED_SCOPE_NAMES: &[&str] = &[
"free_float_cap", "free_float_cap",
"pe_ttm", "pe_ttm",
"volume", "volume",
"tick_volume", "minute_volume",
"bid1_volume", "bid1_volume",
"ask1_volume", "ask1_volume",
"turnover_ratio", "turnover_ratio",
+20 -54
View File
@@ -43,8 +43,6 @@ pub struct StrategyRuntimeSpec {
pub struct StrategyBenchmarkSpec { pub struct StrategyBenchmarkSpec {
#[serde(default)] #[serde(default)]
pub instrument_id: Option<String>, pub instrument_id: Option<String>,
#[serde(default)]
pub fallback_instrument_id: Option<String>,
} }
#[derive(Debug, Clone, Default, Deserialize, Serialize)] #[derive(Debug, Clone, Default, Deserialize, Serialize)]
@@ -64,8 +62,6 @@ pub struct StrategyRebalanceSpec {
#[derive(Debug, Clone, Default, Deserialize, Serialize)] #[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct StrategyExecutionSpec { pub struct StrategyExecutionSpec {
#[serde(default)]
pub compatibility_profile: Option<String>,
#[serde(default)] #[serde(default)]
pub matching_type: Option<String>, pub matching_type: Option<String>,
#[serde(default)] #[serde(default)]
@@ -96,8 +92,6 @@ pub struct StrategyEngineConfig {
#[serde(default)] #[serde(default)]
pub template_id: Option<String>, pub template_id: Option<String>,
#[serde(default)] #[serde(default)]
pub compatibility_profile: Option<String>,
#[serde(default)]
pub profile_name: Option<String>, pub profile_name: Option<String>,
#[serde(default)] #[serde(default)]
pub benchmark_symbol: Option<String>, pub benchmark_symbol: Option<String>,
@@ -393,10 +387,10 @@ fn valid_non_negative(value: Option<f64>) -> Option<f64> {
value.filter(|item| item.is_finite() && *item >= 0.0) value.filter(|item| item.is_finite() && *item >= 0.0)
} }
fn is_aiquant_compatibility_profile(value: Option<&str>) -> bool { fn is_aiquant_profile(value: Option<&str>) -> bool {
value value
.map(|item| item.trim().to_ascii_lowercase().replace('-', "_")) .map(|item| item.trim().to_ascii_lowercase().replace('-', "_"))
.is_some_and(|item| item == "aiquant_rqalpha" || item == "aiquant") .is_some_and(|item| item == "aiquant")
} }
fn apply_cost_overrides( fn apply_cost_overrides(
@@ -789,14 +783,6 @@ pub fn platform_expr_config_from_spec(
{ {
cfg.signal_symbol = spec_signal_symbol.clone(); cfg.signal_symbol = spec_signal_symbol.clone();
} }
if cfg.signal_symbol.trim().is_empty()
&& let Some(spec_signal_symbol) = benchmark
.fallback_instrument_id
.as_ref()
.filter(|value| !value.trim().is_empty())
{
cfg.signal_symbol = spec_signal_symbol.clone();
}
} }
if let Some(universe) = spec.universe.as_ref() { if let Some(universe) = spec.universe.as_ref() {
cfg.universe_exclude = universe cfg.universe_exclude = universe
@@ -1111,20 +1097,12 @@ pub fn platform_expr_config_from_spec(
if !cfg.benchmark_symbol.trim().is_empty() { if !cfg.benchmark_symbol.trim().is_empty() {
cfg.benchmark_symbol = normalize_symbol(&cfg.benchmark_symbol, None); cfg.benchmark_symbol = normalize_symbol(&cfg.benchmark_symbol, None);
} }
let aiquant_compat = is_aiquant_compatibility_profile( let aiquant_profile = is_aiquant_profile(
spec.execution
.as_ref()
.and_then(|execution| execution.compatibility_profile.as_deref()),
) || is_aiquant_compatibility_profile(
spec.engine_config
.as_ref()
.and_then(|engine| engine.compatibility_profile.as_deref()),
) || is_aiquant_compatibility_profile(
spec.engine_config spec.engine_config
.as_ref() .as_ref()
.and_then(|engine| engine.profile_name.as_deref()), .and_then(|engine| engine.profile_name.as_deref()),
); );
if aiquant_compat { if aiquant_profile {
cfg.aiquant_transaction_cost = true; cfg.aiquant_transaction_cost = true;
let trading = spec let trading = spec
.runtime_expressions .runtime_expressions
@@ -1150,7 +1128,7 @@ pub fn platform_expr_config_from_spec(
.and_then(|runtime_expr| runtime_expr.trading.as_ref()) .and_then(|runtime_expr| runtime_expr.trading.as_ref())
.and_then(|trading| trading.delayed_limit_open_exit) .and_then(|trading| trading.delayed_limit_open_exit)
.is_some(); .is_some();
if aiquant_compat && !delayed_limit_open_exit_explicit && trade_times.len() > 1 { if aiquant_profile && !delayed_limit_open_exit_explicit && trade_times.len() > 1 {
let delayed_time = trade_times[0]; let delayed_time = trade_times[0];
if trade_times if trade_times
.last() .last()
@@ -1588,7 +1566,7 @@ mod tests {
"signalSymbol": "000852.SH", "signalSymbol": "000852.SH",
"benchmark": { "instrumentId": "000852.SH" }, "benchmark": { "instrumentId": "000852.SH" },
"universe": { "exclude": ["paused", "st", "kcb", "one_yuan"] }, "universe": { "exclude": ["paused", "st", "kcb", "one_yuan"] },
"execution": { "compatibilityProfile": "aiquant_rqalpha" }, "engineConfig": { "profileName": "aiquant" },
"runtimeExpressions": { "runtimeExpressions": {
"prelude": "let stocknum = 8;", "prelude": "let stocknum = 8;",
"selection": { "selection": {
@@ -1653,13 +1631,13 @@ mod tests {
fn parses_execution_cost_overrides_into_platform_config() { fn parses_execution_cost_overrides_into_platform_config() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "execution": {
"compatibilityProfile": "aiquant_rqalpha",
"commissionRate": 0.0003, "commissionRate": 0.0003,
"minimumCommission": 5.0, "minimumCommission": 5.0,
"stampTaxRateBeforeChange": 0.0005, "stampTaxRateBeforeChange": 0.0005,
"stampTaxRateAfterChange": 0.0005 "stampTaxRateAfterChange": 0.0005
}, },
"engineConfig": { "engineConfig": {
"profileName": "aiquant",
"commissionRate": 0.0008 "commissionRate": 0.0008
} }
}); });
@@ -1677,13 +1655,13 @@ mod tests {
fn parses_execution_slippage_overrides_into_platform_config() { fn parses_execution_slippage_overrides_into_platform_config() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "execution": {
"compatibilityProfile": "aiquant_rqalpha",
"matchingType": "next_minute_last", "matchingType": "next_minute_last",
"slippageModel": "price_ratio", "slippageModel": "price_ratio",
"slippageValue": 0.001, "slippageValue": 0.001,
"strictValueBudget": true "strictValueBudget": true
}, },
"engineConfig": { "engineConfig": {
"profileName": "aiquant",
"matchingType": "current_bar_close", "matchingType": "current_bar_close",
"slippageModel": "none", "slippageModel": "none",
"slippageValue": 0.0, "slippageValue": 0.0,
@@ -1744,8 +1722,8 @@ mod tests {
#[test] #[test]
fn aiquant_profile_defaults_to_daily_top_up_and_empty_retry() { fn aiquant_profile_defaults_to_daily_top_up_and_empty_retry() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "engineConfig": {
"compatibilityProfile": "aiquant_rqalpha" "profileName": "aiquant"
} }
}); });
@@ -1756,8 +1734,8 @@ mod tests {
assert!(cfg.retry_empty_rebalance); assert!(cfg.retry_empty_rebalance);
let explicit_off = serde_json::json!({ let explicit_off = serde_json::json!({
"execution": { "engineConfig": {
"compatibilityProfile": "aiquant_rqalpha" "profileName": "aiquant"
}, },
"runtimeExpressions": { "runtimeExpressions": {
"trading": { "trading": {
@@ -1774,22 +1752,10 @@ mod tests {
} }
#[test] #[test]
fn engine_config_aiquant_profile_enables_aiquant_semantics() { fn engine_config_profile_name_enables_aiquant_semantics() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"engineConfig": { "engineConfig": {
"compatibilityProfile": "aiquant_rqalpha" "profileName": "aiquant"
}
});
let cfg = platform_expr_config_from_value("", "", &spec).expect("config");
assert!(cfg.aiquant_transaction_cost);
assert!(cfg.daily_top_up_enabled);
assert!(cfg.retry_empty_rebalance);
let spec = serde_json::json!({
"engineConfig": {
"profileName": "aiquant-rqalpha"
} }
}); });
@@ -1801,8 +1767,8 @@ mod tests {
#[test] #[test]
fn runtime_expressions_infer_ma_windows_from_literal_strategy_logic() { fn runtime_expressions_infer_ma_windows_from_literal_strategy_logic() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "engineConfig": {
"compatibilityProfile": "aiquant_rqalpha" "profileName": "aiquant"
}, },
"runtimeExpressions": { "runtimeExpressions": {
"selection": { "selection": {
@@ -1856,7 +1822,7 @@ mod tests {
#[test] #[test]
fn parses_daily_schedule_time_for_aiquant_execution_quotes() { fn parses_daily_schedule_time_for_aiquant_execution_quotes() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "compatibilityProfile": "aiquant_rqalpha" }, "engineConfig": { "profileName": "aiquant" },
"runtimeExpressions": { "runtimeExpressions": {
"schedule": { "frequency": "daily", "time": "09:33" } "schedule": { "frequency": "daily", "time": "09:33" }
} }
@@ -1876,7 +1842,7 @@ mod tests {
#[test] #[test]
fn parses_aiquant_rebalance_trade_times_for_delayed_limit_exit() { fn parses_aiquant_rebalance_trade_times_for_delayed_limit_exit() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "compatibilityProfile": "aiquant_rqalpha" }, "engineConfig": { "profileName": "aiquant" },
"rebalance": { "tradeTimes": ["10:31", "10:40"] }, "rebalance": { "tradeTimes": ["10:31", "10:40"] },
"runtimeExpressions": { "runtimeExpressions": {
"schedule": { "frequency": "daily", "time": "10:40" } "schedule": { "frequency": "daily", "time": "10:40" }
@@ -1899,7 +1865,7 @@ mod tests {
#[test] #[test]
fn parses_explicit_delayed_limit_open_exit() { fn parses_explicit_delayed_limit_open_exit() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "compatibilityProfile": "aiquant_rqalpha" }, "engineConfig": { "profileName": "aiquant" },
"runtimeExpressions": { "runtimeExpressions": {
"schedule": { "frequency": "daily", "time": "10:40" }, "schedule": { "frequency": "daily", "time": "10:40" },
"trading": { "trading": {
@@ -1925,7 +1891,7 @@ mod tests {
#[test] #[test]
fn explicit_delayed_limit_open_exit_false_overrides_aiquant_trade_times() { fn explicit_delayed_limit_open_exit_false_overrides_aiquant_trade_times() {
let spec = serde_json::json!({ let spec = serde_json::json!({
"execution": { "compatibilityProfile": "aiquant_rqalpha" }, "engineConfig": { "profileName": "aiquant" },
"rebalance": { "tradeTimes": ["10:31", "10:40"] }, "rebalance": { "tradeTimes": ["10:31", "10:40"] },
"runtimeExpressions": { "runtimeExpressions": {
"schedule": { "frequency": "daily", "time": "10:40" }, "schedule": { "frequency": "daily", "time": "10:40" },
+7 -7
View File
@@ -981,7 +981,7 @@ mod tests {
} }
#[test] #[test]
fn cash_dividend_can_preserve_avg_cost_for_aiquant_compatibility() { fn cash_dividend_can_preserve_avg_cost_for_aiquant_rules() {
let date = NaiveDate::from_ymd_opt(2025, 1, 2).unwrap(); let date = NaiveDate::from_ymd_opt(2025, 1, 2).unwrap();
let mut position = Position::new("603102.SH"); let mut position = Position::new("603102.SH");
position.buy(date, 1000, 46.45); position.buy(date, 1000, 46.45);
@@ -1033,7 +1033,7 @@ mod tests {
ask1: 10.01, ask1: 10.01,
prev_close: 9.8, prev_close: 9.8,
volume: 1000, volume: 1000,
tick_volume: 1000, minute_volume: 1000,
bid1_volume: 1000, bid1_volume: 1000,
ask1_volume: 1000, ask1_volume: 1000,
trading_phase: None, trading_phase: None,
@@ -1056,7 +1056,7 @@ mod tests {
ask1: 10.51, ask1: 10.51,
prev_close: 10.0, prev_close: 10.0,
volume: 1000, volume: 1000,
tick_volume: 1000, minute_volume: 1000,
bid1_volume: 1000, bid1_volume: 1000,
ask1_volume: 1000, ask1_volume: 1000,
trading_phase: None, trading_phase: None,
@@ -1144,7 +1144,7 @@ mod tests {
ask1: 10.51, ask1: 10.51,
prev_close: 10.0, prev_close: 10.0,
volume: 1000, volume: 1000,
tick_volume: 1000, minute_volume: 1000,
bid1_volume: 1000, bid1_volume: 1000,
ask1_volume: 1000, ask1_volume: 1000,
trading_phase: None, trading_phase: None,
@@ -1228,7 +1228,7 @@ mod tests {
ask1: 10.31, ask1: 10.31,
prev_close: 10.0, prev_close: 10.0,
volume: 1000, volume: 1000,
tick_volume: 1000, minute_volume: 1000,
bid1_volume: 1000, bid1_volume: 1000,
ask1_volume: 1000, ask1_volume: 1000,
trading_phase: None, trading_phase: None,
@@ -1297,7 +1297,7 @@ mod tests {
ask1: 3.02, ask1: 3.02,
prev_close: 2.98, prev_close: 2.98,
volume: 152_975, volume: 152_975,
tick_volume: 152_975, minute_volume: 152_975,
bid1_volume: 338, bid1_volume: 338,
ask1_volume: 2476, ask1_volume: 2476,
trading_phase: None, trading_phase: None,
@@ -1320,7 +1320,7 @@ mod tests {
ask1: 3.07, ask1: 3.07,
prev_close: 3.06, prev_close: 3.06,
volume: 160_000, volume: 160_000,
tick_volume: 160_000, minute_volume: 160_000,
bid1_volume: 1000, bid1_volume: 1000,
ask1_volume: 1000, ask1_volume: 1000,
trading_phase: None, trading_phase: None,
+1 -1
View File
@@ -174,7 +174,7 @@ mod tests {
ask1: last_price, ask1: last_price,
prev_close: 6.25, prev_close: 6.25,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+2 -2
View File
@@ -1969,7 +1969,7 @@ impl OmniMicroCapStrategy {
return Some(0); return Some(0);
} }
let snapshot = ctx.data.market(date, symbol)?; let snapshot = ctx.data.market(date, symbol)?;
if snapshot.tick_volume == 0 { if snapshot.minute_volume == 0 {
return None; return None;
} }
@@ -1991,7 +1991,7 @@ impl OmniMicroCapStrategy {
let consumed_turnover = *execution_state.intraday_turnover.get(symbol).unwrap_or(&0); let consumed_turnover = *execution_state.intraday_turnover.get(symbol).unwrap_or(&0);
let raw_limit = let raw_limit =
((snapshot.tick_volume as f64) * 0.25).round() as i64 - consumed_turnover as i64; ((snapshot.minute_volume as f64) * 0.25).round() as i64 - consumed_turnover as i64;
if raw_limit <= 0 { if raw_limit <= 0 {
return None; return None;
} }
+4 -4
View File
@@ -42,7 +42,7 @@ fn snapshot(open: f64, upper_limit: f64, lower_limit: f64) -> DailyMarketSnapsho
ask1: open, ask1: open,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 50_000, bid1_volume: 50_000,
ask1_volume: 50_000, ask1_volume: 50_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -67,8 +67,8 @@ fn china_cost_model_applies_minimum_commission_and_stamp_tax() {
} }
#[test] #[test]
fn aiquant_rqalpha_cost_model_matches_alv_run_options() { fn aiquant_cost_model_matches_alv_run_options() {
let model = ChinaAShareCostModel::aiquant_rqalpha_default(); let model = ChinaAShareCostModel::aiquant_default();
let buy = model.calculate(d(2026, 5, 19), OrderSide::Buy, 49_978.84); let buy = model.calculate(d(2026, 5, 19), OrderSide::Buy, 49_978.84);
assert!((buy.commission - 12.49471).abs() < 1e-9); assert!((buy.commission - 12.49471).abs() < 1e-9);
@@ -260,7 +260,7 @@ fn china_rule_hooks_allow_sell_when_last_price_is_above_lower_limit() {
ask1: 2.53, ask1: 2.53,
prev_close: 2.80, prev_close: 2.80,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 50_000, bid1_volume: 50_000,
ask1_volume: 50_000, ask1_volume: 50_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+3 -3
View File
@@ -122,7 +122,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -145,7 +145,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -168,7 +168,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -83,7 +83,7 @@ fn engine_preloads_declared_decision_quotes_for_current_positions() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.8, prev_close: 9.8,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -106,7 +106,7 @@ fn engine_preloads_declared_decision_quotes_for_current_positions() {
ask1: 10.6, ask1: 10.6,
prev_close: 10.0, prev_close: 10.0,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -249,7 +249,7 @@ fn engine_reuses_preloaded_decision_quotes_without_loader_call() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.8, prev_close: 9.8,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -272,7 +272,7 @@ fn engine_reuses_preloaded_decision_quotes_without_loader_call() {
ask1: 10.6, ask1: 10.6,
prev_close: 10.0, prev_close: 10.0,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -480,7 +480,7 @@ fn engine_loads_distinct_decision_quote_times_on_same_day() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.8, prev_close: 9.8,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -503,7 +503,7 @@ fn engine_loads_distinct_decision_quote_times_on_same_day() {
ask1: 10.6, ask1: 10.6,
prev_close: 10.0, prev_close: 10.0,
volume: 10_000, volume: 10_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+6 -6
View File
@@ -81,7 +81,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run()
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -104,7 +104,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run()
ask1: 5.01, ask1: 5.01,
prev_close: 5.0, prev_close: 5.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -127,7 +127,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run()
ask1: 5.11, ask1: 5.11,
prev_close: 5.0, prev_close: 5.0,
volume: 120_000, volume: 120_000,
tick_volume: 120_000, minute_volume: 120_000,
bid1_volume: 120_000, bid1_volume: 120_000,
ask1_volume: 120_000, ask1_volume: 120_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -304,7 +304,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -327,7 +327,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() {
ask1: 20.0, ask1: 20.0,
prev_close: 20.0, prev_close: 20.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -350,7 +350,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() {
ask1: 21.0, ask1: 21.0,
prev_close: 20.0, prev_close: 20.0,
volume: 120_000, volume: 120_000,
tick_volume: 120_000, minute_volume: 120_000,
bid1_volume: 120_000, bid1_volume: 120_000,
ask1_volume: 120_000, ask1_volume: 120_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+29 -29
View File
@@ -58,7 +58,7 @@ fn single_day_anchor_data(date: NaiveDate) -> DataSet {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000_000, minute_volume: 1_000_000,
bid1_volume: 1_000_000, bid1_volume: 1_000_000,
ask1_volume: 1_000_000, ask1_volume: 1_000_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -116,7 +116,7 @@ fn market_row(date: NaiveDate, symbol: &str, open: f64, close: f64) -> DailyMark
ask1: close, ask1: close,
prev_close: open, prev_close: open,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000_000, minute_volume: 1_000_000,
bid1_volume: 1_000_000, bid1_volume: 1_000_000,
ask1_volume: 1_000_000, ask1_volume: 1_000_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -627,7 +627,7 @@ struct UniverseDirectiveStrategy {
snapshots: Rc<RefCell<Vec<String>>>, snapshots: Rc<RefCell<Vec<String>>>,
} }
struct TickProbeStrategy { struct MinuteProbeStrategy {
seen_ticks: Rc<RefCell<Vec<String>>>, seen_ticks: Rc<RefCell<Vec<String>>>,
ordered: bool, ordered: bool,
} }
@@ -797,7 +797,7 @@ impl Strategy for UniverseDirectiveStrategy {
} }
} }
impl Strategy for TickProbeStrategy { impl Strategy for MinuteProbeStrategy {
fn name(&self) -> &str { fn name(&self) -> &str {
"minute-probe" "minute-probe"
} }
@@ -883,13 +883,13 @@ impl Strategy for DataApiProbeStrategy {
.map(|value| format!("{value:.2}")) .map(|value| format!("{value:.2}"))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(","); .join(",");
let tick_last = ctx let minute_last = ctx
.history_bars("000001.SZ", 2, "1m", "last", true) .history_bars("000001.SZ", 2, "1m", "last", true)
.iter() .iter()
.map(|value| format!("{value:.2}")) .map(|value| format!("{value:.2}"))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(","); .join(",");
let previous_tick_last = ctx let previous_minute_last = ctx
.history_bars("000001.SZ", 2, "1m", "last", false) .history_bars("000001.SZ", 2, "1m", "last", false)
.iter() .iter()
.map(|value| format!("{value:.2}")) .map(|value| format!("{value:.2}"))
@@ -930,7 +930,7 @@ impl Strategy for DataApiProbeStrategy {
ctx.instruments_history(&["000001.SZ", "000002.SZ"]).len(); ctx.instruments_history(&["000001.SZ", "000002.SZ"]).len();
let active_instrument_count = ctx.active_instruments(&["000001.SZ", "000002.SZ"]).len(); let active_instrument_count = ctx.active_instruments(&["000001.SZ", "000002.SZ"]).len();
self.snapshots.borrow_mut().push(format!( self.snapshots.borrow_mut().push(format!(
"daily={daily_close};previous={previous_close};minute={tick_last};previous_minute={previous_tick_last};current={current_close};instrument={instrument_name};all={};history={instrument_history_count};active={active_instrument_count};range={trading_date_count};prev={prev_date};next={next_date};suspended={suspended};st={st_flags};price_daily={daily_price_count};price_tick={minute_price_count};minute_frequency={minute_frequency}", "daily={daily_close};previous={previous_close};minute={minute_last};previous_minute={previous_minute_last};current={current_close};instrument={instrument_name};all={};history={instrument_history_count};active={active_instrument_count};range={trading_date_count};prev={prev_date};next={next_date};suspended={suspended};st={st_flags};price_daily={daily_price_count};price_tick={minute_price_count};minute_frequency={minute_frequency}",
ctx.all_instruments().len() ctx.all_instruments().len()
)); ));
} }
@@ -1056,7 +1056,7 @@ fn engine_runs_strategy_hooks_in_daily_order() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1079,7 +1079,7 @@ fn engine_runs_strategy_hooks_in_daily_order() {
ask1: 10.1, ask1: 10.1,
prev_close: 10.0, prev_close: 10.0,
volume: 110_000, volume: 110_000,
tick_volume: 110_000, minute_volume: 110_000,
bid1_volume: 110_000, bid1_volume: 110_000,
ask1_volume: 110_000, ask1_volume: 110_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1252,7 +1252,7 @@ fn engine_executes_open_auction_decisions_before_on_day() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -1351,7 +1351,7 @@ fn engine_executes_futures_order_intents_against_future_account() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 1_000_000, volume: 1_000_000,
tick_volume: 1_000_000, minute_volume: 1_000_000,
bid1_volume: 1_000_000, bid1_volume: 1_000_000,
ask1_volume: 1_000_000, ask1_volume: 1_000_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1915,7 +1915,7 @@ fn strategy_context_exposes_advanced_data_helpers() {
} }
#[test] #[test]
fn engine_runs_subscribed_tick_hooks_and_executes_tick_orders() { fn engine_runs_minute_hooks_and_executes_minute_orders() {
let date = d(2025, 1, 2); let date = d(2025, 1, 2);
let data = DataSet::from_components_with_actions_and_quotes( let data = DataSet::from_components_with_actions_and_quotes(
vec![Instrument { vec![Instrument {
@@ -1941,7 +1941,7 @@ fn engine_runs_subscribed_tick_hooks_and_executes_tick_orders() {
ask1: 10.2, ask1: 10.2,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2013,7 +2013,7 @@ fn engine_runs_subscribed_tick_hooks_and_executes_tick_orders() {
.expect("dataset"); .expect("dataset");
let seen_ticks = Rc::new(RefCell::new(Vec::new())); let seen_ticks = Rc::new(RefCell::new(Vec::new()));
let strategy = TickProbeStrategy { let strategy = MinuteProbeStrategy {
seen_ticks: seen_ticks.clone(), seen_ticks: seen_ticks.clone(),
ordered: false, ordered: false,
}; };
@@ -2114,7 +2114,7 @@ fn strategy_context_exposes_engine_native_data_helpers() {
ask1: close + 0.01, ask1: close + 0.01,
prev_close, prev_close,
volume, volume,
tick_volume: volume, minute_volume: volume,
bid1_volume: volume, bid1_volume: volume,
ask1_volume: volume, ask1_volume: volume,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2285,7 +2285,7 @@ fn strategy_context_exposes_final_order_runtime_view() {
ask1: 10.2, ask1: 10.2,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2502,7 +2502,7 @@ fn engine_applies_account_cash_flow_and_financing_intents() {
ask1: 10.01, ask1: 10.01,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2525,7 +2525,7 @@ fn engine_applies_account_cash_flow_and_financing_intents() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2686,7 +2686,7 @@ fn engine_rejects_pending_limit_orders_at_market_close() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2709,7 +2709,7 @@ fn engine_rejects_pending_limit_orders_at_market_close() {
ask1: 9.7, ask1: 9.7,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2856,7 +2856,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -2879,7 +2879,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() {
ask1: 10.1, ask1: 10.1,
prev_close: 10.0, prev_close: 10.0,
volume: 110_000, volume: 110_000,
tick_volume: 110_000, minute_volume: 110_000,
bid1_volume: 110_000, bid1_volume: 110_000,
ask1_volume: 110_000, ask1_volume: 110_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -2902,7 +2902,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() {
ask1: 10.2, ask1: 10.2,
prev_close: 10.1, prev_close: 10.1,
volume: 120_000, volume: 120_000,
tick_volume: 120_000, minute_volume: 120_000,
bid1_volume: 120_000, bid1_volume: 120_000,
ask1_volume: 120_000, ask1_volume: 120_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3105,7 +3105,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3128,7 +3128,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() {
ask1: 10.1, ask1: 10.1,
prev_close: 10.0, prev_close: 10.0,
volume: 110_000, volume: 110_000,
tick_volume: 110_000, minute_volume: 110_000,
bid1_volume: 110_000, bid1_volume: 110_000,
ask1_volume: 110_000, ask1_volume: 110_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3151,7 +3151,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() {
ask1: 10.2, ask1: 10.2,
prev_close: 10.1, prev_close: 10.1,
volume: 120_000, volume: 120_000,
tick_volume: 120_000, minute_volume: 120_000,
bid1_volume: 120_000, bid1_volume: 120_000,
ask1_volume: 120_000, ask1_volume: 120_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3485,7 +3485,7 @@ fn engine_applies_dynamic_universe_and_subscription_directives() {
ask1: 10.01, ask1: 10.01,
prev_close: 9.95, prev_close: 9.95,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3508,7 +3508,7 @@ fn engine_applies_dynamic_universe_and_subscription_directives() {
ask1: 20.01, ask1: 20.01,
prev_close: 19.95, prev_close: 19.95,
volume: 100_000, volume: 100_000,
tick_volume: 5_000, minute_volume: 5_000,
bid1_volume: 2_000, bid1_volume: 2_000,
ask1_volume: 2_000, ask1_volume: 2_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3667,7 +3667,7 @@ fn engine_exposes_current_process_context_to_strategies() {
ask1: 10.0, ask1: 10.0,
prev_close: 9.9, prev_close: 9.9,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
+40 -40
View File
@@ -32,7 +32,7 @@ fn order_value_rounding_data(date: NaiveDate, symbol: &str, price: f64) -> DataS
ask1: price, ask1: price,
prev_close: price, prev_close: price,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -137,7 +137,7 @@ fn broker_executes_explicit_order_value_buy() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -259,7 +259,7 @@ fn broker_order_value_budget_includes_buy_commission() {
} }
#[test] #[test]
fn broker_delayed_limit_open_sell_uses_tick_price() { fn broker_delayed_limit_open_sell_uses_minute_price() {
let date = NaiveDate::from_ymd_opt(2025, 6, 27).unwrap(); let date = NaiveDate::from_ymd_opt(2025, 6, 27).unwrap();
let prev_date = NaiveDate::from_ymd_opt(2025, 6, 26).unwrap(); let prev_date = NaiveDate::from_ymd_opt(2025, 6, 26).unwrap();
let symbol = "300635.SZ"; let symbol = "300635.SZ";
@@ -287,7 +287,7 @@ fn broker_delayed_limit_open_sell_uses_tick_price() {
ask1: 12.40, ask1: 12.40,
prev_close: 13.24, prev_close: 13.24,
volume: 329_575, volume: 329_575,
tick_volume: 10_000, minute_volume: 10_000,
bid1_volume: 10_000, bid1_volume: 10_000,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -419,7 +419,7 @@ fn broker_executes_order_shares_and_order_lots() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -545,7 +545,7 @@ fn broker_executes_target_shares_like_order_to() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -665,7 +665,7 @@ fn broker_executes_target_portfolio_smart_with_custom_prices() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -688,7 +688,7 @@ fn broker_executes_target_portfolio_smart_with_custom_prices() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -845,7 +845,7 @@ fn broker_executes_target_portfolio_smart_with_algo_order_style() {
ask1: 10.21, ask1: 10.21,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -986,7 +986,7 @@ fn broker_executes_order_percent_and_target_percent() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1107,7 +1107,7 @@ fn broker_uses_day_open_price_for_open_auction_matching() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -1211,7 +1211,7 @@ fn broker_open_auction_uses_auction_volume_without_quote_liquidity() {
ask1: 0.0, ask1: 0.0,
prev_close: 10.0, prev_close: 10.0,
volume: 1_000, volume: 1_000,
tick_volume: 1_000, minute_volume: 1_000,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -1312,7 +1312,7 @@ fn broker_cancels_buy_when_open_hits_upper_limit() {
ask1: 11.0, ask1: 11.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 50_000, bid1_volume: 50_000,
ask1_volume: 50_000, ask1_volume: 50_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1425,7 +1425,7 @@ fn broker_applies_price_ratio_slippage_on_snapshot_fills() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1525,7 +1525,7 @@ fn broker_applies_dynamic_slippage_on_snapshot_fills() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1630,7 +1630,7 @@ fn broker_applies_tick_size_slippage_on_intraday_last_fills() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1748,7 +1748,7 @@ fn broker_rejects_intraday_last_order_without_execution_quotes() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1855,7 +1855,7 @@ fn broker_executes_intraday_last_on_start_quote_without_trade_delta() {
ask1: 15.21, ask1: 15.21,
prev_close: 15.0, prev_close: 15.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -1971,7 +1971,7 @@ fn broker_cancels_market_order_remainder_when_intraday_quote_liquidity_exhausted
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2073,7 +2073,7 @@ fn broker_cancels_market_order_remainder_when_intraday_quote_liquidity_exhausted
} }
#[test] #[test]
fn broker_cancels_market_buy_when_tick_has_no_volume() { fn broker_cancels_market_buy_when_minute_has_no_volume() {
let date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap(); let date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap();
let data = DataSet::from_components( let data = DataSet::from_components(
vec![Instrument { vec![Instrument {
@@ -2099,7 +2099,7 @@ fn broker_cancels_market_buy_when_tick_has_no_volume() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 0, volume: 0,
tick_volume: 0, minute_volume: 0,
bid1_volume: 0, bid1_volume: 0,
ask1_volume: 0, ask1_volume: 0,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2203,7 +2203,7 @@ fn broker_splits_intraday_quote_fills_and_tracks_commission_by_order() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2364,7 +2364,7 @@ fn broker_aggregates_intraday_quote_fills_into_vwap_leg() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2509,7 +2509,7 @@ fn broker_executes_algo_vwap_value_with_time_window() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2667,7 +2667,7 @@ fn broker_executes_algo_twap_percent_across_window_quotes() {
ask1: 12.01, ask1: 12.01,
prev_close: 12.0, prev_close: 12.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2827,7 +2827,7 @@ fn broker_uses_best_own_price_for_intraday_matching() {
ask1: 10.02, ask1: 10.02,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -2942,7 +2942,7 @@ fn broker_uses_best_counterparty_price_for_intraday_matching() {
ask1: 10.02, ask1: 10.02,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3070,7 +3070,7 @@ fn rebalance_optimizer_skips_unfunded_buy_when_existing_position_cannot_sell() {
ask1: 9.81, ask1: 9.81,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3093,7 +3093,7 @@ fn rebalance_optimizer_skips_unfunded_buy_when_existing_position_cannot_sell() {
ask1: 10.11, ask1: 10.11,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3259,7 +3259,7 @@ fn rebalance_uses_prev_close_for_open_auction_valuation() {
ask1: 20.0, ask1: 20.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3282,7 +3282,7 @@ fn rebalance_uses_prev_close_for_open_auction_valuation() {
ask1: 10.0, ask1: 10.0,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 100_000, bid1_volume: 100_000,
ask1_volume: 100_000, ask1_volume: 100_000,
trading_phase: Some("open_auction".to_string()), trading_phase: Some("open_auction".to_string()),
@@ -3442,7 +3442,7 @@ fn rebalance_optimizer_prioritizes_higher_target_weight_when_cash_is_tight() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3465,7 +3465,7 @@ fn rebalance_optimizer_prioritizes_higher_target_weight_when_cash_is_tight() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3617,7 +3617,7 @@ fn broker_uses_board_specific_min_quantity_and_step_size_for_buy_sizing() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3716,7 +3716,7 @@ fn broker_allows_bjse_quantities_above_minimum_without_round_lot_step() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3817,7 +3817,7 @@ fn broker_allows_full_odd_lot_sell_when_liquidating_position() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 10_000, volume: 10_000,
tick_volume: 1_400, minute_volume: 1_400,
bid1_volume: 350, bid1_volume: 350,
ask1_volume: 10_000, ask1_volume: 10_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -3926,7 +3926,7 @@ fn same_day_sell_then_rebuy_reinserts_position_at_end() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -4063,7 +4063,7 @@ fn two_day_limit_order_data(day1_open: f64, day2_open: f64) -> DataSet {
ask1: day1_open + 0.01, ask1: day1_open + 0.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -4086,7 +4086,7 @@ fn two_day_limit_order_data(day1_open: f64, day2_open: f64) -> DataSet {
ask1: day2_open + 0.01, ask1: day2_open + 0.01,
prev_close: day1_open, prev_close: day1_open,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),
@@ -4510,7 +4510,7 @@ fn broker_reserves_sellable_quantity_for_open_limit_sells() {
ask1: 10.01, ask1: 10.01,
prev_close: 10.0, prev_close: 10.0,
volume: 100_000, volume: 100_000,
tick_volume: 100_000, minute_volume: 100_000,
bid1_volume: 80_000, bid1_volume: 80_000,
ask1_volume: 80_000, ask1_volume: 80_000,
trading_phase: Some("continuous".to_string()), trading_phase: Some("continuous".to_string()),