Skip to content

Commit ff01d8e

Browse files
committed
feat: \Exchange\ generic over Market
1 parent db12f61 commit ff01d8e

File tree

7 files changed

+132
-123
lines changed

7 files changed

+132
-123
lines changed

examples/binance/market_futures.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
use std::env;
22

3-
use v_exchanges::{binance::Binance, core::Exchange};
3+
use v_exchanges::{
4+
binance::{self},
5+
core::{Exchange, MarketTrait as _},
6+
};
47

58
#[tokio::main]
69
async fn main() {
710
color_eyre::install().unwrap();
811
v_utils::utils::init_subscriber(v_utils::utils::LogDestination::xdg("v_exchanges"));
912

10-
let mut bn = Binance::default();
13+
let m = binance::Market::Futures;
14+
let mut bn = m.client();
1115

12-
let klines = bn.futures_klines(("BTC", "USDT").into(), "1m".into(), 2.into()).await.unwrap();
13-
let price = bn.futures_price(("BTC", "USDT").into()).await.unwrap();
16+
let klines = bn.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
17+
let price = bn.price(("BTC", "USDT").into(), m).await.unwrap();
1418
dbg!(&klines, price);
1519

1620
if let (Ok(key), Ok(secret)) = (env::var("BINANCE_TIGER_READ_KEY"), env::var("BINANCE_TIGER_READ_SECRET")) {
1721
bn.auth(key, secret);
18-
let balance = bn.futures_asset_balance("USDT".into()).await.unwrap();
22+
let balance = bn.asset_balance("USDT".into(), m).await.unwrap();
1923
dbg!(&balance);
2024
} else {
2125
eprintln!("BINANCE_TIGER_READ_KEY or BINANCE_TIGER_READ_SECRET is missing, skipping private API methods.");

examples/binance/market_spot.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
use v_exchanges::{binance::Binance, core::Exchange};
1+
use v_exchanges::{
2+
binance::{self},
3+
core::{Exchange, MarketTrait as _},
4+
};
25

36
#[tokio::main]
47
async fn main() {
58
color_eyre::install().unwrap();
69
v_utils::utils::init_subscriber(v_utils::utils::LogDestination::xdg("v_exchanges"));
7-
let bn = Binance::default();
810

9-
let spot_klines = bn.spot_klines(("BTC", "USDT").into(), "1m".into(), 2.into()).await.unwrap();
11+
let m = binance::Market::Spot;
12+
let bn = m.client();
13+
14+
let spot_klines = bn.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
1015
dbg!(&spot_klines);
1116

12-
let spot_prices = bn.spot_prices(None).await.unwrap();
17+
let spot_prices = bn.prices(None, m).await.unwrap();
1318
dbg!(&spot_prices[..5]);
1419
}

examples/bybit/market.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use std::env;
22

3-
use v_exchanges::{bybit::Bybit, core::Exchange, Market};
3+
use v_exchanges::{bybit::{self, Bybit}, core::{Exchange, MarketTrait as _}};
44

55
#[tokio::main]
66
async fn main() {
77
color_eyre::install().unwrap();
88
v_utils::utils::init_subscriber(v_utils::utils::LogDestination::xdg("v_exchanges"));
99

10-
let m: Market = "Bybit/Linear".into();
10+
//let m: Market = "Bybit/Linear".into(); // would be nice to be able to do it like this
11+
let m = bybit::Market::Linear;
1112
let mut bb = m.client();
12-
let mut bb = Bybit::default();
1313

1414
//let ticker: serde_json::Value =
1515
//bb.get("/v5/market/tickers", &[("category", "spot"), ("symbol", "BTCUSDT")], [BybitOption::Default])
@@ -24,17 +24,17 @@ async fn main() {
2424

2525
if let (Ok(key), Ok(secret)) = (env::var("BYBIT_TIGER_READ_KEY"), env::var("BYBIT_TIGER_READ_SECRET")) {
2626
bb.auth(key, secret);
27-
private(&mut bb).await;
27+
private(&mut bb, m).await;
2828
} else {
2929
eprintln!("BYBIT_TIGER_READ_KEY or BYBIT_TIGER_READ_SECRET is missing, skipping private API methods.");
3030
}
3131
}
3232

33-
async fn private(bb: &mut Bybit) {
33+
async fn private(bb: &mut Bybit, m: bybit::Market) {
3434
//let key_permissions: serde_json::Value = bb.get_no_query("/v5/user/query-api", [BybitOption::HttpAuth(BybitHttpAuth::V3AndAbove)])
3535
// .await
3636
// .unwrap();
3737

38-
let balances = bb.futures_balances().await.unwrap();
38+
let balances = bb.balances(m).await.unwrap();
3939
dbg!(&balances);
4040
}

v_exchanges/src/binance/mod.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,49 @@ use eyre::Result;
88
use v_exchanges_adapters::Client;
99
use v_utils::trades::{Asset, Pair, Timeframe};
1010

11-
use crate::core::{AssetBalance, Exchange, Klines, KlinesRequestRange, Market as M};
11+
use crate::core::{AssetBalance, Exchange, Klines, KlinesRequestRange};
1212

1313
#[derive(Clone, Debug, Default, Deref, DerefMut)]
1414
pub struct Binance(pub Client);
1515

1616
//? currently client ends up importing this from crate::binance, but could it be possible to lift the [Client] reexport up, and still have the ability to call all exchange methods right on it?
1717
impl Exchange for Binance {
18+
type M = Market;
19+
1820
fn auth<S: Into<String>>(&mut self, key: S, secret: S) {
1921
self.update_default_option(BinanceOption::Key(key.into()));
2022
self.update_default_option(BinanceOption::Secret(secret.into()));
2123
}
2224

23-
async fn klines(&self, pair: Pair, tf: Timeframe, range: KlinesRequestRange, m: M) -> Result<Klines> {
24-
match m {
25-
M::Binance(m) => market::klines(&self.0, pair, tf, range, m).await,
26-
_ => unimplemented!(),
27-
}
25+
async fn klines(&self, pair: Pair, tf: Timeframe, range: KlinesRequestRange, m: Self::M) -> Result<Klines> {
26+
market::klines(&self.0, pair, tf, range, m).await
2827
}
2928

30-
async fn prices(&self, pairs: Option<Vec<Pair>>, m: M) -> Result<Vec<(Pair, f64)>> {
29+
async fn prices(&self, pairs: Option<Vec<Pair>>, m: Self::M) -> Result<Vec<(Pair, f64)>> {
3130
match m {
32-
M::Binance(Market::Spot) => spot::market::prices(&self.0, pairs).await,
31+
Market::Spot => spot::market::prices(&self.0, pairs).await,
3332
_ => unimplemented!(),
3433
}
3534
}
3635

37-
async fn price(&self, pair: Pair, m: M) -> Result<f64> {
36+
async fn price(&self, pair: Pair, m: Self::M) -> Result<f64> {
3837
match m {
39-
M::Binance(Market::Spot) => spot::market::price(&self.0, pair).await,
40-
M::Binance(Market::Futures) => futures::market::price(&self.0, pair).await,
38+
Market::Spot => spot::market::price(&self.0, pair).await,
39+
Market::Futures => futures::market::price(&self.0, pair).await,
4140
_ => unimplemented!(),
4241
}
4342
}
4443

45-
async fn asset_balance(&self, asset: Asset, m: M) -> Result<AssetBalance> {
44+
async fn asset_balance(&self, asset: Asset, m: Self::M) -> Result<AssetBalance> {
4645
match m {
47-
M::Binance(Market::Futures) => futures::account::asset_balance(self, asset).await,
46+
Market::Futures => futures::account::asset_balance(self, asset).await,
4847
_ => unimplemented!(),
4948
}
5049
}
5150

52-
async fn balances(&self, m: M) -> Result<Vec<AssetBalance>> {
51+
async fn balances(&self, m: Self::M) -> Result<Vec<AssetBalance>> {
5352
match m {
54-
M::Binance(Market::Futures) => futures::account::balances(&self.0).await,
53+
Market::Futures => futures::account::balances(&self.0).await,
5554
_ => unimplemented!(),
5655
}
5756
}
@@ -64,8 +63,9 @@ pub enum Market {
6463
Spot,
6564
Margin,
6665
}
67-
impl Market {
68-
pub fn client(&self) -> Box<dyn Exchange> {
69-
Box::new(Binance::default())
66+
impl crate::core::MarketTrait for Market {
67+
type Client = Binance;
68+
fn client(&self) -> Binance {
69+
Binance::default()
7070
}
7171
}

v_exchanges/src/bybit/mod.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,48 @@ use eyre::Result;
88
use v_exchanges_adapters::Client;
99
use v_utils::trades::{Asset, Pair, Timeframe};
1010

11-
use crate::core::{Market as M, AssetBalance, Exchange, Klines, KlinesRequestRange};
11+
use crate::core::{AssetBalance, Exchange, Klines, KlinesRequestRange};
1212

1313
#[derive(Clone, Debug, Default, Deref, DerefMut)]
1414
pub struct Bybit(pub Client);
1515

1616
//? currently client ends up importing this from crate::binance, but could it be possible to lift the [Client] reexport up, and still have the ability to call all exchange methods right on it?
1717
impl Exchange for Bybit {
18+
type M = Market;
19+
1820
fn auth<S: Into<String>>(&mut self, key: S, secret: S) {
1921
self.update_default_option(BybitOption::Key(key.into()));
2022
self.update_default_option(BybitOption::Secret(secret.into()));
2123
}
2224

23-
async fn klines(&self, pair: Pair, tf: Timeframe, range: KlinesRequestRange, m: M) -> Result<Klines> {
25+
async fn klines(&self, pair: Pair, tf: Timeframe, range: KlinesRequestRange, m: Self::M) -> Result<Klines> {
2426
match m {
25-
M::Bybit(Market::Linear) => market::klines(&self.0, pair, tf, range).await,
27+
Market::Linear => market::klines(&self.0, pair, tf, range).await,
2628
_ => unimplemented!(),
2729
}
2830
}
2931

30-
async fn price(&self, pair: Pair, m: M) -> Result<f64> {
32+
async fn price(&self, pair: Pair, m: Self::M) -> Result<f64> {
3133
match m {
32-
M::Bybit(Market::Linear) => market::price(&self.0, pair).await,
34+
Market::Linear => market::price(&self.0, pair).await,
3335
_ => unimplemented!(),
3436
}
3537
}
3638

37-
async fn prices(&self, pairs: Option<Vec<Pair>>, m: M) -> Result<Vec<(Pair, f64)>> {
39+
async fn prices(&self, pairs: Option<Vec<Pair>>, m: Self::M) -> Result<Vec<(Pair, f64)>> {
3840
todo!();
3941
}
4042

41-
async fn asset_balance(&self, asset: Asset, m: M) -> Result<AssetBalance> {
43+
async fn asset_balance(&self, asset: Asset, m: Self::M) -> Result<AssetBalance> {
4244
match m {
43-
M::Bybit(Market::Linear) => account::asset_balance(&self.0, asset).await,
45+
Market::Linear => account::asset_balance(&self.0, asset).await,
4446
_ => unimplemented!(),
4547
}
4648
}
4749

48-
async fn balances(&self, m: M) -> Result<Vec<AssetBalance>> {
50+
async fn balances(&self, m: Self::M) -> Result<Vec<AssetBalance>> {
4951
match m{
50-
M::Bybit(Market::Linear) => account::balances(&self.0).await,
52+
Market::Linear => account::balances(&self.0).await,
5153
_ => unimplemented!(),
5254
}
5355
}
@@ -61,8 +63,9 @@ pub enum Market {
6163
Spot,
6264
Inverse,
6365
}
64-
impl Market {
65-
pub fn client(&self) -> Box<impl Exchange> {
66-
Box::new(Bybit::default())
66+
impl crate::core::MarketTrait for Market {
67+
type Client = Bybit;
68+
fn client(&self) -> Bybit {
69+
Bybit::default()
6770
}
6871
}

0 commit comments

Comments
 (0)