|
| 1 | +use adapters::binance::{BinanceHttpUrl, BinanceOption}; |
| 2 | +use chrono::{DateTime, Utc}; |
| 3 | +use derive_more::{Display, FromStr}; |
| 4 | +use eyre::Result; |
| 5 | +use serde::Deserialize; |
| 6 | +use serde_json::json; |
| 7 | +use v_utils::{ |
| 8 | + Percent, |
| 9 | + trades::{Pair, Timeframe}, |
| 10 | +}; |
| 11 | + |
| 12 | +use super::Binance; |
| 13 | + |
| 14 | +#[derive(Clone, Debug, Display, FromStr)] |
| 15 | +pub enum LsrWho { |
| 16 | + Global, |
| 17 | + Top, |
| 18 | +} |
| 19 | +impl From<&str> for LsrWho { |
| 20 | + fn from(s: &str) -> Self { |
| 21 | + Self::from_str(s).unwrap() |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +impl Binance { |
| 26 | + pub async fn global_lsr_account(&self, pair: Pair, tf: Timeframe, limit: u32, who: LsrWho) -> Result<Vec<Lsr>> { |
| 27 | + let allowed_range = 1..=500; |
| 28 | + //TODO!!: add a `limit outside of range` error, generic for all exchanges |
| 29 | + assert!(allowed_range.contains(&limit)); |
| 30 | + |
| 31 | + let ending = match who { |
| 32 | + LsrWho::Global => "globalLongShortAccountRatio", |
| 33 | + LsrWho::Top => "topLongShortPositionRatio", |
| 34 | + }; |
| 35 | + let params = json!({ |
| 36 | + "symbol": pair.to_string(), |
| 37 | + "period": tf.format_binance()?, |
| 38 | + "limit": limit, |
| 39 | + }); |
| 40 | + let r: serde_json::Value = self |
| 41 | + .0 |
| 42 | + .get(&format!("/futures/data/{ending}"), ¶ms, [BinanceOption::HttpUrl(BinanceHttpUrl::FuturesUsdM)]) |
| 43 | + .await?; |
| 44 | + let r: Vec<LsrResponse> = serde_json::from_value(r).unwrap(); |
| 45 | + Ok(r.into_iter().map(|r| r.into()).collect()) |
| 46 | + } |
| 47 | +} |
| 48 | +#[derive(Clone, Debug, Default, Deserialize)] |
| 49 | +#[serde(rename_all = "camelCase")] |
| 50 | +pub struct LsrResponse { |
| 51 | + pub symbol: String, |
| 52 | + pub long_account: String, |
| 53 | + pub long_short_ratio: String, |
| 54 | + pub short_account: String, |
| 55 | + pub timestamp: i64, |
| 56 | +} |
| 57 | +#[derive(Clone, Debug, Default, Copy)] |
| 58 | +pub struct Lsr { |
| 59 | + pub time: DateTime<Utc>, |
| 60 | + pub pair: Pair, |
| 61 | + pub long: Percent, |
| 62 | + pub short: Percent, |
| 63 | +} |
| 64 | +impl Lsr { |
| 65 | + pub fn ratio(&self) -> f64 { |
| 66 | + *self.long / *self.short |
| 67 | + } |
| 68 | +} |
| 69 | +impl From<LsrResponse> for Lsr { |
| 70 | + fn from(r: LsrResponse) -> Self { |
| 71 | + Self { |
| 72 | + time: DateTime::from_timestamp_millis(r.timestamp).unwrap(), |
| 73 | + pair: Pair::from_str(&r.symbol).unwrap(), |
| 74 | + long: Percent::from_str(&r.long_account).unwrap(), |
| 75 | + short: Percent::from_str(&r.short_account).unwrap(), |
| 76 | + } |
| 77 | + } |
| 78 | +} |
0 commit comments