Expose process event context to strategy runtime

This commit is contained in:
boris
2026-04-23 05:12:07 -07:00
parent 4d43d1b176
commit 2857f72d84
8 changed files with 742 additions and 92 deletions

View File

@@ -70,6 +70,8 @@ pub struct StrategyContext<'a> {
pub data: &'a DataSet,
pub portfolio: &'a PortfolioState,
pub open_orders: &'a [OpenOrderView],
pub process_events: &'a [ProcessEvent],
pub active_process_event: Option<&'a ProcessEvent>,
}
impl StrategyContext<'_> {
@@ -154,6 +156,103 @@ impl StrategyContext<'_> {
pub fn available_sellable_qty(&self, symbol: &str, raw_sellable_qty: u32) -> u32 {
raw_sellable_qty.saturating_sub(self.symbol_open_sell_quantity(symbol))
}
pub fn has_process_events(&self) -> bool {
!self.process_events.is_empty() || self.active_process_event.is_some()
}
pub fn process_event_count(&self) -> usize {
self.process_events.len() + usize::from(self.active_process_event.is_some())
}
pub fn process_event_count_by_kind(&self, kind: crate::events::ProcessEventKind) -> usize {
self.process_events
.iter()
.filter(|event| event.kind == kind)
.count()
+ usize::from(
self.active_process_event
.is_some_and(|event| event.kind == kind),
)
}
pub fn latest_process_event(&self) -> Option<&ProcessEvent> {
self.active_process_event
.or_else(|| self.process_events.last())
}
pub fn latest_process_event_kind(&self) -> &'static str {
self.latest_process_event()
.map(|event| event.kind.as_str())
.unwrap_or("")
}
pub fn latest_process_event_order_id(&self) -> u64 {
self.latest_process_event()
.and_then(|event| event.order_id)
.unwrap_or(0)
}
pub fn latest_process_event_symbol(&self) -> &str {
self.latest_process_event()
.and_then(|event| event.symbol.as_deref())
.unwrap_or("")
}
pub fn latest_process_event_side(&self) -> &'static str {
self.latest_process_event()
.and_then(|event| event.side.as_ref())
.map(OrderSide::as_str)
.unwrap_or("")
}
pub fn latest_process_event_detail(&self) -> &str {
self.latest_process_event()
.map(|event| event.detail.as_str())
.unwrap_or("")
}
pub fn current_process_event_kind(&self) -> &'static str {
self.active_process_event
.map(|event| event.kind.as_str())
.unwrap_or("")
}
pub fn current_process_event_order_id(&self) -> u64 {
self.active_process_event
.and_then(|event| event.order_id)
.unwrap_or(0)
}
pub fn current_process_event_symbol(&self) -> &str {
self.active_process_event
.and_then(|event| event.symbol.as_deref())
.unwrap_or("")
}
pub fn current_process_event_side(&self) -> &'static str {
self.active_process_event
.and_then(|event| event.side.as_ref())
.map(OrderSide::as_str)
.unwrap_or("")
}
pub fn current_process_event_detail(&self) -> &str {
self.active_process_event
.map(|event| event.detail.as_str())
.unwrap_or("")
}
pub fn process_event_counts(&self) -> BTreeMap<String, i64> {
let mut counts = BTreeMap::<String, i64>::new();
for event in self.process_events {
*counts.entry(event.kind.as_str().to_string()).or_insert(0) += 1;
}
if let Some(event) = self.active_process_event {
*counts.entry(event.kind.as_str().to_string()).or_insert(0) += 1;
}
counts
}
}
#[derive(Debug, Clone, Default)]