1use std::any::Any;
4
5use async_trait::async_trait;
6use serde::{de::DeserializeOwned, Deserialize, Serialize};
7use tesser_core::{
8 AccountBalance, Candle, Instrument, Order, OrderBook, OrderId, OrderRequest,
9 OrderUpdateRequest, Position, Signal, Symbol, Tick,
10};
11use thiserror::Error;
12
13pub mod limiter;
14
15pub use governor::Quota;
16pub use limiter::{RateLimiter, RateLimiterError};
17
18pub type BrokerResult<T> = Result<T, BrokerError>;
20
21#[derive(Debug, Error)]
23pub enum BrokerError {
24 #[error("transport error: {0}")]
26 Transport(String),
27 #[error("authentication failed: {0}")]
29 Authentication(String),
30 #[error("invalid request: {0}")]
32 InvalidRequest(String),
33 #[error("serialization error: {0}")]
35 Serialization(String),
36 #[error("exchange error: {0}")]
38 Exchange(String),
39 #[error("unexpected error: {0}")]
41 Other(String),
42}
43
44impl BrokerError {
45 pub fn from_display(err: impl std::fmt::Display, kind: BrokerErrorKind) -> Self {
47 match kind {
48 BrokerErrorKind::Transport => Self::Transport(err.to_string()),
49 BrokerErrorKind::Authentication => Self::Authentication(err.to_string()),
50 BrokerErrorKind::InvalidRequest => Self::InvalidRequest(err.to_string()),
51 BrokerErrorKind::Serialization => Self::Serialization(err.to_string()),
52 BrokerErrorKind::Exchange => Self::Exchange(err.to_string()),
53 BrokerErrorKind::Other => Self::Other(err.to_string()),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy)]
60pub enum BrokerErrorKind {
61 Transport,
62 Authentication,
63 InvalidRequest,
64 Serialization,
65 Exchange,
66 Other,
67}
68
69#[derive(Clone, Debug, Serialize, Deserialize)]
71pub struct BrokerInfo {
72 pub name: String,
73 pub markets: Vec<String>,
74 pub supports_testnet: bool,
75}
76
77#[async_trait]
79pub trait MarketStream: Send + Sync {
80 type Subscription: Send + Sync + Serialize;
82
83 fn name(&self) -> &str;
85
86 fn info(&self) -> Option<&BrokerInfo> {
88 None
89 }
90
91 async fn subscribe(&mut self, subscription: Self::Subscription) -> BrokerResult<()>;
93
94 async fn next_tick(&mut self) -> BrokerResult<Option<Tick>>;
96
97 async fn next_candle(&mut self) -> BrokerResult<Option<Candle>>;
99
100 async fn next_order_book(&mut self) -> BrokerResult<Option<OrderBook>>;
102}
103
104#[async_trait]
106pub trait ExecutionClient: Send + Sync {
107 fn info(&self) -> BrokerInfo;
109
110 async fn place_order(&self, request: OrderRequest) -> BrokerResult<Order>;
112
113 async fn cancel_order(&self, order_id: OrderId, symbol: Symbol) -> BrokerResult<()>;
115
116 async fn amend_order(&self, request: OrderUpdateRequest) -> BrokerResult<Order>;
118
119 async fn list_open_orders(&self, symbol: Symbol) -> BrokerResult<Vec<Order>>;
121
122 async fn account_balances(&self) -> BrokerResult<Vec<AccountBalance>>;
124
125 async fn positions(&self) -> BrokerResult<Vec<Position>>;
127
128 async fn list_instruments(&self, category: &str) -> BrokerResult<Vec<Instrument>>;
130
131 fn as_any(&self) -> &dyn Any;
133}
134
135#[async_trait]
137pub trait EventPublisher: Send + Sync {
138 async fn publish<T>(&self, topic: &str, payload: &T) -> BrokerResult<()>
140 where
141 T: Serialize + Send + Sync;
142}
143
144#[async_trait]
146pub trait HistoricalData {
147 async fn candles(
149 &self,
150 symbol: &str,
151 interval: tesser_core::Interval,
152 limit: usize,
153 ) -> BrokerResult<Vec<Candle>>;
154
155 async fn ticks(&self, symbol: &str, limit: usize) -> BrokerResult<Vec<Tick>>;
157}
158
159#[async_trait]
161pub trait SignalBus: Send + Sync {
162 async fn dispatch(&self, signal: Signal) -> BrokerResult<()>;
164}
165
166pub trait PayloadExt: Sized {
168 fn from_json_bytes(bytes: &[u8]) -> BrokerResult<Self>
170 where
171 Self: DeserializeOwned,
172 {
173 serde_json::from_slice(bytes).map_err(|err| {
174 BrokerError::Serialization(format!("failed to deserialize payload: {err}"))
175 })
176 }
177}
178
179impl<T> PayloadExt for T where T: DeserializeOwned {}
180
181mod connector;
182pub use connector::{
183 get_connector_factory, register_connector_factory, registered_connectors, ConnectorFactory,
184 ConnectorStream, ConnectorStreamConfig,
185};
186pub mod router;
187pub use router::RouterExecutionClient;