| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- use std::cmp::Ordering;
- use std::str::FromStr;
- use rust_decimal::{Decimal};
- use rust_decimal::prelude::FromPrimitive;
- use rust_decimal_macros::dec;
- use tracing::{error, info};
- use exchanges::response_base::ResponseData;
- use global::public_params;
- use crate::exchange::ExchangeEnum;
- use crate::{binance_swap_handle, gate_swap_handle, bybit_swap_handle, bitget_swap_handle, kucoin_handle};
- use crate::{Account, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
- #[allow(dead_code)]
- pub struct HandleSwapInfo;
- pub struct DepthParam {
- pub depth_asks: Vec<MarketOrder>,
- pub depth_bids: Vec<MarketOrder>,
- pub t: Decimal,
- pub create_at: i64
- }
- #[allow(dead_code)]
- impl HandleSwapInfo {
- // 处理账号信息
- pub fn handle_account_info(exchange: ExchangeEnum, res_data: &ResponseData, symbol: &String) -> Account {
- match exchange {
- // ExchangeEnum::BinanceSwap => {
- // error!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
- // panic!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
- // }
- ExchangeEnum::GateSwap => {
- gate_swap_handle::handle_account_info(res_data, symbol)
- }
- // ExchangeEnum::KucoinSwap => {
- // kucoin_handle::handle_account_info(res_data, symbol)
- // }
- // ExchangeEnum::KucoinSpot => {
- // kucoin_spot_handle::handle_account_info(res_data, symbol)
- // }
- // ExchangeEnum::OkxSwap => {
- // okx_handle::handle_account_info(res_data, symbol)
- // }
- // ExchangeEnum::BitgetSpot => {
- // bitget_spot_handle::handle_account_info(res_data, symbol)
- // },
- ExchangeEnum::BitgetSwap => {
- bitget_swap_handle::handle_account_info(res_data, symbol)
- },
- ExchangeEnum::BybitSwap => {
- bybit_swap_handle::handle_account_info(res_data, symbol)
- }
- _ => {
- error!("未找到该交易所!handle_account_info: {:?}",exchange);
- panic!("未找到该交易所!handle_account_info: {:?}", exchange);
- }
- }
- }
- // 处理Ticker信息
- pub fn handle_book_ticker(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
- match exchange {
- // ExchangeEnum::BinanceSpot => {
- // binance_spot_handle::handle_special_ticker(res_data)
- // }
- ExchangeEnum::BinanceSwap => {
- binance_swap_handle::handle_book_ticker(res_data)
- }
- ExchangeEnum::GateSwap => {
- gate_swap_handle::handle_book_ticker(res_data)
- }
- ExchangeEnum::KucoinSwap => {
- kucoin_handle::handle_book_ticker(res_data)
- }
- // ExchangeEnum::KucoinSpot => {
- // kucoin_spot_handle::handle_special_ticker(res_data)
- // }
- // ExchangeEnum::KucoinSpot => {
- // kucoin_spot_handle::handle_special_ticker(res_data)
- // }
- // ExchangeEnum::OkxSwap => {
- // okx_handle::handle_special_ticker(res_data)
- // }
- // ExchangeEnum::BitgetSpot => {
- // bitget_spot_handle::handle_special_ticker(res_data)
- // },
- ExchangeEnum::BitgetSwap => {
- info!(?res_data);
- panic!("BitgetSwap 85 未实现格式化");
- // bitget_swap_handle::handle_special_ticker(res_data)
- },
- ExchangeEnum::BybitSwap => {
- bybit_swap_handle::handle_ticker(res_data)
- }
- }
- }
- // 处理position信息
- pub fn handle_position(exchange: ExchangeEnum, res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
- match exchange {
- ExchangeEnum::BinanceSwap => {
- error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- }
- ExchangeEnum::GateSwap => {
- gate_swap_handle::handle_position(res_data, ct_val)
- }
- ExchangeEnum::KucoinSwap => {
- kucoin_handle::handle_position(res_data, ct_val)
- }
- // ExchangeEnum::KucoinSpot => {
- // error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- // panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- // }
- // ExchangeEnum::OkxSwap => {
- // okx_handle::handle_position(res_data, ct_val)
- // }
- // ExchangeEnum::BitgetSpot => {
- // error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- // panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
- // },
- ExchangeEnum::BitgetSwap => {
- bitget_swap_handle::handle_position(res_data, ct_val)
- },
- ExchangeEnum::BybitSwap => {
- bybit_swap_handle::handle_position(res_data, ct_val)
- }
- }
- }
- // 处理订单信息
- pub fn handle_order(exchange: ExchangeEnum, res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
- match exchange {
- ExchangeEnum::BinanceSwap => {
- error!("暂未提供此交易所方法!handle_order:{:?}", exchange);
- panic!("暂未提供此交易所方法!handle_order:{:?}", exchange);
- }
- ExchangeEnum::GateSwap => {
- gate_swap_handle::handle_order(res_data, ct_val)
- }
- ExchangeEnum::KucoinSwap => {
- kucoin_handle::handle_order(res_data, ct_val)
- }
- // ExchangeEnum::KucoinSpot => {
- // kucoin_spot_handle::handle_order(res_data, ct_val)
- // }
- // ExchangeEnum::OkxSwap => {
- // okx_handle::handle_order(res_data, ct_val)
- // }
- // ExchangeEnum::BitgetSpot => {
- // bitget_spot_handle::handle_order(res_data, ct_val)
- // },
- ExchangeEnum::BitgetSwap => {
- bitget_swap_handle::handle_order(res_data, ct_val)
- },
- ExchangeEnum::BybitSwap => {
- bybit_swap_handle::handle_order(res_data, ct_val)
- }
- }
- }
- // 处理深度信息
- pub fn handle_special_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
- let label = res_data.label.clone();
- // 格式化
- let mut format_depth = format_depth(exchange, res_data);
- // 运算、组装
- make_special_depth(label, &mut format_depth.depth_asks, &mut format_depth.depth_bids, format_depth.t, format_depth.create_at)
- }
- }
- pub fn make_special_depth(label: String, depth_asks: &mut Vec<MarketOrder>, depth_bids: &mut Vec<MarketOrder>, t: Decimal, create_at: i64) -> SpecialDepth {
- depth_asks.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap_or(Ordering::Equal));
- depth_bids.sort_by(|a, b| b.price.partial_cmp(&a.price).unwrap_or(Ordering::Equal));
- // TODO 不排序的话,有4us可以省下来。
- let mp = (depth_asks[0].price + depth_bids[0].price) * dec!(0.5);
- let step = (public_params::EFF_RANGE * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round_dp(mp.scale());
- let mut ap = Vec::new();
- let mut bp = Vec::new();
- let mut av: Vec<Decimal> = Vec::new();
- let mut bv: Vec<Decimal> = Vec::new();
- for i in 0..public_params::LEVEL {
- let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_asks[0].price.scale());
- ap.push(price);
- }
- for i in 0..public_params::LEVEL {
- let price = (depth_bids[0].price - step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_bids[0].price.scale());
- bp.push(price);
- }
- let mut ap_price_tag = depth_asks[0].price + step;
- let mut ap_index = 0;
- for item in depth_asks.iter() {
- let price = item.price;
- let amount = item.amount;
- if av.get(ap_index).is_none() { av.push(Decimal::ZERO) };
- if price < ap_price_tag {
- av[ap_index] += amount;
- } else {
- ap_price_tag += step;
- ap_index += 1;
- if ap_index == public_params::LEVEL {
- break;
- }
- av[ap_index] += amount
- }
- }
- let mut bp_price_tag = depth_bids[0].price - step;
- let mut bp_index = 0;
- for item in depth_bids.iter() {
- let price = item.price;
- let amount = item.amount;
- if bv.get(bp_index).is_none() { bv.push(Decimal::ZERO) };
- if price > bp_price_tag {
- bv[bp_index] += amount;
- } else {
- bp_price_tag -= step;
- bp_index += 1;
- if bp_index == public_params::LEVEL {
- break;
- }
- bv[bp_index] += amount
- }
- }
- let ticker_info = SpecialTicker { sell: depth_asks[0].price, buy: depth_bids[0].price, mid_price: mp, t, create_at };
- let depth_info = bp.iter().cloned().chain(bv.iter().cloned()).chain(ap.iter().cloned()).chain(av.iter().cloned()).collect();
- SpecialDepth {
- name: label,
- depth: depth_info,
- ticker: ticker_info,
- t,
- create_at,
- }
- }
- pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthParam {
- let depth_asks: Vec<MarketOrder>;
- let depth_bids: Vec<MarketOrder>;
- let t: Decimal;
- let create_at: i64;
- match exchange {
- // ExchangeEnum::BinanceSpot => {
- // depth_asks = binance_swap_handle::format_depth_items(res_data_json["asks"].clone());
- // depth_bids = binance_swap_handle::format_depth_items(res_data_json["bids"].clone());
- // t = Decimal::from_str(&res_data_json["lastUpdateId"].to_string()).unwrap();
- // create_at = 0;
- // }
- ExchangeEnum::BinanceSwap => {
- depth_asks = binance_swap_handle::format_depth_items(res_data.data["a"].clone());
- depth_bids = binance_swap_handle::format_depth_items(res_data.data["b"].clone());
- t = Decimal::from_str(&res_data.data["u"].to_string()).unwrap();
- create_at = res_data.data["E"].as_i64().unwrap() * 1000;
- }
- ExchangeEnum::GateSwap => {
- depth_asks = gate_swap_handle::format_depth_items(&res_data.data["asks"]);
- depth_bids = gate_swap_handle::format_depth_items(&res_data.data["bids"]);
- // todo! 有id可以取 保证与py一致
- t = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
- create_at = res_data.data["t"].as_i64().unwrap() * 1000;
- }
- ExchangeEnum::KucoinSwap => {
- depth_asks = kucoin_handle::format_depth_items(res_data.data["asks"].clone());
- depth_bids = kucoin_handle::format_depth_items(res_data.data["bids"].clone());
- t = Decimal::from_str(&res_data.data["sequence"].to_string()).unwrap();
- create_at = res_data.data["ts"].as_i64().unwrap() * 1000;
- }
- // ExchangeEnum::KucoinSpot => {
- // depth_asks = kucoin_spot_handle::format_depth_items(res_data_json["asks"].clone());
- // depth_bids = kucoin_spot_handle::format_depth_items(res_data_json["bids"].clone());
- // t = Decimal::from_str(&res_data_json["timestamp"].to_string()).unwrap();
- // create_at = res_data_json["timestamp"].as_i64().unwrap() * 1000;
- // }
- // ExchangeEnum::OkxSwap => {
- // depth_asks = okx_handle::format_depth_items(res_data_json[0]["asks"].clone());
- // depth_bids = okx_handle::format_depth_items(res_data_json[0]["bids"].clone());
- // t = Decimal::from_str(&res_data_json[0]["seqId"].to_string()).unwrap();
- // create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
- // }
- // ExchangeEnum::BitgetSpot => {
- // depth_asks = bitget_spot_handle::format_depth_items(res_data_json[0]["asks"].clone());
- // depth_bids = bitget_spot_handle::format_depth_items(res_data_json[0]["bids"].clone());
- // t = Decimal::from_str(res_data_json[0]["ts"].as_str().unwrap()).unwrap();
- // create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
- // }
- ExchangeEnum::BitgetSwap => {
- depth_asks = bitget_swap_handle::format_depth_items(res_data.data[0]["asks"].clone());
- depth_bids = bitget_swap_handle::format_depth_items(res_data.data[0]["bids"].clone());
- t = Decimal::from_str(res_data.data[0]["ts"].as_str().unwrap()).unwrap();
- create_at = res_data.data[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
- }
- ExchangeEnum::BybitSwap => {
- depth_asks = bybit_swap_handle::format_depth_items(res_data.data["a"].clone());
- depth_bids = bybit_swap_handle::format_depth_items(res_data.data["b"].clone());
- t = Decimal::from_i64(res_data.reach_time).unwrap();
- create_at = res_data.reach_time * 1000;
- }
- }
- DepthParam {
- depth_asks,
- depth_bids,
- t,
- create_at
- }
- }
|