Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions hftbacktest/src/backtest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,11 @@ where
self.local.get(asset_no).unwrap().state_values()
}

#[inline]
fn mutable_state_values(&mut self, asset_no: usize) -> &mut StateValues {
self.local.get_mut(asset_no).unwrap().state_values_mut()
}

fn depth(&self, asset_no: usize) -> &MD {
self.local.get(asset_no).unwrap().depth()
}
Expand All @@ -897,6 +902,14 @@ where
self.local.get(asset_no).unwrap().last_trades()
}

fn last_trade_price(&self, asset_no: usize) -> f64 {
self.local.get(asset_no).unwrap().last_trade_price()
}

fn last_trade_size(&self, asset_no: usize) -> f64 {
self.local.get(asset_no).unwrap().last_trade_size()
}

#[inline]
fn clear_last_trades(&mut self, asset_no: Option<usize>) {
match asset_no {
Expand Down
30 changes: 28 additions & 2 deletions hftbacktest/src/backtest/proc/l3_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ where
trades: Vec<Event>,
last_feed_latency: Option<(i64, i64)>,
last_order_latency: Option<(i64, i64, i64)>,
last_trade_price: f64,
last_trade_size: f64,
}

impl<AT, LM, MD, FM> L3Local<AT, LM, MD, FM>
Expand All @@ -70,6 +72,8 @@ where
trades: Vec::with_capacity(trade_len),
last_feed_latency: None,
last_order_latency: None,
last_trade_price: 0.0,
last_trade_size: 0.0,
}
}
}
Expand Down Expand Up @@ -113,6 +117,8 @@ where
self.order_l2e.request(order, |order| {
order.req = Status::Rejected;
});
self.state_values_mut().num_messages += 1;
self.state_values_mut().num_creations += 1;

Ok(())
}
Expand Down Expand Up @@ -148,6 +154,8 @@ where
order.price_tick = orig_price_tick;
order.qty = orig_qty;
});
self.state_values_mut().num_messages += 1;
self.state_values_mut().num_modifications += 1;

Ok(())
}
Expand All @@ -168,6 +176,8 @@ where
self.order_l2e.request(order.clone(), |order| {
order.req = Status::Rejected;
});
self.state_values_mut().num_messages += 1;
self.state_values_mut().num_cancellations += 1;

Ok(())
}
Expand All @@ -188,6 +198,10 @@ where
self.state.values()
}

fn state_values_mut(&mut self) -> &mut StateValues {
self.state.values_mut()
}

fn depth(&self) -> &MD {
&self.depth
}
Expand All @@ -200,6 +214,14 @@ where
self.trades.as_slice()
}

fn last_trade_price(&self) -> f64 {
self.last_trade_price
}

fn last_trade_size(&self) -> f64 {
self.last_trade_size
}

fn clear_last_trades(&mut self) {
self.trades.clear();
}
Expand Down Expand Up @@ -246,8 +268,12 @@ where
self.depth.delete_order(ev.order_id, ev.local_ts)?;
}
// Processes a trade event
else if ev.is(LOCAL_TRADE_EVENT) && self.trades.capacity() > 0 {
self.trades.push(ev.clone());
else if ev.is(LOCAL_TRADE_EVENT) {
if self.trades.capacity() > 0 {
self.trades.push(ev.clone());
}
self.last_trade_size = ev.qty;
self.last_trade_price = ev.px;
}

// Stores the current feed latency
Expand Down
30 changes: 28 additions & 2 deletions hftbacktest/src/backtest/proc/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ where
trades: Vec<Event>,
last_feed_latency: Option<(i64, i64)>,
last_order_latency: Option<(i64, i64, i64)>,
last_trade_price: f64,
last_trade_size: f64,
}

impl<AT, LM, MD, FM> Local<AT, LM, MD, FM>
Expand All @@ -70,6 +72,8 @@ where
trades: Vec::with_capacity(last_trades_cap),
last_feed_latency: None,
last_order_latency: None,
last_trade_size: 0.0,
last_trade_price: 0.0,
}
}

