327 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bitgetservice
 | ||
| 
 | ||
| import (
 | ||
| 	DbModels "go-admin/app/admin/models"
 | ||
| 	"go-admin/models"
 | ||
| 	"go-admin/models/positiondto"
 | ||
| 
 | ||
| 	"gorm.io/gorm"
 | ||
| )
 | ||
| 
 | ||
| // JudgeCreateOrder 判断是否需要创建订单
 | ||
| // symbolType 1:现货 2:合约
 | ||
| func JudgeCreateOrder(trade models.TradeSet, symbolType int) error {
 | ||
| 	// var key string
 | ||
| 
 | ||
| 	// if symbolType == 1 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.PreSpotOrderList, global.EXCHANGE_BITGET)
 | ||
| 	// } else if symbolType == 2 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.PreFutOrderList, global.EXCHANGE_BITGET)
 | ||
| 	// } else {
 | ||
| 	// 	return fmt.Errorf("不支持的交易类型")
 | ||
| 	// }
 | ||
| 
 | ||
| 	// preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
 | ||
| 	// db := commonservice.GetDBConnection()
 | ||
| 
 | ||
| 	// if len(preOrderVal) == 0 {
 | ||
| 	// 	return fmt.Errorf("预订单列表为空")
 | ||
| 	// }
 | ||
| 
 | ||
| 	// // spotApi := SpotRestApi{}
 | ||
| 	// for _, item := range preOrderVal {
 | ||
| 	// 	preOrder := dto.PreOrderRedisList{}
 | ||
| 	// 	if err := sonic.Unmarshal([]byte(item), &preOrder); err != nil {
 | ||
| 	// 		logger.Error("反序列化失败")
 | ||
| 	// 		continue
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if preOrder.Symbol == trade.Coin+trade.Currency {
 | ||
| 	// 		orderPrice, _ := decimal.NewFromString(preOrder.Price)
 | ||
| 	// 		tradePrice, _ := decimal.NewFromString(trade.LastPrice)
 | ||
| 	// 		//买入
 | ||
| 	// 		if strings.ToUpper(preOrder.Site) == "BUY" && orderPrice.Cmp(tradePrice) >= 0 && orderPrice.Cmp(decimal.Zero) > 0 && tradePrice.Cmp(decimal.Zero) > 0 {
 | ||
| 	// 			// SpotOrderLock(db, &preOrder, item, spotApi)
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 	// }
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // 判断是否触发加仓
 | ||
| func JudgeAddPositionOrder(trade models.TradeSet, symbolType int) error {
 | ||
| 	// var key string
 | ||
| 
 | ||
| 	// if symbolType == 1 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BITGET)
 | ||
| 	// } else if symbolType == 2 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BITGET)
 | ||
| 	// } else {
 | ||
| 	// 	return fmt.Errorf("不支持的交易类型")
 | ||
| 	// }
 | ||
| 	// preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
 | ||
| 	// db := commonservice.GetDBConnection()
 | ||
| 
 | ||
| 	// if len(preOrderVal) == 0 {
 | ||
| 	// 	return fmt.Errorf("预订单列表为空")
 | ||
| 	// }
 | ||
| 
 | ||
| 	// // spotApi := SpotRestApi{}
 | ||
| 	// for _, item := range preOrderVal {
 | ||
| 	// 	preOrder := positiondto.AddPositionList{}
 | ||
| 	// 	if err := sonic.Unmarshal([]byte(item), &preOrder); err != nil {
 | ||
| 	// 		logger.Error("反序列化失败")
 | ||
| 	// 		continue
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if preOrder.Symbol == trade.Coin+trade.Currency {
 | ||
| 	// 		orderPrice := preOrder.Price
 | ||
| 	// 		tradePrice, _ := decimal.NewFromString(trade.LastPrice)
 | ||
| 	// 		//买入
 | ||
| 	// 		if strings.ToUpper(preOrder.Side) == "BUY" && orderPrice.Cmp(tradePrice) >= 0 && orderPrice.Cmp(decimal.Zero) > 0 && tradePrice.Cmp(decimal.Zero) > 0 {
 | ||
| 	// 			// SpotAddPositionTrigger(db, &preOrder, item, spotApi)
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 	// }
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // JudgeReduceOrder 判断是否需要减仓
 | ||
| func JudgeReduceOrder(trade models.TradeSet, symbolType int) error {
 | ||
| 	// var key string
 | ||
| 	// var reduceReduceListKey string
 | ||
| 
 | ||
| 	// if symbolType == 1 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BITGET)
 | ||
| 	// 	reduceReduceListKey = fmt.Sprintf(rediskey.SpotOrderReduceStrategyList, global.EXCHANGE_BITGET)
 | ||
| 	// } else if symbolType == 2 {
 | ||
| 	// 	key = fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BITGET)
 | ||
| 	// 	reduceReduceListKey = fmt.Sprintf(rediskey.FutOrderReduceStrategyList, global.EXCHANGE_BITGET)
 | ||
| 	// } else {
 | ||
| 	// 	return fmt.Errorf("不支持的交易类型")
 | ||
| 	// }
 | ||
| 
 | ||
| 	// db := commonservice.GetDBConnection()
 | ||
| 	// // spotApi := SpotRestApi{}
 | ||
| 	// setting, err := cacheservice.GetSystemSetting(db)
 | ||
| 
 | ||
| 	// if err != nil {
 | ||
| 	// 	logger.Error("获取系统设置失败")
 | ||
| 	// 	return errors.New("获取系统设置失败")
 | ||
| 	// }
 | ||
| 
 | ||
| 	// reduceOrder := positiondto.ReduceListItem{}
 | ||
| 	// tradePrice, _ := decimal.NewFromString(trade.LastPrice)
 | ||
| 	// //减仓单减仓策略
 | ||
| 	// orderReduceVal, _ := helper.DefaultRedis.HGetAllFields(reduceReduceListKey)
 | ||
| 	// reduceOrderStrategy := dto.LineOrderReduceStrategyResp{}
 | ||
| 	// orderService := orderservice.OrderService{}
 | ||
| 	// orderService.Orm = db
 | ||
| 
 | ||
| 	// for _, item := range orderReduceVal {
 | ||
| 	// 	sonic.Unmarshal([]byte(item), &reduceOrderStrategy)
 | ||
| 
 | ||
| 	// 	for index, item2 := range reduceOrderStrategy.Items {
 | ||
| 	// 		if reduceOrderStrategy.Symbol == trade.Coin+trade.Currency {
 | ||
| 	// 			//买入
 | ||
| 	// 			if strings.ToUpper(reduceOrderStrategy.Side) == "SELL" &&
 | ||
| 	// 				item2.TriggerPrice.Cmp(tradePrice) >= 0 &&
 | ||
| 	// 				item2.TriggerPrice.Cmp(decimal.Zero) > 0 &&
 | ||
| 	// 				tradePrice.Cmp(decimal.Zero) > 0 {
 | ||
| 	// 				lock := helper.NewRedisLock(fmt.Sprintf(rediskey.ReduceStrategySpotTriggerLock, reduceOrder.ApiId, reduceOrder.Symbol), 50, 15, 100*time.Millisecond)
 | ||
| 
 | ||
| 	// 				if ok, err := lock.AcquireWait(context.Background()); err != nil {
 | ||
| 	// 					logger.Error("获取锁失败", err)
 | ||
| 	// 					return errors.New("获取锁失败")
 | ||
| 	// 				} else if ok {
 | ||
| 	// 					defer lock.Release()
 | ||
| 	// 					hasrecord, _ := helper.DefaultRedis.HExists(reduceReduceListKey, utility.IntTostring(reduceOrderStrategy.OrderId), item)
 | ||
| 
 | ||
| 	// 					if !hasrecord {
 | ||
| 	// 						logger.Debug("减仓缓存中不存在", item)
 | ||
| 	// 						return fmt.Errorf("减仓缓存中不存在")
 | ||
| 	// 					}
 | ||
| 
 | ||
| 	// 					order, err := orderService.CreateReduceReduceOrder(db, reduceOrderStrategy.OrderId, item2.Price, item2.Num, trade.PriceDigit)
 | ||
| 
 | ||
| 	// 					if err != nil {
 | ||
| 	// 						logger.Errorf("%d 生成订单失败", reduceOrderStrategy.OrderId)
 | ||
| 	// 					}
 | ||
| 
 | ||
| 	// 					reduceOrder.ApiId = order.ApiId
 | ||
| 	// 					reduceOrder.Id = order.Id
 | ||
| 	// 					reduceOrder.Pid = order.Pid
 | ||
| 	// 					reduceOrder.MainId = order.MainId
 | ||
| 	// 					reduceOrder.Symbol = order.Symbol
 | ||
| 	// 					reduceOrder.Side = reduceOrderStrategy.Side
 | ||
| 	// 					reduceOrder.OrderSn = order.OrderSn
 | ||
| 	// 					reduceOrder.Price = item2.Price
 | ||
| 	// 					reduceOrder.Num = item2.Num
 | ||
| 	// 					if SpotReduceTrigger(db, reduceOrder, spotApi, setting, reduceReduceListKey, item, true, reduceOrderStrategy.OrderId) {
 | ||
| 	// 						reduceOrderStrategy.Items[index].Actived = true
 | ||
| 	// 						allActive := true
 | ||
| 	// 						orderId := utility.IntToString(reduceOrderStrategy.OrderId)
 | ||
| 
 | ||
| 	// 						for _, item3 := range reduceOrderStrategy.Items {
 | ||
| 	// 							if !item3.Actived {
 | ||
| 	// 								allActive = false
 | ||
| 	// 								break
 | ||
| 	// 							}
 | ||
| 	// 						}
 | ||
| 
 | ||
| 	// 						if allActive {
 | ||
| 	// 							if err := helper.DefaultRedis.HDelField(reduceReduceListKey, orderId); err != nil {
 | ||
| 	// 								logger.Errorf("删除redis reduceReduceListKey失败 %s", err.Error())
 | ||
| 	// 							}
 | ||
| 	// 						} else {
 | ||
| 	// 							str, _ := sonic.MarshalString(reduceOrderStrategy)
 | ||
| 	// 							if err := helper.DefaultRedis.HSetField(reduceReduceListKey, orderId, str); err != nil {
 | ||
| 	// 								logger.Errorf("更新redis reduceReduceListKey失败 %s", err.Error())
 | ||
| 	// 							}
 | ||
| 	// 						}
 | ||
| 	// 					}
 | ||
| 	// 				}
 | ||
| 	// 			}
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 	// }
 | ||
| 
 | ||
| 	// //减仓单
 | ||
| 	// reduceVal, _ := helper.DefaultRedis.GetAllList(key)
 | ||
| 
 | ||
| 	// for _, item := range reduceVal {
 | ||
| 	// 	if err := sonic.Unmarshal([]byte(item), &reduceOrder); err != nil {
 | ||
| 	// 		logger.Error("反序列化失败")
 | ||
| 	// 		continue
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if reduceOrder.Symbol == trade.Coin+trade.Currency {
 | ||
| 	// 		orderPrice := reduceOrder.Price
 | ||
| 	// 		//买入
 | ||
| 	// 		if strings.ToUpper(reduceOrder.Side) == "SELL" &&
 | ||
| 	// 			orderPrice.Cmp(tradePrice) >= 0 &&
 | ||
| 	// 			orderPrice.Cmp(decimal.Zero) > 0 &&
 | ||
| 	// 			tradePrice.Cmp(decimal.Zero) > 0 {
 | ||
| 
 | ||
| 	// 			// SpotReduceTrigger(db, reduceOrder, spotApi, setting, key, item, false, 0)
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 	// }
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // 触发现货减仓
 | ||
| // isStrategy 是否是策略减仓单
 | ||
| // reduceId 策略主减仓单id
 | ||
| func SpotReduceTrigger(db *gorm.DB, reduceOrder positiondto.ReduceListItem, setting DbModels.LineSystemSetting, key, item string, isStrategy bool, reduceId int) bool {
 | ||
| 	// tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, reduceOrder.Symbol, 1)
 | ||
| 	result := true
 | ||
| 
 | ||
| 	// if err != nil {
 | ||
| 	// 	logger.Error("获取交易设置失败")
 | ||
| 	// 	return false
 | ||
| 	// }
 | ||
| 	// lock := helper.NewRedisLock(fmt.Sprintf(rediskey.SpotTrigger, reduceOrder.ApiId, reduceOrder.Symbol), 20, 5, 100*time.Millisecond)
 | ||
| 
 | ||
| 	// if ok, err := lock.AcquireWait(context.Background()); err != nil {
 | ||
| 	// 	logger.Error("获取锁失败", err)
 | ||
| 	// 	return false
 | ||
| 	// } else if ok {
 | ||
| 	// 	defer lock.Release()
 | ||
| 	// 	takeOrders := make([]DbModels.LinePreOrder, 0)
 | ||
| 	// 	if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND order_type IN (1,2,4) AND status IN (1,5)", reduceOrder.MainId).Find(&takeOrders).Error; err != nil {
 | ||
| 	// 		logger.Error("查询止盈单失败")
 | ||
| 	// 		return false
 | ||
| 	// 	}
 | ||
| 	// 	var hasrecord bool
 | ||
| 
 | ||
| 	// 	if isStrategy {
 | ||
| 	// 		hasrecord, _ = helper.DefaultRedis.HExists(key, utility.IntToString(reduceId), item)
 | ||
| 	// 	} else {
 | ||
| 	// 		hasrecord, _ = helper.DefaultRedis.IsElementInList(key, item)
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if !hasrecord {
 | ||
| 	// 		logger.Debug("减仓缓存中不存在", item)
 | ||
| 	// 		return false
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	apiInfo, _ := GetApiInfo(reduceOrder.ApiId)
 | ||
| 
 | ||
| 	// 	if apiInfo.Id == 0 {
 | ||
| 	// 		logger.Error("现货减仓 查询api用户不存在")
 | ||
| 	// 		return false
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	for _, takeOrder := range takeOrders {
 | ||
| 	// 		err := CancelOpenOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
 | ||
| 
 | ||
| 	// 		if err != nil {
 | ||
| 	// 			logger.Error("现货撤单失败", err)
 | ||
| 	// 			return false
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 	// 	price := reduceOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.ReducePremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
 | ||
| 
 | ||
| 	// 	params := OrderPlacementService{
 | ||
| 	// 		ApiId:            reduceOrder.ApiId,
 | ||
| 	// 		Side:             reduceOrder.Side,
 | ||
| 	// 		Type:             "LIMIT",
 | ||
| 	// 		TimeInForce:      "GTC",
 | ||
| 	// 		Symbol:           reduceOrder.Symbol,
 | ||
| 	// 		Price:            price,
 | ||
| 	// 		Quantity:         reduceOrder.Num,
 | ||
| 	// 		NewClientOrderId: reduceOrder.OrderSn,
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if err := spotApi.OrderPlaceLoop(db, params, 3); err != nil {
 | ||
| 	// 		result = false
 | ||
| 	// 		logger.Errorf("现货减仓挂单失败 id:%s err:%v", reduceOrder.Id, err)
 | ||
| 
 | ||
| 	// 		if err2 := db.Model(&DbModels.LinePreOrder{}).
 | ||
| 	// 			Where("id =? AND status =0", reduceOrder.Id).
 | ||
| 	// 			Updates(map[string]interface{}{"status": 2, "desc": err.Error()}).Error; err2 != nil {
 | ||
| 	// 			logger.Errorf("修改现货减仓状态失败 id:%s err:%v", reduceOrder.Id, err2)
 | ||
| 	// 		}
 | ||
| 	// 	} else {
 | ||
| 	// 		if err := db.Model(&DbModels.LinePreOrder{}).Where("id =?", reduceOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil {
 | ||
| 	// 			logger.Error("更新预下单触发事件失败 ordersn:", reduceOrder.OrderSn)
 | ||
| 	// 		}
 | ||
| 
 | ||
| 	// 		if err := db.Model(&DbModels.LinePreOrder{}).
 | ||
| 	// 			Where("id =? AND status =0", reduceOrder.Id).
 | ||
| 	// 			Updates(map[string]interface{}{"status": 1}).Error; err != nil {
 | ||
| 	// 			logger.Errorf("修改现货减仓状态失败 id:%s err:%v", reduceOrder.Id, err)
 | ||
| 	// 		}
 | ||
| 
 | ||
| 	// 		//处理减仓单减仓策略
 | ||
| 	// 		if err := CacheOrderStrategyAndReCreate(db, reduceOrder, 1, tradeSet, setting); err != nil {
 | ||
| 	// 			logger.Errorf("现货减仓 处理减仓策略失败 id:%v err:%v", reduceOrder.Id, err)
 | ||
| 	// 		}
 | ||
| 	// 	}
 | ||
| 
 | ||
| 	// 	if _, err := helper.DefaultRedis.LRem(key, item); err != nil {
 | ||
| 	// 		result = false
 | ||
| 	// 		logger.Errorf("现货减仓 删除缓存失败 id:%v err:%v", reduceOrder.Id, err)
 | ||
| 	// 	}
 | ||
| 	// } else {
 | ||
| 	// 	logger.Error("获取锁失败")
 | ||
| 	// 	result = false
 | ||
| 	// }
 | ||
| 
 | ||
| 	return result
 | ||
| }
 | ||
| 
 | ||
| // JudgeTakeOrder 判断是否止盈
 | ||
| func JudgeTakeOrder(trades []models.TradeSet, symbolType int) error {
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // JudgeStopOrder 判断是否止损
 | ||
| func JudgeStopOrder(trades []models.TradeSet, symbolType int) error {
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 |