From ca92638554e74fe782f6dbd1cd86277e6f903648 Mon Sep 17 00:00:00 2001 From: hucan <951870319@qq.com> Date: Mon, 3 Mar 2025 17:35:41 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E7=B4=AF=E8=AE=A1=E4=BA=8F=E6=8D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/binanceservice/commonservice.go | 18 ++++++++---- .../binanceservice/futuresjudgeservice.go | 7 ----- services/binanceservice/futuresrest.go | 18 +++++++++--- services/binanceservice/spotreset.go | 29 ++++++++++++++----- .../positionservice/position_management.go | 21 ++++++++++---- 5 files changed, 65 insertions(+), 28 deletions(-) diff --git a/services/binanceservice/commonservice.go b/services/binanceservice/commonservice.go index d554c8c..091f1c6 100644 --- a/services/binanceservice/commonservice.go +++ b/services/binanceservice/commonservice.go @@ -422,8 +422,8 @@ func savePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) positiondto.Posi SymbolType: preOrder.SymbolType, Symbol: preOrder.Symbol, Price: utility.StrToDecimal(preOrder.Price), - Side: preOrder.Site, - Quantity: utility.StrToDecimal(preOrder.Num), + // Side: preOrder.Site, + Quantity: utility.StrToDecimal(preOrder.Num), } switch { @@ -436,8 +436,16 @@ func savePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) positiondto.Posi } //减仓单 数量为负 - if preOrder.OrderType == 4 { + if preOrder.OrderType != 0 { + if preOrder.Site == "BUY" { + positionReq.Side = "SELL" + } else { + positionReq.Side = "BUY" + } + positionReq.Quantity = positionReq.Quantity.Mul(decimal.NewFromInt(-1)) + } else { + positionReq.Side = preOrder.Site } positionData, err := positionManage.SavePosition(&positionReq, global.EXCHANGE_BINANCE) @@ -453,9 +461,9 @@ func getOpenPositionMainOrderId(db *gorm.DB, newId, apiId, symbolType int, excha mainOrders := make([]DbModels.LinePreOrder, 0) if err := db.Model(&DbModels.LinePreOrder{}). - Where("api_id =? AND status>4 AND status<7 AND symbol=? AND symbol_type =? AND side= ? AND exchange_type=? AND id!=?", + Where("api_id =? AND status>4 AND status<7 AND symbol=? AND symbol_type =? AND site= ? AND exchange_type=? AND id!=?", apiId, symbol, symbolType, side, exchangeType, newId). - Select("id", "order_sn").Find(&mainOrders).Error; err != nil { + Select("id", "main_id", "order_sn").Find(&mainOrders).Error; err != nil { return nil, err } diff --git a/services/binanceservice/futuresjudgeservice.go b/services/binanceservice/futuresjudgeservice.go index 2966fc7..1c098ce 100644 --- a/services/binanceservice/futuresjudgeservice.go +++ b/services/binanceservice/futuresjudgeservice.go @@ -87,13 +87,6 @@ func futTriggerOrder(db *gorm.DB, v *dto.PreOrderRedisList, item string, futApi return } - //判断是否有已触发交易对 - count, _ := GetSymbolTriggerCount(db, v.Symbol, v.ApiId, 2) - - if count > 0 { - return - } - price, _ := decimal.NewFromString(v.Price) num, _ := decimal.NewFromString(preOrder.Num) diff --git a/services/binanceservice/futuresrest.go b/services/binanceservice/futuresrest.go index 719dc7e..5e7d289 100644 --- a/services/binanceservice/futuresrest.go +++ b/services/binanceservice/futuresrest.go @@ -160,7 +160,7 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { if v.OrderType == 1 { //亏损大于0 重新计算比例 if positionData.TotalLoss.Cmp(decimal.Zero) > 0 && orderExt.Id > 0 { - percentag := positionData.TotalLoss.Div(totalNum).Div(price) + percentag := positionData.TotalLoss.Div(totalNum).Div(price).Mul(decimal.NewFromInt(100)) percentag = percentag.Add(orderExt.TakeProfitRatio).Truncate(2) v.Rate = percentag.String() percentag = percentag.Div(decimal.NewFromInt(100)) @@ -434,6 +434,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) { // 获取和保存持仓数据 positionData := savePosition(db, preOrder) orderExt := models.LinePreOrderExt{} + db.Model(&orderExt).Where("order_id =?", preOrder.Id).First(&orderExt) num := getFuturesPositionAvailableQuantity(db, apiInfo, preOrder, tradeSet).Truncate(int32(tradeSet.AmountDigit)) // 更新订单数量并处理止盈、止损、减仓 @@ -449,7 +450,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) { case 1: // 止盈 //亏损大于0 重新计算比例 if positionData.TotalLoss.Cmp(decimal.Zero) > 0 && orderExt.Id > 0 { - percentag := positionData.TotalLoss.Div(num).Div(price) + percentag := positionData.TotalLoss.Div(num).Div(price).Mul(decimal.NewFromInt(100)) percentag = percentag.Add(orderExt.TakeProfitRatio).Truncate(2) order.Rate = percentag.String() percentag = percentag.Div(decimal.NewFromInt(100)) @@ -492,8 +493,13 @@ func cancelPositionOtherOrders(apiUserInfo DbModels.LineApiUser, db *gorm.DB, pr mainIds := []int{} for _, mainOrder := range mainOrders { - removeFutLossAndAddPosition(mainOrder.Id, mainOrder.OrderSn) - mainIds = append(mainIds, mainOrder.Id) + mainId := mainOrder.Id + + if mainOrder.MainId > 0 { + mainId = mainOrder.MainId + } + removeFutLossAndAddPosition(mainId, mainOrder.OrderSn) + mainIds = append(mainIds, mainId) } if len(mainIds) > 0 { @@ -512,6 +518,10 @@ func cancelPositionOtherOrders(apiUserInfo DbModels.LineApiUser, db *gorm.DB, pr logger.Errorf("批量取消订单失败 orderSns:%v", item) } } + + if err := db.Exec("UPDATE line_pre_order SET `status`=4, `desc`=CONCAT(`desc`, ' 新单触发取消') WHERE id IN ? AND `status` =6", mainIds).Error; err != nil { + logger.Errorf("合约 新下单成功后更新主单取消状态失败, 新主单号:%s, 错误信息:%v", preOrder.MainId, err) + } } return nil } diff --git a/services/binanceservice/spotreset.go b/services/binanceservice/spotreset.go index f2c2a38..dfbc5e5 100644 --- a/services/binanceservice/spotreset.go +++ b/services/binanceservice/spotreset.go @@ -211,7 +211,7 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { if orders[index].OrderType == 1 { //亏损大于0 重新计算比例 if positionData.TotalLoss.Cmp(decimal.Zero) > 0 && orderExt.Id > 0 { - percentag := positionData.TotalLoss.Div(totalNum).Div(price) + percentag := positionData.TotalLoss.Div(totalNum).Div(price).Mul(decimal.NewFromInt(100)) percentag = percentag.Add(orderExt.TakeProfitRatio).Truncate(2) orders[index].Rate = percentag.String() percentag = percentag.Div(decimal.NewFromInt(100)) @@ -429,11 +429,11 @@ func handleSpotTakeProfitFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { return err } - if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND status=0").Update("status", 4).Error; err != nil { - logger.Errorf("止盈订单回调失败, 回调订单号:%s 更新取消状态失败:%v", preOrder.OrderSn, err) + // if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND status=0",).Update("status", 4).Error; err != nil { + // logger.Errorf("止盈订单回调失败, 回调订单号:%s 更新取消状态失败:%v", preOrder.OrderSn, err) - return err - } + // return err + // } return nil }) @@ -522,8 +522,19 @@ func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { mainOrders, _ := getOpenPositionMainOrderId(db, preOrder.Id, preOrder.ApiId, preOrder.SymbolType, preOrder.ExchangeType, preOrder.Symbol, preOrder.Site) if len(mainOrders) > 0 { + mainIds := []int{} for _, mainOrder := range mainOrders { - removeSpotLossAndAddPosition(mainOrder.Id, mainOrder.OrderSn) + mainId := mainOrder.Id + + if mainOrder.MainId > 0 { + mainId = mainOrder.MainId + } + + removeSpotLossAndAddPosition(mainId, mainOrder.OrderSn) + + if !utility.ContainsInt(mainIds, mainId) { + mainIds = append(mainIds, mainId) + } } spotApi := SpotRestApi{} @@ -531,6 +542,10 @@ func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { if err != nil { logger.Errorf("取消未成交订单失败, 交易对:%s 主单号:%s, 错误信息:%v", preOrder.Symbol, preOrder.MainId, err) + } else if len(mainIds) > 0 { + if err := db.Exec("UPDATE line_pre_order SET status=4,desc=desc +' 新单触发取消' WHERE id IN ? AND status =6", mainIds).Error; err != nil { + logger.Errorf("新下单成功后更新主单取消状态失败, 新主单号:%s, 错误信息:%v", preOrder.MainId, err) + } } } } @@ -658,7 +673,7 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd case 1: // 止盈 //亏损大于0 重新计算比例 if positionData.TotalLoss.Cmp(decimal.Zero) > 0 && orderExt.Id > 0 { - percentag := positionData.TotalLoss.Div(num).Div(price) + percentag := positionData.TotalLoss.Div(num).Div(price).Mul(decimal.NewFromInt(100)) percentag = percentag.Add(orderExt.TakeProfitRatio).Truncate(2) order.Rate = percentag.String() percentag = percentag.Div(decimal.NewFromInt(100)) diff --git a/services/positionservice/position_management.go b/services/positionservice/position_management.go index dd74aa4..78221c3 100644 --- a/services/positionservice/position_management.go +++ b/services/positionservice/position_management.go @@ -56,20 +56,31 @@ func (e *BinancePositionManagement) SavePosition(data *positiondto.PositionAddRe } var totalLoss decimal.Decimal - if result.LastPrice.Cmp(decimal.Zero) > 0 { switch { //多 买入 case data.PositionSide == "LONG": - totalLoss = result.LastPrice.Sub(data.Price).Abs().Mul(result.Quantity) + totalLoss = result.LastPrice.Sub(data.Price).Mul(result.Quantity) + if data.Price.Cmp(result.LastPrice) < 0 { + result.LastPrice = data.Price + } case data.PositionSide == "SHORT": - totalLoss = data.Price.Sub(result.LastPrice).Abs().Mul(result.Quantity) + totalLoss = data.Price.Sub(result.LastPrice).Mul(result.Quantity) + + if data.Price.Cmp(result.LastPrice) > 0 { + result.LastPrice = data.Price + } } + } else { + //默认没有金额的时候 + result.LastPrice = data.Price + } + + if totalLoss.Cmp(decimal.Zero) > 0 { + result.TotalLoss = result.TotalLoss.Add(totalLoss) } - result.LastPrice = data.Price - result.TotalLoss = result.TotalLoss.Add(totalLoss) result.Quantity = data.Quantity.Add(result.Quantity) dataVal, _ := sonic.MarshalString(result)