engine/strategies/
external.rs1use super::Strategy;
3use crate::types::{Observation, OrderRequest};
4
5pub struct ExternalStrategy {
17 last_observation: Option<Observation>,
18 pending_requests: Vec<OrderRequest>,
19}
20
21impl Default for ExternalStrategy {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl ExternalStrategy {
28 pub fn new() -> Self {
29 Self {
30 last_observation: None,
31 pending_requests: Vec::new(),
32 }
33 }
34
35 pub fn last_observation(&self) -> Option<&Observation> {
37 self.last_observation.as_ref()
38 }
39
40 pub fn set_pending_requests(&mut self, requests: Vec<OrderRequest>) {
42 self.pending_requests = requests;
43 }
44}
45
46impl Strategy for ExternalStrategy {
47 fn on_tick(&mut self, obs: &Observation, requests: &mut Vec<OrderRequest>) {
48 self.last_observation = Some(obs.clone());
49 requests.append(&mut self.pending_requests);
50 }
51
52 fn as_any(&self) -> &dyn std::any::Any {
53 self
54 }
55 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
56 self
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use crate::types::{Order, PortfolioSnapshot, Side};
64
65 fn sample_obs() -> Observation {
66 Observation {
67 timestamp: 0.0,
68 best_bid: 99.0,
69 best_ask: 101.0,
70 last_price: Some(100.0),
71 portfolio: PortfolioSnapshot {
72 cash: 10000.0,
73 position: 0.0,
74 },
75 volatility: Some(0.2),
76 drift: None,
77 parameters: None,
78 }
79 }
80
81 #[test]
82 fn test_captures_observation() {
83 let mut strat = ExternalStrategy::new();
84 assert!(strat.last_observation().is_none());
85
86 let obs = sample_obs();
87 let mut buf = Vec::new();
88 strat.on_tick(&obs, &mut buf);
89
90 assert!(strat.last_observation().is_some());
91 assert!(buf.is_empty());
92 }
93
94 #[test]
95 fn test_drains_pending_requests() {
96 let mut strat = ExternalStrategy::new();
97 strat.set_pending_requests(vec![
98 OrderRequest::CancelAll,
99 OrderRequest::New(Order::new(1, Side::Buy, 99.5, 1.0)),
100 ]);
101
102 let obs = sample_obs();
103 let mut buf = Vec::new();
104 strat.on_tick(&obs, &mut buf);
105
106 assert_eq!(buf.len(), 2);
107 let mut buf2 = Vec::new();
109 strat.on_tick(&obs, &mut buf2);
110 assert!(buf2.is_empty());
111 }
112}