Forráskód Böngészése

定价接入完成

JiahengHe 4 hónapja
szülő
commit
eeac5b9f17

+ 1 - 1
standard/src/handle_info.rs

@@ -347,7 +347,7 @@ pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthPar
         depth_bids,
         t,
         create_at,
-        timestamp_us: chrono::Utc::now().timestamp_millis() as u64,
+        timestamp_us: chrono::Utc::now().timestamp_subsec_micros() as u64,
     }
 }
 

+ 36 - 6
strategy/src/binance_usdt_swap.rs

@@ -10,6 +10,7 @@ use global::trace_stack::{TraceStack};
 use standard::exchange::ExchangeEnum::BinanceSwap;
 use crate::core::Core;
 use exchanges::binance_swap_ws::{BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
+use standard::{Trade, TradeSide};
 use crate::exchange_disguise::{on_special_depth};
 use crate::model::OriginalTradeBa;
 
@@ -26,7 +27,7 @@ pub(crate) async fn reference_binance_swap_run(is_shutdown_arc: Arc<AtomicBool>,
         let mut ws = BinanceSwapWs::new_label(name, is_colo, None, BinanceSwapWsType::PublicAndPrivate);
         ws.set_symbols(symbols);
         ws.set_subscribe(vec![
-            // BinanceSwapSubscribeType::PuDepth20levels100ms,
+            BinanceSwapSubscribeType::PuDepth20levels100ms,
             BinanceSwapSubscribeType::PuBookTicker,
             BinanceSwapSubscribeType::PuAggTrade
         ]);
@@ -59,8 +60,30 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
 
     match response.channel.as_str() {
         "aggTrade" => {
-            let trade: Vec<OriginalTradeBa> = serde_json::from_str(response.data.as_str().unwrap()).unwrap();
-            info!("收到aggTrade信息,内容:{}", response.data.to_string());
+            let binance_trade: OriginalTradeBa = serde_json::from_str(response.data.to_string().as_str()).unwrap();
+            // 如true,则此次成交是一个主动卖出单,否则是一个主动买入单。
+            let side = if binance_trade.m {
+                TradeSide::Sell
+            }else {
+                TradeSide::Buy
+            };
+            let trade = Trade{
+                timestamp_us: chrono::Utc::now().timestamp_micros() as u64,
+                price: binance_trade.p,
+                amount: binance_trade.q,
+                side,
+            };
+            // trade更新
+            {
+                let mut core = core_arc_clone.lock().await;
+                let price = core.pricing_engine.on_trade_message(trade);
+                match price {
+                    Some(price) => {
+                        core.on_ref_price_update(&response.label, price, &mut trace_stack).await;
+                    },
+                    _ => {}
+                }
+            }
         }
         "bookTicker" => {
             trace_stack.set_source("binance_usdt_swap.bookTicker".to_string());
@@ -75,9 +98,16 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
             // 将depth数据转换为模拟深度
             let depth = standard::handle_info::HandleSwapInfo::handle_depth(BinanceSwap, &response);
             trace_stack.on_after_format();
-
-            info!("depth asks: {:?}", depth.depth_asks);
-            info!("depth bids: {:?}", depth.depth_bids);
+            {
+                let mut core = core_arc_clone.lock().await;
+                let price = core.pricing_engine.on_depth_message(depth);
+                match price {
+                    Some(price) => {
+                        core.on_ref_price_update(&response.label, price, &mut trace_stack).await;
+                    },
+                    _ => {}
+                }
+            }
         }
         _ => {
             error!("未知推送类型");

+ 150 - 80
strategy/src/core.rs

@@ -24,6 +24,7 @@ use global::trade::Trade;
 use standard::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker};
 use standard::exchange::{Exchange};
 use standard::exchange::ExchangeEnum::{BinanceSwap, BitgetSwap, BybitSwap, CoinexSwap, GateSwap, HtxSwap, KucoinSwap};
+use standard::handle_info::DepthParam;
 use crate::fix_price::PricingEngine;
 use crate::model::{LocalPosition, OrderInfo, TokenParam};
 use crate::predictor::Predictor;
@@ -126,6 +127,7 @@ pub struct Core {
     pub is_sigma_allow_open: bool, // 是否允许开单
 
     pub trading_volume: Decimal, // 交易量统计
+    pub last_ref_price: Decimal, // 最后一次进入挂单的参考价格
 }
 
 impl Core {
@@ -269,6 +271,7 @@ impl Core {
             is_sigma_abnormal: false,
             is_sigma_allow_open: true,
             trading_volume: Default::default(),
+            last_ref_price: Default::default(),
         };
         for i in 0..=params.ref_exchange.len() - 1 {
             // 拼接不会消耗原字符串
@@ -681,6 +684,71 @@ impl Core {
         }
     }
 
+    pub async fn on_ref_price_update(&mut self, name_ref: &String, ref_price: Decimal, trace_stack: &mut TraceStack){
+        let now_time = Utc::now().timestamp_millis();
+        self.market_update_time.insert(name_ref.clone(), now_time);
+        if ref_price == Decimal::ZERO{
+            return;
+        }
+        // 过滤条件 价格变化很大 时间间隔很长
+        let mut flag = 0;
+
+        let price_rate = (ref_price -  self.last_ref_price).abs() / ref_price;
+        let rate = dec!(0.0002);
+        // 验证这次获取的预定价格要比上次的预定价格相差0.0002以上并且距离上次进入开单的时间间隔 > 50
+        if price_rate > rate || Utc::now().timestamp_millis() - self.on_tick_event_time > 50 {
+            // 允许交易
+            flag = 1;
+            // 更新ontick触发时间记录
+            self.on_tick_event_time = Utc::now().timestamp_millis();
+            // // 全局记录一下最后的预定价格
+            self.last_ref_price = ref_price;
+        }
+
+        // 允许交易
+        if self.mode_signal == 0 && self.ready == 1 && flag == 1 {
+            // 更新交易数据
+            self.update_trade_msg();
+            // 更新预定价格
+            self.ref_price = vec![vec![ref_price, ref_price]];
+            // 触发事件撤单逻辑
+            // 更新策略时间
+            self.strategy.local_time = Utc::now().timestamp_millis();
+
+            // 产生交易信号
+            let mut orders = self.strategy.on_tick(&self.local_orders,
+                                                   &self.local_position_by_orders,
+                                                   &self.agg_market,
+                                                   &self.local_cash,
+                                                   &self.local_coin,
+                                                   &self.ref_price,
+                                                   &self.predict,
+                                                   &true,
+                                                   &trace_stack.ins);
+            trace_stack.on_after_strategy();
+
+            if orders.is_not_empty() {
+                let mut platform_rest_fb = self.platform_rest.clone_box();
+                // 先更新本地记录再发单。
+                self._update_local_orders(&mut orders);
+                // info!("订单指令:{:?}", orders);
+                let mut ts = trace_stack.clone();
+                spawn(async move {
+                    platform_rest_fb.command_order(&mut orders, &mut ts).await;
+                });
+
+                // 更新中控账户相关信息
+                {
+                    let mut now_balance = self.strategy.equity / self.used_pct;
+                    now_balance.rescale(4);
+
+                    let mut cci = self.cci_arc.lock().await;
+                    cci.now_balance = now_balance;
+                }
+            }
+        }
+    }
+
     // #[instrument(skip(self, depth, name_ref, trace_stack), level="TRACE")]
     pub async fn on_depth_update(&mut self, depth: &Vec<Decimal>, name_ref: &String, trace_stack: &mut TraceStack) {
         // 要从回调传入的深度信息中获取data.name
@@ -705,71 +773,71 @@ impl Core {
             }
         } else if *name_ref == self.ref_name[0] { // 判断是否为当前跟踪的盘口
             // 写入行情数据
-            let ticker = self.tickers.get(name_ref).unwrap();
-            if self.trade_vec.len() == 100 {
-                self.trade_vec.pop_front();
-            }
-            self.trade_vec.push_back(Trade::new_by_ticker(ticker.mid_price.clone(), ticker.create_at/1000));
-            // 更新波动率
-            if self.trade_vec.len() > 99 {
-                self.calc_sigma();
-                // 波动率正常,但还是不开单信号,允许开单
-                if !self.is_sigma_abnormal && !self.is_sigma_allow_open {
-                    self.is_sigma_allow_open = true;
-                }
-            }
-            // 判断是否需要触发ontick 对行情进行过滤
-            // 过滤条件 价格变化很大 时间间隔很长
-            let mut flag = 0;
-            let bid_price_rate = (depth[BID_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[BID_PRICE_INDEX]).abs() / depth[BID_PRICE_INDEX];
-            let ask_price_rate = (depth[ASK_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[ASK_PRICE_INDEX]).abs() / depth[ASK_PRICE_INDEX];
-            let rate = dec!(0.0002);
-            if bid_price_rate > rate || ask_price_rate > rate || Utc::now().timestamp_millis() - self.on_tick_event_time > 50 {
-                // 允许交易
-                flag = 1;
-                // 更新ontick触发时间记录
-                self.on_tick_event_time = Utc::now().timestamp_millis();
-            }
-            // 允许交易
-            if self.mode_signal == 0 && self.ready == 1 && flag == 1 {
-                // 更新交易数据
-                self.update_trade_msg();
-                // 触发事件撤单逻辑
-                // 更新策略时间
-                self.strategy.local_time = Utc::now().timestamp_millis();
-
-                // 产生交易信号
-                let mut orders = self.strategy.on_tick(&self.local_orders,
-                                                       &self.local_position_by_orders,
-                                                       &self.agg_market,
-                                                       &self.local_cash,
-                                                       &self.local_coin,
-                                                       &self.ref_price,
-                                                       &self.predict,
-                                                       &self.is_sigma_allow_open,
-                                                       &trace_stack.ins);
-                trace_stack.on_after_strategy();
-
-                if orders.is_not_empty() {
-                    let mut platform_rest_fb = self.platform_rest.clone_box();
-                    // 先更新本地记录再发单。
-                    self._update_local_orders(&mut orders);
-                    // info!("订单指令:{:?}", orders);
-                    let mut ts = trace_stack.clone();
-                    spawn(async move {
-                        platform_rest_fb.command_order(&mut orders, &mut ts).await;
-                    });
-
-                    // 更新中控账户相关信息
-                    {
-                        let mut now_balance = self.strategy.equity / self.used_pct;
-                        now_balance.rescale(4);
-
-                        let mut cci = self.cci_arc.lock().await;
-                        cci.now_balance = now_balance;
-                    }
-                }
-            }
+            // let ticker = self.tickers.get(name_ref).unwrap();
+            // if self.trade_vec.len() == 100 {
+            //     self.trade_vec.pop_front();
+            // }
+            // self.trade_vec.push_back(Trade::new_by_ticker(ticker.mid_price.clone(), ticker.create_at/1000));
+            // // 更新波动率
+            // if self.trade_vec.len() > 99 {
+            //     self.calc_sigma();
+            //     // 波动率正常,但还是不开单信号,允许开单
+            //     if !self.is_sigma_abnormal && !self.is_sigma_allow_open {
+            //         self.is_sigma_allow_open = true;
+            //     }
+            // }
+            // // 判断是否需要触发ontick 对行情进行过滤
+            // // 过滤条件 价格变化很大 时间间隔很长
+            // let mut flag = 0;
+            // let bid_price_rate = (depth[BID_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[BID_PRICE_INDEX]).abs() / depth[BID_PRICE_INDEX];
+            // let ask_price_rate = (depth[ASK_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[ASK_PRICE_INDEX]).abs() / depth[ASK_PRICE_INDEX];
+            // let rate = dec!(0.0002);
+            // if bid_price_rate > rate || ask_price_rate > rate || Utc::now().timestamp_millis() - self.on_tick_event_time > 50 {
+            //     // 允许交易
+            //     flag = 1;
+            //     // 更新ontick触发时间记录
+            //     self.on_tick_event_time = Utc::now().timestamp_millis();
+            // }
+            // // 允许交易
+            // if self.mode_signal == 0 && self.ready == 1 && flag == 1 {
+            //     // 更新交易数据
+            //     self.update_trade_msg();
+            //     // 触发事件撤单逻辑
+            //     // 更新策略时间
+            //     self.strategy.local_time = Utc::now().timestamp_millis();
+            //
+            //     // 产生交易信号
+            //     let mut orders = self.strategy.on_tick(&self.local_orders,
+            //                                            &self.local_position_by_orders,
+            //                                            &self.agg_market,
+            //                                            &self.local_cash,
+            //                                            &self.local_coin,
+            //                                            &self.ref_price,
+            //                                            &self.predict,
+            //                                            &self.is_sigma_allow_open,
+            //                                            &trace_stack.ins);
+            //     trace_stack.on_after_strategy();
+            //
+            //     if orders.is_not_empty() {
+            //         let mut platform_rest_fb = self.platform_rest.clone_box();
+            //         // 先更新本地记录再发单。
+            //         self._update_local_orders(&mut orders);
+            //         // info!("订单指令:{:?}", orders);
+            //         let mut ts = trace_stack.clone();
+            //         spawn(async move {
+            //             platform_rest_fb.command_order(&mut orders, &mut ts).await;
+            //         });
+            //
+            //         // 更新中控账户相关信息
+            //         {
+            //             let mut now_balance = self.strategy.equity / self.used_pct;
+            //             now_balance.rescale(4);
+            //
+            //             let mut cci = self.cci_arc.lock().await;
+            //             cci.now_balance = now_balance;
+            //         }
+            //     }
+            // }
         }
 
         {
@@ -933,21 +1001,22 @@ impl Core {
         // self.trade_msg.position = self.local_position_by_orders.clone();
         // self.trade_msg.orders = self.local_orders.clone();
         // 更新 ref
-        let mut ref_tickers: BTreeMap<String, Ticker> = BTreeMap::new();
-        for i in &self.ref_name {
-            let bp = self.tickers.get(i).unwrap().buy;
-            let ap = self.tickers.get(i).unwrap().sell;
-            ref_tickers.insert(i.clone(), Ticker {
-                time: 0,
-                high: Default::default(),
-                low: Default::default(),
-                sell: ap,
-                buy: bp,
-                last: Default::default(),
-                volume: Default::default(),
-            });
-        }
-        self.ref_price = self.predictor.get_ref_price(&ref_tickers);
+        // let mut ref_tickers: BTreeMap<String, Ticker> = BTreeMap::new();
+        // for i in &self.ref_name {
+        //     let bp = self.tickers.get(i).unwrap().buy;
+        //     let ap = self.tickers.get(i).unwrap().sell;
+        //     ref_tickers.insert(i.clone(), Ticker {
+        //         time: 0,
+        //         high: Default::default(),
+        //         low: Default::default(),
+        //         sell: ap,
+        //         buy: bp,
+        //         last: Default::default(),
+        //         volume: Default::default(),
+        //     });
+        // }
+        // ref_price = [[bid_price, ask_price]]
+        // self.ref_price = self.predictor.get_ref_price(&ref_tickers);
     }
 
     // 本地记录所有报单信息
@@ -1867,6 +1936,7 @@ pub fn run_strategy(core_arc: Arc<Mutex<Core>>) -> JoinHandle<()> {
                         }
                     }
                 } else {
+                    tokio::time::sleep(Duration::from_secs(1)).await;
                     core.check_ready();
                 }
                 // 计算耗时并进行休眠

+ 117 - 14
strategy/src/fix_price.rs

@@ -1,6 +1,6 @@
-use std::str::FromStr;
 use rust_decimal::Decimal;
 use rust_decimal::prelude::{FromPrimitive, Signed, ToPrimitive};
+use tracing::info;
 use standard::{MarketOrder, Trade, TradeSide};
 use standard::handle_info::DepthParam;
 // --- 1. 数据结构定义 ---
@@ -90,7 +90,6 @@ fn signed_log(val: Decimal) -> Decimal {
 /// 如果一个交易组完成,则返回 `Some(TradeCum)`,否则返回 `None`。
 pub fn process_raw_trade(state: &mut PricingState, trade: Trade) -> Option<TradeCum> {
     let current_timestamp = trade.timestamp_us;
-
     // 如果是第一笔交易,或者当前交易与上一笔交易的时间差在阈值内,则加入当前组
     if state.last_trade_timestamp_us == 0 || (current_timestamp - state.last_trade_timestamp_us) <= state.trade_interception_tau_us {
         state.current_trade_group.push(trade);
@@ -197,10 +196,10 @@ pub fn calculate_depth_pricing(state: &mut PricingState, current_depth: DepthPar
         Decimal::ZERO // 如果订单簿为空,midprice 为 0
     };
     let depth_minus_mid = ibary_p - midprice;
-    let number_1 = Decimal::from_str("7.722e-7").unwrap();
-    let number_2 = Decimal::from_str("2.157e-7").unwrap();
-    let number_3 = Decimal::from_str("3.478e-7").unwrap();
-    let number_4 = Decimal::from_str("0.3429").unwrap();
+    let number_1 = Decimal::from_f64(7.722e-7f64).unwrap();
+    let number_2 = Decimal::from_f64(2.157e-7f64).unwrap();
+    let number_3 = Decimal::from_f64(3.478e-7f64).unwrap();
+    let number_4 = Decimal::from_f64(0.3429f64).unwrap();
 
     // 7. 计算 depth_theo
     let alpha = number_1 * trade_flow_cum_sum_log
@@ -263,11 +262,11 @@ pub fn calculate_trade_cum_pricing(state: &mut PricingState, current_trade_cum:
     // 和 `current_trade_cum` 在内的所有 `trade_cum` 组的 `v` 总和。
     let trade_flow_cum_sum_n: Decimal = state.trade_cums_between_depths.iter().map(|tc| tc.v).sum::<Decimal>() + current_trade_cum.v;
     let trade_flow_cum_sum_log = signed_log(trade_flow_cum_sum_n);
-    let number_1 = Decimal::from_str("2.461e-6").unwrap();
-    let number_2 = Decimal::from_str("8.486e-7").unwrap();
-    let number_3 = Decimal::from_str("5.788e-7").unwrap();
-    let number_4 = Decimal::from_str("5.989e-7").unwrap();
-    let number_5 = Decimal::from_str("0.1854").unwrap();
+    let number_1 = Decimal::from_f64(2.461e-6f64).unwrap();
+    let number_2 = Decimal::from_f64(8.486e-7f64).unwrap();
+    let number_3 = Decimal::from_f64(5.788e-7f64).unwrap();
+    let number_4 = Decimal::from_f64(5.989e-7f64).unwrap();
+    let number_5 = Decimal::from_f64(0.1854f64).unwrap();
 
     // 3. 计算 trade_theo
     let alpha = number_1 * tradeflow_log
@@ -316,14 +315,18 @@ impl PricingEngine {
 
     /// 当从 WebSocket 接收到新的深度行情消息时调用此方法。
     /// 它会刷新任何待处理的交易组,计算 `depth_theo` 价格,并返回它。
-    pub fn on_depth_message(&mut self, depth: DepthParam) -> Decimal {
+    pub fn on_depth_message(&mut self, depth: DepthParam) -> Option<Decimal> {
         // 在计算 depth_theo 之前,确保所有在当前深度更新前发生的交易组都被刷新。
         if let Some(trade_cum) = flush_trade_group(&mut self.state) {
             self.state.trade_cums_between_depths.push(trade_cum);
         }
 
         let depth_theo = calculate_depth_pricing(&mut self.state, depth);
-        depth_theo
+        if depth_theo > Decimal::ZERO {
+            Some(depth_theo)
+        } else {
+            None
+        }
     }
 
     /// 返回最后一次计算的 `depth_theo` 和 `trade_theo` 价格。
@@ -339,9 +342,71 @@ impl PricingEngine {
 mod tests {
     use std::str::FromStr;
     use rust_decimal::Decimal;
+    use rust_decimal::prelude::FromPrimitive;
+    use serde::{Deserialize, Deserializer};
+    use serde_json::Value;
     use standard::handle_info::DepthParam;
     use crate::fix_price::{MarketOrder, PricingEngine, Trade, TradeSide};
 
+    #[derive(Deserialize)]
+    struct A{
+        a: Decimal
+    }
+
+    #[derive(Deserialize)]
+    struct OptionA{
+        #[serde(deserialize_with = "deserialize_option_decimal")]
+        a: Option<Decimal>
+    }
+    // 自定义反序列化函数
+    // 'de 生命周期参数是 serde 反序列化所需的
+    // D 是一个 Deserializer trait 的实现类型
+    // 自定义反序列化函数,能够处理 null, empty string, number string, and JSON number
+    fn deserialize_option_decimal<'de, D>(
+        deserializer: D,
+    ) -> Result<Option<Decimal>, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        // 1. 尝试将值反序列化为 serde_json::Value 枚举
+        // 这能捕获 JSON 中的任何类型 (null, boolean, number, string, array, object)
+        match Value::deserialize(deserializer)? {
+            Value::Null => {
+                // 如果是 JSON null,我们希望 Option<Decimal> 是 None
+                Ok(None)
+            }
+            Value::String(s) => {
+                // 如果是 JSON string
+                if s.is_empty() {
+                    // 如果字符串是空的,我们希望 Option<Decimal> 是 None
+                    Ok(None)
+                } else {
+                    // 如果字符串不是空的,尝试解析为 Decimal
+                    // 使用 .map(|d| Some(d)) 包装解析成功的 Decimal
+                    // 使用 .map_err 转换 rust_decimal::Error 为 Serde Deserialization Error
+                    s.parse::<Decimal>()
+                        .map(|d| Some(d))
+                        .map_err(|e| serde::de::Error::custom(format!("Invalid Decimal string: {}", e)))
+                }
+            }
+            Value::Number(num) => {
+                // 如果是 JSON number
+                // 将 serde_json::Number 转换为其字符串表示
+                // 然后解析这个字符串为 Decimal。这是一个安全且精确的方法。
+                let s = num.to_string();
+                s.parse::<Decimal>()
+                    .map(|d| Some(d))
+                    .map_err(|e| serde::de::Error::custom(format!("Could not parse number token {} as Decimal: {}", s, e)))
+
+                // 注意:直接从 f64 转换会损失精度,所以上面的方法更可取。
+                // rust_decimal::Decimal::from_f64(num.as_f64()?) // 这种方式不推荐 for precision
+                // 或者 if let Some(i) = num.as_i64() { Ok(Some(Decimal::from(i))) } ...
+            }
+            // 如果是其他 JSON 类型 (Bool, Array, Object),则返回错误
+            _ => Err(serde::de::Error::custom("Invalid type for Option<Decimal>, expected null, string, or number")),
+        }
+    }
+
     #[test]
     fn clip_test() {
         // 初始化定价引擎,设置交易截取阈值为 0.1ms (100微秒)
@@ -407,7 +472,7 @@ mod tests {
             ],
         };
         let depth_theo = pricing_engine.on_depth_message(depth1);
-        println!("DepthParam 1 触发 depth_theo: {}", depth_theo);
+        println!("DepthParam 1 触发 depth_theo: {}", depth_theo.unwrap());
 
         // --- 模拟后续交易消息 ---
         println!("\n--- 模拟后续交易消息处理 ---");
@@ -422,4 +487,42 @@ mod tests {
         let final_pricing = pricing_engine.get_current_pricing_output();
         println!("\n最终定价结果: {:?}", final_pricing);
     }
+
+    #[test]
+    fn test_num(){
+        // 原始的科学计数法字符串。
+        // 如果您是从其他地方(如文件、网络)读取这个字符串,
+        // 请确保将其粘贴到此处进行测试,或者替换为读取到的实际字符串变量。
+        let s_original = 7.722e-7f64;
+
+        // 3. 尝试将修剪后的字符串解析为 Decimal 类型
+        match Decimal::from_f64(s_original) {
+            Some(d) => {
+                // 如果成功,打印转换后的 Decimal 值
+                println!("\n✅ 成功将字符串 \"{}\" 转换为 Decimal: {}", s_original, d);
+                // 此时 'd' 就是你需要的 Decimal 类型的值
+                // 你可以对 'd' 进行各种 Decimal 相关的数学运算
+            }
+            None => {
+                // 如果失败,打印错误信息到标准错误输出
+                eprintln!("\n❌ 转换字符串 \"{}\" 为 Decimal 失败", s_original);
+            }
+        }
+    }
+
+    #[test]
+    fn test_decimal(){
+        let str = "{\"a\": \"\"}";
+        // let a: A = serde_json::from_str(str).unwrap();
+        let a_op: OptionA = serde_json::from_str(str).unwrap();
+        // println!("a.a: {}", a.a);
+        match a_op.a {
+            None => {
+                println!("解析为空!");
+            }
+            Some(x) => {
+                println!("a_op.a: {}", x);
+            }
+        }
+    }
 }

+ 1 - 1
strategy/src/predictor.rs

@@ -115,7 +115,7 @@ impl Predictor {
 
     // 市场信息处理器,也是python里的onTime方法
     // #[instrument(skip(self, new_market_info), level="TRACE")]
-    pub fn market_info_handler(&mut self, new_market_info: &Vec<Decimal>) {
+    pub fn  market_info_handler(&mut self, new_market_info: &Vec<Decimal>) {
         // 空数据不处理
         if new_market_info.len() == 0 {
             return;

+ 2 - 2
strategy/src/strategy.rs

@@ -933,7 +933,7 @@ impl Strategy {
             if self.pos.long_pos * self.mp > self._min_amount_value {
                 if pd_order_num == 0 {
                     let mut price = (short_lower + short_upper) * dec!(0.5);
-                    price = utils::clip(price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
+                    // price = utils::clip(price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
                     price = utils::fix_price(price, self.tick_size);
                     let mut amount = self.pos.long_pos;
                     amount = utils::fix_amount(amount, self.step_size);
@@ -957,7 +957,7 @@ impl Strategy {
             if self.pos.short_pos > self._min_amount_value {
                 if pk_order_num == 0 {
                     let mut price = (long_upper + long_lower) * dec!(0.5);
-                    price = utils::clip(price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
+                    // price = utils::clip(price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
                     price = utils::fix_price(price, self.tick_size);
                     let mut amount = self.pos.short_pos;
                     amount = utils::fix_amount(amount, self.step_size);