Skip to content

Commit e80bc82

Browse files
authored
Merge pull request #18 from valeratrades/abs_market
AbsMarket
2 parents ac18521 + f70d555 commit e80bc82

File tree

12 files changed

+217
-183
lines changed

12 files changed

+217
-183
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
![Minimum Supported Rust Version](https://img.shields.io/badge/nightly-1.85+-ab6000.svg)
33
[<img alt="crates.io" src="https://img.shields.io/crates/v/v_exchanges.svg?color=fc8d62&logo=rust" height="20" style=flat-square>](https://crates.io/crates/v_exchanges)
44
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs&style=flat-square" height="20">](https://docs.rs/v_exchanges)
5-
![Lines Of Code](https://img.shields.io/badge/LoC-3769-lightblue)
5+
![Lines Of Code](https://img.shields.io/badge/LoC-3864-lightblue)
66
<br>
77
[<img alt="ci errors" src="https://img.shields.io/github/actions/workflow/status/valeratrades/v_exchanges/errors.yml?branch=master&style=for-the-badge&style=flat-square&label=errors&labelColor=420d09" height="20">](https://github.com/valeratrades/v_exchanges/actions?query=branch%3Amaster) <!--NB: Won't find it if repo is private-->
88
[<img alt="ci warnings" src="https://img.shields.io/github/actions/workflow/status/valeratrades/v_exchanges/warnings.yml?branch=master&style=for-the-badge&style=flat-square&label=warnings&labelColor=d16002" height="20">](https://github.com/valeratrades/v_exchanges/actions?query=branch%3Amaster) <!--NB: Won't find it if repo is private-->

examples/binance/market_futures.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
use std::env;
22

33
use v_exchanges::{
4-
binance,
5-
core::{Exchange, MarketTrait as _},
4+
prelude::*,
65
};
76

87
#[tokio::main]
98
async fn main() {
109
color_eyre::install().unwrap();
1110
v_utils::utils::init_subscriber(v_utils::utils::LogDestination::xdg("v_exchanges"));
1211

13-
let m = binance::Market::Futures;
14-
let mut bn = m.client();
12+
let m: AbsMarket = "Binance/Futures".into();
13+
let mut c = m.client();
1514

16-
let exchange_info = bn.exchange_info(m).await.unwrap();
17-
dbg!( &exchange_info .pairs .iter() .take(2) .collect::<Vec<_>>());
15+
let exchange_info = c.exchange_info(m).await.unwrap();
16+
dbg!(&exchange_info.pairs.iter().take(2).collect::<Vec<_>>());
1817

19-
let klines = bn.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
20-
let price = bn.price(("BTC", "USDT").into(), m).await.unwrap();
18+
let klines = c.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
19+
let price = c.price(("BTC", "USDT").into(), m).await.unwrap();
2120
dbg!(&klines, price);
2221

2322
if let (Ok(key), Ok(secret)) = (env::var("BINANCE_TIGER_READ_KEY"), env::var("BINANCE_TIGER_READ_SECRET")) {
24-
bn.auth(key, secret);
25-
let balance = bn.asset_balance("USDT".into(), m).await.unwrap();
23+
c.auth(key, secret);
24+
let balance = c.asset_balance("USDT".into(), m).await.unwrap();
2625
dbg!(&balance);
2726
} else {
2827
eprintln!("BINANCE_TIGER_READ_KEY or BINANCE_TIGER_READ_SECRET is missing, skipping private API methods.");

examples/binance/market_spot.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use v_exchanges::{
2-
binance,
3-
core::{Exchange, MarketTrait as _},
4-
};
1+
use v_exchanges::prelude::*;
52

63
#[tokio::main]
74
async fn main() {
@@ -10,12 +7,13 @@ async fn main() {
107

118
//let m: Market = "Binance/Spot".into(); // would be nice to be able to do it like this, without having to carry around exchange-specific type
129
// Currently if I want to pass around the market struct in my code after initializing it, I have to pass around eg `binance::Market`, which is a ridiculous thing to hardcode into function signatures
13-
let m = binance::Market::Spot;
14-
let bn = m.client();
10+
//let m = binance::Market::Spot;
11+
let m: AbsMarket = "Binance/Spot".into();
12+
let c = m.client();
1513

16-
let spot_klines = bn.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
14+
let spot_klines = c.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
1715
dbg!(&spot_klines);
1816

19-
let spot_prices = bn.prices(None, m).await.unwrap();
17+
let spot_prices = c.prices(None, m).await.unwrap();
2018
dbg!(&spot_prices[..5]);
2119
}

examples/bybit/market.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,34 @@
11
use std::env;
22

3-
use v_exchanges::{
4-
bybit::{self, Bybit},
5-
core::{Exchange, MarketTrait as _},
6-
};
3+
use v_exchanges::prelude::*;
74

85
#[tokio::main]
96
async fn main() {
107
color_eyre::install().unwrap();
118
v_utils::utils::init_subscriber(v_utils::utils::LogDestination::xdg("v_exchanges"));
129

1310
//let m: Market = "Bybit/Linear".into(); // would be nice to be able to do it like this
14-
let m = bybit::Market::Linear;
15-
let mut bb = m.client();
11+
let m: AbsMarket = "Bybit/Linear".into();
12+
let mut c = m.client();
1613

17-
let klines = bb.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
14+
let klines = c.klines(("BTC", "USDT").into(), "1m".into(), 2.into(), m).await.unwrap();
1815
dbg!(&klines);
19-
let price = bb.price(("BTC", "USDT").into(), m).await.unwrap();
16+
let price = c.price(("BTC", "USDT").into(), m).await.unwrap();
2017
dbg!(&price);
2118

2219
if let (Ok(key), Ok(secret)) = (env::var("BYBIT_TIGER_READ_KEY"), env::var("BYBIT_TIGER_READ_SECRET")) {
23-
bb.auth(key, secret);
24-
private(&mut bb, m).await;
20+
c.auth(key, secret);
21+
private(&mut c, m).await;
2522
} else {
2623
eprintln!("BYBIT_TIGER_READ_KEY or BYBIT_TIGER_READ_SECRET is missing, skipping private API methods.");
2724
}
2825
}
2926

30-
async fn private(bb: &mut Bybit, m: bybit::Market) {
27+
async fn private(c: &mut Box<dyn Exchange>, m: AbsMarket) {
3128
//let key_permissions: serde_json::Value = bb.get_no_query("/v5/user/query-api", [BybitOption::HttpAuth(BybitHttpAuth::V3AndAbove)])
3229
// .await
3330
// .unwrap();
3431

35-
let balances = bb.balances(m).await.unwrap();
32+
let balances = c.balances(m).await.unwrap();
3633
dbg!(&balances);
3734
}

examples/data.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use v_exchanges::{binance::Binance, bitmex::Bitmex};
22

3+
/// things in here are not on [Exchange](v_exchanges::core::Exchange) trait, so can't use generics, must specify exact exchange client methods are referenced from.
34
#[tokio::main]
45
async fn main() {
56
color_eyre::install().unwrap();

v_exchanges/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ rustdoc-args = ["--cfg", "docsrs"]
2424
ignored = ["derive-new", "color-eyre", "serde", "tokio", "v_utils"]
2525

2626
[dependencies]
27+
async-trait = "0.1.85"
2728
chrono = { version = "0.4.39", features = ["serde"] }
2829
derive-new.workspace = true
2930
derive_more.workspace = true
@@ -40,7 +41,6 @@ tracing.workspace = true
4041
v_utils = { workspace = true }
4142

4243
v_exchanges_adapters = { version = "^0.3.0", path = "../v_exchanges_adapters/", features = ["full"] }
43-
async-trait = "0.1.85"
4444

4545
reqwest = { version = "^0.12.12", optional = true }
4646

v_exchanges/src/binance/futures/general.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
use adapters::binance::{BinanceHttpUrl, BinanceOption};
32
use chrono::DateTime;
43
use eyre::Result;

v_exchanges/src/binance/mod.rs

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,76 +3,96 @@ mod futures;
33
mod market;
44
mod spot;
55
use adapters::binance::BinanceOption;
6-
use derive_more::{Deref, DerefMut, Display, FromStr};
6+
use derive_more::{Deref, DerefMut};
77
use eyre::Result;
88
use v_exchanges_adapters::Client;
99
use v_utils::trades::{Asset, Pair, Timeframe};
1010

11-
use crate::core::{AssetBalance, Exchange, ExchangeInfo, Klines, RequestRange};
11+
use crate::core::{AbsMarket, AssetBalance, Exchange, ExchangeInfo, Klines, RequestRange, WrongExchangeError};
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
#[async_trait::async_trait]
1818
impl Exchange for Binance {
19-
type M = Market;
19+
fn exchange_name(&self) -> &'static str {
20+
"Binance"
21+
}
2022

2123
fn auth(&mut self, key: String, secret: String) {
2224
self.update_default_option(BinanceOption::Key(key));
2325
self.update_default_option(BinanceOption::Secret(secret));
2426
}
2527

26-
async fn exchange_info(&self, m: Self::M) -> Result<ExchangeInfo> {
27-
match m {
28-
Market::Futures => futures::general::exchange_info(&self.0).await,
29-
_ => unimplemented!(),
28+
async fn exchange_info(&self, am: AbsMarket) -> Result<ExchangeInfo> {
29+
match am {
30+
AbsMarket::Binance(m) => match m {
31+
Market::Futures => futures::general::exchange_info(&self.0).await,
32+
_ => unimplemented!(),
33+
},
34+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
3035
}
3136
}
3237

33-
async fn klines(&self, pair: Pair, tf: Timeframe, range: RequestRange, m: Self::M) -> Result<Klines> {
34-
market::klines(&self.0, pair, tf, range, m).await
38+
async fn klines(&self, pair: Pair, tf: Timeframe, range: RequestRange, am: AbsMarket) -> Result<Klines> {
39+
match am {
40+
AbsMarket::Binance(m) => market::klines(&self.0, pair, tf, range, m).await,
41+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
42+
}
3543
}
3644

37-
async fn prices(&self, pairs: Option<Vec<Pair>>, m: Self::M) -> Result<Vec<(Pair, f64)>> {
38-
match m {
39-
Market::Spot => spot::market::prices(&self.0, pairs).await,
40-
_ => unimplemented!(),
45+
async fn prices(&self, pairs: Option<Vec<Pair>>, am: AbsMarket) -> Result<Vec<(Pair, f64)>> {
46+
match am {
47+
AbsMarket::Binance(m) => match m {
48+
Market::Spot => spot::market::prices(&self.0, pairs).await,
49+
_ => unimplemented!(),
50+
},
51+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
4152
}
4253
}
4354

44-
async fn price(&self, pair: Pair, m: Self::M) -> Result<f64> {
45-
match m {
46-
Market::Spot => spot::market::price(&self.0, pair).await,
47-
Market::Futures => futures::market::price(&self.0, pair).await,
48-
_ => unimplemented!(),
55+
async fn price(&self, pair: Pair, am: AbsMarket) -> Result<f64> {
56+
match am {
57+
AbsMarket::Binance(m) => match m {
58+
Market::Spot => spot::market::price(&self.0, pair).await,
59+
Market::Futures => futures::market::price(&self.0, pair).await,
60+
_ => unimplemented!(),
61+
},
62+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
4963
}
5064
}
5165

52-
async fn asset_balance(&self, asset: Asset, m: Self::M) -> Result<AssetBalance> {
53-
match m {
54-
Market::Futures => futures::account::asset_balance(self, asset).await,
55-
_ => unimplemented!(),
66+
async fn asset_balance(&self, asset: Asset, am: AbsMarket) -> Result<AssetBalance> {
67+
match am {
68+
AbsMarket::Binance(m) => match m {
69+
Market::Futures => futures::account::asset_balance(self, asset).await,
70+
_ => unimplemented!(),
71+
},
72+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
5673
}
5774
}
5875

59-
async fn balances(&self, m: Self::M) -> Result<Vec<AssetBalance>> {
60-
match m {
61-
Market::Futures => futures::account::balances(&self.0).await,
62-
_ => unimplemented!(),
76+
async fn balances(&self, am: AbsMarket) -> Result<Vec<AssetBalance>> {
77+
match am {
78+
AbsMarket::Binance(m) => match m {
79+
Market::Futures => futures::account::balances(&self.0).await,
80+
_ => unimplemented!(),
81+
},
82+
_ => Err(WrongExchangeError::new(self.exchange_name(), am).into()),
6383
}
6484
}
6585
}
6686

67-
#[derive(Debug, Clone, Default, Copy, Display, FromStr)]
87+
#[derive(Debug, Clone, Default, Copy, derive_more::Display, derive_more::FromStr)]
6888
pub enum Market {
6989
#[default]
7090
Futures,
7191
Spot,
7292
Margin,
7393
}
7494
impl crate::core::MarketTrait for Market {
75-
fn client(&self) -> Box<dyn Exchange<M = Self>> {
95+
fn client(&self) -> Box<dyn Exchange> {
7696
Box::new(Binance::default())
7797
}
7898

v_exchanges/src/bybit/market.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::VecDeque;
22

3-
use chrono::{DateTime, TimeZone};
3+
use chrono::DateTime;
44
use eyre::Result;
55
use serde::{Deserialize, Serialize};
66
use serde_json::{Value, json};

0 commit comments

Comments
 (0)