Skip to content

Commit

Permalink
Add Cache index build
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdsellers committed Apr 27, 2024
1 parent 9f34244 commit 5369328
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 7 deletions.
215 changes: 210 additions & 5 deletions nautilus_core/common/src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use nautilus_model::{
quote::QuoteTick,
trade::TradeTick,
},
enums::{AggregationSource, OrderSide, PositionSide, PriceType},
enums::{AggregationSource, OrderSide, PositionSide, PriceType, TriggerType},
identifiers::{
account_id::AccountId, client_id::ClientId, client_order_id::ClientOrderId,
component_id::ComponentId, exec_algorithm_id::ExecAlgorithmId, instrument_id::InstrumentId,
Expand All @@ -42,8 +42,9 @@ use nautilus_model::{
orderbook::book::OrderBook,
orders::{base::OrderAny, list::OrderList},
polymorphism::{
GetClientOrderId, GetExecAlgorithmId, GetExecSpawnId, GetInstrumentId, GetOrderFilledQty,
GetOrderLeavesQty, GetOrderQuantity, GetOrderSide, GetStrategyId, IsClosed,
GetClientOrderId, GetEmulationTrigger, GetExecAlgorithmId, GetExecSpawnId, GetInstrumentId,
GetOrderFilledQty, GetOrderLeavesQty, GetOrderQuantity, GetOrderSide, GetPositionId,
GetStrategyId, GetVenueOrderId, IsClosed, IsInflight, IsOpen,
},
position::Position,
types::{currency::Currency, price::Price, quantity::Quantity},
Expand Down Expand Up @@ -330,8 +331,212 @@ impl Cache {
Ok(())
}

pub fn build_index(&self) {
todo!() // Needs order query methods
pub fn build_index(&mut self) {
self.index.clear();
debug!("Building index");

// Index accounts
for account_id in self.accounts.keys() {
self.index
.venue_account
.insert(account_id.get_issuer(), *account_id);
}

// Index orders
for (client_order_id, order) in &self.orders {
let instrument_id = order.instrument_id();
let venue = instrument_id.venue;
let strategy_id = order.strategy_id();

// 1: Build _index_venue_orders -> {Venue, {ClientOrderId}}
if let Some(venue_orders) = self.index.venue_orders.get_mut(&venue) {
venue_orders.insert(*client_order_id);
} else {
let mut venue_orders = HashSet::new();
venue_orders.insert(*client_order_id);
self.index.venue_orders.insert(venue, venue_orders);
}

// 2: Build _index_order_ids -> {VenueOrderId, ClientOrderId}
if let Some(venue_order_id) = order.venue_order_id() {
self.index
.order_ids
.insert(venue_order_id, *client_order_id);
}

// 3: Build _index_order_position -> {ClientOrderId, PositionId}
if let Some(position_id) = order.position_id() {
self.index
.order_position
.insert(*client_order_id, position_id);
}

// 4: Build _index_order_strategy -> {ClientOrderId, StrategyId}
self.index
.order_strategy
.insert(*client_order_id, order.strategy_id());

// 5: Build _index_instrument_orders -> {InstrumentId, {ClientOrderId}}
if let Some(instrument_orders) = self.index.instrument_orders.get_mut(&instrument_id) {
instrument_orders.insert(*client_order_id);
} else {
let mut instrument_orders = HashSet::new();
instrument_orders.insert(*client_order_id);
self.index
.instrument_orders
.insert(instrument_id, instrument_orders);
}

// 6: Build _index_strategy_orders -> {StrategyId, {ClientOrderId}}
if let Some(strategy_orders) = self.index.strategy_orders.get_mut(&strategy_id) {
strategy_orders.insert(*client_order_id);
} else {
let mut strategy_orders = HashSet::new();
strategy_orders.insert(*client_order_id);
self.index
.strategy_orders
.insert(strategy_id, strategy_orders);
}

// 7: Build _index_exec_algorithm_orders -> {ExecAlgorithmId, {ClientOrderId}}
if let Some(exec_algorithm_id) = order.exec_algorithm_id() {
if let Some(exec_algorithm_orders) =
self.index.exec_algorithm_orders.get_mut(&exec_algorithm_id)
{
exec_algorithm_orders.insert(*client_order_id);
} else {
let mut exec_algorithm_orders = HashSet::new();
exec_algorithm_orders.insert(*client_order_id);
self.index
.exec_algorithm_orders
.insert(exec_algorithm_id, exec_algorithm_orders);
}
}

// 8: Build _index_exec_spawn_orders -> {ClientOrderId, {ClientOrderId}}
if let Some(exec_spawn_id) = order.exec_spawn_id() {
if let Some(exec_spawn_orders) =
self.index.exec_spawn_orders.get_mut(&exec_spawn_id)
{
exec_spawn_orders.insert(*client_order_id);
} else {
let mut exec_spawn_orders = HashSet::new();
exec_spawn_orders.insert(*client_order_id);
self.index
.exec_spawn_orders
.insert(exec_spawn_id, exec_spawn_orders);
}
}

// 9: Build _index_orders -> {ClientOrderId}
self.index.orders.insert(*client_order_id);

// 10: Build _index_orders_open -> {ClientOrderId}
if order.is_open() {
self.index.orders_open.insert(*client_order_id);
}

// 11: Build _index_orders_closed -> {ClientOrderId}
if order.is_closed() {
self.index.orders_closed.insert(*client_order_id);
}

// 12: Build _index_orders_emulated -> {ClientOrderId}
if let Some(emulation_trigger) = order.emulation_trigger() {
if emulation_trigger != TriggerType::NoTrigger && !order.is_closed() {
self.index.orders_emulated.insert(*client_order_id);
}
}

// 13: Build _index_orders_inflight -> {ClientOrderId}
if order.is_inflight() {
self.index.orders_inflight.insert(*client_order_id);
}

// 14: Build _index_strategies -> {StrategyId}
self.index.strategies.insert(strategy_id);

// 15: Build _index_strategies -> {ExecAlgorithmId}
if let Some(exec_algorithm_id) = order.exec_algorithm_id() {
self.index.exec_algorithms.insert(exec_algorithm_id);
}
}

// Index positions
for (position_id, position) in &self.positions {
let instrument_id = position.instrument_id;
let venue = instrument_id.venue;
let strategy_id = position.strategy_id;

// 1: Build _index_venue_positions -> {Venue, {PositionId}}
if let Some(venue_positions) = self.index.venue_positions.get_mut(&venue) {
venue_positions.insert(*position_id);
} else {
let mut venue_positions = HashSet::new();
venue_positions.insert(*position_id);
self.index.venue_positions.insert(venue, venue_positions);
}

// 2: Build _index_position_strategy -> {PositionId, StrategyId}
self.index
.position_strategy
.insert(*position_id, position.strategy_id);

// 3: Build _index_position_orders -> {PositionId, {ClientOrderId}}
if let Some(position_orders) = self.index.position_orders.get_mut(position_id) {
for client_order_id in position.client_order_ids() {
position_orders.insert(client_order_id);
}
} else {
let mut position_orders = HashSet::new();
for client_order_id in position.client_order_ids() {
position_orders.insert(client_order_id);
}
self.index
.position_orders
.insert(*position_id, position_orders);
}

// 4: Build _index_instrument_positions -> {InstrumentId, {PositionId}}
if let Some(instrument_positions) =
self.index.instrument_positions.get_mut(&instrument_id)
{
instrument_positions.insert(*position_id);
} else {
let mut instrument_positions = HashSet::new();
instrument_positions.insert(*position_id);
self.index
.instrument_positions
.insert(instrument_id, instrument_positions);
}

// 5: Build _index_strategy_positions -> {StrategyId, {PositionId}}
if let Some(strategy_positions) = self.index.strategy_positions.get_mut(&strategy_id) {
strategy_positions.insert(*position_id);
} else {
let mut strategy_positions = HashSet::new();
strategy_positions.insert(*position_id);
self.index
.strategy_positions
.insert(strategy_id, strategy_positions);
}

// 6: Build _index_positions -> {PositionId}
self.index.positions.insert(*position_id);

// 7: Build _index_positions_open -> {PositionId}
if position.is_open() {
self.index.positions_open.insert(*position_id);
}

// 8: Build _index_positions_closed -> {PositionId}
if position.is_closed() {
self.index.positions_closed.insert(*position_id);
}

// 9: Build _index_strategies -> {StrategyId}
self.index.strategies.insert(strategy_id);
}
}

#[must_use]
Expand Down
35 changes: 34 additions & 1 deletion nautilus_core/model/src/orders/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ use crate::{
polymorphism::{
GetClientOrderId, GetEmulationTrigger, GetExecAlgorithmId, GetExecSpawnId, GetInstrumentId,
GetLimitPrice, GetOrderFilledQty, GetOrderLeavesQty, GetOrderQuantity, GetOrderSide,
GetOrderSideSpecified, GetStopPrice, GetStrategyId, GetVenueOrderId, IsClosed, IsOpen,
GetOrderSideSpecified, GetPositionId, GetStopPrice, GetStrategyId, GetVenueOrderId,
IsClosed, IsInflight, IsOpen,
},
types::{currency::Currency, money::Money, price::Price, quantity::Quantity},
};
Expand Down Expand Up @@ -213,6 +214,22 @@ impl GetStrategyId for OrderAny {
}
}

impl GetPositionId for OrderAny {
fn position_id(&self) -> Option<PositionId> {
match self {
Self::Limit(order) => order.position_id,
Self::LimitIfTouched(order) => order.position_id,
Self::Market(order) => order.position_id,
Self::MarketIfTouched(order) => order.position_id,
Self::MarketToLimit(order) => order.position_id,
Self::StopLimit(order) => order.position_id,
Self::StopMarket(order) => order.position_id,
Self::TrailingStopLimit(order) => order.position_id,
Self::TrailingStopMarket(order) => order.position_id,
}
}
}

impl GetExecAlgorithmId for OrderAny {
fn exec_algorithm_id(&self) -> Option<ExecAlgorithmId> {
match self {
Expand Down Expand Up @@ -373,6 +390,22 @@ impl IsClosed for OrderAny {
}
}

impl IsInflight for OrderAny {
fn is_inflight(&self) -> bool {
match self {
Self::Limit(order) => order.is_inflight(),
Self::LimitIfTouched(order) => order.is_inflight(),
Self::Market(order) => order.is_inflight(),
Self::MarketIfTouched(order) => order.is_inflight(),
Self::MarketToLimit(order) => order.is_inflight(),
Self::StopLimit(order) => order.is_inflight(),
Self::StopMarket(order) => order.is_inflight(),
Self::TrailingStopLimit(order) => order.is_inflight(),
Self::TrailingStopMarket(order) => order.is_inflight(),
}
}
}

#[derive(Clone, Debug)]
pub enum PassiveOrderAny {
Limit(LimitOrderAny),
Expand Down
11 changes: 10 additions & 1 deletion nautilus_core/model/src/polymorphism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use crate::{
enums::{OrderSide, OrderSideSpecified, TriggerType},
identifiers::{
client_order_id::ClientOrderId, exec_algorithm_id::ExecAlgorithmId,
instrument_id::InstrumentId, strategy_id::StrategyId, venue_order_id::VenueOrderId,
instrument_id::InstrumentId, position_id::PositionId, strategy_id::StrategyId,
venue_order_id::VenueOrderId,
},
types::{price::Price, quantity::Quantity},
};
Expand All @@ -46,6 +47,10 @@ pub trait GetStrategyId {
fn strategy_id(&self) -> StrategyId;
}

pub trait GetPositionId {
fn position_id(&self) -> Option<PositionId>;
}

pub trait GetExecAlgorithmId {
fn exec_algorithm_id(&self) -> Option<ExecAlgorithmId>;
}
Expand Down Expand Up @@ -93,3 +98,7 @@ pub trait IsOpen {
pub trait IsClosed {
fn is_closed(&self) -> bool;
}

pub trait IsInflight {
fn is_inflight(&self) -> bool;
}

0 comments on commit 5369328

Please sign in to comment.