use crypto_market_type::MarketType;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use super::utils::http_get;
static CONTRACT_VALUES: Lazy<HashMap<MarketType, HashMap<String, f64>>> = Lazy::new(|| {
let linear_swap: HashMap<String, f64> = {
let mut m: HashMap<String, f64> = vec![
("1INCH/USDT", 1_f64),
("AAVE/USDT", 0.1_f64),
("ACH/USDT", 10_f64),
("ADA/USDT", 10_f64),
("AGIX/USDT", 1_f64),
("AGLD/USDT", 1_f64),
("AIDOGE/USDT", 1000000000_f64),
("AKRO/USDT", 100_f64),
("ALGO/USDT", 10_f64),
("ALICE/USDT", 0.1_f64),
("ANC/USDT", 1_f64),
("ANKR/USDT", 10_f64),
("ANT/USDT", 1_f64),
("APE/USDT", 1_f64),
("API3/USDT", 0.1_f64),
("APT/USDT", 0.1_f64),
("AR/USDT", 0.1_f64),
("ARB/USDT", 1_f64),
("ARK/USDT", 1_f64),
("ARPA/USDT", 10_f64),
("ATOM/USDT", 1_f64),
("AVAX/USDT", 1_f64),
("AXS/USDT", 0.1_f64),
("BADGER/USDT", 0.1_f64),
("BAGS/USDT", 0.01_f64),
("BAL/USDT", 0.1_f64),
("BAND/USDT", 1_f64),
("BAT/USDT", 10_f64),
("BCH/USDT", 0.01_f64),
("BICO/USDT", 0.1_f64),
("BIGTIME/USDT", 1_f64),
("BLUR/USDT", 1_f64),
("BLZ/USDT", 10_f64),
("BNB/USDT", 0.1_f64),
("BNT/USDT", 1_f64),
("BONK/USDT", 100000_f64),
("BSV/USDT", 0.01_f64),
("BTC/USDT", 0.001_f64),
("BTS/USDT", 100_f64),
("BTT/USDT", 1000000_f64), ("C98/USDT", 1_f64),
("CAKE/USDT", 0.1_f64),
("CEL/USDT", 1_f64),
("CELO/USDT", 0.1_f64),
("CELR/USDT", 10_f64),
("CFX/USDT", 1_f64),
("CHR/USDT", 10_f64),
("CHZ/USDT", 10_f64),
("CLV/USDT", 1_f64),
("COMP/USDT", 0.01_f64),
("CORE/USDT", 0.1_f64),
("COTI/USDT", 10_f64),
("CRO/USDT", 10_f64),
("CRV/USDT", 1_f64),
("CSPR/USDT", 1_f64),
("CTSI/USDT", 10_f64),
("CVC/USDT", 10_f64),
("CYBER/USDT", 0.1_f64),
("DASH/USDT", 0.1_f64),
("DOGE/USDT", 100_f64),
("DOT/USDT", 1_f64),
("DYDX/USDT", 0.1_f64),
("EGLD/USDT", 0.01_f64),
("EGS/USDT", 10_f64),
("ENJ/USDT", 1_f64),
("ENS/USDT", 0.01_f64),
("EOS/USDT", 1_f64),
("ETC/USDT", 1_f64),
("ETH/USDT", 0.01_f64),
("ETHW/USDT", 0.01_f64),
("FET/USDT", 1_f64),
("FIL/USDT", 0.1_f64),
("FITFI/USDT", 10_f64),
("FLOKI/USDT", 10000_f64),
("FLOW/USDT", 0.1_f64),
("FORTH/USDT", 0.1_f64),
("FRONT/USDT", 1_f64),
("FTM/USDT", 1_f64),
("FTT/USDT", 1_f64), ("GAL/USDT", 0.1_f64),
("GALA/USDT", 10_f64),
("GAS/USDT", 0.1_f64),
("GLMR/USDT", 0.1_f64),
("GMT/USDT", 1_f64),
("GRT/USDT", 10_f64),
("GST/USDT", 0.1_f64),
("HBAR/USDT", 10_f64),
("HT/USDT", 0.1_f64),
("ICP/USDT", 0.01_f64),
("IMX/USDT", 0.1_f64),
("INJ/USDT", 0.1_f64),
("IOST/USDT", 100_f64),
("IOTA/USDT", 10_f64),
("IOTX/USDT", 10_f64),
("JASMY/USDT", 10_f64),
("JST/USDT", 10_f64),
("KAVA/USDT", 1_f64),
("KNC/USDT", 1_f64),
("KSM/USDT", 0.1_f64),
("LADYS/USDT", 1000000_f64),
("LAT/USDT", 10_f64),
("LDO/USDT", 1_f64),
("LINA/USDT", 10_f64),
("LINK/USDT", 0.1_f64),
("LOOKS/USDT", 0.1_f64),
("LOOM/USDT", 1_f64),
("LPT/USDT", 0.1_f64),
("LRC/USDT", 10_f64),
("LTC/USDT", 0.1_f64),
("LUNA/USDT", 1_f64),
("LUNC/USDT", 10000_f64),
("MANA/USDT", 10_f64),
("MASK/USDT", 0.1_f64),
("MASS/USDT", 1_f64),
("MATIC/USDT", 100_f64),
("MDX/USDT", 1_f64),
("MEME/USDT", 10_f64),
("METIS/USDT", 0.01_f64),
("MINA/USDT", 1_f64),
("MIR/USDT", 1_f64),
("MKR/USDT", 0.001_f64),
("MTL/USDT", 1_f64),
("NEAR/USDT", 1_f64),
("NEO/USDT", 0.1_f64),
("NFT/USDT", 1000000_f64),
("NKN/USDT", 10_f64),
("NYM/USDT", 1_f64),
("O3/USDT", 1_f64),
("OG/USDT", 0.1_f64),
("OGN/USDT", 1_f64),
("OKB/USDT", 0.1_f64),
("OMG/USDT", 1_f64),
("ONE/USDT", 100_f64),
("ONT/USDT", 10_f64),
("OP/USDT", 0.1_f64),
("ORDI/USDT", 0.1_f64),
("PEOPLE/USDT", 10_f64),
("PEPE/USDT", 1000000_f64),
("PERP/USDT", 1_f64),
("PHA/USDT", 1_f64),
("POLYX/USDT", 1_f64),
("PYTH/USDT", 1_f64),
("QNT/USDT", 0.01_f64),
("QTUM/USDT", 1_f64),
("RDNT/USDT", 1_f64),
("REEF/USDT", 100_f64),
("REN/USDT", 10_f64),
("RNDR/USDT", 1_f64),
("ROSE/USDT", 1_f64),
("RSR/USDT", 100_f64),
("RUNE/USDT", 0.1_f64),
("RVN/USDT", 10_f64),
("SAND/USDT", 10_f64),
("SEI/USDT", 1_f64),
("SHIB/USDT", 1000_f64),
("SKL/USDT", 10_f64),
("SLP/USDT", 100_f64),
("SNT/USDT", 10_f64),
("SNX/USDT", 1_f64),
("SOL/USDT", 1_f64),
("SOS/USDT", 100000_f64),
("SRM/USDT", 1_f64),
("SSV/USDT", 0.01_f64),
("STEEM/USDT", 1_f64),
("STG/USDT", 1_f64),
("STORJ/USDT", 1_f64),
("SUI/USDT", 1_f64),
("SUSHI/USDT", 1_f64),
("SXP/USDT", 1_f64),
("THETA/USDT", 10_f64),
("TIA/USDT", 0.1_f64),
("TON/USDT", 0.1_f64),
("TRB/USDT", 0.1_f64),
("TRIBE/USDT", 10_f64),
("TRX/USDT", 100_f64),
("TURBO/USDT", 100_f64),
("UMA/USDT", 0.1_f64),
("UNFI/USDT", 0.1_f64),
("UNI/USDT", 1_f64),
("USDC/USDT", 1_f64),
("USTC/USDT", 10_f64),
("VET/USDT", 100_f64),
("VRA/USDT", 100_f64),
("WAVES/USDT", 1_f64),
("WAXP/USDT", 10_f64),
("WIN/USDT", 10000_f64),
("WLD/USDT", 1_f64),
("WOJAK/USDT", 1000_f64),
("WOO/USDT", 10_f64),
("XCH/USDT", 0.001_f64),
("XCN/USDT", 10_f64),
("XEC/USDT", 10000_f64),
("XEM/USDT", 10_f64),
("XLM/USDT", 10_f64),
("XMR/USDT", 0.01_f64),
("XRP/USDT", 10_f64),
("XTZ/USDT", 1_f64),
("XVG/USDT", 100_f64),
("YFI/USDT", 0.0001_f64),
("YFII/USDT", 0.001_f64),
("YGG/USDT", 1_f64),
("ZEC/USDT", 0.1_f64),
("ZEN/USDT", 0.1_f64),
("ZIL/USDT", 100_f64),
("ZKS/USDT", 0.1_f64),
("ZRX/USDT", 1_f64),
]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
let from_online = fetch_contract_size(LINEAR_SWAP_URL);
for (pair, contract_value) in from_online {
m.insert(pair, contract_value);
}
m
};
let linear_option: HashMap<String, f64> = {
let m: HashMap<String, f64> = vec![("BTC/USDT", 0.001), ("ETH/USDT", 0.01)]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
debug_assert!(!LINEAR_OPTION_URL.is_empty());
m
};
let mut result = HashMap::<MarketType, HashMap<String, f64>>::new();
result.insert(MarketType::LinearSwap, linear_swap);
result.insert(MarketType::EuropeanOption, linear_option);
result
});
const LINEAR_SWAP_URL: &str = "https://api.hbdm.com/linear-swap-api/v1/swap_contract_info";
const LINEAR_OPTION_URL: &str = "https://api.hbdm.com/option-api/v1/option_contract_info";
fn fetch_contract_size(url: &str) -> BTreeMap<String, f64> {
#[derive(Serialize, Deserialize)]
struct RawMarket {
symbol: String,
contract_code: String,
contract_size: f64,
}
#[derive(Serialize, Deserialize)]
struct Response {
status: String,
data: Vec<RawMarket>,
ts: i64,
}
let mut mapping: BTreeMap<String, f64> = BTreeMap::new();
if let Ok(txt) = http_get(url) {
if let Ok(response) = serde_json::from_str::<Response>(&txt) {
for market in response.data.iter() {
mapping.insert(
crypto_pair::normalize_pair(&market.contract_code, "huobi").unwrap(),
market.contract_size,
);
}
}
}
mapping
}
pub(crate) fn get_contract_value(market_type: MarketType, pair: &str) -> Option<f64> {
match market_type {
MarketType::InverseSwap | MarketType::InverseFuture => {
Some(if pair.starts_with("BTC") { 100.0 } else { 10.0 })
}
MarketType::LinearSwap | MarketType::LinearFuture | MarketType::EuropeanOption => {
Some(CONTRACT_VALUES[&market_type][pair])
}
_ => None,
}
}
#[cfg(test)]
mod tests {
use crypto_market_type::MarketType;
use super::{fetch_contract_size, LINEAR_OPTION_URL, LINEAR_SWAP_URL};
#[ignore]
#[test]
fn linear_swap() {
let mut mapping = fetch_contract_size(LINEAR_SWAP_URL);
for (key, value) in super::CONTRACT_VALUES[&MarketType::LinearSwap].iter() {
if !mapping.contains_key(key) {
mapping.insert(key.to_string(), *value);
}
}
for (pair, contract_value) in &mapping {
println!("(\"{pair}\", {contract_value}_f64),");
}
}
#[ignore]
#[test]
fn linear_option() {
let mapping = fetch_contract_size(LINEAR_OPTION_URL);
for (pair, contract_value) in mapping {
println!("(\"{pair}\", {contract_value}_f64),");
}
}
}