v_exchanges/binance/
data.rs1use adapters::binance::{BinanceHttpUrl, BinanceOption};
2use derive_more::{Display, FromStr};
3use jiff::Timestamp;
4use serde::Deserialize;
5use serde_json::json;
6use v_utils::{
7 Percent,
8 prelude::*,
9 trades::{Pair, Timeframe},
10};
11
12use super::Binance;
13use crate::{
14 ExchangeError, ExchangeName,
15 core::RequestRange,
16 other_types::{Lsr, Lsrs},
17 utils::join_params,
18};
19
20#[derive(Clone, Debug, Display, FromStr)]
21pub enum LsrWho {
22 Global,
23 Top,
24}
25impl From<&str> for LsrWho {
26 fn from(s: &str) -> Self {
27 Self::from_str(s).unwrap()
28 }
29}
30
31impl Binance {
32 pub async fn lsr(&self, pair: Pair, tf: Timeframe, range: RequestRange, who: LsrWho) -> Result<Lsrs, ExchangeError> {
33 range.ensure_allowed(0..=500, &tf)?;
34 let range_json = range.serialize(ExchangeName::Binance);
35
36 let ending = match who {
37 LsrWho::Global => "globalLongShortAccountRatio",
38 LsrWho::Top => "topLongShortPositionRatio",
39 };
40 let base_json = json!({
41 "symbol": pair.fmt_binance(),
42 "period": tf,
43 });
44 let params = join_params(base_json, range_json);
45 let options = [BinanceOption::HttpUrl(BinanceHttpUrl::FuturesUsdM)];
46 let r: serde_json::Value = self.get(&format!("/futures/data/{ending}"), ¶ms, options).await?;
47 let r: Vec<LsrResponse> = serde_json::from_value(r).unwrap();
48 Ok(Lsrs {
49 values: r.into_iter().map(Lsr::from).collect(),
50 pair,
51 })
52 }
53}
54#[derive(Clone, Debug, Default, Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct LsrResponse {
57 pub symbol: String,
58 pub long_account: String,
59 pub long_short_ratio: String,
60 pub short_account: String,
61 pub timestamp: i64,
62}
63impl From<LsrResponse> for Lsr {
64 fn from(r: LsrResponse) -> Self {
65 Self {
66 time: Timestamp::from_millisecond(r.timestamp).unwrap(),
67 long: Percent::from_str(&r.long_account).unwrap(),
68 }
69 }
70}