bourse_de/agents/
random_agent.rs1use super::Agent;
2use crate::types::{OrderId, Price, Side, Status, TraderId, Vol};
3use crate::Env;
4use rand::seq::SliceRandom;
5use rand::Rng;
6use rand::RngCore;
7
8pub struct RandomAgents {
49 orders: Vec<Option<OrderId>>,
50 tick_range: (Price, Price),
51 vol_range: (Vol, Vol),
52 tick_size: Price,
53 activity_rate: f32,
54}
55
56impl RandomAgents {
57 pub fn new(
68 n_agents: usize,
69 tick_range: (Price, Price),
70 vol_range: (Vol, Vol),
71 tick_size: Price,
72 activity_rate: f32,
73 ) -> Self {
74 Self {
75 orders: vec![None; n_agents],
76 tick_range,
77 vol_range,
78 tick_size,
79 activity_rate,
80 }
81 }
82}
83
84impl Agent for RandomAgents {
85 fn update<R: RngCore>(&mut self, env: &mut Env, rng: &mut R) {
86 let new_orders: Vec<Option<OrderId>> = self
87 .orders
88 .iter_mut()
89 .enumerate()
90 .map(|(n, i)| {
91 let p = rng.gen::<f32>();
92
93 match p < self.activity_rate {
94 true => {
95 if (i.is_some()) && (env.order_status(i.unwrap()) == Status::Active) {
96 env.cancel_order(i.unwrap());
97 None
98 } else {
99 let side = [Side::Ask, Side::Bid].choose(rng).unwrap();
100 let tick = rng.gen_range(self.tick_range.0..self.tick_range.1);
101 let vol = rng.gen_range(self.vol_range.0..self.vol_range.1);
102 Some(
103 env.place_order(
104 *side,
105 vol,
106 TraderId::try_from(n).unwrap(),
107 Some(tick * self.tick_size),
108 )
109 .unwrap(),
110 )
111 }
112 }
113 false => *i,
114 }
115 })
116 .collect();
117
118 self.orders = new_orders;
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125 use bourse_book::types::Event;
126 use rand::SeedableRng;
127 use rand_xoshiro::Xoroshiro128StarStar;
128
129 #[test]
130 fn test_activity_rate() {
131 let mut env = Env::new(0, 1, 1000, true);
132 let mut rng = Xoroshiro128StarStar::seed_from_u64(101);
133
134 let mut agents = RandomAgents::new(2, (10, 20), (20, 30), 1, 0.0);
135
136 agents.update(&mut env, &mut rng);
137 assert!(env.get_transactions().len() == 0);
138
139 agents.activity_rate = 1.0;
140 agents.update(&mut env, &mut rng);
141 assert!(env.get_transactions().len() == 2);
142 }
143
144 #[test]
145 fn test_order_place_then_cancel() {
146 let mut env = Env::new(0, 1, 1000, true);
147 let mut rng = Xoroshiro128StarStar::seed_from_u64(101);
148
149 let mut agents = RandomAgents::new(1, (10, 20), (20, 30), 1, 1.0);
150
151 agents.update(&mut env, &mut rng);
152 assert!(env.get_transactions().len() == 1);
153 assert!(matches!(env.get_transactions()[0], Event::New { .. }));
154 assert!(agents.orders == vec![Some(0)]);
155
156 env.step(&mut rng);
157
158 agents.update(&mut env, &mut rng);
159 assert!(env.get_transactions().len() == 1);
160 assert!(matches!(
161 env.get_transactions()[0],
162 Event::Cancellation { .. }
163 ));
164
165 env.step(&mut rng);
166
167 agents.update(&mut env, &mut rng);
168 assert!(env.get_transactions().len() == 1);
169 assert!(matches!(env.get_transactions()[0], Event::New { .. }));
170 assert!(agents.orders == vec![Some(1)]);
171 }
172}