bourse_de/
lib.rs

1//! Discrete event market simulation library
2//!
3//! Implements a discrete event simulation
4//! environment ([Env]) and utilities for writing
5//! discrete event market simulations.
6//!
7//! # Model
8//!
9//! In the discrete event model the state of
10//! the market is updated in fixed size
11//! time-steps. Inside each step agents can
12//! submit updates/instructions to the
13//! the simulated market, which are then processed
14//! at the end of the step.
15//!
16//! Each simulation update performs the following
17//! steps:
18//!
19//! - Iterate over all the agents, updating their
20//!   state, and market instructions submitted to
21//!   a queue.
22//! - The instructions are randomly shuffled, and
23//!   then processed in sequence, updating the state
24//!   of the market.
25//! - Record the state of the market.
26//!
27//! Hence agents can only observe the state of the
28//! market at the end of the previous step when
29//! updating, and have no guarantee of the ordering
30//! of transactions.
31//!
32//! See [bourse_book] for details of the limit
33//! order-book used in this environment.
34//!
35//! # Examples
36//!
37//! ```
38//! use bourse_de::types::{Price, Side, Vol};
39//! use bourse_de::agents;
40//! use bourse_de::agents::Agent;
41//! use bourse_de::{sim_runner, Env};
42//! use rand::{RngCore, Rng};
43//!
44//! // Define a set of agents using built
45//! // in definitions
46//! #[derive(agents::Agents)]
47//! struct SimAgents {
48//!     pub a: agents::MomentumAgent,
49//!     pub b: agents::NoiseAgent,
50//! }
51//!
52//! // Initialise agent parameters
53//! let m_params = agents::MomentumParams {
54//!     tick_size: 2,
55//!     p_cancel: 0.1,
56//!     trade_vol: 100,
57//!     decay: 1.0,
58//!     demand: 5.0,
59//!     scale: 0.5,
60//!     order_ratio: 1.0,
61//!     price_dist_mu: 0.0,
62//!     price_dist_sigma: 10.0,
63//! };
64//!
65//! let n_params = agents::NoiseAgentParams{
66//!     tick_size: 2,
67//!     p_limit: 0.2,
68//!     p_market: 0.2,
69//!     p_cancel: 0.1,
70//!     trade_vol: 100,
71//!     price_dist_mu: 0.0,
72//!     price_dist_sigma: 1.0,
73//! };
74//!
75//! let mut agents = SimAgents {
76//!     a: agents::MomentumAgent::new(0, 10, m_params),
77//!     b: agents::NoiseAgent::new(10, 20, n_params),
78//! };
79//!
80//! // Initialise the environment and agents
81//! let mut env = Env::new(0, 1, 1_000_000, true);
82//!
83//! // Run the simulation
84//! sim_runner(&mut env, &mut agents, 101, 50, true);
85//!
86//! // Get history of level 2 data over the course of the simulation
87//! let data = env.level_2_data();
88//! ```
89//!
90//! # Implementing Your Own Agents
91//!
92//! For use in [sim_runner] simulation agents should implement the [agents::AgentSet]
93//! trait. For a set of homogeneous agents (i.e. all the agents are the
94//! same type) this can be implemented directly.
95//!
96//! For a mixture of agent types, the [agents::Agents] macro can be used
97//! to automatically implement [agents::AgentSet] for a struct of agents
98//! all implementing [agents::Agent]. For examples
99//!
100//! ```
101//! use bourse_de::{Env, sim_runner};
102//! use bourse_de::agents::{Agent, AgentSet, Agents};
103//! use rand::RngCore;
104//!
105//! struct AgentTypeA{}
106//!
107//! impl Agent for AgentTypeA{
108//!     fn update<R: RngCore>(
109//!         &mut self, env: &mut bourse_de::Env, rng: &mut R
110//!     ) {}
111//! }
112//!
113//! struct AgentTypeB{}
114//!
115//! impl Agent for AgentTypeB{
116//!     fn update<R: RngCore>(
117//!         &mut self, env: &mut bourse_de::Env, rng: &mut R
118//!     ) {}
119//! }
120//!
121//! #[derive(Agents)]
122//! struct SimAgents {
123//!     pub a: AgentTypeA,
124//!     pub b: AgentTypeB,
125//! }
126//!
127//! let mut env = bourse_de::Env::new(0, 1, 1_000_000, true);
128//! let mut agents = SimAgents{a: AgentTypeA{}, b: AgentTypeB{}};
129//!
130//! sim_runner(&mut env, &mut agents, 101, 50, true);
131//! ```
132//!
133//! # Randomness
134//!
135//! To ensure simulations are deterministic (given a random seed)
136//! random generators (that implement the [rand::RngCore] trait) are
137//! passed to agents during the simulation. The [rand_distr] crate
138//! can be used to sample from common distributions.
139//!
140
141pub mod agents;
142mod env;
143mod runner;
144
145pub use bourse_book::{types, OrderError};
146pub use env::Env;
147pub use runner::sim_runner;