rust-okx 0.6.0

Async Rust client for the OKX v5 REST API
Documentation
use std::collections::VecDeque;

use rust_okx::api::account::{AccountBalance, BalanceDetail};
use rust_okx::ws::model::{CandleUpdate, TickerUpdate};

#[derive(Clone)]
pub struct OhlcBar {
    pub ts: u64,
    pub open: f64,
    pub high: f64,
    pub low: f64,
    pub close: f64,
    pub confirm: bool,
}

impl From<rust_okx::api::market::Candle> for OhlcBar {
    fn from(c: rust_okx::api::market::Candle) -> Self {
        Self {
            ts: c.ts.as_str().parse().unwrap_or(0),
            open: c.open.as_str().parse().unwrap_or(0.0),
            high: c.high.as_str().parse().unwrap_or(0.0),
            low: c.low.as_str().parse().unwrap_or(0.0),
            close: c.close.as_str().parse().unwrap_or(0.0),
            confirm: c.confirm.as_str() == "1",
        }
    }
}

impl From<CandleUpdate> for OhlcBar {
    fn from(c: CandleUpdate) -> Self {
        Self {
            ts: c.ts.as_str().parse().unwrap_or(0),
            open: c.o.as_str().parse().unwrap_or(0.0),
            high: c.h.as_str().parse().unwrap_or(0.0),
            low: c.l.as_str().parse().unwrap_or(0.0),
            close: c.c.as_str().parse().unwrap_or(0.0),
            confirm: c.confirm.as_str() == "1",
        }
    }
}

#[derive(Clone, Copy, PartialEq)]
pub enum Tab {
    Account,
    Chart,
    Feed,
}

pub enum AppMsg {
    Candle(CandleUpdate),
    Ticker(TickerUpdate),
}

pub struct App {
    pub tab: Tab,
    pub balances: Vec<AccountBalance>,
    pub perm: String,
    pub inst_id: String,
    pub bar: String,
    pub candles: VecDeque<OhlcBar>,
    pub tickers: VecDeque<TickerUpdate>,
}

impl App {
    pub fn next_tab(&mut self) {
        self.tab = match self.tab {
            Tab::Account => Tab::Chart,
            Tab::Chart => Tab::Feed,
            Tab::Feed => Tab::Account,
        };
    }

    pub fn prev_tab(&mut self) {
        self.tab = match self.tab {
            Tab::Account => Tab::Feed,
            Tab::Chart => Tab::Account,
            Tab::Feed => Tab::Chart,
        };
    }

    pub fn push_candle(&mut self, cu: CandleUpdate) {
        let bar = OhlcBar::from(cu);
        if let Some(last) = self.candles.back_mut()
            && last.ts == bar.ts
        {
            *last = bar;
            return;
        }
        self.candles.push_back(bar);
        if self.candles.len() > 100 {
            self.candles.pop_front();
        }
    }

    pub fn push_ticker(&mut self, tu: TickerUpdate) {
        self.tickers.push_front(tu);
        if self.tickers.len() > 50 {
            self.tickers.pop_back();
        }
    }

    pub fn balance_details(&self) -> impl Iterator<Item = &BalanceDetail> {
        self.balances
            .iter()
            .flat_map(|b| b.details.iter())
            .filter(|d| {
                let eq: f64 = d.eq.as_str().parse().unwrap_or(0.0);
                eq != 0.0
            })
    }
}