v_exchanges/binance/
data.rs

1use 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}"), &params, 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}