Files
exchange_go/services/binanceservice/reduce_order_strategy_service.go
hucan cdd3f951a2 1、减仓策略
2、减仓后减仓节点(60%)
2025-04-03 18:32:23 +08:00

135 lines
4.1 KiB
Go

package binanceservice
import (
"fmt"
"go-admin/app/admin/models"
"go-admin/app/admin/service/dto"
"go-admin/common/const/rediskey"
"go-admin/common/global"
"go-admin/common/helper"
models2 "go-admin/models"
"github.com/bytedance/sonic"
"github.com/go-admin-team/go-admin-core/logger"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)
// 缓存减仓节点和重新生成
// reduceOrder:原始减仓单
// reduceOrderStrategy:减仓策略
func CacheOrderStrategyAndReCreate(db *gorm.DB, reduceOrder ReduceListItem, symbolType int, tradeSet models2.TradeSet, setting models.LineSystemSetting) error {
reduceOrderStrategy := models.LineReduceStrategy{}
var key string
if symbolType == 1 {
key = fmt.Sprintf(rediskey.SpotOrderReduceStrategyList, global.EXCHANGE_BINANCE)
} else {
key = fmt.Sprintf(rediskey.FutOrderReduceStrategyList, global.EXCHANGE_BINANCE)
}
if err := db.Model(&reduceOrderStrategy).Where("order_id =?", reduceOrder.Id).Find(reduceOrderStrategy).Error; err != nil {
logger.Errorf("获取减仓策略失败,err:%v", err)
return err
}
if reduceOrderStrategy.Id > 0 {
strategyCache := dto.LineOrderReduceStrategyResp{
OrderId: reduceOrder.Id,
}
for _, item := range reduceOrderStrategy.Items {
var rate decimal.Decimal
var triggerRate decimal.Decimal
if reduceOrder.Side == "BUY" {
rate = (decimal.NewFromInt(100).Sub(item.LossPercent)).Div(decimal.NewFromInt(100))
if setting.ReduceEarlyTriggerPercent.Cmp(decimal.Zero) > 0 {
triggerRate = rate.Add(setting.ReduceEarlyTriggerPercent.Div(decimal.NewFromInt(100)))
} else {
triggerRate = rate
}
} else {
rate = (decimal.NewFromInt(100).Add(item.LossPercent)).Div(decimal.NewFromInt(100))
if setting.ReduceEarlyTriggerPercent.Cmp(decimal.Zero) > 0 {
triggerRate = rate.Sub(setting.ReduceEarlyTriggerPercent.Div(decimal.NewFromInt(100)))
} else {
triggerRate = rate
}
}
price := reduceOrder.Price.Mul(rate).Truncate(int32(tradeSet.PriceDigit))
triggerPrice := reduceOrder.Price.Mul(triggerRate).Truncate(int32(tradeSet.PriceDigit))
strategyCache.Items = append(strategyCache.Items, dto.LineOrderReduceStrategyRespItem{
LossPercent: item.LossPercent,
OrderType: item.OrderType,
Price: price,
TriggerPrice: triggerPrice,
})
}
str, _ := sonic.MarshalString(reduceOrderStrategy)
if str != "" {
if err := helper.DefaultRedis.SetString(key, str); err != nil {
logger.Errorf("减仓单缓存减仓策略,err:%v", err)
}
}
}
return nil
}
// 根据订单id获取订单减仓策略
func GetReduceStrategyById(db *gorm.DB, orderId int) (models.LineOrderReduceStrategy, error) {
result := models.LineOrderReduceStrategy{}
if err := db.Model(result).Where("order_id =?", orderId).Select("id", "order_id").First(&result).Error; err != nil {
return result, err
}
return result, nil
}
// 减仓单成功回调
func ReduceCallBack(db *gorm.DB, preOrder *models.LinePreOrder) error {
reduceOrderId := preOrder.Id
var key string
if preOrder.ReduceOrderId > 0 {
reduceOrderId = preOrder.ReduceOrderId
}
switch preOrder.SymbolType {
case 1:
key = fmt.Sprintf(rediskey.SpotOrderReduceStrategyList, global.EXCHANGE_BINANCE)
case 2:
key = fmt.Sprintf(rediskey.FutOrderReduceStrategyList, global.EXCHANGE_BINANCE)
default:
return fmt.Errorf("交易对类型错误")
}
arrays, _ := helper.DefaultRedis.GetAllList(key)
cache := dto.LineOrderReduceStrategyResp{}
for _, v := range arrays {
sonic.Unmarshal([]byte(v), &cache)
if cache.OrderId == reduceOrderId {
if _, err := helper.DefaultRedis.LRem(key, v); err != nil {
logger.Errorf("移除减仓单减仓策略失败redis err:%v", err)
}
}
}
orderReduceStrategy, _ := GetReduceStrategyById(db, reduceOrderId)
if orderReduceStrategy.Id > 0 {
if err := db.Model(&orderReduceStrategy).Update("actived", 1).Error; err != nil {
logger.Errorf("更新减仓单减仓策略状态失败 order_id:%d err:%v", orderReduceStrategy.OrderId, err)
}
}
return nil
}