mod utils;
const EXCHANGE_NAME: &str = "zb";
#[cfg(test)]
mod trade {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_message::TradeSide;
use crypto_msg_parser::{extract_symbol, extract_timestamp, parse_trade, round};
#[test]
fn spot() {
let raw_msg = r#"{"data":[{"date":1653774784,"amount":"0.0380","price":"29029.5","trade_type":"ask","type":"sell","tid":2796890056},{"date":1653774785,"amount":"0.0001","price":"29041.49","trade_type":"bid","type":"buy","tid":2796890057}],"dataType":"trades","channel":"btcusdt_trades"}"#;
let trades = &parse_trade(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap();
assert_eq!(2, trades.len());
let trade = &trades[0];
crate::utils::check_trade_fields(
EXCHANGE_NAME,
MarketType::Spot,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap(),
trade,
raw_msg,
);
assert_eq!(
1653774785000,
extract_timestamp(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap().unwrap()
);
assert_eq!(1653774784000, trade.timestamp);
assert_eq!(trade.price, 29029.5);
assert_eq!(trade.quantity_base, 0.038);
assert_eq!(trade.quantity_quote, 29029.5 * 0.038);
assert_eq!(trade.quantity_contract, None);
assert_eq!(trade.side, TradeSide::Sell);
}
#[test]
fn linear_swap() {
let raw_msg = r#"{"channel":"BTC_USDT.Trade","data":[[29011.85,0.441,1,1653774742]]}"#;
let trades = &parse_trade(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap();
assert_eq!(trades.len(), 1);
let trade = &trades[0];
crate::utils::check_trade_fields(
EXCHANGE_NAME,
MarketType::LinearSwap,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap(),
trade,
raw_msg,
);
assert_eq!(
1653774742000,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
assert_eq!(trade.timestamp, 1653774742000);
assert_eq!(trade.price, 29011.85);
assert_eq!(trade.quantity_contract, Some(0.441));
assert_eq!(trade.quantity_base, 0.441);
assert_eq!(trade.quantity_quote, round(0.441 * 29011.85));
assert_eq!(trade.side, TradeSide::Buy);
}
}
#[cfg(test)]
mod l2_event {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_msg_parser::{extract_symbol, extract_timestamp, parse_l2, round};
use crypto_msg_type::MessageType;
#[test]
fn linear_swap_snapshot() {
let raw_msg = r#"{"channel":"BTC_USDT.Depth","type":"Whole","data":{"asks":[[31676.32,0.06],[31676.36,0.106],[31676.49,0.03]],"bids":[[31602.01,0.06],[31601.98,0.106],[31593.12,0.276]],"time":"1654002963803"}}"#;
let orderbook = &parse_l2(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg, None).unwrap()[0];
assert_eq!(orderbook.asks.len(), 3);
assert_eq!(orderbook.bids.len(), 3);
assert!(orderbook.snapshot);
crate::utils::check_orderbook_fields(
EXCHANGE_NAME,
MarketType::LinearSwap,
MessageType::L2Event,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap(),
orderbook,
raw_msg,
);
assert_eq!(
1654002963803,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
assert_eq!(orderbook.timestamp, 1654002963803);
assert_eq!(orderbook.seq_id, None);
assert_eq!(orderbook.prev_seq_id, None);
assert_eq!(orderbook.asks[0].price, 31676.32);
assert_eq!(orderbook.asks[0].quantity_base, 0.06);
assert_eq!(orderbook.asks[0].quantity_quote, round(31676.32 * 0.06));
assert_eq!(orderbook.asks[0].quantity_contract.unwrap(), 0.06);
assert_eq!(orderbook.asks[2].price, 31676.49);
assert_eq!(orderbook.asks[2].quantity_base, 0.03);
assert_eq!(orderbook.asks[2].quantity_quote, 31676.49 * 0.03);
assert_eq!(orderbook.asks[2].quantity_contract.unwrap(), 0.03);
assert_eq!(orderbook.bids[0].price, 31602.01);
assert_eq!(orderbook.bids[0].quantity_base, 0.06);
assert_eq!(orderbook.bids[0].quantity_quote, round(31602.01 * 0.06));
assert_eq!(orderbook.bids[0].quantity_contract.unwrap(), 0.06);
assert_eq!(orderbook.bids[2].price, 31593.12);
assert_eq!(orderbook.bids[2].quantity_base, 0.276);
assert_eq!(orderbook.bids[2].quantity_quote, 31593.12 * 0.276);
assert_eq!(orderbook.bids[2].quantity_contract.unwrap(), 0.276);
}
#[test]
fn linear_swap_update() {
let raw_msg = r#"{"channel":"BTC_USDT.Depth","data":{"bids":[[31526.35,0.176],[31526.45,0.006],[31551.55,0]],"asks":[[31765.4,0.332],[31765.59,0],[31765.6,0]],"time":"1654003817266"}}"#;
let orderbook = &parse_l2(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg, None).unwrap()[0];
assert_eq!(orderbook.asks.len(), 3);
assert_eq!(orderbook.bids.len(), 3);
assert!(!orderbook.snapshot);
crate::utils::check_orderbook_fields(
EXCHANGE_NAME,
MarketType::LinearSwap,
MessageType::L2Event,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap(),
orderbook,
raw_msg,
);
assert_eq!(
1654003817266,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
assert_eq!(orderbook.timestamp, 1654003817266);
assert_eq!(orderbook.seq_id, None);
assert_eq!(orderbook.prev_seq_id, None);
assert_eq!(orderbook.asks[0].price, 31765.4);
assert_eq!(orderbook.asks[0].quantity_base, 0.332);
assert_eq!(orderbook.asks[0].quantity_quote, round(31765.4 * 0.332));
assert_eq!(orderbook.asks[0].quantity_contract.unwrap(), 0.332);
assert_eq!(orderbook.asks[2].price, 31765.6);
assert_eq!(orderbook.asks[2].quantity_base, 0.0);
assert_eq!(orderbook.asks[2].quantity_quote, 0.0);
assert_eq!(orderbook.asks[2].quantity_contract.unwrap(), 0.0);
assert_eq!(orderbook.bids[0].price, 31526.35);
assert_eq!(orderbook.bids[0].quantity_base, 0.176);
assert_eq!(orderbook.bids[0].quantity_quote, round(31526.35 * 0.176));
assert_eq!(orderbook.bids[0].quantity_contract.unwrap(), 0.176);
assert_eq!(orderbook.bids[2].price, 31551.55);
assert_eq!(orderbook.bids[2].quantity_base, 0.0);
assert_eq!(orderbook.bids[2].quantity_quote, 0.0);
assert_eq!(orderbook.bids[2].quantity_contract.unwrap(), 0.0);
}
#[test]
fn linear_swap_update_2() {
let raw_msg = r#"{"channel":"1000LUNC_USDT.Depth","data":{"bids":[[0.11,1.0]],"time":"1654009289339"}}"#;
let orderbook = &parse_l2(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg, None).unwrap()[0];
assert_eq!(orderbook.asks.len(), 0);
assert_eq!(orderbook.bids.len(), 1);
assert!(!orderbook.snapshot);
crate::utils::check_orderbook_fields(
EXCHANGE_NAME,
MarketType::LinearSwap,
MessageType::L2Event,
"1000LUNC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap(),
orderbook,
raw_msg,
);
assert_eq!(
"1000LUNC_USDT",
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap()
);
assert_eq!(
1654009289339,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
assert_eq!(orderbook.timestamp, 1654009289339);
assert_eq!(orderbook.seq_id, None);
assert_eq!(orderbook.prev_seq_id, None);
assert_eq!(orderbook.bids[0].price, 0.11);
assert_eq!(orderbook.bids[0].quantity_base, 1.0);
assert_eq!(orderbook.bids[0].quantity_quote, round(0.11 * 1.0));
assert_eq!(orderbook.bids[0].quantity_contract.unwrap(), 1.0);
}
}
#[cfg(test)]
mod l2_topk {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_msg_parser::{extract_symbol, extract_timestamp, parse_l2_topk, round};
use crypto_msg_type::MessageType;
#[test]
fn spot() {
let raw_msg = r#"{"asks":[[32383.57,0.0062],[32333.34,0.0002],[32333.0,0.0350]],"dataType":"depth","bids":[[31753.03,0.1500],[31749.61,0.6260],[31742.88,0.3500]],"channel":"btcusdt_depth","timestamp":1653997711}"#;
let orderbook = &parse_l2_topk(EXCHANGE_NAME, MarketType::Spot, raw_msg, None).unwrap()[0];
assert_eq!(orderbook.asks.len(), 3);
assert_eq!(orderbook.bids.len(), 3);
assert!(orderbook.snapshot);
crate::utils::check_orderbook_fields(
EXCHANGE_NAME,
MarketType::Spot,
MessageType::L2TopK,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap(),
orderbook,
raw_msg,
);
assert_eq!(
1653997711000,
extract_timestamp(EXCHANGE_NAME, MarketType::Spot, raw_msg,).unwrap().unwrap()
);
assert_eq!(1653997711000, orderbook.timestamp);
assert_eq!(orderbook.seq_id, None);
assert_eq!(orderbook.prev_seq_id, None);
assert_eq!(orderbook.bids[0].price, 31753.03);
assert_eq!(orderbook.bids[0].quantity_base, 0.15);
assert_eq!(orderbook.bids[0].quantity_quote, 31753.03 * 0.15);
assert_eq!(orderbook.bids[0].quantity_contract, None);
assert_eq!(orderbook.bids[2].price, 31742.88);
assert_eq!(orderbook.bids[2].quantity_base, 0.35);
assert_eq!(orderbook.bids[2].quantity_quote, 31742.88 * 0.35);
assert_eq!(orderbook.bids[2].quantity_contract, None);
assert_eq!(orderbook.asks[0].price, 32333.0);
assert_eq!(orderbook.asks[0].quantity_base, 0.035);
assert_eq!(orderbook.asks[0].quantity_quote, 32333.0 * 0.035);
assert_eq!(orderbook.asks[0].quantity_contract, None);
assert_eq!(orderbook.asks[2].price, 32383.57);
assert_eq!(orderbook.asks[2].quantity_base, 0.0062);
assert_eq!(orderbook.asks[2].quantity_quote, 32383.57 * 0.0062);
assert_eq!(orderbook.asks[2].quantity_contract, None);
}
#[test]
fn linear_swap() {
let raw_msg = r#"{"channel":"BTC_USDT.DepthWhole","data":{"asks":[[31625.55,0.03],[31625.57,0.06],[31676.49,0.03]],"bids":[[31620.75,0.05],[31615.26,0.03],[31607.92,0.04]],"time":"1654000236324"}}"#;
let orderbook =
&parse_l2_topk(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg, None).unwrap()[0];
assert_eq!(orderbook.asks.len(), 3);
assert_eq!(orderbook.bids.len(), 3);
assert!(orderbook.snapshot);
crate::utils::check_orderbook_fields(
EXCHANGE_NAME,
MarketType::LinearSwap,
MessageType::L2TopK,
"BTC/USDT".to_string(),
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap(),
orderbook,
raw_msg,
);
assert_eq!(
1654000236324,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
assert_eq!(orderbook.timestamp, 1654000236324);
assert_eq!(orderbook.seq_id, None);
assert_eq!(orderbook.prev_seq_id, None);
assert_eq!(orderbook.asks[0].price, 31625.55);
assert_eq!(orderbook.asks[0].quantity_base, 0.03);
assert_eq!(orderbook.asks[0].quantity_quote, 0.03 * 31625.55);
assert_eq!(orderbook.asks[0].quantity_contract, Some(0.03));
assert_eq!(orderbook.asks[2].price, 31676.49);
assert_eq!(orderbook.asks[2].quantity_base, 0.03);
assert_eq!(orderbook.asks[2].quantity_quote, 0.03 * 31676.49);
assert_eq!(orderbook.asks[2].quantity_contract, Some(0.03));
assert_eq!(orderbook.bids[0].price, 31620.75);
assert_eq!(orderbook.bids[0].quantity_base, 0.05);
assert_eq!(orderbook.bids[0].quantity_quote, round(0.05 * 31620.75));
assert_eq!(orderbook.bids[0].quantity_contract, Some(0.05));
assert_eq!(orderbook.bids[2].price, 31607.92);
assert_eq!(orderbook.bids[2].quantity_base, 0.04);
assert_eq!(orderbook.bids[2].quantity_quote, 0.04 * 31607.92);
assert_eq!(orderbook.bids[2].quantity_contract, Some(0.04));
}
}
#[cfg(test)]
mod ticker {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_msg_parser::{extract_symbol, extract_timestamp};
#[test]
fn spot() {
let raw_msg = r#"{"date":"1653781987181","ticker":{"high":"29249.63","vol":"4499.6492","last":"29046.17","low":"28527.54","buy":"29039.24","sell":"29056.69","turnover":"129792765.9200","open":"28598.8","riseRate":"1.57"},"dataType":"ticker","channel":"btcusdt_ticker"}"#;
assert_eq!("btcusdt", extract_symbol(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap());
assert_eq!(
1653781987181,
extract_timestamp(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap().unwrap()
);
}
#[test]
fn linear_swap() {
let raw_msg = r#"{"channel":"BTC_USDT.Ticker","data":[28669.4,29244.73,27980,29012.96,24264.005,1.2,1653783012,257344.9552]}"#;
assert_eq!(
"BTC_USDT",
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap()
);
assert_eq!(
1653783012000,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
}
#[test]
fn linear_swap_all_ticker() {
let raw_msg = r#"{"channel": "All.Ticker","data": {"ETH_USDT": [1739.34, 1807.79, 1721.41, 1790.14, 238051.871, 2.92, 1653783366, 15871.560254],"BTC_USDT": [28735.84, 29244.73, 27980, 28988.05, 24123.201, 0.88, 1653783365, 257010.950105]}}"#;
assert_eq!("All", extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap());
assert_eq!(
1653783366000,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
}
}
#[cfg(test)]
mod candlestick {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_msg_parser::{extract_symbol, extract_timestamp, parse_candlestick};
#[test]
fn spot() {
let raw_msg = r#"{"datas":{"data":[[1653782100000,29055.22,29055.22,29030.81,29032.9,19.3130],[1653782160000,29036.33,29036.33,29036.33,29036.33,0.0001]]},"channel":"btcusdt_kline_1min","isSuc":true}"#;
assert_eq!("btcusdt", extract_symbol(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap());
assert_eq!(
1653782160000,
extract_timestamp(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap().unwrap()
);
let arr = parse_candlestick(EXCHANGE_NAME, MarketType::Spot, raw_msg, None).unwrap();
assert_eq!(2, arr.len());
let candlestick_msg = &arr[0];
assert_eq!("btcusdt", candlestick_msg.symbol);
assert_eq!("BTC/USDT", candlestick_msg.pair);
assert_eq!(1653782100000, candlestick_msg.timestamp);
assert_eq!("1min", candlestick_msg.period);
assert_eq!(1653782040000, candlestick_msg.begin_time);
assert_eq!(29055.22, candlestick_msg.open);
assert_eq!(29055.22, candlestick_msg.high);
assert_eq!(29030.81, candlestick_msg.low);
assert_eq!(29032.9, candlestick_msg.close);
assert_eq!(19.3130, candlestick_msg.volume);
assert_eq!(Some(560917.8397375), candlestick_msg.quote_volume);
}
#[test]
fn linear_swap() {
let raw_msg = r#"{"channel":"BTC_USDT.KLine_1M","type":"Whole","data":[[28993.54,28996.39,28992.58,28994.78,0.921,1653783840]]}"#;
assert_eq!(
"BTC_USDT",
extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap()
);
assert_eq!(
1653783840000,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
let arr = parse_candlestick(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg, None).unwrap();
assert_eq!(1, arr.len());
let candlestick_msg = &arr[0];
assert_eq!("BTC_USDT", candlestick_msg.symbol);
assert_eq!("BTC/USDT", candlestick_msg.pair);
assert_eq!(1653783840000, candlestick_msg.timestamp);
assert_eq!("1M", candlestick_msg.period);
assert_eq!(1653783780000, candlestick_msg.begin_time);
assert_eq!(28993.54, candlestick_msg.open);
assert_eq!(28996.39, candlestick_msg.high);
assert_eq!(28992.58, candlestick_msg.low);
assert_eq!(28994.78, candlestick_msg.close);
assert_eq!(0.921, candlestick_msg.volume);
assert_eq!(Some(26703.7710225), candlestick_msg.quote_volume);
}
}
#[cfg(test)]
mod l2_snapshot {
use super::EXCHANGE_NAME;
use crypto_market_type::MarketType;
use crypto_msg_parser::{extract_symbol, extract_timestamp};
#[test]
fn spot() {
let raw_msg = r#"{"asks":[[29704.57,0.0002],[29700.54,0.1500],[29695.72,0.1500]],"bids":[[29680.86,0.1500],[29677.89,0.1500],[29674.97,0.6260]],"timestamp":1654329612}"#;
assert_eq!("NONE", extract_symbol(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap());
assert_eq!(
1654329612000,
extract_timestamp(EXCHANGE_NAME, MarketType::Spot, raw_msg).unwrap().unwrap()
);
}
#[test]
fn linear_swap() {
let raw_msg = r#"{"code":10000,"desc":"操作成功","data":{"asks":[[29663.89,0.03],[29668.69,0.04],[29676.09,0.04]],"bids":[[29659.12,0.06],[29658.84,0.03],[29652.77,0.04]],"time":1654330502522}}"#;
assert_eq!("NONE", extract_symbol(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap());
assert_eq!(
1654330502522,
extract_timestamp(EXCHANGE_NAME, MarketType::LinearSwap, raw_msg).unwrap().unwrap()
);
}
}