use crypto_market_type::MarketType;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use super::utils::http_get;
use serde_json::Value;
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),
("ADA/USDT", 100_f64),
("AGLD/USDT", 1_f64),
("AIDOGE/USDT", 10000000000_f64),
("ALGO/USDT", 10_f64),
("ALPHA/USDT", 1_f64),
("ANC/USDT", 1_f64),
("ANT/USDT", 1_f64),
("APE/USDT", 0.1_f64),
("API3/USDT", 1_f64),
("APT/USDT", 1_f64),
("AR/USDT", 0.1_f64),
("ARB/USDT", 10_f64),
("ASTR/USDT", 10_f64),
("ATOM/USDT", 1_f64),
("AVAX/USDT", 1_f64),
("AXS/USDT", 0.1_f64),
("BABYDOGE/USDT", 1000000000_f64),
("BADGER/USDT", 0.1_f64),
("BAL/USDT", 0.1_f64),
("BAND/USDT", 1_f64),
("BAT/USDT", 10_f64),
("BCH/USDT", 0.1_f64),
("BICO/USDT", 1_f64),
("BIGTIME/USDT", 10_f64),
("BLUR/USDT", 10_f64),
("BNB/USDT", 0.01_f64),
("BNT/USDT", 10_f64),
("BSV/USDT", 1_f64),
("BTC/USDC", 0.0001_f64),
("BTC/USDT", 0.01_f64),
("BTM/USDT", 100_f64),
("BTT/USDT", 1000000_f64),
("BZZ/USDT", 0.1_f64),
("CEL/USDT", 10_f64),
("CELO/USDT", 1_f64),
("CETUS/USDT", 10_f64),
("CFX/USDT", 10_f64),
("CHZ/USDT", 10_f64),
("COMP/USDT", 0.1_f64),
("CONV/USDT", 10_f64),
("CORE/USDT", 1_f64),
("CQT/USDT", 1_f64),
("CRO/USDT", 10_f64),
("CRV/USDT", 1_f64),
("CSPR/USDT", 1_f64),
("CVC/USDT", 100_f64),
("DASH/USDT", 0.1_f64),
("DOGE/USDT", 1000_f64),
("DOME/USDT", 100_f64),
("DORA/USDT", 0.1_f64),
("DOT/USDT", 1_f64),
("DYDX/USDT", 1_f64),
("EFI/USDT", 1_f64),
("EGLD/USDT", 0.1_f64),
("ELON/USDT", 1000000_f64),
("ENJ/USDT", 1_f64),
("ENS/USDT", 0.1_f64),
("EOS/USDT", 10_f64),
("ETC/USDT", 10_f64),
("ETH/USDC", 0.001_f64),
("ETH/USDT", 0.1_f64),
("ETHW/USDT", 0.1_f64),
("FIL/USDT", 0.1_f64),
("FITFI/USDT", 10_f64),
("FLM/USDT", 10_f64),
("FLOKI/USDT", 100000_f64),
("FLOW/USDT", 10_f64),
("FRONT/USDT", 10_f64),
("FTM/USDT", 10_f64),
("GALA/USDT", 10_f64),
("GAS/USDT", 1_f64),
("GFT/USDT", 100_f64),
("GMT/USDT", 1_f64),
("GMX/USDT", 0.1_f64),
("GODS/USDT", 1_f64),
("GRT/USDT", 10_f64),
("HBAR/USDT", 100_f64),
("ICP/USDT", 0.01_f64),
("IMX/USDT", 1_f64),
("IOST/USDT", 1000_f64),
("IOTA/USDT", 10_f64),
("JST/USDT", 100_f64),
("KISHU/USDT", 1000000000_f64),
("KLAY/USDT", 10_f64),
("KNC/USDT", 1_f64),
("KSM/USDT", 0.1_f64),
("LAT/USDT", 10_f64),
("LDO/USDT", 1_f64),
("LINK/USDT", 1_f64),
("LON/USDT", 1_f64),
("LOOKS/USDT", 1_f64),
("LPT/USDT", 0.1_f64),
("LRC/USDT", 10_f64),
("LTC/USDT", 1_f64),
("LUNA/USDT", 1_f64),
("LUNC/USDT", 10000_f64),
("MAGIC/USDT", 1_f64),
("MANA/USDT", 10_f64),
("MASK/USDT", 1_f64),
("MATIC/USDT", 10_f64),
("MEME/USDT", 100_f64),
("MINA/USDT", 1_f64),
("MIR/USDT", 1_f64),
("MKR/USDT", 0.01_f64),
("NEAR/USDT", 10_f64),
("NEO/USDT", 1_f64),
("NFT/USDT", 1000000_f64),
("NYM/USDT", 1_f64),
("OMG/USDT", 1_f64),
("ONT/USDT", 10_f64),
("OP/USDT", 1_f64),
("ORBS/USDT", 100_f64),
("ORDI/USDT", 0.1_f64),
("PEOPLE/USDT", 100_f64),
("PEPE/USDT", 10000000_f64),
("PERP/USDT", 1_f64),
("PYTH/USDT", 10_f64),
("QTUM/USDT", 1_f64),
("RACA/USDT", 10000_f64),
("RDNT/USDT", 10_f64),
("REN/USDT", 10_f64),
("RNDR/USDT", 1_f64),
("RSR/USDT", 100_f64),
("RSS3/USDT", 10_f64),
("RVN/USDT", 10_f64),
("SAND/USDT", 10_f64),
("SC/USDT", 100_f64),
("SHIB/USDT", 1000000_f64),
("SLP/USDT", 10_f64),
("SNX/USDT", 1_f64),
("SOL/USDT", 1_f64),
("SOS/USDT", 1000000_f64),
("SRM/USDT", 1_f64),
("SSV/USDT", 0.1_f64),
("STARL/USDT", 100000_f64),
("STORJ/USDT", 10_f64),
("STX/USDT", 10_f64),
("SUI/USDT", 1_f64),
("SUN/USDT", 0.1_f64),
("SUSHI/USDT", 1_f64),
("SWEAT/USDT", 100_f64),
("SWRV/USDT", 1_f64),
("THETA/USDT", 10_f64),
("TIA/USDT", 1_f64),
("TON/USDT", 1_f64),
("TONCOIN/USDT", 1_f64),
("TORN/USDT", 0.01_f64),
("TRB/USDT", 0.1_f64),
("TRX/USDT", 1000_f64),
("UMA/USDT", 0.1_f64),
("UMEE/USDT", 10_f64),
("UNI/USDT", 1_f64),
("USDC/USDT", 10_f64),
("USTC/USDT", 100_f64),
("VRA/USDT", 1000_f64),
("WAVES/USDT", 1_f64),
("WAXP/USDT", 100_f64),
("WEMIX/USDT", 1_f64),
("WLD/USDT", 1_f64),
("WNCG/USDT", 1_f64),
("WNXM/USDT", 0.1_f64),
("WOO/USDT", 10_f64),
("WSM/USDT", 100_f64),
("XCH/USDT", 0.01_f64),
("XEM/USDT", 10_f64),
("XLM/USDT", 100_f64),
("XMR/USDT", 0.1_f64),
("XRP/USDT", 100_f64),
("XTZ/USDT", 1_f64),
("YFI/USDT", 0.0001_f64),
("YFII/USDT", 0.001_f64),
("YGG/USDT", 1_f64),
("ZEC/USDT", 0.1_f64),
("ZEN/USDT", 1_f64),
("ZIL/USDT", 100_f64),
("ZRX/USDT", 10_f64),
]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
let from_online = fetch_contract_val("SWAP");
for (pair, contract_value) in from_online {
m.insert(pair, contract_value);
}
m
};
let linear_future: HashMap<String, f64> = {
let mut m: HashMap<String, f64> = vec![
("ADA/USDT", 100_f64),
("BCH/USDT", 0.1_f64),
("BSV/USDT", 1_f64),
("BTC/USDC", 0.0001_f64),
("BTC/USDT", 0.01_f64),
("DOT/USDT", 1_f64),
("EOS/USDT", 10_f64),
("ETC/USDT", 10_f64),
("ETH/USDC", 0.001_f64),
("ETH/USDT", 0.1_f64),
("FIL/USDT", 0.1_f64),
("LINK/USDT", 1_f64),
("LTC/USDT", 1_f64),
("TRX/USDT", 1000_f64),
("XRP/USDT", 100_f64),
]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
let from_online = fetch_contract_val("FUTURES");
for (pair, contract_value) in &from_online {
m.insert(pair.clone(), *contract_value);
}
m
};
let option: HashMap<String, f64> = vec![("BTC/USD", 0.1), ("ETH/USD", 1.0), ("EOS/USD", 100.0)]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
let mut result = HashMap::<MarketType, HashMap<String, f64>>::new();
result.insert(MarketType::LinearSwap, linear_swap);
result.insert(MarketType::LinearFuture, linear_future);
result.insert(MarketType::EuropeanOption, option);
result
});
fn fetch_contract_val(inst_type: &str) -> BTreeMap<String, f64> {
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
struct RawMarket {
instType: String, instId: String, ctVal: String, ctType: String, #[serde(flatten)]
extra: HashMap<String, Value>,
}
let mut mapping: BTreeMap<String, f64> = BTreeMap::new();
let markets = {
let url = format!("https://www.okx.com/api/v5/public/instruments?instType={inst_type}");
let txt = match http_get(url.as_str()) {
Ok(txt) => {
let json_obj = serde_json::from_str::<HashMap<String, Value>>(&txt).unwrap();
serde_json::to_string(json_obj.get("data").unwrap()).unwrap()
}
Err(_) => "[]".to_string(),
};
serde_json::from_str::<Vec<RawMarket>>(&txt).unwrap()
};
for market in markets.iter().filter(|x| x.ctType == "linear") {
let pair = crypto_pair::normalize_pair(&market.instId, "okx").unwrap();
mapping.insert(pair, market.ctVal.parse::<f64>().unwrap());
}
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 => {
Some(CONTRACT_VALUES[&market_type][pair])
}
MarketType::EuropeanOption => Some(1.0),
_ => None,
}
}
#[cfg(test)]
mod tests {
use crypto_market_type::MarketType;
use super::fetch_contract_val;
#[ignore]
#[test]
fn linear_swap() {
let mut mapping = fetch_contract_val("SWAP");
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_future() {
let mut mapping = fetch_contract_val("FUTURES");
for (key, value) in super::CONTRACT_VALUES[&MarketType::LinearFuture].iter() {
if !mapping.contains_key(key) {
mapping.insert(key.to_string(), *value);
}
}
for (pair, contract_value) in &mapping {
println!("(\"{pair}\", {contract_value}_f64),");
}
}
}