Expand Down Expand Up @@ -175,6 +179,8 @@ where
order.req = Status::Rejected;
});

self.state_values_mut().num_messages += 1;
self.state_values_mut().num_creations += 1;
Ok(())
}

Expand Down Expand Up @@ -210,6 +216,8 @@ where
order.qty = orig_qty;
});

self.state_values_mut().num_messages += 1;
self.state_values_mut().num_modifications += 1;
Ok(())
}

Expand All @@ -230,6 +238,8 @@ where
order.req = Status::Rejected;
});

self.state_values_mut().num_messages += 1;
self.state_values_mut().num_cancellations += 1;
Ok(())
}

Expand All @@ -249,6 +259,10 @@ where
self.state.values()
}

fn state_values_mut(&mut self) -> &mut StateValues {
self.state.values_mut()
}

fn depth(&self) -> &MD {
&self.depth
}
Expand All @@ -261,6 +275,14 @@ where
self.trades.as_slice()
}

fn last_trade_price(&self) -> f64 {
self.last_trade_price
}

fn last_trade_size(&self) -> f64 {
self.last_trade_size
}

fn clear_last_trades(&mut self) {
self.trades.clear();
}
Expand Down Expand Up @@ -299,8 +321,12 @@ where
self.depth.update_ask_depth(ev.px, ev.qty, ev.local_ts);
}
// Processes a trade event
else if ev.is(LOCAL_TRADE_EVENT) && self.trades.capacity() > 0 {
self.trades.push(ev.clone());
else if ev.is(LOCAL_TRADE_EVENT) {
if self.trades.capacity() > 0 {
self.trades.push(ev.clone());
}
self.last_trade_size = ev.qty;
self.last_trade_price = ev.px;
}

// Stores the current feed latency
Expand Down
9 changes: 9 additions & 0 deletions hftbacktest/src/backtest/proc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ where
/// Returns the state's values such as balance, fee, and so on.
fn state_values(&self) -> &StateValues;

/// Returns the state's values such as balance, fee, and so on, mutable.
fn state_values_mut(&mut self) -> &mut StateValues;

/// Returns the [`MarketDepth`].
fn depth(&self) -> &MD;

Expand All @@ -89,6 +92,12 @@ where
/// Returns the last market trades.
fn last_trades(&self) -> &[Event];

/// Returns the last trade's price
fn last_trade_price(&self) -> f64;

/// Returns the last trade's size
fn last_trade_size(&self) -> f64;

/// Clears the last market trades from the buffer.
fn clear_last_trades(&mut self);

Expand Down
10 changes: 10 additions & 0 deletions hftbacktest/src/backtest/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ where
num_trades: 0,
trading_volume: 0.0,
trading_value: 0.0,
num_messages: 0,
num_creations: 0,
num_modifications: 0,
num_cancellations: 0,
},
fee_model,
asset_type,
Expand All @@ -41,6 +45,7 @@ where
self.state_values.balance -= amount * AsRef::<f64>::as_ref(&order.side);
self.state_values.fee += self.fee_model.amount(order, amount);
self.state_values.num_trades += 1;
self.state_values.num_messages += 1;
self.state_values.trading_volume += order.exec_qty;
self.state_values.trading_value += amount;
}
Expand All @@ -59,4 +64,9 @@ where
pub fn values(&self) -> &StateValues {
&self.state_values
}

#[inline]
pub fn values_mut(&mut self) -> &mut StateValues {
&mut self.state_values
}
}
27 changes: 25 additions & 2 deletions hftbacktest/src/live/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ impl<MD> LiveBotBuilder<MD> {
/// Provides the same interface as the backtesters in [`backtest`](`crate::backtest`).
///
/// ```
/// use hftbacktest::{live::{Instrument, LiveBot}, prelude::HashMapMarketDepth};
/// use hftbacktest::{live::{Instrument, LiveBotBuilder, ipc::iceoryx::IceoryxUnifiedChannel}, prelude::HashMapMarketDepth};
///
/// let tick_size = 0.1;
/// let lot_size = 1.0;
///
/// let mut hbt = LiveBot::builder()
/// let hbt: hftbacktest::live::LiveBot<IceoryxUnifiedChannel, HashMapMarketDepth> = LiveBotBuilder::new()
/// .register(Instrument::new(
/// "connector_name",
/// "symbol",
Expand Down Expand Up @@ -439,6 +439,11 @@ where
&self.instruments.get(asset_no).unwrap().state
}

