extern crate lazy_static;
use chrono::{DateTime, Utc};
use core::panic;
use kucoin_rs::kucoin::model::market::OrderBook; use kucoin_rs::kucoin::model::websocket::Level2;
use kucoin_rs::tokio::sync::broadcast;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
pub type PriceVolume = HashMap<String, String>;
#[derive(Debug, Clone)]
pub struct BookData {
pub pricevolume: PriceVolume,
time: DateTime<Utc>,
sequence: i64,
}
pub type PartialBook = HashMap<String, BookData>;
use kucoin_rs::tokio::sync::broadcast::{Receiver, Sender};
lazy_static::lazy_static! {
pub static ref ASKS: Arc<Mutex<PartialBook>> = Arc::new(Mutex::new(PartialBook::new()));
pub static ref BIDS: Arc<Mutex<PartialBook>> = Arc::new(Mutex::new(PartialBook::new()));
pub static ref BROADCAST: Arc<Mutex<(Sender<(String, BookData)>, Receiver<(String, BookData)>)>> = Arc::new(Mutex::new(broadcast::channel(32))); }
pub fn get_local_asks(symbol: &String) -> Option<BookData> {
let mut p = ASKS.lock().unwrap();
let res = (*p).remove(symbol).clone();
return res;
}
pub fn get_local_bids(symbol: &String) -> Option<BookData> {
let mut p = ASKS.lock().unwrap();
let res = (*p).remove(symbol);
return res;
}
pub fn set_local_asks(symbol: String, book_data: BookData) -> Option<BookData> {
let mut p = ASKS.lock().unwrap();
(*p).insert(symbol, book_data)
}
pub fn set_local_bids(symbol: String, book_data: BookData) -> Option<BookData> {
let mut p = BIDS.lock().unwrap();
(*p).insert(symbol, book_data)
}
pub fn store_orderbook(symbol: String, orderbook: OrderBook) {
let asks = orderbook.asks;
let bids = orderbook.bids;
let queue_err_msg = "symbol not found locally";
let mut local_asks = BookData {
pricevolume: PriceVolume::new(),
time: Utc::now(),
sequence: 0,
};
let mut local_bids = BookData {
pricevolume: PriceVolume::new(),
time: Utc::now(),
sequence: 0,
};
let f1 = store_book_changes(&mut local_asks, asks).is_none();
let f2 = store_book_changes(&mut local_bids, bids).is_none();
if f1 || f2 {
panic!("There were previous data stored locally");
}
}
pub fn print_changes(changes: Vec<Vec<String>>) {
for change in changes.into_iter() {
if change.len().ne(&3) {
panic!("wrong format");
}
let price = change.get(0).unwrap();
let size = change.get(1).unwrap();
let sequence = change.get(2).unwrap();
log::info!("price:{price}");
log::info!("size:{size}");
log::info!("sequence:{sequence}");
}
}
fn store_book_changes(book_data: &mut BookData, changes: Vec<Vec<String>>) -> Option<i64> {
let mut updated_sequence: i64 = book_data.sequence;
let format_err_msg = "wrong format";
let mut is_none = true;
for change in changes.into_iter() {
if change.len().ne(&3) {
panic!("{format_err_msg}");
}
let price = change.get(0).expect(format_err_msg);
let size = change.get(1).expect(format_err_msg);
let sequence = change.get(2).expect(format_err_msg);
let sequence_int = sequence.parse::<i64>().expect(format_err_msg);
if sequence_int <= updated_sequence {
continue;
}
updated_sequence = sequence_int;
if book_data
.pricevolume
.insert(price.clone(), size.clone())
.is_some()
{
is_none = false;
}
}
book_data.sequence = updated_sequence;
return if is_none {
None
} else {
Some(updated_sequence)
};
}
pub fn ge_string_as_f64() {
unimplemented!()
}
pub fn print_l2(l2: Level2) {
log::info!("print_l2");
let asks = l2.changes.asks;
let bids = l2.changes.bids;
if asks.len() > 0 {
log::info!("asks");
print_changes(asks);
}
if bids.len() > 0 {
log::info!("bids");
print_changes(bids);
}
}
pub fn store_orderbook_changes(symbol: &String, l2: Level2) {
let queue_err_msg = "symbol not found locally";
let mut local_asks = get_local_asks(symbol).expect(queue_err_msg);
let mut local_bids = get_local_bids(symbol).expect(queue_err_msg);
store_book_changes(&mut local_asks, l2.changes.asks);
store_book_changes(&mut local_bids, l2.changes.bids);
}
#[derive(Debug, Clone)]
pub enum Action {
Buy,
Sell,
}
#[derive(Debug, Clone)]
pub struct ActionInfo {
action: Action,
ticker: String,
volume: String,
}
type ActionSequence = [ActionInfo; 3];