1
This commit is contained in:
@ -443,6 +443,13 @@ func (e FutRestApi) OrderPlace(orm *gorm.DB, params FutOrderPlace) error {
|
|||||||
paramsMaps["workingType"] = "MARK_PRICE"
|
paramsMaps["workingType"] = "MARK_PRICE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.ToUpper(params.OrderType) == "TAKE_PROFIT" {
|
||||||
|
paramsMaps["timeInForce"] = "GTC"
|
||||||
|
paramsMaps["price"] = params.Price.String()
|
||||||
|
paramsMaps["stopprice"] = params.Profit.String()
|
||||||
|
paramsMaps["workingType"] = "MARK_PRICE"
|
||||||
|
}
|
||||||
|
|
||||||
if strings.ToUpper(params.OrderType) == "STOP_MARKET" {
|
if strings.ToUpper(params.OrderType) == "STOP_MARKET" {
|
||||||
paramsMaps["stopprice"] = params.StopPrice.String()
|
paramsMaps["stopprice"] = params.StopPrice.String()
|
||||||
paramsMaps["workingType"] = "MARK_PRICE"
|
paramsMaps["workingType"] = "MARK_PRICE"
|
||||||
|
|||||||
@ -153,7 +153,7 @@ func JudgeFuturesReduce(trade models.TradeSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
db := GetDBConnection()
|
db := GetDBConnection()
|
||||||
spotApi := SpotRestApi{}
|
futApi := FutRestApi{}
|
||||||
setting, err := GetSystemSetting(db)
|
setting, err := GetSystemSetting(db)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -161,13 +161,6 @@ func JudgeFuturesReduce(trade models.TradeSet) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tradeSet, err := GetTradeSet(trade.Coin+trade.Currency, 0)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error("获取交易设置失败")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range reduceVal {
|
for _, item := range reduceVal {
|
||||||
reduceOrder := ReduceListItem{}
|
reduceOrder := ReduceListItem{}
|
||||||
if err := sonic.Unmarshal([]byte(item), &reduceOrder); err != nil {
|
if err := sonic.Unmarshal([]byte(item), &reduceOrder); err != nil {
|
||||||
@ -184,14 +177,20 @@ func JudgeFuturesReduce(trade models.TradeSet) {
|
|||||||
((strings.ToUpper(reduceOrder.Side) == "SELL" && orderPrice.Cmp(tradePrice) >= 0) ||
|
((strings.ToUpper(reduceOrder.Side) == "SELL" && orderPrice.Cmp(tradePrice) >= 0) ||
|
||||||
(strings.ToUpper(reduceOrder.Side) == "BUY" && orderPrice.Cmp(tradePrice) <= 0)) {
|
(strings.ToUpper(reduceOrder.Side) == "BUY" && orderPrice.Cmp(tradePrice) <= 0)) {
|
||||||
|
|
||||||
SpotReduceTrigger(db, reduceOrder, spotApi, setting, tradeSet, key, item)
|
FuturesReduceTrigger(db, reduceOrder, futApi, setting, key, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发合约减仓
|
// 触发合约减仓
|
||||||
func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRestApi, setting DbModels.LineSystemSetting, tradeSet models.TradeSet, key, item string) {
|
func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRestApi, setting DbModels.LineSystemSetting, key, item string) {
|
||||||
|
tradeSet, _ := GetTradeSet(reduceOrder.Symbol, 1)
|
||||||
|
|
||||||
|
if tradeSet.LastPrice == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.FutTrigger, reduceOrder.ApiId, reduceOrder.Symbol), 20, 5, 100*time.Millisecond)
|
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.FutTrigger, reduceOrder.ApiId, reduceOrder.Symbol), 20, 5, 100*time.Millisecond)
|
||||||
|
|
||||||
if ok, err := lock.AcquireWait(context.Background()); err != nil {
|
if ok, err := lock.AcquireWait(context.Background()); err != nil {
|
||||||
@ -205,6 +204,13 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasrecord, _ := helper.DefaultRedis.IsElementInList(key, item)
|
||||||
|
|
||||||
|
if !hasrecord {
|
||||||
|
log.Debug("减仓缓存中不存在", item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
||||||
|
|
||||||
if apiInfo.Id == 0 {
|
if apiInfo.Id == 0 {
|
||||||
@ -216,7 +222,8 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
|||||||
for x := 1; x <= 4; x++ {
|
for x := 1; x <= 4; x++ {
|
||||||
err = futApi.CancelFutOrder(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
err = futApi.CancelFutOrder(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil || strings.Contains(err.Error(), "取消订单被拒绝") {
|
||||||
|
err = nil
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ func ChangeFutureOrder(mapData map[string]interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if originOrderSn != "" {
|
if originOrderSn != nil && originOrderSn != "" {
|
||||||
orderSn = originOrderSn
|
orderSn = originOrderSn
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,6 +375,17 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tradeSet.Coin == "" {
|
||||||
|
logger.Errorf("获取交易对配置失败, 回调订单号:%s", preOrder.OrderSn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//预生成加仓单
|
||||||
|
shouldReturn := createFutPreAddPosition(preOrder, db, tradeSet)
|
||||||
|
if shouldReturn {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err := db.Model(&DbModels.LinePreOrder{}).
|
if err := db.Model(&DbModels.LinePreOrder{}).
|
||||||
Where("pid = ? AND order_type > 0 AND status = '0' ", preOrder.Id).
|
Where("pid = ? AND order_type > 0 AND status = '0' ", preOrder.Id).
|
||||||
Find(&orders).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
Find(&orders).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@ -413,6 +424,65 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成加仓单
|
||||||
|
func createFutPreAddPosition(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSet models2.TradeSet) bool {
|
||||||
|
//主单类型
|
||||||
|
if preOrder.OrderCategory == 1 {
|
||||||
|
orderExts, err := GetOrderExts(db, preOrder.Id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("预生成加仓单失败, 回调订单号:%s 获取主单拓展配置失败:%v", preOrder.OrderSn, err)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
price := utility.StrToDecimal(preOrder.Price)
|
||||||
|
for _, v := range orderExts {
|
||||||
|
if v.OrderId == 0 {
|
||||||
|
var data DbModels.LinePreOrder
|
||||||
|
|
||||||
|
copier.Copy(&data, &v)
|
||||||
|
|
||||||
|
data.Id = 0
|
||||||
|
data.Pid = preOrder.Id
|
||||||
|
data.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
|
||||||
|
data.MainId = preOrder.Id
|
||||||
|
data.CreatedAt = time.Now()
|
||||||
|
data.MainOrderType = v.AddPositionOrderType
|
||||||
|
data.Status = 0
|
||||||
|
data.OrderCategory = 3
|
||||||
|
var percentage decimal.Decimal
|
||||||
|
|
||||||
|
if data.Site == "BUY" {
|
||||||
|
percentage = decimal.NewFromInt(1).Add(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
|
||||||
|
} else {
|
||||||
|
percentage = decimal.NewFromInt(1).Sub(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
|
||||||
|
}
|
||||||
|
data.Price = price.Mul(percentage).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||||
|
|
||||||
|
err := db.Transaction(func(tx *gorm.DB) error {
|
||||||
|
if err2 := tx.Create(&data).Error; err2 != nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
v.OrderId = data.Id
|
||||||
|
if err2 := tx.Model(&v).Update("order_id", data.Id).Error; err2 != nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("预生成加仓单失败, 回调订单号:%s 预生成加仓单失败:%v", preOrder.OrderSn, err)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// 构建合约止盈、减仓单
|
// 构建合约止盈、减仓单
|
||||||
func makeFuturesTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSet models2.TradeSet, orders []DbModels.LinePreOrder) ([]DbModels.LinePreOrder, error) {
|
func makeFuturesTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSet models2.TradeSet, orders []DbModels.LinePreOrder) ([]DbModels.LinePreOrder, error) {
|
||||||
ext := models.LinePreOrderExt{}
|
ext := models.LinePreOrderExt{}
|
||||||
@ -475,6 +545,12 @@ func makeFuturesTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, trad
|
|||||||
stopOrder.Rate = ext.ReducePriceRatio.String()
|
stopOrder.Rate = ext.ReducePriceRatio.String()
|
||||||
stopOrder.Num = num.String()
|
stopOrder.Num = num.String()
|
||||||
|
|
||||||
|
if ext.ReduceNumRatio.Cmp(decimal.Zero) > 0 {
|
||||||
|
stopOrder.Num = num.Mul(ext.ReduceNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||||
|
} else {
|
||||||
|
stopOrder.Num = num.String()
|
||||||
|
}
|
||||||
|
|
||||||
orders = append(orders, stopOrder)
|
orders = append(orders, stopOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,7 +107,7 @@ func GetLastStop(db *gorm.DB, pid int) (DbModels.LinePreOrder, error) {
|
|||||||
// mainId 主单Id
|
// mainId 主单Id
|
||||||
func GetOrderExts(db *gorm.DB, mainId int) ([]models.LinePreOrderExt, error) {
|
func GetOrderExts(db *gorm.DB, mainId int) ([]models.LinePreOrderExt, error) {
|
||||||
result := make([]models.LinePreOrderExt, 0)
|
result := make([]models.LinePreOrderExt, 0)
|
||||||
if err := db.Model(&result).Where("main_id =?", mainId).Find(&result).Error; err != nil {
|
if err := db.Model(&result).Where("main_order_id =?", mainId).Find(&result).Error; err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -192,6 +192,13 @@ func SpotStopLossTrigger(db *gorm.DB, stopOrder dto.StopLossRedisList, spotApi S
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasrecord, _ := helper.DefaultRedis.IsElementInList(key, item)
|
||||||
|
|
||||||
|
if !hasrecord {
|
||||||
|
log.Debug("减仓缓存中不存在", item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
||||||
|
|
||||||
if apiInfo.Id == 0 {
|
if apiInfo.Id == 0 {
|
||||||
@ -259,13 +266,6 @@ func JudgeSpotReduce(trade models.TradeSet) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tradeSet, err := GetTradeSet(trade.Coin+trade.Currency, 0)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error("获取交易设置失败")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range reduceVal {
|
for _, item := range reduceVal {
|
||||||
reduceOrder := ReduceListItem{}
|
reduceOrder := ReduceListItem{}
|
||||||
if err := sonic.Unmarshal([]byte(item), &reduceOrder); err != nil {
|
if err := sonic.Unmarshal([]byte(item), &reduceOrder); err != nil {
|
||||||
@ -282,14 +282,20 @@ func JudgeSpotReduce(trade models.TradeSet) {
|
|||||||
orderPrice.Cmp(decimal.Zero) > 0 &&
|
orderPrice.Cmp(decimal.Zero) > 0 &&
|
||||||
tradePrice.Cmp(decimal.Zero) > 0 {
|
tradePrice.Cmp(decimal.Zero) > 0 {
|
||||||
|
|
||||||
SpotReduceTrigger(db, reduceOrder, spotApi, setting, tradeSet, key, item)
|
SpotReduceTrigger(db, reduceOrder, spotApi, setting, key, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发现货减仓
|
// 触发现货减仓
|
||||||
func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRestApi, setting DbModels.LineSystemSetting, tradeSet models.TradeSet, key, item string) {
|
func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRestApi, setting DbModels.LineSystemSetting, key, item string) {
|
||||||
|
tradeSet, err := GetTradeSet(reduceOrder.Symbol, 0)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("获取交易设置失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.SpotTrigger, reduceOrder.ApiId, reduceOrder.Symbol), 20, 5, 100*time.Millisecond)
|
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 {
|
if ok, err := lock.AcquireWait(context.Background()); err != nil {
|
||||||
@ -302,6 +308,12 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
|||||||
log.Error("查询止盈单失败")
|
log.Error("查询止盈单失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
hasrecord, _ := helper.DefaultRedis.IsElementInList(key, item)
|
||||||
|
|
||||||
|
if !hasrecord {
|
||||||
|
log.Debug("减仓缓存中不存在", item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
||||||
|
|
||||||
@ -325,7 +337,6 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
price := reduceOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.ReducePremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
|
price := reduceOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.ReducePremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
|
||||||
num := utility.StrToDecimal(takeOrder.Num).Truncate(int32(tradeSet.AmountDigit))
|
|
||||||
|
|
||||||
params := OrderPlacementService{
|
params := OrderPlacementService{
|
||||||
ApiId: reduceOrder.ApiId,
|
ApiId: reduceOrder.ApiId,
|
||||||
@ -334,7 +345,7 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
|||||||
TimeInForce: "GTC",
|
TimeInForce: "GTC",
|
||||||
Symbol: reduceOrder.Symbol,
|
Symbol: reduceOrder.Symbol,
|
||||||
Price: price,
|
Price: price,
|
||||||
Quantity: num,
|
Quantity: reduceOrder.Num,
|
||||||
NewClientOrderId: reduceOrder.OrderSn,
|
NewClientOrderId: reduceOrder.OrderSn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ func ChangeSpotOrder(mapData map[string]interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if originOrderSn != "" {
|
if originOrderSn != nil && originOrderSn != "" {
|
||||||
orderSn = originOrderSn
|
orderSn = originOrderSn
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
|||||||
takeProfitOrder.Id = 0
|
takeProfitOrder.Id = 0
|
||||||
takeProfitOrder.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
|
takeProfitOrder.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
|
||||||
takeProfitOrder.Status = 0
|
takeProfitOrder.Status = 0
|
||||||
takeProfitOrder.Price = price.Mul(decimal.NewFromInt(1).Add(ext.TakeProfitRatio)).Truncate(int32(tradeSet.PriceDigit)).String()
|
takeProfitOrder.Price = price.Mul(decimal.NewFromInt(1).Add(ext.TakeProfitRatio.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||||
takeProfitOrder.OrderType = 1
|
takeProfitOrder.OrderType = 1
|
||||||
takeProfitOrder.Rate = "100"
|
takeProfitOrder.Rate = "100"
|
||||||
takeProfitOrder.SignPrice = preOrder.Price
|
takeProfitOrder.SignPrice = preOrder.Price
|
||||||
@ -462,9 +462,9 @@ func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
|||||||
var percentage decimal.Decimal
|
var percentage decimal.Decimal
|
||||||
|
|
||||||
if data.Site == "BUY" {
|
if data.Site == "BUY" {
|
||||||
percentage = decimal.NewFromInt(1).Add(v.AddPositionPriceRatio)
|
percentage = decimal.NewFromInt(1).Add(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
|
||||||
} else {
|
} else {
|
||||||
percentage = decimal.NewFromInt(1).Sub(v.AddPositionPriceRatio)
|
percentage = decimal.NewFromInt(1).Sub(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
|
||||||
}
|
}
|
||||||
data.Price = price.Mul(percentage).Truncate(int32(tradeSet.PriceDigit)).String()
|
data.Price = price.Mul(percentage).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||||
|
|
||||||
@ -563,13 +563,26 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apiInfo, err := GetApiInfo(preOrder.ApiId)
|
||||||
|
if apiInfo.Id == 0 {
|
||||||
|
logger.Error("订单回调查询apiuserinfo失败 err:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
num, err := getSpotPositionNum(apiInfo, preOrder, tradeSet)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("订单回调查询持仓数量失败:", err)
|
||||||
|
num = utility.StrToDecimal(preOrder.Num)
|
||||||
|
}
|
||||||
|
|
||||||
if err := db.Model(&DbModels.LinePreOrder{}).
|
if err := db.Model(&DbModels.LinePreOrder{}).
|
||||||
Where("pid = ? AND order_category = 1 AND order_type > 0 AND status = '0' ", preOrder.Id).
|
Where("pid = ? AND order_category = 1 AND order_type > 0 AND status = '0' ", preOrder.Id).
|
||||||
Find(&orders).Error; err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
Find(&orders).Error; err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
logger.Error("订单回调查询止盈止损单失败:", err)
|
logger.Error("订单回调查询止盈止损单失败:", err)
|
||||||
return
|
return
|
||||||
} else if len(orders) == 0 && preOrder.OrderCategory == 3 {
|
} else if len(orders) == 0 && preOrder.OrderCategory == 3 {
|
||||||
orders, err = makeSpotTakeAndReduce(preOrder, db, tradeSet, orders)
|
orders, err = makeSpotTakeAndReduce(preOrder, db, tradeSet, orders, num)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -577,52 +590,49 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd
|
|||||||
}
|
}
|
||||||
|
|
||||||
spotApi := SpotRestApi{}
|
spotApi := SpotRestApi{}
|
||||||
num, _ := decimal.NewFromString(preOrder.Num)
|
|
||||||
|
|
||||||
for i, order := range orders {
|
for i, order := range orders {
|
||||||
if i >= 2 { // 最多处理 2 个订单
|
if i >= 2 { // 最多处理 2 个订单
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := db.Model(&order).Update("num", num).Error; err != nil {
|
order.Num = num.Mul(decimal.NewFromFloat(0.998)).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||||
|
|
||||||
|
if order.OrderType == 4 {
|
||||||
|
ext := DbModels.LinePreOrderExt{}
|
||||||
|
db.Model(&ext).Where("order_id=?", preOrder.Id).Find(&ext)
|
||||||
|
|
||||||
|
if ext.ReduceNumRatio.Cmp(decimal.Zero) > 0 {
|
||||||
|
order.Num = num.Mul(ext.ReduceNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Model(&order).Update("num", order.Num).Error; err != nil {
|
||||||
logger.Errorf("修改止盈止损数量失败 订单号:%s err:%v", order.OrderSn, err)
|
logger.Errorf("修改止盈止损数量失败 订单号:%s err:%v", order.OrderSn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch order.OrderType {
|
switch order.OrderType {
|
||||||
case 1: // 止盈
|
case 1: // 止盈
|
||||||
processTakeProfitOrder(db, spotApi, order, num)
|
processTakeProfitOrder(db, spotApi, order)
|
||||||
case 2: // 止损
|
case 2: // 止损
|
||||||
processStopLossOrder(order)
|
processStopLossOrder(order)
|
||||||
case 4: //减仓
|
case 4: //减仓
|
||||||
processSpotReduceOrder(order, num)
|
processSpotReduceOrder(order)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建现货止盈、减仓单
|
// 构建现货止盈、减仓单
|
||||||
func makeSpotTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSet models2.TradeSet, orders []DbModels.LinePreOrder) ([]DbModels.LinePreOrder, error) {
|
func makeSpotTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSet models2.TradeSet, orders []DbModels.LinePreOrder, num decimal.Decimal) ([]DbModels.LinePreOrder, error) {
|
||||||
ext := models.LinePreOrderExt{}
|
ext := models.LinePreOrderExt{}
|
||||||
apiInfo, err := GetApiInfo(preOrder.ApiId)
|
|
||||||
price := utility.StrToDecimal(preOrder.Price)
|
price := utility.StrToDecimal(preOrder.Price)
|
||||||
|
|
||||||
if apiInfo.Id == 0 {
|
|
||||||
logger.Error("订单回调查询apiuserinfo失败 err:", err)
|
|
||||||
return nil, errors.New("订单回调查询apiuserinfo失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := db.Model(&ext).Where("order_id = ?", preOrder.Id).First(&ext).Error; err != nil {
|
if err := db.Model(&ext).Where("order_id = ?", preOrder.Id).First(&ext).Error; err != nil {
|
||||||
logger.Error("订单回调查询止盈止损单扩展表失败:", err)
|
logger.Error("订单回调查询止盈止损单扩展表失败:", err)
|
||||||
return nil, errors.New("订单回调查询止盈止损单扩展表失败")
|
return nil, errors.New("订单回调查询止盈止损单扩展表失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
totalLossAmountU, _ := GetTotalLossAmount(db, preOrder.MainId)
|
totalLossAmountU, _ := GetTotalLossAmount(db, preOrder.MainId)
|
||||||
num, err := getSpotPositionNum(apiInfo, preOrder, tradeSet)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("订单回调查询持仓数量失败:", err)
|
|
||||||
return nil, errors.New("订单回调查询持仓数量失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
//止盈单
|
//止盈单
|
||||||
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
||||||
@ -658,7 +668,12 @@ func makeSpotTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSe
|
|||||||
stopOrder.OrderType = 4
|
stopOrder.OrderType = 4
|
||||||
stopOrder.Status = 0
|
stopOrder.Status = 0
|
||||||
stopOrder.Rate = ext.ReducePriceRatio.String()
|
stopOrder.Rate = ext.ReducePriceRatio.String()
|
||||||
stopOrder.Num = num.String()
|
|
||||||
|
if ext.ReduceNumRatio.Cmp(decimal.Zero) > 0 {
|
||||||
|
stopOrder.Num = num.Mul(ext.ReduceNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||||
|
} else {
|
||||||
|
stopOrder.Num = num.String()
|
||||||
|
}
|
||||||
|
|
||||||
orders = append(orders, stopOrder)
|
orders = append(orders, stopOrder)
|
||||||
}
|
}
|
||||||
@ -683,7 +698,7 @@ func makeSpotTakeAndReduce(preOrder *DbModels.LinePreOrder, db *gorm.DB, tradeSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 现货减仓
|
// 现货减仓
|
||||||
func processSpotReduceOrder(preOrder DbModels.LinePreOrder, num decimal.Decimal) {
|
func processSpotReduceOrder(preOrder DbModels.LinePreOrder) {
|
||||||
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
|
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
|
||||||
item := ReduceListItem{
|
item := ReduceListItem{
|
||||||
Id: preOrder.Id,
|
Id: preOrder.Id,
|
||||||
@ -691,7 +706,7 @@ func processSpotReduceOrder(preOrder DbModels.LinePreOrder, num decimal.Decimal)
|
|||||||
Pid: preOrder.Pid,
|
Pid: preOrder.Pid,
|
||||||
MainId: preOrder.MainId,
|
MainId: preOrder.MainId,
|
||||||
Price: utility.StrToDecimal(preOrder.Price),
|
Price: utility.StrToDecimal(preOrder.Price),
|
||||||
Num: num,
|
Num: utility.StrToDecimal(preOrder.Num),
|
||||||
Side: preOrder.Site,
|
Side: preOrder.Site,
|
||||||
Symbol: preOrder.Symbol,
|
Symbol: preOrder.Symbol,
|
||||||
OrderSn: preOrder.OrderSn,
|
OrderSn: preOrder.OrderSn,
|
||||||
@ -711,7 +726,7 @@ func processSpotReduceOrder(preOrder DbModels.LinePreOrder, num decimal.Decimal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理止盈订单
|
// 处理止盈订单
|
||||||
func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LinePreOrder, num decimal.Decimal) {
|
func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LinePreOrder) {
|
||||||
tradeSet, _ := GetTradeSet(order.Symbol, 0)
|
tradeSet, _ := GetTradeSet(order.Symbol, 0)
|
||||||
|
|
||||||
if tradeSet.Coin == "" {
|
if tradeSet.Coin == "" {
|
||||||
@ -726,7 +741,7 @@ func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LineP
|
|||||||
Symbol: order.Symbol,
|
Symbol: order.Symbol,
|
||||||
Side: order.Site,
|
Side: order.Site,
|
||||||
Price: price.Truncate(int32(tradeSet.PriceDigit)),
|
Price: price.Truncate(int32(tradeSet.PriceDigit)),
|
||||||
Quantity: num.Truncate(int32(tradeSet.AmountDigit)),
|
Quantity: utility.StrToDecimal(order.Num),
|
||||||
Type: "TAKE_PROFIT_LIMIT",
|
Type: "TAKE_PROFIT_LIMIT",
|
||||||
TimeInForce: "GTC",
|
TimeInForce: "GTC",
|
||||||
StopPrice: price.Truncate(int32(tradeSet.PriceDigit)),
|
StopPrice: price.Truncate(int32(tradeSet.PriceDigit)),
|
||||||
@ -757,7 +772,7 @@ func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LineP
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("id = ? and status ='0'", order.Id).
|
if err := db.Model(&DbModels.LinePreOrder{}).Where("id = ? and status ='0'", order.Id).
|
||||||
Updates(map[string]interface{}{"status": "1", "num": num.String()}).Error; err != nil {
|
Updates(map[string]interface{}{"status": "1", "num": order.Num}).Error; err != nil {
|
||||||
logger.Error("现货止盈下单成功,更新状态失败:", order.OrderSn, " err:", err)
|
logger.Error("现货止盈下单成功,更新状态失败:", order.OrderSn, " err:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user