qs_backtest/strategy/
feedback.rs1use qs_core::types::FutureEffect;
4
5use crate::ledger::ActionDisposition;
6
7#[derive(Debug, Clone)]
9pub enum StrategyFeedbackEvent {
10 Effect {
11 action_id: Option<String>,
12 effect: FutureEffect,
13 },
14 Disposition(ActionDisposition),
15}
16
17impl StrategyFeedbackEvent {
18 pub fn action_id(&self) -> Option<&str> {
19 match self {
20 Self::Effect { action_id, .. } => action_id.as_deref(),
21 Self::Disposition(disposition) => Some(&disposition.action_id),
22 }
23 }
24
25 pub const fn effect(&self) -> Option<&FutureEffect> {
26 match self {
27 Self::Effect { effect, .. } => Some(effect),
28 Self::Disposition(_) => None,
29 }
30 }
31
32 pub const fn disposition(&self) -> Option<&ActionDisposition> {
33 match self {
34 Self::Effect { .. } => None,
35 Self::Disposition(disposition) => Some(disposition),
36 }
37 }
38}
39
40#[derive(Debug, Clone, Copy, Default)]
44pub struct StrategyFeedback<'a> {
45 effects: &'a [FutureEffect],
46 dispositions: &'a [ActionDisposition],
47 events: &'a [StrategyFeedbackEvent],
48}
49
50impl<'a> StrategyFeedback<'a> {
51 pub const fn new(effects: &'a [FutureEffect], dispositions: &'a [ActionDisposition]) -> Self {
52 Self {
53 effects,
54 dispositions,
55 events: &[],
56 }
57 }
58
59 pub(crate) const fn with_events(
60 effects: &'a [FutureEffect],
61 dispositions: &'a [ActionDisposition],
62 events: &'a [StrategyFeedbackEvent],
63 ) -> Self {
64 Self {
65 effects,
66 dispositions,
67 events,
68 }
69 }
70
71 pub const fn effects(self) -> &'a [FutureEffect] {
72 self.effects
73 }
74
75 pub const fn dispositions(self) -> &'a [ActionDisposition] {
76 self.dispositions
77 }
78
79 pub const fn events(self) -> &'a [StrategyFeedbackEvent] {
80 self.events
81 }
82
83 pub const fn is_empty(self) -> bool {
84 self.effects.is_empty() && self.dispositions.is_empty()
85 }
86}