diff --git a/services/binanceservice/futuresrest.go b/services/binanceservice/futuresrest.go index cec7f4e..81cdd8e 100644 --- a/services/binanceservice/futuresrest.go +++ b/services/binanceservice/futuresrest.go @@ -145,6 +145,8 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { } // rate := utility.StringAsFloat(orderExt.AddPositionVal) + //取消委托中的止盈止损 + cancelTakeProfitByReduce(db, apiUserInfo, preOrder.Symbol, preOrder.MainId, preOrder.SymbolType) // 100%减仓 终止流程 if orderExt.AddPositionVal.Cmp(decimal.NewFromInt(100)) >= 0 { //缓存 @@ -158,8 +160,6 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { return } - //取消委托中的止盈止损 - cancelTakeProfitByReduce(db, apiUserInfo, preOrder.Symbol, preOrder.MainId, preOrder.SymbolType) lock := helper.NewRedisLock(fmt.Sprintf(rediskey.FutReducecCallback, preOrder.ApiId, preOrder.Symbol), 120, 20, 100*time.Millisecond) if ok, err := lock.AcquireWait(context.Background()); err != nil { diff --git a/services/binanceservice/strategy_order_service.go b/services/binanceservice/strategy_order_service.go index 4593a05..158b683 100644 --- a/services/binanceservice/strategy_order_service.go +++ b/services/binanceservice/strategy_order_service.go @@ -165,7 +165,7 @@ func (e *BinanceStrategyOrderService) TriggerOrder(order dto.StrategyOrderRedisL return errors.New("最新成交价小于等于0") } - var mainOrder models.LinePreOrder + mainOrder := models.LinePreOrder{} for _, v := range orders { if v.MainId == 0 { @@ -176,6 +176,12 @@ func (e *BinanceStrategyOrderService) TriggerOrder(order dto.StrategyOrderRedisL GetOrderByPid(&mainOrder, orders, mainOrder.Id) + e.RecalculateOrder(tradeSet, &mainOrder, setting) + + if err := e.Orm.Save(&mainOrder).Error; err != nil { + e.Log.Errorf("order_id:%d 波段触发保存委托单失败:%s", mainOrder.Id, err.Error()) + } + return nil } @@ -265,19 +271,93 @@ func (e *BinanceStrategyOrderService) RecalculateOrder(tradeSet models2.TradeSet //加库存 lastNum = lastNum.Add(utility.StrToDecimal(mainOrder.Child[index].Num)) - //todo 计算子订单 + // 计算子订单 + if len(mainOrder.Child[index].Child) > 0 { + calculateChildOrder(&mainOrder.Child, &tradeSet, ext, lastNum, dataPrice, false) + } //减仓单 case mainOrder.Child[index].OrderType == 4: - // todo 计算 + percentage := decimal.NewFromInt(1) + + if mainOrder.Site == "BUY" && ext.PriceRatio.Cmp(decimal.Zero) > 0 { + percentage = decimal.NewFromInt(1).Sub(ext.PriceRatio.Div(decimal.NewFromInt(100))) + } else if ext.PriceRatio.Cmp(decimal.Zero) > 0 { + percentage = decimal.NewFromInt(1).Add(ext.PriceRatio.Div(decimal.NewFromInt(100))) + } + + dataPrice := utility.StrToDecimal(mainOrder.Price).Mul(percentage).Truncate(int32(tradeSet.PriceDigit)) + mainOrder.Child[index].Price = dataPrice.String() + + //百分比减仓 + if ext.AddPositionType == 1 { + mainOrder.Child[index].Num = lastNum.Mul(ext.AddPositionVal.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String() + + } else { + logger.Error("减仓不能是固定数值") + } + //减库存 - lastNum = lastNum.Add(utility.StrToDecimal(mainOrder.Child[index].Num)) - //todo 计算子订单 + lastNum = lastNum.Sub(utility.StrToDecimal(mainOrder.Child[index].Num)) + // 计算子订单 + if len(mainOrder.Child[index].Child) > 0 { + calculateChildOrder(&mainOrder.Child, &tradeSet, ext, lastNum, dataPrice, false) + } } } } return nil } +// 计算子订单信息 +// isTpTp 是否是止盈后止损止盈 +func calculateChildOrder(orders *[]models.LinePreOrder, tradeSet *models2.TradeSet, ext models.LinePreOrderExt, lastNum decimal.Decimal, price decimal.Decimal, isTpTp bool) error { + for index := range *orders { + orderQuantity := lastNum.Truncate(int32(tradeSet.AmountDigit)) + percentage := decimal.NewFromInt(1) + var addPercentage decimal.Decimal + + switch { + //止盈 + case !isTpTp && (*orders)[index].OrderType == 1: + addPercentage = ext.TakeProfitRatio + if ext.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 { + orderQuantity = lastNum.Mul(ext.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)) + } + //止损 + case !isTpTp && (*orders)[index].OrderType == 2: + addPercentage = ext.StopLossRatio + //止盈后止盈 + case isTpTp && (*orders)[index].OrderType == 1: + addPercentage = ext.TpTpPriceRatio + //止盈后止损 + case isTpTp && (*orders)[index].OrderType == 2: + addPercentage = ext.TpSlPriceRatio + } + + switch { + //做多止盈、做空止损 + case (*orders)[index].OrderType == 1 && (*orders)[index].Site == "SELL", (*orders)[index].OrderType == 2 && (*orders)[index].Site == "BUY": + percentage = decimal.NewFromInt(100).Add(addPercentage).Div(decimal.NewFromInt(100)) + + //做多止损、做空止盈 + case (*orders)[index].OrderType == 2 && (*orders)[index].Site == "SELL", (*orders)[index].OrderType == 1 && (*orders)[index].Site == "BUY": + percentage = decimal.NewFromInt(100).Sub(addPercentage).Div(decimal.NewFromInt(100)) + } + + orderPrice := price.Mul(percentage).Truncate(int32(tradeSet.PriceDigit)) + (*orders)[index].Price = orderPrice.String() + (*orders)[index].Num = orderQuantity.String() + lastOrderQuantity := lastNum.Sub(orderQuantity).Truncate(int32(tradeSet.AmountDigit)) + + //止盈后止盈、止盈后止损 + if len((*orders)[index].Child) > 0 && lastOrderQuantity.Cmp(decimal.Zero) > 0 { + calculateChildOrder(&(*orders)[index].Child, tradeSet, ext, lastOrderQuantity, orderPrice, true) + } + } + + return nil +} + // 递归订单树 func GetOrderByPid(order *models.LinePreOrder, orders []models.LinePreOrder, pid int) { for _, v := range orders {