From f8bc0679ee07111c842d74cbffc8762a52021e80 Mon Sep 17 00:00:00 2001 From: boris Date: Sat, 20 Jun 2026 23:07:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3FiRisk=E5=BC=BA=E5=B9=B3?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E6=9D=A5=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/broker.rs | 2 + crates/fidc-core/src/data.rs | 10 ++ .../fidc-core/src/platform_expr_strategy.rs | 102 +++++++++++++++++- crates/fidc-core/src/portfolio.rs | 2 + crates/fidc-core/src/risk_control.rs | 1 + crates/fidc-core/tests/core_rules.rs | 1 + crates/fidc-core/tests/corporate_actions.rs | 3 + .../fidc-core/tests/decision_quote_preload.rs | 4 + crates/fidc-core/tests/delisting.rs | 6 ++ crates/fidc-core/tests/engine_hooks.rs | 22 ++++ crates/fidc-core/tests/explicit_order_flow.rs | 38 +++++++ 11 files changed, 189 insertions(+), 2 deletions(-) diff --git a/crates/fidc-core/src/broker.rs b/crates/fidc-core/src/broker.rs index 5ddb2da..1e3c41f 100644 --- a/crates/fidc-core/src/broker.rs +++ b/crates/fidc-core/src/broker.rs @@ -5458,6 +5458,7 @@ mod tests { allow_sell, is_kcb: false, is_one_yuan: false, + risk_level_code: None, } } @@ -5706,6 +5707,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index f2ef76d..1f0f9ce 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -208,6 +208,8 @@ pub struct CandidateEligibility { pub allow_sell: bool, pub is_kcb: bool, pub is_one_yuan: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub risk_level_code: Option, } impl CandidateEligibility { @@ -3126,6 +3128,13 @@ fn read_candidates(path: &Path) -> Result, DataSetErro allow_sell: row.parse_bool(6)?, is_kcb: row.parse_optional_bool(7).unwrap_or(false), is_one_yuan: row.parse_optional_bool(8).unwrap_or(false), + risk_level_code: row + .fields + .get(9) + .map(String::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), }); } Ok(snapshots) @@ -3954,6 +3963,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }; let data = DataSet::from_components( vec![instrument("000001.SZ"), instrument("000002.SZ")], diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 92b9836..f746320 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -5956,7 +5956,15 @@ impl PlatformExprStrategy { let Ok(candidate) = ctx.data.require_candidate(date, symbol) else { return Ok(false); }; - if candidate.allow_buy || !candidate.allow_sell || candidate.is_paused { + let Some(_risk_level_code) = candidate + .risk_level_code + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + else { + return Ok(false); + }; + if !candidate.allow_sell || candidate.is_paused { return Ok(false); } if !self.can_sell_position(ctx, date, symbol) { @@ -7860,6 +7868,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8000,6 +8009,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8145,6 +8155,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8240,6 +8251,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8352,6 +8364,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8469,6 +8482,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -8619,6 +8633,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: second_date, @@ -8630,6 +8645,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -8900,6 +8916,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -8911,6 +8928,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -9189,6 +9207,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -9200,6 +9219,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -9418,6 +9438,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: second_date, @@ -9429,6 +9450,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -9626,6 +9648,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -9743,6 +9766,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -9880,6 +9904,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -9985,6 +10010,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -10118,6 +10144,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -10219,6 +10246,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -10348,6 +10376,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -10481,6 +10510,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], benchmark_rows, ) @@ -10588,6 +10618,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date: current, @@ -10699,6 +10730,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -10812,6 +10844,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -10868,7 +10901,7 @@ mod tests { } #[test] - fn platform_aiquant_firisk_buy_disabled_forces_existing_position_exit() { + fn platform_aiquant_firisk_risk_level_forces_existing_position_exit() { let date = d(2023, 5, 5); let symbol = "300621.SZ"; let data = DataSet::from_components( @@ -10924,6 +10957,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: Some("A".to_string()), }], vec![BenchmarkSnapshot { date, @@ -11067,6 +11101,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -11221,6 +11256,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -11374,6 +11410,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -11527,6 +11564,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -11693,6 +11731,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -11850,6 +11889,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), [first_date, second_date] @@ -11997,6 +12037,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -12135,6 +12176,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -12254,6 +12296,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -12403,6 +12446,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -12499,6 +12543,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -12721,6 +12766,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) }) .collect(), @@ -12911,6 +12957,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13009,6 +13056,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13123,6 +13171,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13224,6 +13273,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13405,6 +13455,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13613,6 +13664,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13781,6 +13833,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -13922,6 +13975,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -14080,6 +14134,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: execution_date, @@ -14091,6 +14146,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -14233,6 +14289,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -14244,6 +14301,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -14363,6 +14421,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect::>(); let benchmark_rows = dates @@ -14505,6 +14564,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect::>(); let benchmark_rows = dates @@ -14652,6 +14712,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -14786,6 +14847,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -14921,6 +14983,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15077,6 +15140,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15211,6 +15275,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15367,6 +15432,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15526,6 +15592,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15674,6 +15741,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -15847,6 +15915,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) }) .collect(), @@ -16084,6 +16153,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) }) .collect(), @@ -16243,6 +16313,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -16387,6 +16458,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -16567,6 +16639,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -16744,6 +16817,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -16965,6 +17039,7 @@ mod tests { allow_sell: *symbol != "000001.SZ", is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -17114,6 +17189,7 @@ mod tests { allow_sell: *symbol != "000001.SZ", is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -17265,6 +17341,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -17484,6 +17561,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -17628,6 +17706,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -17766,6 +17845,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -17901,6 +17981,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { @@ -18029,6 +18110,7 @@ mod tests { allow_sell: false, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -18130,6 +18212,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -18282,6 +18365,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) }) .collect(), @@ -18453,6 +18537,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) }) .collect(), @@ -18601,6 +18686,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -18731,6 +18817,7 @@ mod tests { allow_buy: true, allow_sell: true, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -18850,6 +18937,7 @@ mod tests { allow_buy: true, allow_sell: true, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19303,6 +19391,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19426,6 +19515,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19540,6 +19630,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19662,6 +19753,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19802,6 +19894,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -19929,6 +20022,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -20051,6 +20145,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -20167,6 +20262,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -20305,6 +20401,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), dates @@ -20488,6 +20585,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect(), vec![BenchmarkSnapshot { diff --git a/crates/fidc-core/src/portfolio.rs b/crates/fidc-core/src/portfolio.rs index 1616adc..b6b58c0 100644 --- a/crates/fidc-core/src/portfolio.rs +++ b/crates/fidc-core/src/portfolio.rs @@ -1086,6 +1086,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1172,6 +1173,7 @@ mod tests { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, diff --git a/crates/fidc-core/src/risk_control.rs b/crates/fidc-core/src/risk_control.rs index 2855ac8..6b8ffbf 100644 --- a/crates/fidc-core/src/risk_control.rs +++ b/crates/fidc-core/src/risk_control.rs @@ -155,6 +155,7 @@ mod tests { allow_sell: false, is_kcb: false, is_one_yuan: false, + risk_level_code: None, } } diff --git a/crates/fidc-core/tests/core_rules.rs b/crates/fidc-core/tests/core_rules.rs index 91001a3..7233015 100644 --- a/crates/fidc-core/tests/core_rules.rs +++ b/crates/fidc-core/tests/core_rules.rs @@ -23,6 +23,7 @@ fn candidate() -> CandidateEligibility { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, } } diff --git a/crates/fidc-core/tests/corporate_actions.rs b/crates/fidc-core/tests/corporate_actions.rs index cdbf584..4175101 100644 --- a/crates/fidc-core/tests/corporate_actions.rs +++ b/crates/fidc-core/tests/corporate_actions.rs @@ -221,6 +221,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: ex_date, @@ -232,6 +233,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: payable_date, @@ -243,6 +245,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ diff --git a/crates/fidc-core/tests/decision_quote_preload.rs b/crates/fidc-core/tests/decision_quote_preload.rs index 7674ddf..646526c 100644 --- a/crates/fidc-core/tests/decision_quote_preload.rs +++ b/crates/fidc-core/tests/decision_quote_preload.rs @@ -149,6 +149,7 @@ fn engine_preloads_declared_decision_quotes_for_current_positions() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: second, @@ -160,6 +161,7 @@ fn engine_preloads_declared_decision_quotes_for_current_positions() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -361,6 +363,7 @@ fn engine_loads_distinct_decision_quote_times_on_same_day() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: second, @@ -372,6 +375,7 @@ fn engine_loads_distinct_decision_quote_times_on_same_day() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ diff --git a/crates/fidc-core/tests/delisting.rs b/crates/fidc-core/tests/delisting.rs index 71cb71b..c1caf84 100644 --- a/crates/fidc-core/tests/delisting.rs +++ b/crates/fidc-core/tests/delisting.rs @@ -180,6 +180,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run() allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date1, @@ -191,6 +192,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run() allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -202,6 +204,7 @@ fn engine_settles_delisted_position_before_missing_market_snapshot_breaks_run() allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -400,6 +403,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date1, @@ -411,6 +415,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -422,6 +427,7 @@ fn engine_applies_successor_conversion_before_delisted_cash_settlement() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ diff --git a/crates/fidc-core/tests/engine_hooks.rs b/crates/fidc-core/tests/engine_hooks.rs index 177eb62..5f92ced 100644 --- a/crates/fidc-core/tests/engine_hooks.rs +++ b/crates/fidc-core/tests/engine_hooks.rs @@ -87,6 +87,7 @@ fn single_day_anchor_data(date: NaiveDate) -> DataSet { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -154,6 +155,7 @@ fn candidate_row(date: NaiveDate, symbol: &str) -> CandidateEligibility { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, } } @@ -1116,6 +1118,7 @@ fn engine_runs_strategy_hooks_in_daily_order() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -1127,6 +1130,7 @@ fn engine_runs_strategy_hooks_in_daily_order() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -1273,6 +1277,7 @@ fn engine_executes_open_auction_decisions_before_on_day() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1371,6 +1376,7 @@ fn engine_executes_futures_order_intents_against_future_account() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1960,6 +1966,7 @@ fn engine_runs_subscribed_tick_hooks_and_executes_tick_orders() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2143,6 +2150,7 @@ fn strategy_context_exposes_engine_native_data_helpers() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect::>(); let benchmarks = [ @@ -2302,6 +2310,7 @@ fn strategy_context_exposes_final_order_runtime_view() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2555,6 +2564,7 @@ fn engine_applies_account_cash_flow_and_financing_intents() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -2566,6 +2576,7 @@ fn engine_applies_account_cash_flow_and_financing_intents() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -2737,6 +2748,7 @@ fn engine_rejects_pending_limit_orders_at_market_close() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -2748,6 +2760,7 @@ fn engine_rejects_pending_limit_orders_at_market_close() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -2938,6 +2951,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -2949,6 +2963,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date3, @@ -2960,6 +2975,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -3184,6 +3200,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date2, @@ -3195,6 +3212,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: date3, @@ -3206,6 +3224,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -3538,6 +3557,7 @@ fn engine_applies_dynamic_universe_and_subscription_directives() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: *date, @@ -3549,6 +3569,7 @@ fn engine_applies_dynamic_universe_and_subscription_directives() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ] }) @@ -3671,6 +3692,7 @@ fn engine_exposes_current_process_context_to_strategies() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, diff --git a/crates/fidc-core/tests/explicit_order_flow.rs b/crates/fidc-core/tests/explicit_order_flow.rs index d55ea4a..7bbdd94 100644 --- a/crates/fidc-core/tests/explicit_order_flow.rs +++ b/crates/fidc-core/tests/explicit_order_flow.rs @@ -61,6 +61,7 @@ fn order_value_rounding_data(date: NaiveDate, symbol: &str, price: f64) -> DataS allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -165,6 +166,7 @@ fn broker_executes_explicit_order_value_buy() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -314,6 +316,7 @@ fn broker_delayed_limit_open_sell_uses_tick_price() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -445,6 +448,7 @@ fn broker_executes_order_shares_and_order_lots() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -570,6 +574,7 @@ fn broker_executes_target_shares_like_order_to() { allow_buy: true, allow_sell: true, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -726,6 +731,7 @@ fn broker_executes_target_portfolio_smart_with_custom_prices() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -737,6 +743,7 @@ fn broker_executes_target_portfolio_smart_with_custom_prices() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -867,6 +874,7 @@ fn broker_executes_target_portfolio_smart_with_algo_order_style() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1007,6 +1015,7 @@ fn broker_executes_order_percent_and_target_percent() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1127,6 +1136,7 @@ fn broker_uses_day_open_price_for_open_auction_matching() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1230,6 +1240,7 @@ fn broker_open_auction_uses_auction_volume_without_quote_liquidity() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1330,6 +1341,7 @@ fn broker_cancels_buy_when_open_hits_upper_limit() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1442,6 +1454,7 @@ fn broker_applies_price_ratio_slippage_on_snapshot_fills() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1541,6 +1554,7 @@ fn broker_applies_dynamic_slippage_on_snapshot_fills() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1645,6 +1659,7 @@ fn broker_applies_tick_size_slippage_on_intraday_last_fills() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1762,6 +1777,7 @@ fn broker_rejects_intraday_last_order_without_execution_quotes() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1868,6 +1884,7 @@ fn broker_executes_intraday_last_on_start_quote_without_trade_delta() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -1983,6 +2000,7 @@ fn broker_cancels_market_order_remainder_when_intraday_quote_liquidity_exhausted allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2110,6 +2128,7 @@ fn broker_cancels_market_buy_when_tick_has_no_volume() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2213,6 +2232,7 @@ fn broker_splits_intraday_quote_fills_and_tracks_commission_by_order() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2373,6 +2393,7 @@ fn broker_aggregates_intraday_quote_fills_into_vwap_leg() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2517,6 +2538,7 @@ fn broker_executes_algo_vwap_value_with_time_window() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2674,6 +2696,7 @@ fn broker_executes_algo_twap_percent_across_window_quotes() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2833,6 +2856,7 @@ fn broker_uses_best_own_price_for_intraday_matching() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -2947,6 +2971,7 @@ fn broker_uses_best_counterparty_price_for_intraday_matching() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -3111,6 +3136,7 @@ fn rebalance_optimizer_skips_unfunded_buy_when_existing_position_cannot_sell() { allow_sell: false, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -3122,6 +3148,7 @@ fn rebalance_optimizer_skips_unfunded_buy_when_existing_position_cannot_sell() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -3298,6 +3325,7 @@ fn rebalance_uses_prev_close_for_open_auction_valuation() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -3309,6 +3337,7 @@ fn rebalance_uses_prev_close_for_open_auction_valuation() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -3479,6 +3508,7 @@ fn rebalance_optimizer_prioritizes_higher_target_weight_when_cash_is_tight() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date, @@ -3490,6 +3520,7 @@ fn rebalance_optimizer_prioritizes_higher_target_weight_when_cash_is_tight() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![BenchmarkSnapshot { @@ -3615,6 +3646,7 @@ fn broker_uses_board_specific_min_quantity_and_step_size_for_buy_sizing() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -3713,6 +3745,7 @@ fn broker_allows_bjse_quantities_above_minimum_without_round_lot_step() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -3813,6 +3846,7 @@ fn broker_allows_full_odd_lot_sell_when_liquidating_position() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date, @@ -3927,6 +3961,7 @@ fn same_day_sell_then_rebuy_reinserts_position_at_end() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }) .collect::>(); let data = DataSet::from_components( @@ -4094,6 +4129,7 @@ fn two_day_limit_order_data(day1_open: f64, day2_open: f64) -> DataSet { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, CandidateEligibility { date: day2, @@ -4105,6 +4141,7 @@ fn two_day_limit_order_data(day1_open: f64, day2_open: f64) -> DataSet { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }, ], vec![ @@ -4502,6 +4539,7 @@ fn broker_reserves_sellable_quantity_for_open_limit_sells() { allow_sell: true, is_kcb: false, is_one_yuan: false, + risk_level_code: None, }], vec![BenchmarkSnapshot { date,