修正FIDC选股阶段风控语义
This commit is contained in:
@@ -50,20 +50,15 @@ pub struct SelectionContext<'a> {
|
||||
pub data: &'a DataSet,
|
||||
pub dynamic_universe: Option<&'a BTreeSet<String>>,
|
||||
pub risk_config: Option<&'a FidcRiskControlConfig>,
|
||||
pub defer_selection_risk: bool,
|
||||
}
|
||||
|
||||
impl SelectionContext<'_> {
|
||||
fn eligible_universe(&self) -> Vec<EligibleUniverseSnapshot> {
|
||||
let eligible = if self.defer_selection_risk {
|
||||
self.data.fundamental_universe_on(self.decision_date)
|
||||
} else {
|
||||
match self.risk_config {
|
||||
Some(risk_config) => self
|
||||
.data
|
||||
.eligible_universe_on_with_risk_config(self.decision_date, risk_config),
|
||||
None => self.data.eligible_universe_on(self.decision_date).to_vec(),
|
||||
}
|
||||
let eligible = match self.risk_config {
|
||||
Some(risk_config) => self
|
||||
.data
|
||||
.eligible_universe_on_with_risk_config(self.decision_date, risk_config),
|
||||
None => self.data.eligible_universe_on(self.decision_date).to_vec(),
|
||||
};
|
||||
match self.dynamic_universe {
|
||||
Some(symbols) if !symbols.is_empty() => eligible
|
||||
@@ -75,9 +70,6 @@ impl SelectionContext<'_> {
|
||||
}
|
||||
|
||||
fn selection_risk_decisions(&self) -> Vec<FidcRiskDecisionAudit> {
|
||||
if self.defer_selection_risk {
|
||||
return Vec::new();
|
||||
}
|
||||
let default_risk_config;
|
||||
let risk_config = match self.risk_config {
|
||||
Some(value) => value,
|
||||
@@ -411,7 +403,6 @@ mod tests {
|
||||
data: &data,
|
||||
dynamic_universe: None,
|
||||
risk_config: Some(&FidcRiskControlConfig::default()),
|
||||
defer_selection_risk: false,
|
||||
});
|
||||
|
||||
let rules = diagnostics
|
||||
@@ -433,7 +424,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selector_defers_static_execution_risk_for_lagged_execution() {
|
||||
fn selector_applies_configured_selection_risk_on_decision_date() {
|
||||
let data = DataSet::from_components(
|
||||
vec![
|
||||
instrument("000001.SZ"),
|
||||
@@ -466,17 +457,22 @@ mod tests {
|
||||
data: &data,
|
||||
dynamic_universe: None,
|
||||
risk_config: Some(&FidcRiskControlConfig::default()),
|
||||
defer_selection_risk: true,
|
||||
});
|
||||
|
||||
let selected_symbols = selected
|
||||
.iter()
|
||||
.map(|candidate| candidate.symbol.as_str())
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert!(selected_symbols.contains("000001.SZ"));
|
||||
assert!(selected_symbols.contains("688001.SH"));
|
||||
assert!(!selected_symbols.contains("000001.SZ"));
|
||||
assert!(!selected_symbols.contains("688001.SH"));
|
||||
assert!(selected_symbols.contains("000002.SZ"));
|
||||
assert_eq!(diagnostics.not_eligible_count, 0);
|
||||
assert!(diagnostics.risk_decisions.is_empty());
|
||||
assert_eq!(diagnostics.not_eligible_count, 2);
|
||||
let rules = diagnostics
|
||||
.risk_decisions
|
||||
.iter()
|
||||
.map(|decision| decision.rule_code.as_str())
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert!(rules.contains("st"), "{:?}", diagnostics.risk_decisions);
|
||||
assert!(rules.contains("kcb"), "{:?}", diagnostics.risk_decisions);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user