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