|
@@ -1,9 +1,12 @@
|
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
|
use rust_decimal::Decimal;
|
|
use rust_decimal::Decimal;
|
|
|
|
|
+use rust_decimal::prelude::FromPrimitive;
|
|
|
|
|
+use serde_json::Value;
|
|
|
use tokio::time::Instant;
|
|
use tokio::time::Instant;
|
|
|
|
|
+use tracing::info;
|
|
|
use exchanges::response_base::ResponseData;
|
|
use exchanges::response_base::ResponseData;
|
|
|
use global::trace_stack::TraceStack;
|
|
use global::trace_stack::TraceStack;
|
|
|
-use crate::{Account, MarketOrder, Order, SpecialOrder};
|
|
|
|
|
|
|
+use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialOrder};
|
|
|
|
|
|
|
|
// 处理账号信息
|
|
// 处理账号信息
|
|
|
pub fn handle_account_info(response: &ResponseData, _symbol: &String) -> Account {
|
|
pub fn handle_account_info(response: &ResponseData, _symbol: &String) -> Account {
|
|
@@ -17,9 +20,9 @@ pub fn handle_account_info(response: &ResponseData, _symbol: &String) -> Account
|
|
|
// 格式化account信息
|
|
// 格式化account信息
|
|
|
let mut account = Account {
|
|
let mut account = Account {
|
|
|
coin: data["marginCoin"].to_string(),
|
|
coin: data["marginCoin"].to_string(),
|
|
|
- balance: Decimal::from_str(data["accountEquity"].as_str().unwrap()).unwrap(),
|
|
|
|
|
|
|
+ balance: Decimal::from_str(data["usdtEquity"].as_str().unwrap()).unwrap(),
|
|
|
available_balance: Decimal::from_str(data["available"].as_str().unwrap()).unwrap(),
|
|
available_balance: Decimal::from_str(data["available"].as_str().unwrap()).unwrap(),
|
|
|
- frozen_balance: Default::default(),
|
|
|
|
|
|
|
+ frozen_balance: Decimal::from_str(data["frozen"].as_str().unwrap()).unwrap(),
|
|
|
stocks: Default::default(),
|
|
stocks: Default::default(),
|
|
|
available_stocks: Default::default(),
|
|
available_stocks: Default::default(),
|
|
|
frozen_stocks: Default::default(),
|
|
frozen_stocks: Default::default(),
|
|
@@ -46,17 +49,27 @@ pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 处理订单信息
|
|
// 处理订单信息
|
|
|
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
|
|
|
|
|
- let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
|
|
|
|
|
- let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
|
|
|
|
|
- let status = order["status"].as_str().unwrap_or("");
|
|
|
|
|
- let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap()).unwrap();
|
|
|
|
|
-
|
|
|
|
|
- let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
|
|
|
|
|
|
|
+pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
|
|
|
|
|
+ info!(?order);
|
|
|
|
|
+ let price = Decimal::from_str(order["price"].as_str().unwrap().to_string().as_str()).unwrap();
|
|
|
|
|
+ let size = Decimal::from_str(order["size"].as_str().unwrap().to_string().as_str()).unwrap();
|
|
|
|
|
+ let binding = order["status"].clone().as_str().unwrap().to_string();
|
|
|
|
|
+ let status = binding.as_str();
|
|
|
|
|
+ let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap().to_string().as_str()).unwrap();
|
|
|
|
|
+ let avg_price = if order["priceAvg"].is_null() {
|
|
|
|
|
+ Decimal::ZERO
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Decimal::from_str(order["priceAvg"].as_str().unwrap().to_string().as_str()).unwrap()
|
|
|
|
|
+ };
|
|
|
|
|
+ let c_id = if order["clientOid"].is_null() {
|
|
|
|
|
+ ""
|
|
|
|
|
+ } else {
|
|
|
|
|
+ order["clientOid"].as_str().unwrap()
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
let amount = size * ct_val;
|
|
let amount = size * ct_val;
|
|
|
let deal_amount = acc_base_volume * ct_val;
|
|
let deal_amount = acc_base_volume * ct_val;
|
|
|
- let custom_status = if ["filled", "cancelled"].contains(&status) {
|
|
|
|
|
|
|
+ let custom_status = if ["filled", "canceled"].contains(&status) {
|
|
|
"REMOVE".to_string()
|
|
"REMOVE".to_string()
|
|
|
} else if ["init", "live", "new", "partially_filled"].contains(&status) {
|
|
} else if ["init", "live", "new", "partially_filled"].contains(&status) {
|
|
|
"NEW".to_string()
|
|
"NEW".to_string()
|
|
@@ -65,19 +78,19 @@ pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
|
|
|
};
|
|
};
|
|
|
Order {
|
|
Order {
|
|
|
id: order["orderId"].as_str().unwrap().to_string(),
|
|
id: order["orderId"].as_str().unwrap().to_string(),
|
|
|
- custom_id: order["clientOid"].as_str().unwrap().to_string(),
|
|
|
|
|
|
|
+ custom_id: c_id.to_string(),
|
|
|
price,
|
|
price,
|
|
|
amount,
|
|
amount,
|
|
|
deal_amount,
|
|
deal_amount,
|
|
|
avg_price,
|
|
avg_price,
|
|
|
status: custom_status,
|
|
status: custom_status,
|
|
|
order_type: order["orderType"].as_str().unwrap().to_string(),
|
|
order_type: order["orderType"].as_str().unwrap().to_string(),
|
|
|
- trace_stack: TraceStack::new(0, Instant::now()).on_special("84 bitget_swap_handle".to_string()),
|
|
|
|
|
|
|
+ trace_stack: TraceStack::new(0, Instant::now()).on_special("86 bitget_swap_handle".to_string()),
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 格式化深度信息
|
|
// 格式化深度信息
|
|
|
-pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
|
|
|
|
|
|
|
+pub fn format_depth_items(value: Value) -> Vec<MarketOrder> {
|
|
|
let mut depth_items: Vec<MarketOrder> = vec![];
|
|
let mut depth_items: Vec<MarketOrder> = vec![];
|
|
|
for value in value.as_array().unwrap() {
|
|
for value in value.as_array().unwrap() {
|
|
|
depth_items.push(MarketOrder {
|
|
depth_items.push(MarketOrder {
|
|
@@ -88,6 +101,55 @@ pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
|
|
|
return depth_items;
|
|
return depth_items;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 处理position信息
|
|
|
|
|
+pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
|
|
|
|
|
+ let res_data_json = res_data.data.as_array().unwrap();
|
|
|
|
|
+ res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+pub fn format_position_item(position_json: &Value, ct_val: &Decimal) -> Position {
|
|
|
|
|
+ let symbol = position_json["instId"].as_str().unwrap().to_string();
|
|
|
|
|
+ let margin_level = Decimal::from_i64(position_json["leverage"].as_i64().unwrap()).unwrap();
|
|
|
|
|
+ let amount = Decimal::from_str(position_json["total"].as_str().unwrap()).unwrap() * ct_val;
|
|
|
|
|
+ let frozen_amount = Decimal::from_str(position_json["frozen"].as_str().unwrap()).unwrap() * ct_val;
|
|
|
|
|
+ let price = Decimal::from_str(position_json["openPriceAvg"].as_str().unwrap()).unwrap();
|
|
|
|
|
+ let profit = Decimal::from_str(position_json["unrealizedPL"].as_str().unwrap()).unwrap();
|
|
|
|
|
+ let position_mode = match position_json["posMode"].as_str().unwrap() {
|
|
|
|
|
+ "hedge_mode" => {
|
|
|
|
|
+ match position_json["holdSide"].as_str().unwrap() {
|
|
|
|
|
+ "short" => {
|
|
|
|
|
+ PositionModeEnum::Short
|
|
|
|
|
+ }
|
|
|
|
|
+ "long" => {
|
|
|
|
|
+ PositionModeEnum::Long
|
|
|
|
|
+ },
|
|
|
|
|
+ _ => {
|
|
|
|
|
+ panic!("bitget_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
|
|
|
|
|
+ position_json["posMode"].as_str().unwrap(), position_json["holdSide"].as_str().unwrap())
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "one_way_mode" => {
|
|
|
|
|
+ PositionModeEnum::Both
|
|
|
|
|
+ },
|
|
|
|
|
+ _ => {
|
|
|
|
|
+ panic!("bitget_usdt_swap: 未知的持仓模式: {}", position_json["posMode"].as_str().unwrap())
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ let margin = Decimal::from_str(position_json["marginSize"].as_str().unwrap()).unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ Position {
|
|
|
|
|
+ symbol,
|
|
|
|
|
+ margin_level,
|
|
|
|
|
+ amount,
|
|
|
|
|
+ frozen_amount,
|
|
|
|
|
+ price,
|
|
|
|
|
+ profit,
|
|
|
|
|
+ position_mode,
|
|
|
|
|
+ margin,
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 处理特殊深度数据
|
|
// 处理特殊深度数据
|
|
|
// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
|
|
// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
|
|
|
// HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSwap, res_data)
|
|
// HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSwap, res_data)
|