|
@@ -4,7 +4,6 @@ use anyhow::{anyhow, bail, Result};
|
|
|
use rust_decimal::Decimal;
|
|
use rust_decimal::Decimal;
|
|
|
use std::time::{Duration, Instant};
|
|
use std::time::{Duration, Instant};
|
|
|
use rust_decimal_macros::dec;
|
|
use rust_decimal_macros::dec;
|
|
|
-use serde_json::Value;
|
|
|
|
|
use tokio::sync::Mutex;
|
|
use tokio::sync::Mutex;
|
|
|
use tokio::time::sleep;
|
|
use tokio::time::sleep;
|
|
|
use tracing::{info, warn};
|
|
use tracing::{info, warn};
|
|
@@ -105,7 +104,7 @@ impl Strategy {
|
|
|
if dm.best_bid.is_zero() || dm.best_ask.is_zero() {
|
|
if dm.best_bid.is_zero() || dm.best_ask.is_zero() {
|
|
|
return Ok(());
|
|
return Ok(());
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 到这里了就准备完毕了
|
|
// 到这里了就准备完毕了
|
|
|
self.state = StrategyState::Idle;
|
|
self.state = StrategyState::Idle;
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -113,14 +112,14 @@ impl Strategy {
|
|
|
|
|
|
|
|
// 状态1: 空闲状态,下限价买单
|
|
// 状态1: 空闲状态,下限价买单
|
|
|
async fn handle_idle_state(&mut self, dm: &DataManager) -> Result<()> {
|
|
async fn handle_idle_state(&mut self, dm: &DataManager) -> Result<()> {
|
|
|
- info!("============================ 进入空闲状态,准备下买单 ===========================");
|
|
|
|
|
-
|
|
|
|
|
// 检查是否满足下单时间间隔
|
|
// 检查是否满足下单时间间隔
|
|
|
let elapsed = self.last_order_time.elapsed().as_millis();
|
|
let elapsed = self.last_order_time.elapsed().as_millis();
|
|
|
if elapsed < self.min_order_interval_ms {
|
|
if elapsed < self.min_order_interval_ms {
|
|
|
return Ok(());
|
|
return Ok(());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ info!("============================ 进入空闲状态,准备下买单 ===========================");
|
|
|
|
|
+
|
|
|
// 尝试下单,只有成功才转换状态
|
|
// 尝试下单,只有成功才转换状态
|
|
|
match self.place_limit_buy_order(dm.best_bid, self.order_quantity).await {
|
|
match self.place_limit_buy_order(dm.best_bid, self.order_quantity).await {
|
|
|
Ok(order_id) => {
|
|
Ok(order_id) => {
|
|
@@ -158,7 +157,7 @@ impl Strategy {
|
|
|
self.last_query_order_time = Instant::now();
|
|
self.last_query_order_time = Instant::now();
|
|
|
|
|
|
|
|
// 检查订单是否已成交
|
|
// 检查订单是否已成交
|
|
|
- match self.check_order_filled(&order_id).await {
|
|
|
|
|
|
|
+ match self.check_order_filled(&order_id, dm).await {
|
|
|
Ok(true) => {
|
|
Ok(true) => {
|
|
|
info!("限价单已成交,准备执行市价单");
|
|
info!("限价单已成交,准备执行市价单");
|
|
|
self.state = StrategyState::ExecutingMarketOrder { };
|
|
self.state = StrategyState::ExecutingMarketOrder { };
|
|
@@ -187,7 +186,7 @@ impl Strategy {
|
|
|
// 状态3: 撤单处理
|
|
// 状态3: 撤单处理
|
|
|
async fn handle_cancelling_order(
|
|
async fn handle_cancelling_order(
|
|
|
&mut self,
|
|
&mut self,
|
|
|
- _dm: &DataManager,
|
|
|
|
|
|
|
+ dm: &DataManager,
|
|
|
order_id: String,
|
|
order_id: String,
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
info!("撤单中,订单ID: {}", order_id);
|
|
info!("撤单中,订单ID: {}", order_id);
|
|
@@ -202,7 +201,7 @@ impl Strategy {
|
|
|
sleep(Duration::from_millis(3000)).await;
|
|
sleep(Duration::from_millis(3000)).await;
|
|
|
|
|
|
|
|
// 撤单后检查是否有成交
|
|
// 撤单后检查是否有成交
|
|
|
- match self.check_order_partially_filled(&order_id).await {
|
|
|
|
|
|
|
+ match self.check_order_partially_filled(&order_id, dm).await {
|
|
|
Ok(true) => {
|
|
Ok(true) => {
|
|
|
info!("撤单后发现有成交,准备执行市价单");
|
|
info!("撤单后发现有成交,准备执行市价单");
|
|
|
self.state = StrategyState::ExecutingMarketOrder { };
|
|
self.state = StrategyState::ExecutingMarketOrder { };
|
|
@@ -255,7 +254,7 @@ impl Strategy {
|
|
|
// 状态5:等待市价单成交
|
|
// 状态5:等待市价单成交
|
|
|
async fn handle_waiting_market_order(
|
|
async fn handle_waiting_market_order(
|
|
|
&mut self,
|
|
&mut self,
|
|
|
- _dm: &DataManager,
|
|
|
|
|
|
|
+ dm: &DataManager,
|
|
|
order_id: String,
|
|
order_id: String,
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
let elapsed = self.last_query_order_time.elapsed().as_millis();
|
|
let elapsed = self.last_query_order_time.elapsed().as_millis();
|
|
@@ -265,7 +264,7 @@ impl Strategy {
|
|
|
self.last_query_order_time = Instant::now();
|
|
self.last_query_order_time = Instant::now();
|
|
|
|
|
|
|
|
// 等待市价单成交(市价单通常立即成交)
|
|
// 等待市价单成交(市价单通常立即成交)
|
|
|
- match self.check_order_filled(&order_id).await {
|
|
|
|
|
|
|
+ match self.check_order_filled(&order_id, dm).await {
|
|
|
Ok(true) => {
|
|
Ok(true) => {
|
|
|
info!("市价单已成交,返回空闲状态");
|
|
info!("市价单已成交,返回空闲状态");
|
|
|
|
|
|
|
@@ -351,22 +350,22 @@ impl Strategy {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 检查订单是否完全成交
|
|
/// 检查订单是否完全成交
|
|
|
- async fn check_order_filled(&mut self, order_id: &str) -> Result<bool> {
|
|
|
|
|
- self.check_order_filled_status(order_id, true).await
|
|
|
|
|
|
|
+ async fn check_order_filled(&mut self, order_id: &str, dm: &DataManager) -> Result<bool> {
|
|
|
|
|
+ self.check_order_filled_status(order_id, dm, true).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 检查订单是否有部分成交
|
|
/// 检查订单是否有部分成交
|
|
|
- async fn check_order_partially_filled(&mut self, order_id: &str) -> Result<bool> {
|
|
|
|
|
- self.check_order_filled_status(order_id, false).await
|
|
|
|
|
|
|
+ async fn check_order_partially_filled(&mut self, order_id: &str, dm: &DataManager) -> Result<bool> {
|
|
|
|
|
+ self.check_order_filled_status(order_id, dm, false).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 检查订单成交状态
|
|
/// 检查订单成交状态
|
|
|
/// - `require_full_fill`: true 表示只接受完全成交,false 表示部分成交也接受
|
|
/// - `require_full_fill`: true 表示只接受完全成交,false 表示部分成交也接受
|
|
|
- async fn check_order_filled_status(&mut self, order_id: &str, require_full_fill: bool) -> Result<bool> {
|
|
|
|
|
|
|
+ async fn check_order_filled_status(&mut self, order_id: &str, dm: &DataManager, require_full_fill: bool) -> Result<bool> {
|
|
|
let check_type = if require_full_fill { "完全成交" } else { "部分成交" };
|
|
let check_type = if require_full_fill { "完全成交" } else { "部分成交" };
|
|
|
- // info!("检查订单是否{}: {}", check_type, order_id);
|
|
|
|
|
|
|
|
|
|
- let data = self.get_order_result(order_id).await?;
|
|
|
|
|
|
|
+ let data = dm.extended_orders.get(order_id)
|
|
|
|
|
+ .ok_or_else(|| anyhow!("订单暂时不存在: {}", order_id))?;
|
|
|
|
|
|
|
|
let data_str = serde_json::to_string(&data)
|
|
let data_str = serde_json::to_string(&data)
|
|
|
.unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
.unwrap_or_else(|_| "无法序列化 JSON Value".to_string());
|
|
@@ -400,31 +399,6 @@ impl Strategy {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- async fn get_order_result(&self, order_id: &str) -> Result<Value> {
|
|
|
|
|
- let mut client = self.rest_client.lock().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());
|
|
|
|
|
-
|
|
|
|
|
- // 获取并判定 status
|
|
|
|
|
- let status = value.get("status")
|
|
|
|
|
- .and_then(|v| v.as_str())
|
|
|
|
|
- .ok_or_else(|| anyhow!("查单-获取 'status' 失败,原始JSON:{}", value_str))?;
|
|
|
|
|
-
|
|
|
|
|
- if status != "OK" {
|
|
|
|
|
- bail!("查单失败,状态不为OK: {},原始JSON:{}", status, value_str)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 获取 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> {
|
|
fn match_create_order_result(&self, create_result: &Result<Response>) -> Result<String> {
|
|
|
match create_result {
|
|
match create_result {
|
|
|
Ok(response) => {
|
|
Ok(response) => {
|