1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//! accounts balances methods.

use hashbrown::HashMap;

use cxmr_balances::{price, Balance};
use cxmr_currency::{Currency, CurrencyPair};
use cxmr_exchanges::Market;

use super::Broker;

/// User balances in all currencies and total.
#[derive(Serialize)]
pub struct UserBalances {
    pub name: String,
    pub total: f64,
    pub balances: HashMap<Currency, Balance>,
}

/// Gets all accounts balances with total BTC from the broker.
pub fn get_all_balances(broker: &Broker) -> Vec<UserBalances> {
    broker
        .accounts()
        .iter()
        .map(|account| {
            let exchange = account.exchange();
            let mut balances = account.balances().clone();
            balances.iter_mut().for_each(|(symbol, balance)| {
                let total_btc = if *symbol == Currency::Btc {
                    Some(price(balance.total))
                } else if balance.total > 0 {
                    let pair = CurrencyPair::new(symbol.clone(), Currency::Btc);
                    let market = Market::new(*exchange, pair);
                    if let Some(rate) = broker.get_bid_price(market) {
                        Some(price(balance.total) * price(rate))
                    } else {
                        debug!("No exchange rate for {}/BTC", symbol);
                        None
                    }
                } else {
                    None
                };
                balance.total_btc = total_btc;
            });
            let total_balance = balances.iter().fold(0.0, |total, (_, bnc)| {
                bnc.total_btc.map(|btc| btc + total).unwrap_or(total)
            });
            UserBalances {
                name: account.name().to_string(),
                total: total_balance,
                balances: balances,
            }
        })
        .collect()
}