use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use crate::error::OpenPxError;
use crate::models::{
Candlestick, Fill, Market, MarketTrade, Order, OrderSide, Orderbook, OrderbookSnapshot,
Position, PriceHistoryInterval,
};
use super::config::{FetchMarketsParams, FetchOrdersParams, FetchUserActivityParams};
use super::manifest::ExchangeManifest;
#[allow(async_fn_in_trait)]
pub trait Exchange: Send + Sync {
fn id(&self) -> &'static str;
fn name(&self) -> &'static str;
async fn fetch_markets(
&self,
params: &FetchMarketsParams,
) -> Result<(Vec<Market>, Option<String>), OpenPxError>;
async fn fetch_market(&self, market_id: &str) -> Result<Market, OpenPxError>;
async fn create_order(
&self,
market_id: &str,
outcome: &str,
side: OrderSide,
price: f64,
size: f64,
params: HashMap<String, String>,
) -> Result<Order, OpenPxError>;
async fn cancel_order(
&self,
order_id: &str,
market_id: Option<&str>,
) -> Result<Order, OpenPxError>;
async fn fetch_order(
&self,
order_id: &str,
market_id: Option<&str>,
) -> Result<Order, OpenPxError>;
async fn fetch_open_orders(
&self,
params: Option<FetchOrdersParams>,
) -> Result<Vec<Order>, OpenPxError>;
async fn fetch_positions(&self, market_id: Option<&str>) -> Result<Vec<Position>, OpenPxError>;
async fn fetch_balance(&self) -> Result<HashMap<String, f64>, OpenPxError>;
async fn refresh_balance(&self) -> Result<(), OpenPxError> {
Ok(())
}
async fn fetch_orderbook(&self, req: OrderbookRequest) -> Result<Orderbook, OpenPxError> {
let _ = req;
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_orderbook".into()),
))
}
async fn fetch_price_history(
&self,
req: PriceHistoryRequest,
) -> Result<Vec<Candlestick>, OpenPxError> {
let _ = req;
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_price_history".into()),
))
}
async fn fetch_trades(
&self,
req: TradesRequest,
) -> Result<(Vec<MarketTrade>, Option<String>), OpenPxError> {
let _ = req;
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_trades".into()),
))
}
async fn fetch_orderbook_history(
&self,
req: OrderbookHistoryRequest,
) -> Result<(Vec<OrderbookSnapshot>, Option<String>), OpenPxError> {
let _ = req;
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_orderbook_history".into()),
))
}
async fn fetch_balance_raw(&self) -> Result<Value, OpenPxError> {
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_balance_raw".into()),
))
}
async fn fetch_user_activity(
&self,
params: FetchUserActivityParams,
) -> Result<Value, OpenPxError> {
let _ = params;
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_user_activity".into()),
))
}
async fn fetch_fills(
&self,
market_id: Option<&str>,
limit: Option<usize>,
) -> Result<Vec<Fill>, OpenPxError> {
let _ = (market_id, limit);
Err(OpenPxError::Exchange(
crate::error::ExchangeError::NotSupported("fetch_fills".into()),
))
}
fn describe(&self) -> ExchangeInfo {
ExchangeInfo {
id: self.id(),
name: self.name(),
has_fetch_markets: true,
has_create_order: true,
has_cancel_order: true,
has_fetch_positions: true,
has_fetch_balance: true,
has_fetch_orderbook: false,
has_fetch_price_history: false,
has_fetch_trades: false,
has_fetch_user_activity: false,
has_fetch_fills: false,
has_approvals: false,
has_refresh_balance: false,
has_websocket: false,
has_fetch_orderbook_history: false,
}
}
fn manifest(&self) -> &'static ExchangeManifest;
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ExchangeInfo {
pub id: &'static str,
pub name: &'static str,
pub has_fetch_markets: bool,
pub has_create_order: bool,
pub has_cancel_order: bool,
pub has_fetch_positions: bool,
pub has_fetch_balance: bool,
pub has_fetch_orderbook: bool,
pub has_fetch_price_history: bool,
pub has_fetch_trades: bool,
pub has_fetch_user_activity: bool,
pub has_fetch_fills: bool,
pub has_approvals: bool,
pub has_refresh_balance: bool,
pub has_websocket: bool,
pub has_fetch_orderbook_history: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct OrderbookRequest {
pub market_id: String,
pub outcome: Option<String>,
pub token_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct PriceHistoryRequest {
pub market_id: String,
pub outcome: Option<String>,
pub token_id: Option<String>,
pub condition_id: Option<String>,
pub interval: PriceHistoryInterval,
pub start_ts: Option<i64>,
pub end_ts: Option<i64>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TradesRequest {
pub market_id: String,
pub market_ref: Option<String>,
pub outcome: Option<String>,
pub token_id: Option<String>,
pub start_ts: Option<i64>,
pub end_ts: Option<i64>,
pub limit: Option<usize>,
pub cursor: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct OrderbookHistoryRequest {
pub market_id: String,
pub token_id: Option<String>,
pub start_ts: Option<i64>,
pub end_ts: Option<i64>,
pub limit: Option<usize>,
pub cursor: Option<String>,
}