extern crate kucoin_rs;
use kucoin_arbitrage::globals::legacy::{orderbook, symbol};
use kucoin_arbitrage::{strategy, strings, tickers};
use kucoin_rs::futures::future;
use kucoin_rs::kucoin::{
client::{Kucoin, KucoinEnv},
model::market::OrderBookType,
model::websocket::{KucoinWebsocketMsg, Level2, WSResp, WSTopic, WSType},
websocket::KucoinWebsocket,
};
use kucoin_rs::{futures::TryStreamExt, tokio};
use log::*;
async fn insert_single_orderbook_from_api(
api: Kucoin,
symbol_name: String,
) -> Result<(), kucoin_rs::failure::Error> {
let ob_type = OrderBookType::L20;
let res = api.get_orderbook(symbol_name.as_str(), ob_type).await?;
if res.data.is_none() {
panic!("OrderBook error: {:#?}", res.msg.unwrap());
}
orderbook::store_orderbook(symbol_name, res.data.unwrap());
Ok(())
}
async fn insert_all_orderbooks_from_api(
api: Kucoin,
list: Vec<String>,
) -> Result<(), kucoin_rs::failure::Error> {
let futures: Vec<_> = list
.iter()
.map(|name| insert_single_orderbook_from_api(api.clone(), name.to_owned()))
.collect();
future::join_all(futures).await;
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), kucoin_rs::failure::Error> {
kucoin_arbitrage::logger::log_init();
info!("Hello world");
let credentials = kucoin_arbitrage::globals::config::credentials();
info!("{credentials:#?}");
let api = Kucoin::new(KucoinEnv::Live, Some(credentials))?;
let quote1 = "BTC";
let quote2 = "USDT";
let whitelist = tickers::symbol_whitelisted(api.clone(), quote1, quote2).await;
let whitelist = whitelist.unwrap();
let symbolmap = tickers::symbol_list_filtered(api.clone(), whitelist.clone()).await;
let symbolmap = symbolmap.unwrap();
symbol::insert_symbolmap(symbolmap).unwrap();
info!("Generating orderbook, {} in total", whitelist.len());
let _res = insert_all_orderbooks_from_api(api.clone(), whitelist.clone()).await;
info!("Generated");
let url = api.get_socket_endpoint(WSType::Public).await?;
let mut ws = api.websocket();
let v = vec![
whitelist.get(0).unwrap().to_owned(),
whitelist.get(1).unwrap().to_owned(),
whitelist.get(2).unwrap().to_owned(),
];
let subs = vec![WSTopic::OrderBook(v)];
ws.subscribe(url, subs).await?;
info!("Async polling");
tokio::spawn(async move { websocket_runtime(ws).await });
kucoin_arbitrage::tasks::background_routine().await
}
async fn websocket_runtime(mut ws: KucoinWebsocket) -> Result<(), kucoin_rs::failure::Error> {
while let Some(msg) = ws.try_next().await? {
match msg {
KucoinWebsocketMsg::OrderBookMsg(msg) => {
kucoin_arbitrage::globals::performance::increment();
on_order_message_received(msg);
}
KucoinWebsocketMsg::PongMsg(_msg) => {}
KucoinWebsocketMsg::WelcomeMsg(_msg) => {}
_ => {
panic!("unexpected msgs received: {msg:?}")
}
}
}
Ok(())
}
fn on_order_message_received(msg: WSResp<Level2>) {
if msg.subject.ne("trade.l2update") {
error!("unrecognised subject: {:?}", msg.subject);
return;
}
let ticker_name = strings::topic_to_symbol(msg.topic).expect("wrong ticker format");
let data = msg.data;
let symbol = data.symbol.clone();
orderbook::store_orderbook_changes(&ticker_name, data);
if symbol.eq("BTC-USDT") {
return;
}
}