use crate::{
UnindexedAccountEvent, UnindexedAccountSnapshot,
balance::AssetBalance,
error::UnindexedClientError,
order::{
Order,
request::{OrderRequestCancel, OrderRequestOpen, UnindexedOrderResponseCancel},
state::{Open, UnindexedOrderState},
},
trade::Trade,
};
use chrono::{DateTime, Utc};
use futures::Stream;
use rustrade_instrument::{
asset::name::AssetNameExchange, exchange::ExchangeId, instrument::name::InstrumentNameExchange,
};
use std::future::Future;
#[cfg(feature = "alpaca")]
pub mod alpaca;
#[cfg(feature = "binance")]
pub mod binance;
#[cfg(feature = "hyperliquid")]
pub mod hyperliquid;
#[cfg(feature = "ibkr")]
pub mod ibkr;
pub mod mock;
pub trait ExecutionClient
where
Self: Clone,
{
const EXCHANGE: ExchangeId;
type Config: Clone;
type AccountStream: Stream<Item = UnindexedAccountEvent> + Send;
fn new(config: Self::Config) -> Self;
fn account_snapshot(
&self,
assets: &[AssetNameExchange],
instruments: &[InstrumentNameExchange],
) -> impl Future<Output = Result<UnindexedAccountSnapshot, UnindexedClientError>> + Send;
fn account_stream(
&self,
assets: &[AssetNameExchange],
instruments: &[InstrumentNameExchange],
) -> impl Future<Output = Result<Self::AccountStream, UnindexedClientError>> + Send;
fn cancel_order(
&self,
request: OrderRequestCancel<ExchangeId, &InstrumentNameExchange>,
) -> impl Future<Output = Option<UnindexedOrderResponseCancel>> + Send;
fn cancel_orders<'a>(
&self,
requests: impl IntoIterator<Item = OrderRequestCancel<ExchangeId, &'a InstrumentNameExchange>>,
) -> impl Stream<Item = Option<UnindexedOrderResponseCancel>> + Send {
futures::stream::FuturesUnordered::from_iter(
requests
.into_iter()
.map(|request| self.cancel_order(request)),
)
}
fn open_order(
&self,
request: OrderRequestOpen<ExchangeId, &InstrumentNameExchange>,
) -> impl Future<Output = Option<Order<ExchangeId, InstrumentNameExchange, UnindexedOrderState>>>
+ Send;
fn open_orders<'a>(
&self,
requests: impl IntoIterator<Item = OrderRequestOpen<ExchangeId, &'a InstrumentNameExchange>>,
) -> impl Stream<Item = Option<Order<ExchangeId, InstrumentNameExchange, UnindexedOrderState>>> + Send
{
futures::stream::FuturesUnordered::from_iter(
requests.into_iter().map(|request| self.open_order(request)),
)
}
fn fetch_balances(
&self,
assets: &[AssetNameExchange],
) -> impl Future<Output = Result<Vec<AssetBalance<AssetNameExchange>>, UnindexedClientError>> + Send;
fn fetch_open_orders(
&self,
instruments: &[InstrumentNameExchange],
) -> impl Future<
Output = Result<Vec<Order<ExchangeId, InstrumentNameExchange, Open>>, UnindexedClientError>,
> + Send;
fn fetch_trades(
&self,
time_since: DateTime<Utc>,
instruments: &[InstrumentNameExchange],
) -> impl Future<
Output = Result<
Vec<Trade<AssetNameExchange, InstrumentNameExchange>>,
UnindexedClientError,
>,
> + Send;
}