Quellcode durchsuchen

持仓信息y轴

skyffire vor 9 Monaten
Ursprung
Commit
9e89d59fec

+ 3 - 1
standard/src/binance_swap.rs

@@ -3,6 +3,7 @@ use std::io::{Error, ErrorKind};
 use std::result::Result;
 use std::str::FromStr;
 use async_trait::async_trait;
+use chrono::Utc;
 use futures::stream::FuturesUnordered;
 use futures::TryStreamExt;
 use rust_decimal::Decimal;
@@ -640,7 +641,7 @@ impl Platform for BinanceSwap {
     }
 }
 
-pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
+pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
     let mut position_mode = match position["positionSide"].as_str().unwrap_or("") {
         "BOTH" => PositionModeEnum::Both,
         "LONG" => PositionModeEnum::Long,
@@ -671,5 +672,6 @@ pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Po
         profit: Decimal::from_str(position["unRealizedProfit"].as_str().unwrap()).unwrap(),
         position_mode,
         margin: Decimal::from_str(position["isolatedMargin"].as_str().unwrap()).unwrap(),
+        update_time: Decimal::from(Utc::now().timestamp_millis()),
     }
 }

+ 6 - 4
standard/src/binance_swap_handle.rs

@@ -42,16 +42,17 @@ pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account
 // 处理position信息
 pub fn handle_position(res_data: &ResponseData, mul: &Decimal) -> Vec<Position> {
     let res_data_json = res_data.data["a"]["P"].as_array().unwrap();
-    res_data_json.iter().map(|item| { format_position_item(item, mul) }).collect()
+    let update_time = Decimal::from_str(&res_data.data["E"].as_str().unwrap()).unwrap();
+    res_data_json.iter().map(|item| { format_position_item(item, mul, update_time) }).collect()
 }
-pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
+pub fn format_position_item(position: &Value, ct_val: &Decimal, update_time: Decimal) -> Position {
     let mut position_mode = match position["ps"].as_str().unwrap_or("") {
         "BOTH" => PositionModeEnum::Both,
         "LONG" => PositionModeEnum::Long,
         "SHORT" => PositionModeEnum::Short,
         _ => {
-            error!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
+            error!("Binance:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
+            panic!("Binance:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
         }
     };
     let size = Decimal::from_str(&position["pa"].as_str().unwrap()).unwrap();
@@ -75,6 +76,7 @@ pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
         profit: Decimal::from_str(&position["up"].as_str().unwrap()).unwrap(),
         position_mode,
         margin: Decimal::from_str(&position["iw"].as_str().unwrap()).unwrap(),
+        update_time
     }
 }
 

+ 3 - 0
standard/src/bitget_swap.rs

@@ -4,6 +4,7 @@ use std::io::{Error, ErrorKind};
 use tokio::sync::mpsc::Sender;
 use std::str::FromStr;
 use async_trait::async_trait;
+use chrono::Utc;
 use futures::stream::FuturesUnordered;
 use futures::TryStreamExt;
 use rust_decimal::{Decimal, MathematicalOps};
@@ -210,6 +211,7 @@ impl Platform for BitgetSwap {
                 profit,
                 position_mode,
                 margin,
+                update_time: Decimal::from(Utc::now().timestamp_millis()),
             });
         }
 
@@ -286,6 +288,7 @@ impl Platform for BitgetSwap {
                 profit,
                 position_mode,
                 margin,
+                update_time: Decimal::from(Utc::now().timestamp_millis()),
             });
         }
 

+ 2 - 0
standard/src/bitget_swap_handle.rs

@@ -141,6 +141,7 @@ pub fn format_position_item(position_json: &Value, _multiplier: &Decimal) -> Pos
         }
     };
     let margin = Decimal::from_str(position_json["marginSize"].as_str().unwrap()).unwrap();
+    let update_time = Decimal::from_str(position_json["uTime"].as_str().unwrap()).unwrap();
 
     let side = position_json["holdSide"].as_str().unwrap();
     match position_mode {
@@ -163,6 +164,7 @@ pub fn format_position_item(position_json: &Value, _multiplier: &Decimal) -> Pos
         profit,
         position_mode,
         margin,
+        update_time
     }
 }
 

