Carry structured annual finance news emissions

This commit is contained in:
Jan Petykiewicz 2026-04-18 05:45:42 -07:00
commit b4e23838bf
2 changed files with 167 additions and 46 deletions

View file

@ -124,7 +124,10 @@ pub use smp::{
inspect_save_company_and_chairman_analysis_file, inspect_smp_bytes, inspect_smp_file,
load_save_slice_file, load_save_slice_from_report,
};
pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command};
pub use step::{
AnnualFinanceNewsEvent, BoundaryEvent, ServiceEvent, StepCommand, StepResult,
execute_step_command,
};
pub use summary::RuntimeSummary;
pub use win::{
WinAnonymousSelectorRecord, WinHeaderWord, WinInspectionReport, WinReferenceDeltaFrequency,

View file

@ -59,6 +59,17 @@ pub struct BoundaryEvent {
pub calendar: crate::CalendarPoint,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AnnualFinanceNewsEvent {
pub company_id: u32,
pub selector_label: String,
pub action_label: String,
pub retired_principal_total: u64,
pub issued_principal_total: u64,
pub repurchased_share_count: u64,
pub issued_share_count: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ServiceEvent {
pub kind: String,
@ -73,6 +84,8 @@ pub struct ServiceEvent {
pub removed_record_ids: Vec<u32>,
#[serde(default)]
pub finance_news_family_candidates: BTreeMap<u32, String>,
#[serde(default)]
pub annual_finance_news_events: Vec<AnnualFinanceNewsEvent>,
pub dirty_rerun: bool,
}
@ -516,6 +529,7 @@ fn service_company_annual_finance_policy(
let mut mutated_company_ids = BTreeSet::new();
let mut applied_effect_count = 0u32;
let mut finance_news_family_candidates = BTreeMap::new();
let mut annual_finance_news_events = Vec::new();
for company_id in active_company_ids {
let Some(policy_state) = runtime_company_annual_finance_policy_state(state, company_id)
@ -579,6 +593,27 @@ fn service_company_annual_finance_policy(
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
finance_news_family_candidates.insert(company_id, label.to_string());
annual_finance_news_events.push(AnnualFinanceNewsEvent {
company_id,
selector_label: label.to_string(),
action_label:
crate::runtime::runtime_company_annual_finance_policy_action_label(
policy_state.action,
)
.to_string(),
retired_principal_total: state
.service_state
.annual_bond_last_retired_principal_total,
issued_principal_total: state
.service_state
.annual_bond_last_issued_principal_total,
repurchased_share_count: state
.service_state
.annual_stock_repurchase_last_share_count,
issued_share_count: state
.service_state
.annual_stock_issue_last_share_count,
});
}
applied_effect_count += 1;
mutated_company_ids.insert(company_id);
@ -664,6 +699,27 @@ fn service_company_annual_finance_policy(
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
finance_news_family_candidates.insert(company_id, label.to_string());
annual_finance_news_events.push(AnnualFinanceNewsEvent {
company_id,
selector_label: label.to_string(),
action_label:
crate::runtime::runtime_company_annual_finance_policy_action_label(
policy_state.action,
)
.to_string(),
retired_principal_total: state
.service_state
.annual_bond_last_retired_principal_total,
issued_principal_total: state
.service_state
.annual_bond_last_issued_principal_total,
repurchased_share_count: state
.service_state
.annual_stock_repurchase_last_share_count,
issued_share_count: state
.service_state
.annual_stock_issue_last_share_count,
});
}
applied_effect_count += 1;
mutated_company_ids.insert(company_id);
@ -824,6 +880,27 @@ fn service_company_annual_finance_policy(
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
finance_news_family_candidates.insert(company_id, label.to_string());
annual_finance_news_events.push(AnnualFinanceNewsEvent {
company_id,
selector_label: label.to_string(),
action_label:
crate::runtime::runtime_company_annual_finance_policy_action_label(
policy_state.action,
)
.to_string(),
retired_principal_total: state
.service_state
.annual_bond_last_retired_principal_total,
issued_principal_total: state
.service_state
.annual_bond_last_issued_principal_total,
repurchased_share_count: state
.service_state
.annual_stock_repurchase_last_share_count,
issued_share_count: state
.service_state
.annual_stock_issue_last_share_count,
});
}
applied_effect_count += 1;
mutated_company_ids.insert(company_id);
@ -914,6 +991,27 @@ fn service_company_annual_finance_policy(
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
finance_news_family_candidates.insert(company_id, label.to_string());
annual_finance_news_events.push(AnnualFinanceNewsEvent {
company_id,
selector_label: label.to_string(),
action_label:
crate::runtime::runtime_company_annual_finance_policy_action_label(
policy_state.action,
)
.to_string(),
retired_principal_total: state
.service_state
.annual_bond_last_retired_principal_total,
issued_principal_total: state
.service_state
.annual_bond_last_issued_principal_total,
repurchased_share_count: state
.service_state
.annual_stock_repurchase_last_share_count,
issued_share_count: state
.service_state
.annual_stock_issue_last_share_count,
});
}
applied_effect_count += 1;
mutated_company_ids.insert(company_id);
@ -935,6 +1033,7 @@ fn service_company_annual_finance_policy(
deactivated_record_ids: Vec::new(),
removed_record_ids: Vec::new(),
finance_news_family_candidates,
annual_finance_news_events,
dirty_rerun: false,
});
@ -1040,6 +1139,7 @@ fn service_trigger_kind(
deactivated_record_ids,
removed_record_ids,
finance_news_family_candidates: BTreeMap::new(),
annual_finance_news_events: Vec::new(),
dirty_rerun,
});
@ -3013,15 +3113,18 @@ mod tests {
state.service_state.company_market_state[&22].current_issue_calendar_word_2,
0x0001_0001
);
assert!(
result
.service_events
.iter()
.any(|event| event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![22]
&& event.finance_news_family_candidates.get(&22) == Some(&"4053".to_string()))
);
assert!(result.service_events.iter().any(|event| {
event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![22]
&& event.finance_news_family_candidates.get(&22) == Some(&"4053".to_string())
&& event.annual_finance_news_events.iter().any(|news| {
news.company_id == 22
&& news.selector_label == "4053"
&& news.action_label == "stock_issue"
&& news.issued_share_count == 4_000
})
}));
}
#[test]
@ -3173,15 +3276,18 @@ mod tests {
state.service_state.company_market_state[&23].outstanding_shares,
9_000
);
assert!(
result
.service_events
.iter()
.any(|event| event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![23]
&& event.finance_news_family_candidates.get(&23) == Some(&"2887".to_string()))
);
assert!(result.service_events.iter().any(|event| {
event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![23]
&& event.finance_news_family_candidates.get(&23) == Some(&"2887".to_string())
&& event.annual_finance_news_events.iter().any(|news| {
news.company_id == 23
&& news.selector_label == "2887"
&& news.action_label == "stock_repurchase"
&& news.repurchased_share_count == 1_000
})
}));
}
#[test]
@ -3317,15 +3423,19 @@ mod tests {
coupon_rate_raw_u32: 0.09f32.to_bits(),
}]
);
assert!(
result
.service_events
.iter()
.any(|event| event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![24]
&& event.finance_news_family_candidates.get(&24) == Some(&"2886".to_string()))
);
assert!(result.service_events.iter().any(|event| {
event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![24]
&& event.finance_news_family_candidates.get(&24) == Some(&"2886".to_string())
&& event.annual_finance_news_events.iter().any(|news| {
news.company_id == 24
&& news.selector_label == "2886"
&& news.action_label == "bond_issue"
&& news.retired_principal_total == 0
&& news.issued_principal_total == 500_000
})
}));
}
#[test]
@ -3479,15 +3589,19 @@ mod tests {
state.service_state.company_market_state[&25].highest_coupon_live_bond_principal,
None
);
assert!(
result
.service_events
.iter()
.any(|event| event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![25]
&& event.finance_news_family_candidates.get(&25) == Some(&"2885".to_string()))
);
assert!(result.service_events.iter().any(|event| {
event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![25]
&& event.finance_news_family_candidates.get(&25) == Some(&"2885".to_string())
&& event.annual_finance_news_events.iter().any(|news| {
news.company_id == 25
&& news.selector_label == "2885"
&& news.action_label == "bond_issue"
&& news.retired_principal_total == 350_000
&& news.issued_principal_total == 0
})
}));
}
#[test]
@ -3654,15 +3768,19 @@ mod tests {
},
]
);
assert!(
result
.service_events
.iter()
.any(|event| event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![26]
&& event.finance_news_family_candidates.get(&26) == Some(&"2883".to_string()))
);
assert!(result.service_events.iter().any(|event| {
event.kind == "annual_finance_policy"
&& event.applied_effect_count == 1
&& event.mutated_company_ids == vec![26]
&& event.finance_news_family_candidates.get(&26) == Some(&"2883".to_string())
&& event.annual_finance_news_events.iter().any(|news| {
news.company_id == 26
&& news.selector_label == "2883"
&& news.action_label == "bond_issue"
&& news.retired_principal_total == 350_000
&& news.issued_principal_total == 1_000_000
})
}));
}
#[test]