diff --git a/rust/src/backtest/assettype.rs b/rust/src/backtest/assettype.rs index ac0280a..d20e2f9 100644 --- a/rust/src/backtest/assettype.rs +++ b/rust/src/backtest/assettype.rs @@ -7,14 +7,14 @@ pub trait AssetType { fn equity(&self, price: f32, balance: f64, position: f64, fee: f64) -> f64; } -/// The common type of asset. +/// The common type of asset where the contract's notional value is linear to the quote currency. #[derive(Clone)] pub struct LinearAsset { contract_size: f64, } impl LinearAsset { - /// Constructs [`LinearAsset`]. + /// Constructs an instance of `LinearAsset`. pub fn new(contract_size: f64) -> Self { Self { contract_size } } @@ -37,7 +37,7 @@ pub struct InverseAsset { } impl InverseAsset { - /// Constructs [`InverseAsset`]. + /// Constructs an instance of `InverseAsset`. pub fn new(contract_size: f64) -> Self { Self { contract_size } } diff --git a/rust/src/backtest/backtest.rs b/rust/src/backtest/backtest.rs index 3527cf7..ba60080 100644 --- a/rust/src/backtest/backtest.rs +++ b/rust/src/backtest/backtest.rs @@ -10,7 +10,7 @@ use crate::{ Error, }, depth::{HashMapMarketDepth, MarketDepth}, - ty::{Event, OrdType, Order, Side, TimeInForce}, + types::{Event, OrdType, Order, Side, TimeInForce}, BuildError, Interface, }; diff --git a/rust/src/backtest/mod.rs b/rust/src/backtest/mod.rs index 90d1bf0..926aad2 100644 --- a/rust/src/backtest/mod.rs +++ b/rust/src/backtest/mod.rs @@ -12,16 +12,29 @@ use crate::{ state::State, }, depth::MarketDepth, - ty::Event, + types::Event, BuildError, }; +/// Asset types pub mod assettype; + +/// The backtester pub mod backtest; + +/// Latency and queue position models pub mod models; + +/// OrderBus implementation pub mod order; + +/// Local and exchange models pub mod proc; + +/// The data reader pub mod reader; + +/// The state, such as position, cash, and fees. pub mod state; mod evs; diff --git a/rust/src/backtest/models/latencies.rs b/rust/src/backtest/models/latencies.rs index 6d9e2d3..d1e2dec 100644 --- a/rust/src/backtest/models/latencies.rs +++ b/rust/src/backtest/models/latencies.rs @@ -1,4 +1,4 @@ -use crate::{backtest::reader::Data, ty::Order}; +use crate::{backtest::reader::Data, types::Order}; /// Provides the order entry latency and the order response latency. pub trait LatencyModel { diff --git a/rust/src/backtest/models/queue.rs b/rust/src/backtest/models/queue.rs index 93625e0..5fb192f 100644 --- a/rust/src/backtest/models/queue.rs +++ b/rust/src/backtest/models/queue.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use crate::{ depth::MarketDepth, - ty::{Order, Side}, + types::{Order, Side}, }; /// Provides an estimation of the order's queue position. diff --git a/rust/src/backtest/order.rs b/rust/src/backtest/order.rs index 262d38b..a5aa78e 100644 --- a/rust/src/backtest/order.rs +++ b/rust/src/backtest/order.rs @@ -4,7 +4,7 @@ use std::{ rc::Rc, }; -use crate::ty::Order; +use crate::types::Order; /// Provides a bus for transporting backtesting orders between the exchange and the local model /// based on the given timestamp. @@ -21,7 +21,7 @@ impl OrderBus where Q: Clone, { - /// Constructs [`OrderBus`]. + /// Constructs an instance of `OrderBus`. pub fn new() -> Self { Self { order_list: Default::default(), diff --git a/rust/src/backtest/proc/local.rs b/rust/src/backtest/proc/local.rs index 602fadb..1e2c7db 100644 --- a/rust/src/backtest/proc/local.rs +++ b/rust/src/backtest/proc/local.rs @@ -25,7 +25,7 @@ use crate::{ Error, }, depth::MarketDepth, - ty::{Event, OrdType, Order, Side, Status, TimeInForce, BUY, SELL}, + types::{Event, OrdType, Order, Side, Status, TimeInForce, BUY, SELL}, }; pub struct Local diff --git a/rust/src/backtest/proc/nopartialfillexchange.rs b/rust/src/backtest/proc/nopartialfillexchange.rs index 0835ba3..d9586a4 100644 --- a/rust/src/backtest/proc/nopartialfillexchange.rs +++ b/rust/src/backtest/proc/nopartialfillexchange.rs @@ -28,12 +28,12 @@ use crate::{ Error, }, depth::{MarketDepth, INVALID_MAX, INVALID_MIN}, - ty::{Event, Order, Side, Status, TimeInForce, BUY, SELL}, + types::{Event, Order, Side, Status, TimeInForce, BUY, SELL}, }; /// The exchange model without partial fills. /// -/// Support order types: [`crate::ty::OrdType::Limit`] +/// Support order types: [`crate::types::OrdType::Limit`] /// Support time-in-force: [`TimeInForce::GTC`], [`TimeInForce::GTX`] /// /// *Conditions for Full Execution* diff --git a/rust/src/backtest/proc/partialfillexchange.rs b/rust/src/backtest/proc/partialfillexchange.rs index 5658b82..1cf7822 100644 --- a/rust/src/backtest/proc/partialfillexchange.rs +++ b/rust/src/backtest/proc/partialfillexchange.rs @@ -28,12 +28,12 @@ use crate::{ Error, }, depth::{MarketDepth, INVALID_MAX, INVALID_MIN}, - ty::{Event, Order, Side, Status, TimeInForce, BUY, SELL}, + types::{Event, Order, Side, Status, TimeInForce, BUY, SELL}, }; /// The exchange model with partial fills. /// -/// Support order types: [`crate::ty::OrdType::Limit`] +/// Support order types: [`crate::types::OrdType::Limit`] /// Support time-in-force: [`TimeInForce::GTC`], [`TimeInForce::FOK`], [`TimeInForce::IOC`], /// [`TimeInForce::GTX`] /// diff --git a/rust/src/backtest/proc/proc.rs b/rust/src/backtest/proc/proc.rs index 46780bc..3ae788b 100644 --- a/rust/src/backtest/proc/proc.rs +++ b/rust/src/backtest/proc/proc.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{ backtest::{state::StateValues, Error}, depth::MarketDepth, - ty::{Event, OrdType, Order, Side, TimeInForce}, + types::{Event, OrdType, Order, Side, TimeInForce}, }; /// Provides local-specific interaction. diff --git a/rust/src/backtest/reader.rs b/rust/src/backtest/reader.rs index 20e65bc..29cb88a 100644 --- a/rust/src/backtest/reader.rs +++ b/rust/src/backtest/reader.rs @@ -11,7 +11,7 @@ use std::{ use crate::{ backtest::Error, - ty::{BUY, DEPTH_CLEAR_EVENT, DEPTH_EVENT, DEPTH_SNAPSHOT_EVENT, SELL, TRADE_EVENT}, + types::{BUY, DEPTH_CLEAR_EVENT, DEPTH_EVENT, DEPTH_SNAPSHOT_EVENT, SELL, TRADE_EVENT}, }; pub const EXCH_EVENT: i64 = 1 << 31; diff --git a/rust/src/backtest/state.rs b/rust/src/backtest/state.rs index 08097a9..50003ee 100644 --- a/rust/src/backtest/state.rs +++ b/rust/src/backtest/state.rs @@ -1,4 +1,4 @@ -use crate::{backtest::assettype::AssetType, ty::Order}; +use crate::{backtest::assettype::AssetType, types::Order}; #[derive(Debug)] pub struct StateValues { diff --git a/rust/src/connector/binancefutures/mod.rs b/rust/src/connector/binancefutures/mod.rs index 899455d..bec816a 100644 --- a/rust/src/connector/binancefutures/mod.rs +++ b/rust/src/connector/binancefutures/mod.rs @@ -23,7 +23,7 @@ use crate::{ }, get_precision, live::AssetInfo, - ty::{Error, ErrorType, LiveEvent, Order, OrderResponse, Position, Status}, + types::{Error, ErrorKind, LiveEvent, Order, OrderResponse, Position, Status}, BuildError, }; @@ -265,7 +265,7 @@ impl Connector for BinanceFutures { if let Err(error) = client.cancel_all_orders(symbol).await { error!(?error, %symbol, "Couldn't cancel all open orders."); ev_tx - .send(LiveEvent::Error(Error::with(ErrorType::OrderError, error))) + .send(LiveEvent::Error(Error::with(ErrorKind::OrderError, error))) .unwrap(); error_count += 1; continue 'connection; @@ -301,7 +301,7 @@ impl Connector for BinanceFutures { // 1000 indicates user data stream starting error. ev_tx .send(LiveEvent::Error(Error::with( - ErrorType::Custom(1000), + ErrorKind::Custom(1000), error, ))) .unwrap(); @@ -341,14 +341,14 @@ impl Connector for BinanceFutures { error!(?error, "A connection error occurred."); ev_tx .send(LiveEvent::Error(Error::with( - ErrorType::ConnectionInterrupted, + ErrorKind::ConnectionInterrupted, error, ))) .unwrap(); } else { ev_tx .send(LiveEvent::Error(Error::new( - ErrorType::ConnectionInterrupted, + ErrorKind::ConnectionInterrupted, ))) .unwrap(); } @@ -410,7 +410,7 @@ impl Connector for BinanceFutures { .unwrap(); } - tx.send(LiveEvent::Error(Error::with(ErrorType::OrderError, error))) + tx.send(LiveEvent::Error(Error::with(ErrorKind::OrderError, error))) .unwrap(); } } @@ -468,7 +468,7 @@ impl Connector for BinanceFutures { .unwrap(); } - tx.send(LiveEvent::Error(Error::with(ErrorType::OrderError, error))) + tx.send(LiveEvent::Error(Error::with(ErrorKind::OrderError, error))) .unwrap(); } } diff --git a/rust/src/connector/binancefutures/msg/mod.rs b/rust/src/connector/binancefutures/msg/mod.rs index e708a3e..d319bac 100644 --- a/rust/src/connector/binancefutures/msg/mod.rs +++ b/rust/src/connector/binancefutures/msg/mod.rs @@ -4,7 +4,7 @@ use serde::{ Deserializer, }; -use crate::ty::{OrdType, Side, Status, TimeInForce}; +use crate::types::{OrdType, Side, Status, TimeInForce}; pub mod rest; pub mod stream; diff --git a/rust/src/connector/binancefutures/msg/rest.rs b/rust/src/connector/binancefutures/msg/rest.rs index e91387c..3569bdc 100644 --- a/rust/src/connector/binancefutures/msg/rest.rs +++ b/rust/src/connector/binancefutures/msg/rest.rs @@ -9,7 +9,7 @@ use super::{ from_str_to_tif, from_str_to_type, }; -use crate::ty::{OrdType, Side, Status, TimeInForce}; +use crate::types::{OrdType, Side, Status, TimeInForce}; #[derive(Deserialize, Debug)] #[serde(untagged)] diff --git a/rust/src/connector/binancefutures/msg/stream.rs b/rust/src/connector/binancefutures/msg/stream.rs index 86b32d2..f794232 100644 --- a/rust/src/connector/binancefutures/msg/stream.rs +++ b/rust/src/connector/binancefutures/msg/stream.rs @@ -8,7 +8,7 @@ use super::{ from_str_to_tif, from_str_to_type, }; -use crate::ty::{OrdType, Side, Status, TimeInForce}; +use crate::types::{OrdType, Side, Status, TimeInForce}; #[derive(Deserialize, Debug)] pub struct Stream { diff --git a/rust/src/connector/binancefutures/ordermanager.rs b/rust/src/connector/binancefutures/ordermanager.rs index d9d9143..c8c1f20 100644 --- a/rust/src/connector/binancefutures/ordermanager.rs +++ b/rust/src/connector/binancefutures/ordermanager.rs @@ -9,7 +9,7 @@ use tracing::{debug, error}; use crate::{ connector::binancefutures::{msg::rest::OrderResponse, BinanceFuturesError}, - ty::{Order, Status}, + types::{Order, Status}, }; #[derive(Debug)] diff --git a/rust/src/connector/binancefutures/rest.rs b/rust/src/connector/binancefutures/rest.rs index 48660a0..85cee73 100644 --- a/rust/src/connector/binancefutures/rest.rs +++ b/rust/src/connector/binancefutures/rest.rs @@ -18,7 +18,7 @@ use crate::{ BinanceFuturesError, }, live::AssetInfo, - ty::{AsStr, OrdType, Order, Side, Status, TimeInForce}, + types::{AsStr, OrdType, Order, Side, Status, TimeInForce}, }; #[derive(Clone)] diff --git a/rust/src/connector/binancefutures/ws.rs b/rust/src/connector/binancefutures/ws.rs index e6a5552..af71108 100644 --- a/rust/src/connector/binancefutures/ws.rs +++ b/rust/src/connector/binancefutures/ws.rs @@ -24,7 +24,7 @@ use crate::{ ordermanager::OrderManager, }, live::AssetInfo, - ty::{self, Depth, LiveEvent, Order, OrderResponse, Position, Status, BUY, SELL}, + types::{self, Depth, LiveEvent, Order, OrderResponse, Position, Status, BUY, SELL}, }; fn parse_depth( @@ -213,7 +213,7 @@ pub async fn connect( .ok_or(BinanceFuturesError::AssetNotFound)?; ev_tx.send( LiveEvent::Trade( - ty::Trade { + types::Trade { asset_no: asset_info.asset_no, exch_ts: data.transaction_time * 1_000_000, local_ts: Utc::now().timestamp_nanos_opt().unwrap(), diff --git a/rust/src/connector/mod.rs b/rust/src/connector/mod.rs index bd10953..8121a2a 100644 --- a/rust/src/connector/mod.rs +++ b/rust/src/connector/mod.rs @@ -1,6 +1,6 @@ use std::sync::mpsc::Sender; -use crate::ty::{LiveEvent, Order}; +use crate::types::{LiveEvent, Order}; pub mod binancefutures; diff --git a/rust/src/depth/btreemarketdepth.rs b/rust/src/depth/btreemarketdepth.rs index d7e9667..c69442d 100644 --- a/rust/src/depth/btreemarketdepth.rs +++ b/rust/src/depth/btreemarketdepth.rs @@ -3,10 +3,10 @@ use std::collections::BTreeMap; use super::{ApplySnapshot, MarketDepth, INVALID_MAX, INVALID_MIN}; use crate::{ backtest::reader::Data, - ty::{Event, BUY, SELL}, + types::{Event, BUY, SELL}, }; -/// Market depth implementation based on an B-Tree map. +/// L2 Market depth implementation based on a B-Tree map. /// /// If feed data is missing, it may result in the crossing of the best bid and ask, making it /// impossible to restore them to the most recent values through natural refreshing. @@ -21,6 +21,7 @@ pub struct BTreeMarketDepth { } impl BTreeMarketDepth { + /// Constructs an instance of `BTreeMarketDepth`. pub fn new(tick_size: f32, lot_size: f32) -> Self { Self { tick_size, diff --git a/rust/src/depth/hashmapmarketdepth.rs b/rust/src/depth/hashmapmarketdepth.rs index 11128d4..b33c994 100644 --- a/rust/src/depth/hashmapmarketdepth.rs +++ b/rust/src/depth/hashmapmarketdepth.rs @@ -3,10 +3,10 @@ use std::collections::{hash_map::Entry, HashMap}; use super::{ApplySnapshot, MarketDepth, INVALID_MAX, INVALID_MIN}; use crate::{ backtest::reader::Data, - ty::{Event, BUY, SELL}, + types::{Event, BUY, SELL}, }; -/// HashMap-based Market Depth +/// L2 Market depth implementation based on a hash map. /// /// This is considered more robust than a BTreeMap-based Market Depth. This is because in the /// BTreeMap-based approach, missing depth feeds can lead to incorrect best bid or ask prices. @@ -49,6 +49,7 @@ fn depth_above(depth: &HashMap, start: i32, end: i32) -> i32 { } impl HashMapMarketDepth { + /// Constructs an instance of `HashMapMarketDepth`. pub fn new(tick_size: f32, lot_size: f32) -> Self { Self { tick_size, diff --git a/rust/src/depth/mod.rs b/rust/src/depth/mod.rs index e4d62ad..775b16c 100644 --- a/rust/src/depth/mod.rs +++ b/rust/src/depth/mod.rs @@ -1,4 +1,4 @@ -use crate::{backtest::reader::Data, ty::Event}; +use crate::{backtest::reader::Data, types::Event}; mod btreemarketdepth; mod hashmapmarketdepth; @@ -40,7 +40,7 @@ pub trait MarketDepth { timestamp: i64, ) -> (i32, i32, i32, f32, f32, i64); - /// Clears the market depth. If the `side` is neither [crate::ty::BUY] nor [crate::ty::SELL], + /// Clears the market depth. If the `side` is neither [crate::types::BUY] nor [crate::types::SELL], /// both sides are cleared. In this case, `clear_upto_price` is ignored. fn clear_depth(&mut self, side: i64, clear_upto_price: f32); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index db19443..4630cf9 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -14,29 +14,38 @@ //! - Backtesting of multi-asset and multi-exchange models //! - Deployment of a live trading bot using the same algo code //! +//! +//! ## Feature flags +//! +//! Currently, `default` enables all features. +//! +//! - `backtest`: Enables backtesting features. +//! - `live`: Enables a live trading bot. +//! - `binancefutures`: Enables Binance Futures USDM connector for a live trading bot. +//! use std::collections::HashMap; use thiserror::Error; use crate::{ backtest::state::StateValues, - ty::{Event, OrdType, Order, TimeInForce}, + types::{Event, OrdType, Order, TimeInForce}, }; -/// Defines backtesting features. +/// Backtesting features. pub mod backtest; -/// Defines exchange connectors +/// Exchange connectors pub mod connector; -/// Defines a market depth to build the order book from the feed data. +/// A market depth to build the order book from the feed data. pub mod depth; -/// Defines live bot features. +/// Live bot features. pub mod live; -/// Defines types. -pub mod ty; +/// Common types used in both backtesting and live trading. +pub mod types; #[derive(Error, Debug)] pub enum BuildError { @@ -148,8 +157,8 @@ where /// * `wait` - If true, wait until the order placement response is received. fn cancel(&mut self, asset_no: usize, order_id: i64, wait: bool) -> Result; - /// Clears inactive orders from the local [`Self::orders()`] whose status is neither [`ty::Status::New`] nor - /// [`ty::Status::PartiallyFilled`]. + /// Clears inactive orders from the local [`Self::orders()`] whose status is neither [`types::Status::New`] nor + /// [`types::Status::PartiallyFilled`]. fn clear_inactive_orders(&mut self, asset_no: Option); /// Elapses the specified duration. diff --git a/rust/src/live/bot.rs b/rust/src/live/bot.rs index b3d3a23..3f87e08 100644 --- a/rust/src/live/bot.rs +++ b/rust/src/live/bot.rs @@ -18,7 +18,7 @@ use crate::{ connector::Connector, depth::{HashMapMarketDepth, MarketDepth}, live::AssetInfo, - ty::{ + types::{ Error as ErrorEvent, Error, Event, diff --git a/rust/src/ty.rs b/rust/src/types.rs similarity index 96% rename from rust/src/ty.rs rename to rust/src/types.rs index c2c8095..fc53609 100644 --- a/rust/src/ty.rs +++ b/rust/src/types.rs @@ -7,7 +7,7 @@ use std::{ /// Error type assigned to [`Error`]. #[derive(Clone, Copy, Eq, PartialEq, Debug)] #[repr(i64)] -pub enum ErrorType { +pub enum ErrorKind { ConnectionInterrupted = 0, CriticalConnectionError = 1, OrderError = 2, @@ -17,21 +17,21 @@ pub enum ErrorType { /// Error conveyed through [`LiveEvent`]. #[derive(Clone, Debug)] pub struct Error { - pub ty: ErrorType, + pub kind: ErrorKind, pub value: Option>>, } impl Error { - pub fn new(ty: ErrorType) -> Error { - Self { ty, value: None } + pub fn new(kind: ErrorKind) -> Error { + Self { kind, value: None } } - pub fn with(ty: ErrorType, value: T) -> Error + pub fn with(kind: ErrorKind, value: T) -> Error where T: Send + Sync + 'static, { Self { - ty, + kind, value: Some(Arc::new(Box::new(value))), } } @@ -47,7 +47,7 @@ impl Error { } } -/// Events occurring in a live bot sent by a [`Connector`]. +/// Events occurring in a live bot sent by a [`crate::connector::Connector`]. #[derive(Clone, Debug)] pub enum LiveEvent { Depth(Depth),