+ 2 - 0
standard/src/bybit_swap.rs

@@ -3,6 +3,7 @@ use std::io::{Error, ErrorKind};
 use std::str::FromStr;
 use tokio::sync::mpsc::Sender;
 use async_trait::async_trait;
+use chrono::Utc;
 use futures::stream::FuturesUnordered;
 use futures::TryStreamExt;
 use rust_decimal::Decimal;
@@ -721,6 +722,7 @@ pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
         profit,
         position_mode,
         margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
+        update_time: Decimal::from(Utc::now().timestamp_millis()),
     }
 }
 

+ 2 - 0
standard/src/bybit_swap_handle.rs

@@ -79,6 +79,7 @@ pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
     if profit_str != "" {
         profit = Decimal::from_str(profit_str).unwrap();
     }
+    let update_time = Decimal::from_str(position["updatedTime"].as_str().unwrap()).unwrap();
 
     match position_mode {
         PositionModeEnum::Both => {
@@ -99,6 +100,7 @@ pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
         profit,
         position_mode,
         margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
+        update_time
     }
 }
 

+ 2 - 0
standard/src/coinex_swap.rs

@@ -3,6 +3,7 @@ use std::io::{Error, ErrorKind};
 use std::str::FromStr;
 use tokio::sync::mpsc::Sender;
 use async_trait::async_trait;
+use chrono::Utc;
 use futures::stream::FuturesUnordered;
 use futures::TryStreamExt;
 use rust_decimal::Decimal;
@@ -726,6 +727,7 @@ pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
         profit: Decimal::from_str(position["unrealized_pnl"].as_str().unwrap()).unwrap(),
         position_mode,
         margin: Decimal::from_str(position["ath_margin_size"].as_str().unwrap()).unwrap(),
+        update_time: Decimal::from(Utc::now().timestamp_millis()),
     }
 }
 

+ 2 - 0
standard/src/gate_swap.rs

@@ -3,6 +3,7 @@ use std::io::{Error, ErrorKind};
 use std::str::FromStr;
 use tokio::sync::mpsc::Sender;
 use async_trait::async_trait;
+use chrono::Utc;
 use futures::stream::FuturesUnordered;
 use futures::TryStreamExt;
 use rust_decimal::Decimal;
@@ -734,6 +735,7 @@ pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Po
         profit: Decimal::from_str(position["unrealised_pnl"].as_str().unwrap()).unwrap(),
         position_mode,
         margin: Decimal::from_str(position["margin"].as_str().unwrap()).unwrap(),
+        update_time: Decimal::from(Utc::now().timestamp_millis()),
     }
 }
 

+ 1 - 0
standard/src/gate_swap_handle.rs

@@ -75,6 +75,7 @@ pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
         profit: Decimal::from_str(&position["realised_pnl"].as_f64().unwrap().to_string()).unwrap(),
         position_mode,
         margin: Decimal::from_str(&position["margin"].as_f64().unwrap().to_string()).unwrap(),
+        update_time: Decimal::from_str(&position["time_ms"].as_str().unwrap()).unwrap(),
     }
 }
 

+ 5 - 2
standard/src/lib.rs

@@ -3,6 +3,7 @@ use std::fmt;
 use std::fmt::Formatter;
 use std::io::{Error};
 use async_trait::async_trait;
+use chrono::Utc;
 use rust_decimal::Decimal;
 use serde_json::Value;
 use serde::{Serialize, Deserialize};
