1#![forbid(unsafe_code)]
2#![warn(
3 unused,
4 clippy::cognitive_complexity,
5 unused_crate_dependencies,
6 unused_extern_crates,
7 clippy::unused_self,
8 clippy::useless_let_if_seq,
9 missing_debug_implementations,
10 rust_2018_idioms,
11 rust_2024_compatibility
12)]
13#![allow(clippy::type_complexity, clippy::too_many_arguments, type_alias_bounds)]
14
15use crate::{
27 balance::AssetBalance,
28 order::{Order, OrderSnapshot, request::OrderResponseCancel},
29 trade::Trade,
30};
31use barter_instrument::{
32 asset::{AssetIndex, QuoteAsset, name::AssetNameExchange},
33 exchange::{ExchangeId, ExchangeIndex},
34 instrument::{InstrumentIndex, name::InstrumentNameExchange},
35};
36use barter_integration::snapshot::Snapshot;
37use chrono::{DateTime, Utc};
38use derive_more::{Constructor, From};
39use order::state::OrderState;
40use serde::{Deserialize, Serialize};
41
42pub mod balance;
43pub mod client;
44pub mod error;
45pub mod exchange;
46pub mod indexer;
47pub mod map;
48pub mod order;
49pub mod trade;
50
51pub type UnindexedAccountEvent =
54 AccountEvent<ExchangeId, AssetNameExchange, InstrumentNameExchange>;
55
56pub type UnindexedAccountSnapshot =
59 AccountSnapshot<ExchangeId, AssetNameExchange, InstrumentNameExchange>;
60
61#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
62pub struct AccountEvent<
63 ExchangeKey = ExchangeIndex,
64 AssetKey = AssetIndex,
65 InstrumentKey = InstrumentIndex,
66> {
67 pub exchange: ExchangeKey,
68 pub kind: AccountEventKind<ExchangeKey, AssetKey, InstrumentKey>,
69}
70
71impl<ExchangeKey, AssetKey, InstrumentKey> AccountEvent<ExchangeKey, AssetKey, InstrumentKey> {
72 pub fn new<K>(exchange: ExchangeKey, kind: K) -> Self
73 where
74 K: Into<AccountEventKind<ExchangeKey, AssetKey, InstrumentKey>>,
75 {
76 Self {
77 exchange,
78 kind: kind.into(),
79 }
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, From)]
84pub enum AccountEventKind<ExchangeKey, AssetKey, InstrumentKey> {
85 Snapshot(AccountSnapshot<ExchangeKey, AssetKey, InstrumentKey>),
87
88 BalanceSnapshot(Snapshot<AssetBalance<AssetKey>>),
90
91 OrderSnapshot(Snapshot<Order<ExchangeKey, InstrumentKey, OrderState<AssetKey, InstrumentKey>>>),
95
96 OrderCancelled(OrderResponseCancel<ExchangeKey, AssetKey, InstrumentKey>),
98
99 Trade(Trade<QuoteAsset, InstrumentKey>),
101}
102
103impl<ExchangeKey, AssetKey, InstrumentKey> AccountEvent<ExchangeKey, AssetKey, InstrumentKey>
104where
105 AssetKey: Eq,
106 InstrumentKey: Eq,
107{
108 pub fn snapshot(self) -> Option<AccountSnapshot<ExchangeKey, AssetKey, InstrumentKey>> {
109 match self.kind {
110 AccountEventKind::Snapshot(snapshot) => Some(snapshot),
111 _ => None,
112 }
113 }
114}
115
116#[derive(
117 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Constructor,
118)]
119pub struct AccountSnapshot<
120 ExchangeKey = ExchangeIndex,
121 AssetKey = AssetIndex,
122 InstrumentKey = InstrumentIndex,
123> {
124 pub exchange: ExchangeKey,
125 pub balances: Vec<AssetBalance<AssetKey>>,
126 pub instruments: Vec<InstrumentAccountSnapshot<ExchangeKey, AssetKey, InstrumentKey>>,
127}
128
129#[derive(
130 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Constructor,
131)]
132pub struct InstrumentAccountSnapshot<
133 ExchangeKey = ExchangeIndex,
134 AssetKey = AssetIndex,
135 InstrumentKey = InstrumentIndex,
136> {
137 pub instrument: InstrumentKey,
138 #[serde(default = "Vec::new")]
139 pub orders: Vec<OrderSnapshot<ExchangeKey, AssetKey, InstrumentKey>>,
140}
141
142impl<ExchangeKey, AssetKey, InstrumentKey> AccountSnapshot<ExchangeKey, AssetKey, InstrumentKey> {
143 pub fn time_most_recent(&self) -> Option<DateTime<Utc>> {
144 let order_times = self.instruments.iter().flat_map(|instrument| {
145 instrument
146 .orders
147 .iter()
148 .filter_map(|order| order.state.time_exchange())
149 });
150 let balance_times = self.balances.iter().map(|balance| balance.time_exchange);
151
152 order_times.chain(balance_times).max()
153 }
154
155 pub fn assets(&self) -> impl Iterator<Item = &AssetKey> {
156 self.balances.iter().map(|balance| &balance.asset)
157 }
158
159 pub fn instruments(&self) -> impl Iterator<Item = &InstrumentKey> {
160 self.instruments.iter().map(|snapshot| &snapshot.instrument)
161 }
162}