Skip to content

Commit b04303e

Browse files
committed
_
1 parent 0433541 commit b04303e

File tree

12 files changed

+267
-37
lines changed

12 files changed

+267
-37
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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-4655-lightblue)
5+
![Lines Of Code](https://img.shields.io/badge/LoC-4861-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-->

v_exchanges/src/binance/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ impl Exchange for Binance {
2727
self.source_market.unwrap()
2828
}
2929

30+
fn __client(&self) -> &Client {
31+
&self.client
32+
}
33+
34+
fn __client_mut(&mut self) -> &mut Client {
35+
&mut self.client
36+
}
37+
3038
fn auth(&mut self, key: String, secret: SecretString) {
3139
self.update_default_option(BinanceOption::Key(key));
3240
self.update_default_option(BinanceOption::Secret(secret));

v_exchanges/src/bybit/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ impl Exchange for Bybit {
3333
self.source_market.unwrap()
3434
}
3535

36+
fn __client(&self) -> &Client {
37+
&self.client
38+
}
39+
40+
fn __client_mut(&mut self) -> &mut Client {
41+
&mut self.client
42+
}
43+
3644
fn auth(&mut self, key: String, secret: SecretString) {
3745
self.update_default_option(BybitOption::Key(key));
3846
self.update_default_option(BybitOption::Secret(secret));

v_exchanges/src/core.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::{BTreeMap, VecDeque};
22

3+
use adapters::Client;
34
use chrono::{DateTime, TimeDelta, Utc};
45
use derive_more::{Deref, DerefMut};
56
use eyre::{Report, Result, bail};
@@ -18,12 +19,19 @@ pub trait Exchange: std::fmt::Debug + Send {
1819
fn exchange_name(&self) -> &'static str {
1920
self.source_market().exchange_name()
2021
}
22+
fn __client_mut(&mut self) -> &mut Client;
23+
fn __client(&self) -> &Client;
2124
//,}}}
2225

2326
// Config {{{
2427
fn auth(&mut self, key: String, secret: SecretString);
2528
/// Set number of **milliseconds** the request is valid for. Recv Window of over a minute does not make sense, thus it's expressed as u16.
2629
fn set_recv_window(&mut self, recv_window: u16);
30+
fn set_timeout(&mut self, timeout: u16) {
31+
//self.__client_mut().set_timeout(timeout);
32+
todo!();
33+
}
34+
//DO: same for other fields in [RequestConfig](v_exchanges_api_generics::http::RequestConfig)
2735
//,}}}
2836

2937
async fn exchange_info(&self, m: AbsMarket) -> Result<ExchangeInfo>;

v_exchanges/src/mexc/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ impl Exchange for Mexc {
3333
self.source_market.unwrap()
3434
}
3535

36+
fn __client(&self) -> &Client {
37+
&self.client
38+
}
39+
40+
fn __client_mut(&mut self) -> &mut Client {
41+
&mut self.client
42+
}
43+
3644
fn auth(&mut self, key: String, secret: SecretString) {
3745
self.update_default_option(MexcOption::Key(key));
3846
self.update_default_option(MexcOption::Secret(secret));

v_exchanges_adapters/src/exchanges/binance.rs

Lines changed: 203 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,10 @@ where
172172
type Successful = R;
173173
type Unsuccessful = BinanceHandlerError;
174174

175-
fn request_config(&self) -> RequestConfig {
176-
let mut config = self.options.request_config.clone();
177-
if self.options.http_url != BinanceHttpUrl::None {
175+
fn patch_request_config(&self, config: &mut RequestConfig) {
176+
if self.options.http_url == BinanceHttpUrl::default() {
178177
config.url_prefix = self.options.http_url.as_str().to_owned();
179178
}
180-
config
181179
}
182180

183181
#[tracing::instrument(skip_all, fields(?builder))]
@@ -227,6 +225,9 @@ where
227225
})
228226
} else {
229227
// https://binance-docs.github.io/apidocs/spot/en/#limits
228+
//TODO: error parsing from status
229+
//let error_code = BinanceErrorCode::from(status.as_u16());
230+
//XXX: binance doesn't even return these
230231
if status == 429 || status == 418 {
231232
let retry_after = if let Some(value) = headers.get("Retry-After") {
232233
if let Ok(string) = value.to_str() {
@@ -399,3 +400,201 @@ impl Default for BinanceOption {
399400
Self::Default
400401
}
401402
}
403+
404+
#[derive(Debug, Serialize, Deserialize, PartialEq)]
405+
#[serde(from = "i32")]
406+
pub enum BinanceErrorCode {
407+
// 10xx - General Server/Network
408+
Unknown,
409+
Disconnected,
410+
Unauthorized,
411+
TooManyRequests,
412+
UnexpectedResponse,
413+
Timeout,
414+
ServerBusy,
415+
InvalidMessage,
416+
UnknownOrderComposition,
417+
TooManyOrders,
418+
ServiceShuttingDown,
419+
UnsupportedOperation,
420+
InvalidTimestamp,
421+
InvalidSignature,
422+
423+
// 11xx - Request issues
424+
IllegalChars,
425+
TooManyParameters,
426+
MandatoryParamEmptyOrMalformed,
427+
UnknownParam,
428+
UnreadParameters,
429+
ParamEmpty,
430+
ParamNotRequired,
431+
ParamOverflow,
432+
BadPrecision,
433+
NoDepth,
434+
TifNotRequired,
435+
InvalidTif,
436+
InvalidOrderType,
437+
InvalidSide,
438+
EmptyNewClOrdId,
439+
EmptyOrgClOrdId,
440+
BadInterval,
441+
BadSymbol,
442+
InvalidSymbolStatus,
443+
InvalidListenKey,
444+
MoreThanXXHours,
445+
OptionalParamsBadCombo,
446+
InvalidParameter,
447+
BadStrategyType,
448+
InvalidJson,
449+
InvalidTickerType,
450+
InvalidCancelRestrictions,
451+
DuplicateSymbols,
452+
InvalidSbeHeader,
453+
UnsupportedSchemaId,
454+
SbeDisabled,
455+
OcoOrderTypeRejected,
456+
OcoIcebergqtyTimeinforce,
457+
DeprecatedSchema,
458+
BuyOcoLimitMustBeBelow,
459+
SellOcoLimitMustBeAbove,
460+
BothOcoOrdersCannotBeLimit,
461+
InvalidTagNumber,
462+
TagNotDefinedInMessage,
463+
TagAppearsMoreThanOnce,
464+
TagOutOfOrder,
465+
GroupFieldsOutOfOrder,
466+
InvalidComponent,
467+
ResetSeqNumSupport,
468+
AlreadyLoggedIn,
469+
GarbledMessage,
470+
BadSenderCompid,
471+
BadSeqNum,
472+
ExpectedLogon,
473+
TooManyMessages,
474+
ParamsBadCombo,
475+
NotAllowedInDropCopySessions,
476+
DropCopySessionNotAllowed,
477+
DropCopySessionRequired,
478+
NotAllowedInOrderEntrySessions,
479+
NotAllowedInMarketDataSessions,
480+
IncorrectNumInGroupCount,
481+
DuplicateEntriesInAGroup,
482+
InvalidRequestId,
483+
TooManySubscriptions,
484+
BuyOcoStopLossMustBeAbove,
485+
SellOcoStopLossMustBeBelow,
486+
BuyOcoTakeProfitMustBeBelow,
487+
SellOcoTakeProfitMustBeAbove,
488+
489+
// 20xx - Business logic errors
490+
NewOrderRejected,
491+
CancelRejected,
492+
NoSuchOrder,
493+
BadApiKeyFmt,
494+
RejectedMbxKey,
495+
NoTradingWindow,
496+
OrderArchived,
497+
OrderCancelReplacePartiallyFailed,
498+
OrderCancelReplaceFailed,
499+
500+
// Unknown error code
501+
Other(i32),
502+
}
503+
504+
impl From<i32> for BinanceErrorCode {
505+
fn from(code: i32) -> Self {
506+
match code {
507+
-1000 => Self::Unknown,
508+
-1001 => Self::Disconnected,
509+
-1002 => Self::Unauthorized,
510+
-1003 => Self::TooManyRequests,
511+
-1006 => Self::UnexpectedResponse,
512+
-1007 => Self::Timeout,
513+
-1008 => Self::ServerBusy,
514+
-1013 => Self::InvalidMessage,
515+
-1014 => Self::UnknownOrderComposition,
516+
-1015 => Self::TooManyOrders,
517+
-1016 => Self::ServiceShuttingDown,
518+
-1020 => Self::UnsupportedOperation,
519+
-1021 => Self::InvalidTimestamp,
520+
-1022 => Self::InvalidSignature,
521+
522+
-1100 => Self::IllegalChars,
523+
-1101 => Self::TooManyParameters,
524+
-1102 => Self::MandatoryParamEmptyOrMalformed,
525+
-1103 => Self::UnknownParam,
526+
-1104 => Self::UnreadParameters,
527+
-1105 => Self::ParamEmpty,
528+
-1106 => Self::ParamNotRequired,
529+
-1108 => Self::ParamOverflow,
530+
-1111 => Self::BadPrecision,
531+
-1112 => Self::NoDepth,
532+
-1114 => Self::TifNotRequired,
533+
-1115 => Self::InvalidTif,
534+
-1116 => Self::InvalidOrderType,
535+
-1117 => Self::InvalidSide,
536+
-1118 => Self::EmptyNewClOrdId,
537+
-1119 => Self::EmptyOrgClOrdId,
538+
-1120 => Self::BadInterval,
539+
-1121 => Self::BadSymbol,
540+
-1122 => Self::InvalidSymbolStatus,
541+
-1125 => Self::InvalidListenKey,
542+
-1127 => Self::MoreThanXXHours,
543+
-1128 => Self::OptionalParamsBadCombo,
544+
-1130 => Self::InvalidParameter,
545+
-1134 => Self::BadStrategyType,
546+
-1135 => Self::InvalidJson,
547+
-1139 => Self::InvalidTickerType,
548+
-1145 => Self::InvalidCancelRestrictions,
549+
-1151 => Self::DuplicateSymbols,
550+
-1152 => Self::InvalidSbeHeader,
551+
-1153 => Self::UnsupportedSchemaId,
552+
-1155 => Self::SbeDisabled,
553+
-1158 => Self::OcoOrderTypeRejected,
554+
-1160 => Self::OcoIcebergqtyTimeinforce,
555+
-1161 => Self::DeprecatedSchema,
556+
-1165 => Self::BuyOcoLimitMustBeBelow,
557+
-1166 => Self::SellOcoLimitMustBeAbove,
558+
-1168 => Self::BothOcoOrdersCannotBeLimit,
559+
-1169 => Self::InvalidTagNumber,
560+
-1170 => Self::TagNotDefinedInMessage,
561+
-1171 => Self::TagAppearsMoreThanOnce,
562+
-1172 => Self::TagOutOfOrder,
563+
-1173 => Self::GroupFieldsOutOfOrder,
564+
-1174 => Self::InvalidComponent,
565+
-1175 => Self::ResetSeqNumSupport,
566+
-1176 => Self::AlreadyLoggedIn,
567+
-1177 => Self::GarbledMessage,
568+
-1178 => Self::BadSenderCompid,
569+
-1179 => Self::BadSeqNum,
570+
-1180 => Self::ExpectedLogon,
571+
-1181 => Self::TooManyMessages,
572+
-1182 => Self::ParamsBadCombo,
573+
-1183 => Self::NotAllowedInDropCopySessions,
574+
-1184 => Self::DropCopySessionNotAllowed,
575+
-1185 => Self::DropCopySessionRequired,
576+
-1186 => Self::NotAllowedInOrderEntrySessions,
577+
-1187 => Self::NotAllowedInMarketDataSessions,
578+
-1188 => Self::IncorrectNumInGroupCount,
579+
-1189 => Self::DuplicateEntriesInAGroup,
580+
-1190 => Self::InvalidRequestId,
581+
-1191 => Self::TooManySubscriptions,
582+
-1196 => Self::BuyOcoStopLossMustBeAbove,
583+
-1197 => Self::SellOcoStopLossMustBeBelow,
584+
-1198 => Self::BuyOcoTakeProfitMustBeBelow,
585+
-1199 => Self::SellOcoTakeProfitMustBeAbove,
586+
587+
-2010 => Self::NewOrderRejected,
588+
-2011 => Self::CancelRejected,
589+
-2013 => Self::NoSuchOrder,
590+
-2014 => Self::BadApiKeyFmt,
591+
-2015 => Self::RejectedMbxKey,
592+
-2016 => Self::NoTradingWindow,
593+
-2021 => Self::OrderCancelReplacePartiallyFailed,
594+
-2022 => Self::OrderCancelReplaceFailed,
595+
-2026 => Self::OrderArchived,
596+
597+
code => Self::Other(code),
598+
}
599+
}
600+
}

v_exchanges_adapters/src/exchanges/bitflyer.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ pub struct BitFlyerOptions {
7272
}
7373

7474
/// A `enum` that represents the base url of the BitFlyer HTTP API.
75-
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
75+
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
7676
pub enum BitFlyerHttpUrl {
7777
/// `https://api.bitflyer.com`
78-
Default,
78+
Main,
7979
/// The url will not be modified by [BitFlyerRequestHandler]
80+
#[default]
8081
None,
8182
}
8283

@@ -124,12 +125,10 @@ where
124125
type Successful = R;
125126
type Unsuccessful = BitFlyerHandlerError;
126127

127-
fn request_config(&self) -> RequestConfig {
128-
let mut config = self.options.request_config.clone();
129-
if self.options.http_url != BitFlyerHttpUrl::None {
128+
fn patch_request_config(&self, config: &mut RequestConfig) {
129+
if self.options.http_url != BitFlyerHttpUrl::default() {
130130
config.url_prefix = self.options.http_url.as_str().to_owned();
131131
}
132-
config
133132
}
134133

135134
fn build_request(&self, mut builder: RequestBuilder, request_body: &Option<B>, _: u8) -> Result<Request, Self::BuildError> {
@@ -298,7 +297,7 @@ impl BitFlyerHttpUrl {
298297
#[inline(always)]
299298
fn as_str(&self) -> &'static str {
300299
match self {
301-
Self::Default => "https://api.bitflyer.com",
300+
Self::Main => "https://api.bitflyer.com",
302301
Self::None => "",
303302
}
304303
}
@@ -345,7 +344,7 @@ impl Default for BitFlyerOptions {
345344
Self {
346345
key: None,
347346
secret: None,
348-
http_url: BitFlyerHttpUrl::Default,
347+
http_url: BitFlyerHttpUrl::Main,
349348
http_auth: false,
350349
request_config: RequestConfig::default(),
351350
websocket_url: BitFlyerWebSocketUrl::Default,

v_exchanges_adapters/src/exchanges/bybit.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,10 @@ where
148148
type Successful = R;
149149
type Unsuccessful = BybitHandlerError;
150150

151-
fn request_config(&self) -> RequestConfig {
152-
let mut config = self.options.request_config.clone();
153-
if self.options.http_url != BybitHttpUrl::None {
151+
fn patch_request_config(&self, config: &mut RequestConfig) {
152+
if self.options.http_url != BybitHttpUrl::default() {
154153
config.url_prefix = self.options.http_url.as_str().to_owned();
155154
}
156-
config
157155
}
158156

159157
fn build_request(&self, mut builder: RequestBuilder, request_body: &Option<B>, _: u8) -> Result<Request, Self::BuildError> {

0 commit comments

Comments
 (0)