@@ -508,12 +509,13 @@ pub struct Position {
     pub profit: Decimal,
     pub position_mode: PositionModeEnum,
     pub margin: Decimal,
+    pub update_time: Decimal,
 }
 
 impl Position {
-    pub fn new() -> Position {
+    pub fn new(run_symbol: String) -> Position {
         Position {
-            symbol: "".to_string(),
+            symbol: run_symbol,
             margin_level: Default::default(),
             amount: Default::default(),
             frozen_amount: Default::default(),
@@ -521,6 +523,7 @@ impl Position {
             profit: Default::default(),
             position_mode: PositionModeEnum::Both,
             margin: Default::default(),
+            update_time: Decimal::from(Utc::now().timestamp_millis()),
         }
     }
 }

+ 2 - 11
strategy/src/bitget_usdt_swap.rs

@@ -11,7 +11,7 @@ use exchanges::response_base::ResponseData;
 use global::trace_stack::TraceStack;
 use standard::exchange::ExchangeEnum::BitgetSwap;
 use standard::exchange_struct_handler::ExchangeStructHandler;
-use standard::{Depth, OrderBook, Position, PositionModeEnum};
+use standard::{Depth, OrderBook, Position};
 use crate::core::Core;
 use crate::exchange_disguise::{on_depth, on_record, on_ticker, on_trade};
 use crate::model::OrderInfo;
@@ -151,16 +151,7 @@ async fn on_private_data(core_arc_clone: Arc<Mutex<Core>>, ct_val: &Decimal, run
             let mut core = core_arc_clone.lock().await;
 
             if positions.is_empty() {
-                positions.push(Position {
-                    symbol: run_symbol.to_string(),
-                    margin_level: Default::default(),
-                    amount: Default::default(),
-                    frozen_amount: Default::default(),
-                    price: Default::default(),
-                    profit: Default::default(),
-                    position_mode: PositionModeEnum::Both,
-                    margin: Default::default(),
-                });
+                positions.push(Position::new(run_symbol.clone()));
             }
 
             core.update_position(positions).await;

+ 6 - 5
strategy/src/core.rs

@@ -382,7 +382,6 @@ impl Core {
                                 }
                                 self.local_cash -= filled * filled_price;
                                 self.local_coin = filled - fee;
-                                self.predictor.on_inventory(&self.local_position_by_orders.long_pos, &self.local_position_by_orders.long_avg, &self.strategy.min_amount_value).await;
 
                                 // sell 平多
                             } else if side == "pd" {
@@ -398,7 +397,6 @@ impl Core {
                                 }
                                 self.local_cash += filled * filled_price - fee;
                                 self.local_coin -= filled;
-                                self.predictor.on_inventory(&self.local_position_by_orders.long_pos, &self.local_position_by_orders.long_avg, &self.strategy.min_amount_value).await;
 
                             // buy 平空
                             } else if side == "pk" {
@@ -414,7 +412,6 @@ impl Core {
                                 }
                                 self.local_cash -= filled * filled_price;
                                 self.local_coin += filled - fee;
-                                self.predictor.on_inventory(&-self.local_position_by_orders.short_pos, &self.local_position_by_orders.short_avg, &self.strategy.min_amount_value).await;
 
                             // sell 开空
                             } else if side == "kk" {
@@ -431,8 +428,6 @@ impl Core {
                                 }
                                 self.local_cash += filled * filled_price - fee;
                                 self.local_coin -= filled;
-                                self.predictor.on_inventory(&-self.local_position_by_orders.short_pos, &self.local_position_by_orders.short_avg, &self.strategy.min_amount_value).await;
-
                             } else {
                                 info!("错误的仓位方向{}", side);
                             }
@@ -699,7 +694,12 @@ impl Core {
             return;
         }
         let mut position = LocalPosition::new();
+        let mut pos_avg_price = Decimal::ZERO;
+        let mut update_time = Decimal::ZERO;
         for pos in &data {
+            pos_avg_price = pos.price;
+            update_time = pos.update_time;
+
             if pos.position_mode == PositionModeEnum::Long {
                 position.long_pos = pos.amount;
                 position.long_avg = pos.price;
@@ -722,6 +722,7 @@ impl Core {
             pos = self.local_position.long_pos - self.local_position.short_pos;
         }
         pos.rescale(8);
+        self.predictor.on_inventory(&pos, &pos_avg_price, &self.strategy.min_amount_value, update_time).await;
 
         let mut entry_price;
         if pos.gt(&Decimal::ZERO) {

+ 19 - 11
strategy/src/predictor.rs

@@ -73,7 +73,7 @@ impl Predictor {
 
         let account_port = params.port.clone();
         tokio::spawn(async move {
-            let len = 16usize;
+            let len = 17usize;
             let mut prev_save_time = Decimal::from(Utc::now().timestamp_millis());
             let mut debugs: Vec<VecDeque<Option<Decimal>>> = vec![VecDeque::new(); len];
 
@@ -100,7 +100,7 @@ impl Predictor {
                 for i in 0..len {
                     if value[i] == Self::DONT_VIEW {
                         // 可能会遇见按时序插入的
-                        if debugs[i].len() > 0 && insert_index < debugs.len() {
+                        if debugs[i].len() > 0 && insert_index < debugs[i].len() {
                             // 在合适的位置插入新元素
                             debugs[i].insert(insert_index, None);
                         } else {
@@ -108,7 +108,7 @@ impl Predictor {
                         }
                     } else {
                         // 可能会遇见按时序插入的
-                        if debugs[i].len() > 0 && insert_index < debugs.len() {
+                        if debugs[i].len() > 0 && insert_index < debugs[i].len() {
                             // 在合适的位置插入新元素
                             debugs[i].insert(insert_index, Some(value[i]));
                         } else {
@@ -201,7 +201,8 @@ impl Predictor {
         if self.mid_price.is_zero() {
             return;
         }
-        self.processor(depth.time).await;
+
+        self.processor(depth.time, false).await;
     }
 
     pub async fn on_trade(&mut self, trade: &Trade, _index: usize) {
@@ -214,7 +215,7 @@ impl Predictor {
 
     pub async fn on_record(&mut self, _record: &Record) {}
 
-    pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, min_amount_value: &Decimal) {
+    pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, min_amount_value: &Decimal, update_time: Decimal) {
         if self.mid_price.is_zero() {
             return;
         }
@@ -231,7 +232,7 @@ impl Predictor {
             };
         }
 
-        self.processor(Decimal::from(Utc::now().timestamp_millis())).await;
+        self.processor(update_time, true).await;
     }
 
     pub async fn on_balance(&mut self, balance: Decimal) {
@@ -376,7 +377,7 @@ impl Predictor {
     }
 
     // #[instrument(skip(self), level="TRACE")]
-    async fn processor(&mut self, data_time: Decimal) {
+    async fn processor(&mut self, data_time: Decimal, is_hard_update: bool) {
         self.check_ready();
         if !self.is_ready {
             return;
@@ -384,6 +385,10 @@ impl Predictor {
 
         self.update_delta();
 
+        if !self.inventory.is_zero() {
+            info!(?data_time, is_hard_update)
+        }
+
         // let cci_arc = self.cci_arc.clone();
         let now = data_time;
         let mid_price = self.mid_price;
@@ -411,9 +416,13 @@ impl Predictor {
         let flow_ratio = Decimal::ZERO;
 
         let need_append = now - self.prev_insert_time > Decimal::ONE_HUNDRED;
-        if !need_append {
+        if !need_append && !is_hard_update {
             return;
         }
+        if !is_hard_update {
+            self.prev_insert_time = Decimal::from(Utc::now().timestamp_millis())
+        }
+        let pos_avg_price = self.pos_avg_price;
 
         self.debug_sender.unbounded_send(vec![
             now,
@@ -431,10 +440,9 @@ impl Predictor {
             gamma,
             kappa,
             flow_ratio,
-            fair_price
+            fair_price,
+            pos_avg_price
         ]).unwrap();
-
-        self.prev_insert_time = Decimal::from(Utc::now().timestamp_millis())
     }
 
     // #[instrument(skip(self, ref_ticker_map), level="TRACE")]

+ 1 - 1
strategy/src/utils.rs

@@ -225,7 +225,7 @@ pub fn build_html_file(data_c: &Vec<VecDeque<Option<Decimal>>>) -> String {
           let color = "";
           if(item > 0) color = "#F2495E"
           if(item < 0) color = "#13BF86"
-          inventoryList.push({ name: "inventory",itemStyle:{color: color}, value: item, xAxis: index, yAxis: data[1][index] });
+          inventoryList.push({ name: "inventory",itemStyle:{color: color}, value: item, xAxis: index, yAxis: data[16][index] });
         }
       });
       return {