|
|
@@ -63,7 +63,7 @@ impl Strategy {
|
|
|
}
|
|
|
}
|
|
|
StrategyState::CancellingOrder { order_id, price, last_order_time } => {
|
|
|
- if let Err(e) = self.handle_cancelling_order(dm, order_id, price, last_order_time).await {
|
|
|
+ if let Err(e) = self.handle_cancelling_order(dm, price, order_id, last_order_time).await {
|
|
|
warn!("撤单状态处理失败: {}", e);
|
|
|
}
|
|
|
}
|
|
|
@@ -150,9 +150,9 @@ impl Strategy {
|
|
|
// 状态3: 撤单处理
|
|
|
async fn handle_cancelling_order(
|
|
|
&mut self,
|
|
|
- dm: &DataManager,
|
|
|
+ _dm: &DataManager,
|
|
|
+ _price: Decimal,
|
|
|
order_id: String,
|
|
|
- price: Decimal,
|
|
|
last_order_time: Instant,
|
|
|
) -> Result<()> {
|
|
|
info!("撤单中,订单ID: {}", order_id);
|
|
|
@@ -188,8 +188,8 @@ impl Strategy {
|
|
|
// 状态4: 执行市价单
|
|
|
async fn handle_executing_market_order(
|
|
|
&mut self,
|
|
|
- dm: &DataManager,
|
|
|
- last_order_time: Instant,
|
|
|
+ _dm: &DataManager,
|
|
|
+ _last_order_time: Instant,
|
|
|
) -> Result<()> {
|
|
|
info!("执行市价卖单");
|
|
|
|
|
|
@@ -301,105 +301,77 @@ impl Strategy {
|
|
|
|
|
|
/// 检查订单是否完全成交
|
|
|
async fn check_order_filled(&mut self, order_id: &str) -> Result<bool> {
|
|
|
- info!("检查订单是否成交: {}", order_id);
|
|
|
-
|
|
|
- let query_result = self.get_order_result(order_id).await;
|
|
|
-
|
|
|
- match query_result {
|
|
|
- Ok(data) => {
|
|
|
- let data_str = serde_json::to_string(&data).unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
|
-
|
|
|
- // 获取order的状态[NEW, PARTIALLY_FILLED, FILLED, UNTRIGGERED, CANCELLED, REJECTED, EXPIRED, TRIGGERED]
|
|
|
- let status = data.get("status")
|
|
|
- .and_then(|v| v.as_str())
|
|
|
- .ok_or_else(|| anyhow!("查单-获取 'data.status' 失败,原始JSON:{}", data_str))?;
|
|
|
-
|
|
|
- // 只考虑完全成交的
|
|
|
- if status == "FILLED" {
|
|
|
- // 获取真实成交数量
|
|
|
- let filled_qty = data.get("filledQty")
|
|
|
- .and_then(|v| v.as_str())
|
|
|
- .ok_or_else(|| anyhow!("查单-获取 'data.filledQty' 失败,原始JSON:{}", data_str))
|
|
|
- .and_then(|v| Decimal::from_str(v)
|
|
|
- .map_err(|e| anyhow!("查单-解析 'data.filledQty' 为 Decimal 失败: {}, 值: {}", e, v))
|
|
|
- )?;
|
|
|
-
|
|
|
- self.filled_quantity = filled_qty;
|
|
|
-
|
|
|
- Ok(true)
|
|
|
- } else {
|
|
|
- Ok(false)
|
|
|
- }
|
|
|
- }
|
|
|
- Err(error) => {
|
|
|
- bail!("查单失败: {}", error);
|
|
|
- }
|
|
|
- }
|
|
|
+ self.check_order_filled_status(order_id, true).await
|
|
|
}
|
|
|
|
|
|
/// 检查订单是否有部分成交
|
|
|
async fn check_order_partially_filled(&mut self, order_id: &str) -> Result<bool> {
|
|
|
- info!("检查订单是否有部分成交: {}", order_id);
|
|
|
+ self.check_order_filled_status(order_id, false).await
|
|
|
+ }
|
|
|
|
|
|
- let query_result = self.get_order_result(order_id).await;
|
|
|
-
|
|
|
- match query_result {
|
|
|
- Ok(data) => {
|
|
|
- let data_str = serde_json::to_string(&data).unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
|
+ /// 检查订单成交状态
|
|
|
+ /// - `require_full_fill`: true 表示只接受完全成交,false 表示部分成交也接受
|
|
|
+ async fn check_order_filled_status(&mut self, order_id: &str, require_full_fill: bool) -> Result<bool> {
|
|
|
+ let check_type = if require_full_fill { "完全成交" } else { "部分成交" };
|
|
|
+ info!("检查订单是否{}: {}", check_type, order_id);
|
|
|
|
|
|
- // 获取order的状态[NEW, PARTIALLY_FILLED, FILLED, UNTRIGGERED, CANCELLED, REJECTED, EXPIRED, TRIGGERED]
|
|
|
- let status = data.get("status")
|
|
|
- .and_then(|v| v.as_str())
|
|
|
- .ok_or_else(|| anyhow!("查单-获取 'data.status' 失败,原始JSON:{}", data_str))?;
|
|
|
-
|
|
|
- // 只考虑完全成交的
|
|
|
- if status == "FILLED" || status == "PARTIALLY_FILLED" {
|
|
|
- // 获取真实成交数量
|
|
|
- let filled_qty = data.get("filledQty")
|
|
|
- .and_then(|v| v.as_str())
|
|
|
- .ok_or_else(|| anyhow!("查单-获取 'data.filledQty' 失败,原始JSON:{}", data_str))
|
|
|
- .and_then(|v| Decimal::from_str(v)
|
|
|
- .map_err(|e| anyhow!("查单-解析 'data.filledQty' 为 Decimal 失败: {}, 值: {}", e, v))
|
|
|
- )?;
|
|
|
-
|
|
|
- self.filled_quantity = filled_qty;
|
|
|
-
|
|
|
- Ok(true)
|
|
|
- } else {
|
|
|
- Ok(false)
|
|
|
- }
|
|
|
- }
|
|
|
- Err(error) => {
|
|
|
- bail!("查单失败: {}", error);
|
|
|
- }
|
|
|
+ let data = self.get_order_result(order_id).await?;
|
|
|
+
|
|
|
+ let data_str = serde_json::to_string(&data)
|
|
|
+ .unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
|
+
|
|
|
+ // 获取订单状态 [NEW, PARTIALLY_FILLED, FILLED, UNTRIGGERED, CANCELLED, REJECTED, EXPIRED, TRIGGERED]
|
|
|
+ let status = data.get("status")
|
|
|
+ .and_then(|v| v.as_str())
|
|
|
+ .ok_or_else(|| anyhow!("查单-获取 'data.status' 失败,原始JSON:{}", data_str))?;
|
|
|
+
|
|
|
+ // 根据要求判断是否符合成交条件
|
|
|
+ let is_filled = if require_full_fill {
|
|
|
+ status == "FILLED"
|
|
|
+ } else {
|
|
|
+ status == "FILLED" || status == "PARTIALLY_FILLED"
|
|
|
+ };
|
|
|
+
|
|
|
+ if is_filled {
|
|
|
+ // 获取真实成交数量
|
|
|
+ let filled_qty = data.get("filledQty")
|
|
|
+ .and_then(|v| v.as_str())
|
|
|
+ .ok_or_else(|| anyhow!("查单-获取 'data.filledQty' 失败,原始JSON:{}", data_str))
|
|
|
+ .and_then(|v| Decimal::from_str(v)
|
|
|
+ .map_err(|e| anyhow!("查单-解析 'data.filledQty' 为 Decimal 失败: {}, 值: {}", e, v))
|
|
|
+ )?;
|
|
|
+
|
|
|
+ self.filled_quantity = filled_qty;
|
|
|
+ info!("订单 {} 已{},成交数量: {}", order_id, check_type, filled_qty);
|
|
|
+ Ok(true)
|
|
|
+ } else {
|
|
|
+ Ok(false)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async fn get_order_result(&self, id: &str) -> Result<Value> {
|
|
|
+ async fn get_order_result(&self, order_id: &str) -> Result<Value> {
|
|
|
let mut client = self.rest_client.lock().await;
|
|
|
- let response = client.get_order(id).await;
|
|
|
+ let response = client.get_order(order_id).await;
|
|
|
|
|
|
let value = &response.data;
|
|
|
|
|
|
// 预先捕获整个 Value 的字符串表示,用于错误报告
|
|
|
- let value_str = serde_json::to_string(&value).unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
|
+ let value_str = serde_json::to_string(&value)
|
|
|
+ .unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
|
|
|
|
- // 获取status
|
|
|
+ // 获取并判定 status
|
|
|
let status = value.get("status")
|
|
|
.and_then(|v| v.as_str())
|
|
|
.ok_or_else(|| anyhow!("查单-获取 'status' 失败,原始JSON:{}", value_str))?;
|
|
|
|
|
|
- // 判定status
|
|
|
if status != "OK" {
|
|
|
- bail!("查单失败,状态不为OK,原始JSON:{}", value_str)
|
|
|
+ bail!("查单失败,状态不为OK: {},原始JSON:{}", status, value_str)
|
|
|
}
|
|
|
|
|
|
- // 尝试获取 data 字段
|
|
|
- let data = value.get("data")
|
|
|
- .ok_or_else(|| anyhow!("下单-获取 'data' 字段失败,原始 JSON: {}", value_str))?;
|
|
|
-
|
|
|
- // data返回给查单
|
|
|
- Ok(data.clone())
|
|
|
+ // 获取 data 字段
|
|
|
+ value.get("data")
|
|
|
+ .cloned()
|
|
|
+ .ok_or_else(|| anyhow!("查单-获取 'data' 字段失败,原始 JSON: {}", value_str))
|
|
|
}
|
|
|
|
|
|
fn match_create_order_result(&self, create_result: &Result<Response>) -> Result<String> {
|