bitculator 1.1.0

Official Rust SDK for the Bitculator Data API
Documentation
use std::sync::Arc;

use serde::de::DeserializeOwned;
use serde_json::{json, Value};

use crate::error::Error;
use crate::http::{enc, HttpClient};
use crate::pagination::Page;
use crate::params::Params;

/// Global market aggregates.
pub struct GlobalMarket {
    http: Arc<HttpClient>,
}

impl GlobalMarket {
    pub(crate) fn new(http: Arc<HttpClient>) -> Self {
        Self { http }
    }

    /// Global market snapshot (total marketcap, volume, dominance, ...).
    pub fn snapshot<T: DeserializeOwned>(&self) -> Result<T, Error> {
        self.http.get("/api/v1/global", &Params::new())
    }

    /// Market heatmap data.
    pub fn heatmap<T: DeserializeOwned>(&self) -> Result<T, Error> {
        self.http.get("/api/v1/global/heatmap", &Params::new())
    }

    /// Global marketcap or volume history. `metric` is e.g. "marketcap" or
    /// "volume". Params: period.
    pub fn history<T: DeserializeOwned>(&self, metric: &str, params: Params) -> Result<T, Error> {
        self.http.get(&format!("/api/v1/global/history/{}", enc(metric)), &params)
    }
}

/// Community sentiment and market-wide sentiment indices.
pub struct Sentiment {
    http: Arc<HttpClient>,
}

impl Sentiment {
    pub(crate) fn new(http: Arc<HttpClient>) -> Self {
        Self { http }
    }

    /// Community vote tallies for a coin.
    pub fn votes<T: DeserializeOwned>(&self, slug: &str) -> Result<T, Error> {
        self.http.get(&format!("/api/v1/coins/{}/votes", enc(slug)), &Params::new())
    }

    /// Cast a sentiment vote for a coin ("bullish" or "bearish").
    pub fn vote(&self, slug: &str, vote: &str) -> Result<Value, Error> {
        self.http.post_value(&format!("/api/v1/coins/{}/votes", enc(slug)), Some(json!({ "vote": vote })))
    }

    /// Fear & Greed index. Params: coin. Each reading carries `index` (0-100, as shown
    /// on Bitculator; use it for display) and the raw `score` (-100..+100).
    pub fn fear_greed<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/sentiment/fear-greed", &params)
    }

    /// Bull / Bear index. Params: coin.
    pub fn bull_bear<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/sentiment/bull-bear", &params)
    }

    /// Altseason index. Params: days.
    pub fn altseason<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/sentiment/altseason", &params)
    }

    /// Aggregate market indicator tally.
    pub fn indicators<T: DeserializeOwned>(&self) -> Result<T, Error> {
        self.http.get("/api/v1/sentiment/indicators", &Params::new())
    }
}

/// Liquidation feed and aggregates.
pub struct Liquidations {
    http: Arc<HttpClient>,
}

impl Liquidations {
    pub(crate) fn new(http: Arc<HttpClient>) -> Self {
        Self { http }
    }

    /// Live liquidation feed (paginated). Params: page, per_page, exchange,
    /// instrument, position, order, symbol, min_usd.
    pub fn feed<T: DeserializeOwned>(&self, params: Params) -> Result<Page<T>, Error> {
        Page::fetch(self.http.clone(), "/api/v1/liquidations", params)
    }

    /// Hourly liquidation totals. Params: hours.
    pub fn hourly<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/liquidations/hourly", &params)
    }

    /// Daily liquidation totals. Params: days.
    pub fn daily<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/liquidations/daily", &params)
    }

    /// Today's liquidation summary.
    pub fn summary<T: DeserializeOwned>(&self) -> Result<T, Error> {
        self.http.get("/api/v1/liquidations/summary", &Params::new())
    }

    /// Long/short liquidation netflow. Params: days.
    pub fn netflow<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/liquidations/netflow", &params)
    }

    /// Most-liquidated coins. Params: hours, limit.
    pub fn coins<T: DeserializeOwned>(&self, params: Params) -> Result<T, Error> {
        self.http.get("/api/v1/liquidations/coins", &params)
    }
}