mod utils; use crypto_market_type::MarketType; use crypto_pair::{get_market_type, normalize_currency, normalize_pair}; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; use utils::http_get; const EXCHANGE_NAME: &str = "zbg"; #[derive(Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] struct SpotMarket { symbol: String, base_currency: String, quote_currency: String, #[serde(flatten)] extra: HashMap, } #[derive(Serialize, Deserialize)] struct ResMsg { message: String, method: Option, code: String, } #[derive(Serialize, Deserialize)] #[allow(non_snake_case)] struct Response { datas: Vec, resMsg: ResMsg, } // See https://zbgapi.github.io/docs/spot/v1/en/#public-get-all-supported-trading-symbols fn fetch_spot_markets_raw() -> Vec { let txt = http_get("https://www.zbg.com/exchange/api/v1/common/symbols").unwrap(); let resp = serde_json::from_str::>(&txt).unwrap(); resp.datas } #[ignore = "Always get HTTP 503 on Github action runners"] #[test] fn verify_spot_symbols() { let markets = fetch_spot_markets_raw(); for market in markets.iter() { let pair = normalize_pair(&market.symbol, EXCHANGE_NAME).unwrap(); let pair_expected = format!( "{}/{}", normalize_currency(&market.base_currency, EXCHANGE_NAME), normalize_currency(&market.quote_currency, EXCHANGE_NAME) ); assert_eq!(pair.as_str(), pair_expected); assert_eq!(MarketType::Spot, get_market_type(&market.symbol, EXCHANGE_NAME, None)); } } #[derive(Serialize, Deserialize)] #[allow(non_snake_case)] struct SwapMarket { symbol: String, currencyName: String, commodityName: Option, #[serde(flatten)] extra: HashMap, } // See https://zbgapi.github.io/docs/future/v1/en/#public-get-contracts fn fetch_swap_markets_raw() -> Vec { let txt = http_get("https://www.zbg.com/exchange/api/v1/future/common/contracts").unwrap(); let resp = serde_json::from_str::>(&txt).unwrap(); resp.datas } #[ignore = "prone to HTTP request timeout"] #[test] fn verify_swap_symbols() { let markets = fetch_swap_markets_raw(); for market in markets.iter().filter(|x| x.commodityName.is_some()) { let pair = normalize_pair(&market.symbol, EXCHANGE_NAME).unwrap(); let pair_expected = if market.symbol.ends_with("_USD-R") { format!( "{}/{}", normalize_currency(&market.currencyName, EXCHANGE_NAME), normalize_currency(&market.commodityName.clone().unwrap(), EXCHANGE_NAME) ) } else { format!( "{}/{}", normalize_currency(&market.commodityName.clone().unwrap(), EXCHANGE_NAME), normalize_currency(&market.currencyName, EXCHANGE_NAME) ) }; assert_eq!(pair.as_str(), pair_expected); let market_type = get_market_type(&market.symbol, EXCHANGE_NAME, None); assert!(market_type == MarketType::LinearSwap || market_type == MarketType::InverseSwap); } }