From a80590e592a8f69047a5687eccc76a66d1a77307 Mon Sep 17 00:00:00 2001 From: mxyhi Date: Thu, 30 Oct 2025 13:06:14 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20feat(trader):=20aster=E5=B9=B3?= =?UTF-8?q?=E4=BB=93=E5=90=8E=E8=87=AA=E5=8A=A8=E5=8F=96=E6=B6=88=E6=8C=82?= =?UTF-8?q?=E5=8D=95=20-=20=E8=B0=83=E6=95=B4=20CloseLong/CloseShort=20?= =?UTF-8?q?=E9=80=BB=E8=BE=91,=20=E5=9C=A8=E5=B9=B3=E4=BB=93=E5=90=8E?= =?UTF-8?q?=E8=B0=83=E7=94=A8=20CancelAllOrders=20=E6=B8=85=E7=90=86?= =?UTF-8?q?=E6=8C=82=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- trader/aster_trader.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/trader/aster_trader.go b/trader/aster_trader.go index 9aaf078c..e3a96aed 100644 --- a/trader/aster_trader.go +++ b/trader/aster_trader.go @@ -195,11 +195,11 @@ func (t *AsterTrader) formatQuantity(symbol string, quantity float64) (float64, func (t *AsterTrader) formatFloatWithPrecision(value float64, precision int) string { // 使用指定精度格式化 formatted := strconv.FormatFloat(value, 'f', precision, 64) - + // 去除末尾的0和小数点(如果有) formatted = strings.TrimRight(formatted, "0") formatted = strings.TrimRight(formatted, ".") - + return formatted } @@ -556,7 +556,7 @@ func (t *AsterTrader) OpenLong(symbol string, quantity float64, leverage int) (m priceStr := t.formatFloatWithPrecision(formattedPrice, prec.PricePrecision) qtyStr := t.formatFloatWithPrecision(formattedQty, prec.QuantityPrecision) - log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", + log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", limitPrice, priceStr, prec.PricePrecision, quantity, qtyStr, prec.QuantityPrecision) params := map[string]interface{}{ @@ -618,7 +618,7 @@ func (t *AsterTrader) OpenShort(symbol string, quantity float64, leverage int) ( priceStr := t.formatFloatWithPrecision(formattedPrice, prec.PricePrecision) qtyStr := t.formatFloatWithPrecision(formattedQty, prec.QuantityPrecision) - log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", + log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", limitPrice, priceStr, prec.PricePrecision, quantity, qtyStr, prec.QuantityPrecision) params := map[string]interface{}{ @@ -693,7 +693,7 @@ func (t *AsterTrader) CloseLong(symbol string, quantity float64) (map[string]int priceStr := t.formatFloatWithPrecision(formattedPrice, prec.PricePrecision) qtyStr := t.formatFloatWithPrecision(formattedQty, prec.QuantityPrecision) - log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", + log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", limitPrice, priceStr, prec.PricePrecision, quantity, qtyStr, prec.QuantityPrecision) params := map[string]interface{}{ @@ -717,6 +717,12 @@ func (t *AsterTrader) CloseLong(symbol string, quantity float64) (map[string]int } log.Printf("✓ 平多仓成功: %s 数量: %s", symbol, qtyStr) + + // 平仓后取消该币种的所有挂单(止损止盈单) + if err := t.CancelAllOrders(symbol); err != nil { + log.Printf(" ⚠ 取消挂单失败: %v", err) + } + return result, nil } @@ -770,7 +776,7 @@ func (t *AsterTrader) CloseShort(symbol string, quantity float64) (map[string]in priceStr := t.formatFloatWithPrecision(formattedPrice, prec.PricePrecision) qtyStr := t.formatFloatWithPrecision(formattedQty, prec.QuantityPrecision) - log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", + log.Printf(" 📏 精度处理: 价格 %.8f -> %s (精度=%d), 数量 %.8f -> %s (精度=%d)", limitPrice, priceStr, prec.PricePrecision, quantity, qtyStr, prec.QuantityPrecision) params := map[string]interface{}{ @@ -794,6 +800,12 @@ func (t *AsterTrader) CloseShort(symbol string, quantity float64) (map[string]in } log.Printf("✓ 平空仓成功: %s 数量: %s", symbol, qtyStr) + + // 平仓后取消该币种的所有挂单(止损止盈单) + if err := t.CancelAllOrders(symbol); err != nil { + log.Printf(" ⚠ 取消挂单失败: %v", err) + } + return result, nil } From b75a671b2c86a7028a471a449b2203c226a89af2 Mon Sep 17 00:00:00 2001 From: mxyhi Date: Thu, 30 Oct 2025 13:08:26 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20fix(order):=20=E5=BC=80?= =?UTF-8?q?=E4=BB=93=E5=89=8D=E5=85=88=E6=92=A4=E9=94=80=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=8C=82=E5=8D=95=20-=20=E5=85=88=E5=9C=A8=E5=BC=80=E4=BB=93?= =?UTF-8?q?=E5=89=8D=E5=8F=96=E6=B6=88=E6=89=80=E6=9C=89=E6=8C=82=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E9=98=B2=E6=AD=A2=E6=AE=8B=E7=95=99=E6=8C=82=E5=8D=95?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E4=BB=93=E4=BD=8D=E5=8F=A0=E5=8A=A0=20-=20?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=8C=82=E5=8D=95=E5=A4=B1=E8=B4=A5=E6=97=B6?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=AD=A6=E5=91=8A=EF=BC=8C=E4=BD=86=E4=BB=8D?= =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E5=BC=80=E4=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- trader/aster_trader.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/trader/aster_trader.go b/trader/aster_trader.go index e3a96aed..b821be61 100644 --- a/trader/aster_trader.go +++ b/trader/aster_trader.go @@ -522,6 +522,11 @@ func (t *AsterTrader) GetPositions() ([]map[string]interface{}, error) { // OpenLong 开多单 func (t *AsterTrader) OpenLong(symbol string, quantity float64, leverage int) (map[string]interface{}, error) { + // 开仓前先取消所有挂单,防止残留挂单导致仓位叠加 + if err := t.CancelAllOrders(symbol); err != nil { + log.Printf(" ⚠ 取消挂单失败(继续开仓): %v", err) + } + // 先设置杠杆 if err := t.SetLeverage(symbol, leverage); err != nil { return nil, fmt.Errorf("设置杠杆失败: %w", err) @@ -584,6 +589,11 @@ func (t *AsterTrader) OpenLong(symbol string, quantity float64, leverage int) (m // OpenShort 开空单 func (t *AsterTrader) OpenShort(symbol string, quantity float64, leverage int) (map[string]interface{}, error) { + // 开仓前先取消所有挂单,防止残留挂单导致仓位叠加 + if err := t.CancelAllOrders(symbol); err != nil { + log.Printf(" ⚠ 取消挂单失败(继续开仓): %v", err) + } + // 先设置杠杆 if err := t.SetLeverage(symbol, leverage); err != nil { return nil, fmt.Errorf("设置杠杆失败: %w", err)