#[inline]
fn mutable_state_values(&mut self, asset_no: usize) -> &mut StateValues {
&mut self.instruments.get_mut(asset_no).unwrap().state
}

#[inline]
fn depth(&self, asset_no: usize) -> &MD {
&self.instruments.get(asset_no).unwrap().depth
Expand All @@ -453,6 +458,24 @@ where
.as_slice()
}

#[inline]
fn last_trade_size(&self, asset_no: usize) -> f64 {
self.instruments
.get(asset_no)
.unwrap()
.last_trade_size
.clone()
}

#[inline]
fn last_trade_price(&self, asset_no: usize) -> f64 {
self.instruments
.get(asset_no)
.unwrap()
.last_trade_price
.clone()
}

fn clear_last_trades(&mut self, asset_no: Option<usize>) {
match asset_no {
Some(asset_no) => {
Expand Down
4 changes: 4 additions & 0 deletions hftbacktest/src/live/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub struct Instrument<MD> {
last_feed_latency: Option<(i64, i64)>,
last_order_latency: Option<(i64, i64, i64)>,
state: StateValues,
last_trade_size: f64,
last_trade_price: f64,
}

impl<MD> Instrument<MD> {
Expand Down Expand Up @@ -53,6 +55,8 @@ impl<MD> Instrument<MD> {
last_feed_latency: None,
last_order_latency: None,
state: Default::default(),
last_trade_price: 0.0,
last_trade_size: 0.0,
}
}
}
30 changes: 30 additions & 0 deletions hftbacktest/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,15 @@ impl AsRef<str> for OrdType {
///
/// **Usage:**
/// ```
/// use hftbacktest::types::AnyClone;
/// use std::any::Any;
///
/// // Define your custom data type
/// #[derive(Clone)]
/// struct QueuePos {
/// pos: usize,
/// }
///
/// impl AnyClone for QueuePos {
/// fn as_any(&self) -> &dyn Any {
/// self
Expand Down Expand Up @@ -746,6 +755,14 @@ pub struct StateValues {
pub trading_volume: f64,
/// Backtest only
pub trading_value: f64,
/// Number of messages (backtest only)
pub num_messages: i64,
/// Number of quote cancellation messages (backtest only)
pub num_cancellations: i64,
/// Number of quote creation messages (backtest only)
pub num_creations: i64,
/// Number of modification messages (backtest only)
pub num_modifications: i64,
}

/// Provides errors that can occur in builders.
Expand Down Expand Up @@ -796,6 +813,9 @@ where
/// Returns the state's values such as balance, fee, and so on.
fn state_values(&self, asset_no: usize) -> &StateValues;

/// Returns the state's values such as balance, fee, and so on, mutable.
fn mutable_state_values(&mut self, asset_no: usize) -> &mut StateValues;

/// Returns the [`MarketDepth`].
///
/// * `asset_no` - Asset number from which the market depth will be retrieved.
Expand All @@ -806,6 +826,16 @@ where
/// * `asset_no` - Asset number from which the last market trades will be retrieved.
fn last_trades(&self, asset_no: usize) -> &[Event];

/// Returns the last trade's price
///
/// * `asset_no` - Asset number from which the last market trades will be retrieved.
fn last_trade_price(&self, asset_no: usize) -> f64;

/// Returns the last trade's size
///
/// * `asset_no` - Asset number from which the last market trades will be retrieved.
fn last_trade_size(&self, asset_no: usize) -> f64;

/// Clears the last market trades from the buffer.
///
/// * `asset_no` - Asset number at which this command will be executed. If `None`, all last
Expand Down
Loading