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, Position, Signal,
9 Tick,
10};
11use thiserror::Error;
12
13pub type BrokerResult<T> = Result<T, BrokerError>;
15
16#[derive(Debug, Error)]
18pub enum BrokerError {
19 #[error("transport error: {0}")]
21 Transport(String),
22 #[error("authentication failed: {0}")]
24 Authentication(String),
25 #[error("invalid request: {0}")]
27 InvalidRequest(String),
28 #[error("serialization error: {0}")]
30 Serialization(String),
31 #[error("exchange error: {0}")]
33 Exchange(String),
34 #[error("unexpected error: {0}")]
36 Other(String),
37}
38
39impl BrokerError {
40 pub fn from_display(err: impl std::fmt::Display, kind: BrokerErrorKind) -> Self {
42 match kind {
43 BrokerErrorKind::Transport => Self::Transport(err.to_string()),
44 BrokerErrorKind::Authentication => Self::Authentication(err.to_string()),
45 BrokerErrorKind::InvalidRequest => Self::InvalidRequest(err.to_string()),
46 BrokerErrorKind::Serialization => Self::Serialization(err.to_string()),
47 BrokerErrorKind::Exchange => Self::Exchange(err.to_string()),
48 BrokerErrorKind::Other => Self::Other(err.to_string()),
49 }
50 }
51}
52
53#[derive(Debug, Clone, Copy)]
55pub enum BrokerErrorKind {
56 Transport,
57 Authentication,
58 InvalidRequest,
59 Serialization,
60 Exchange,
61 Other,
62}
63
64#[derive(Clone, Debug, Serialize, Deserialize)]
66pub struct BrokerInfo {
67 pub name: String,
68 pub markets: Vec<String>,
69 pub supports_testnet: bool,
70}
71
72#[async_trait]
74pub trait MarketStream: Send + Sync {
75 type Subscription: Send + Sync + Serialize;
77
78 fn name(&self) -> &str;
80
81 fn info(&self) -> Option<&BrokerInfo> {
83 None
84 }
85
86 async fn subscribe(&mut self, subscription: Self::Subscription) -> BrokerResult<()>;
88
89 async fn next_tick(&mut self) -> BrokerResult<Option<Tick>>;
91
92 async fn next_candle(&mut self) -> BrokerResult<Option<Candle>>;
94
95 async fn next_order_book(&mut self) -> BrokerResult<Option<OrderBook>>;
97}
98
99#[async_trait]
101pub trait ExecutionClient: Send + Sync {
102 fn info(&self) -> BrokerInfo;
104
105 async fn place_order(&self, request: OrderRequest) -> BrokerResult<Order>;
107
108 async fn cancel_order(&self, order_id: OrderId, symbol: &str) -> BrokerResult<()>;
110
111 async fn list_open_orders(&self, symbol: &str) -> BrokerResult<Vec<Order>>;
113
114 async fn account_balances(&self) -> BrokerResult<Vec<AccountBalance>>;
116
117 async fn positions(&self) -> BrokerResult<Vec<Position>>;
119
120 async fn list_instruments(&self, category: &str) -> BrokerResult<Vec<Instrument>>;
122
123 fn as_any(&self) -> &dyn Any;
125}
126
127#[async_trait]
129pub trait EventPublisher: Send + Sync {
130 async fn publish<T>(&self, topic: &str, payload: &T) -> BrokerResult<()>
132 where
133 T: Serialize + Send + Sync;
134}
135
136#[async_trait]
138pub trait HistoricalData {
139 async fn candles(
141 &self,
142 symbol: &str,
143 interval: tesser_core::Interval,
144 limit: usize,
145 ) -> BrokerResult<Vec<Candle>>;
146
147 async fn ticks(&self, symbol: &str, limit: usize) -> BrokerResult<Vec<Tick>>;
149}
150
151#[async_trait]
153pub trait SignalBus: Send + Sync {
154 async fn dispatch(&self, signal: Signal) -> BrokerResult<()>;
156}
157
158pub trait PayloadExt: Sized {
160 fn from_json_bytes(bytes: &[u8]) -> BrokerResult<Self>
162 where
163 Self: DeserializeOwned,
164 {
165 serde_json::from_slice(bytes).map_err(|err| {
166 BrokerError::Serialization(format!("failed to deserialize payload: {err}"))
167 })
168 }
169}
170
171impl<T> PayloadExt for T where T: DeserializeOwned {}