From f105b7fd6138c7f9128b8a837936a67a83bb5ddd Mon Sep 17 00:00:00 2001 From: hucan <951870319@qq.com> Date: Thu, 20 Feb 2025 15:13:30 +0800 Subject: [PATCH] 1 --- app/admin/models/line_pre_order.go | 58 +++++++++++++------------- app/admin/service/line_pre_order.go | 18 ++++++-- services/binanceservice/futuresrest.go | 33 +++++++++++++++ services/binanceservice/spotreset.go | 40 +++++++++++++++++- 4 files changed, 116 insertions(+), 33 deletions(-) diff --git a/app/admin/models/line_pre_order.go b/app/admin/models/line_pre_order.go index f790c17..5fb59ed 100644 --- a/app/admin/models/line_pre_order.go +++ b/app/admin/models/line_pre_order.go @@ -9,34 +9,36 @@ import ( type LinePreOrder struct { models.Model - ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"` - Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"` - MainId int `json:"mainId" gorm:"type:int;comment:主单id"` - ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"` - GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"` - Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"` - QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"` - SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"` - SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"` - SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"` - Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"` - Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"` - Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"` - BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"` - SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"` - OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"` - Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"` - OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"` - OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"` - Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"` - Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"` - CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"` - ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"` - MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"` - LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"` - Child []LinePreOrder `json:"child" gorm:"-"` - ApiName string `json:"api_name" gorm:"->"` - ChildNum int64 `json:"child_num" gorm:"->"` + ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"` + Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"` + MainId int `json:"mainId" gorm:"type:int;comment:主单id"` + ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"` + GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"` + Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"` + QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"` + SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"` + SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"` + SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"` + Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"` + Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"` + Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"` + BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"` + SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"` + OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"` + Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"` + OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"` + OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"` + Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"` + Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"` + CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"` + ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"` + MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"` + LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"` + Child []LinePreOrder `json:"child" gorm:"-"` + ApiName string `json:"api_name" gorm:"->"` + ChildNum int64 `json:"child_num" gorm:"->"` + AddPositionStatus int `json:"add_position_status" gorm:"->"` + ReduceStatus int `json:"reduce_status" gorm:"->"` // LinePreOrder 线上预埋单\ models.ModelTime models.ControlBy diff --git a/app/admin/service/line_pre_order.go b/app/admin/service/line_pre_order.go index 7f9fcdf..f4c258c 100644 --- a/app/admin/service/line_pre_order.go +++ b/app/admin/service/line_pre_order.go @@ -1312,15 +1312,20 @@ func (e *LinePreOrder) SpotClosePosition(position *dto.ClosePosition, errs *[]er //查询已经开仓的现货交易对 var spotList []models.LinePreOrder if position.Symbol == "" { //全平 - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId).Find(&spotList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol_type =1 AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId).Find(&spotList) } else { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId, position.Symbol).Find(&spotList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol_type =1 AND symbol = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId, position.Symbol).Find(&spotList) } if len(spotList) <= 0 { *errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId))) } api := binanceservice.SpotRestApi{} + if len(spotList) == 0 { + *errs = append(*errs, errors.New("无仓可平")) + return + } + for _, list := range spotList { for _, balance := range balanceInfo.Balances { suffix := utility.ReplaceSuffix(list.Symbol, list.QuoteSymbol, "") @@ -1406,9 +1411,9 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err //查询已经开仓的合约交易对 var futList []models.LinePreOrder if position.Symbol == "" { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND order_type =0 AND main_id = 0", position.ApiId).Find(&futList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND symbol_type =2 AND order_type =0 AND main_id = 0", position.ApiId).Find(&futList) } else { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND order_type = 0 AND main_id = 0", position.ApiId, position.Symbol).Find(&futList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND symbol_type =2 AND status = 6 AND order_type = 0 AND main_id = 0", position.ApiId, position.Symbol).Find(&futList) } if len(futList) <= 0 { *errs = append(*errs, fmt.Errorf("api_id:%d 没有可平仓的交易对", position.ApiId)) @@ -1417,6 +1422,11 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err api := binanceservice.FutRestApi{} + if len(futList) == 0 { + *errs = append(*errs, errors.New("无仓可平")) + return + } + for _, list := range futList { risks, err := api.GetPositionV3(&apiUserInfo, list.Symbol) if err != nil { diff --git a/services/binanceservice/futuresrest.go b/services/binanceservice/futuresrest.go index c1e7f2a..f85ea0c 100644 --- a/services/binanceservice/futuresrest.go +++ b/services/binanceservice/futuresrest.go @@ -276,6 +276,16 @@ func getFuturesPositionNum(apiUserInfo DbModels.LineApiUser, preOrder *DbModels. // 平仓单成交 func handleClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + + futApi := FutRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止盈成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ?", ids).Update("status", 9).Error; err != nil { @@ -286,6 +296,20 @@ func handleClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) { // 止损单成交 func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止损成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ?", ids).Update("status", 9).Error; err != nil { @@ -297,6 +321,15 @@ func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) { func handleTakeProfit(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + futApi := FutRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止盈成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ? AND order_type=0", ids).Update("status", 9).Error; err != nil { diff --git a/services/binanceservice/spotreset.go b/services/binanceservice/spotreset.go index 216564f..0365b22 100644 --- a/services/binanceservice/spotreset.go +++ b/services/binanceservice/spotreset.go @@ -136,6 +136,19 @@ func handleOrderByType(db *gorm.DB, preOrder *DbModels.LinePreOrder, orderStatus if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND status =0", preOrder.MainId).Update("status", 4).Error; err != nil { logger.Errorf("主单止损回调 订单号:%s 修改主单状态失败:%v", preOrder.OrderSn, err) } + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } } } @@ -361,16 +374,41 @@ func handleMainOrderClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) return nil }) - } removeSpotLossAndAddPosition(preOrder) + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } } // 止盈成交 func handleSpotTakeProfitFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeSpotLossAndAddPosition(preOrder) + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + db.Transaction(func(tx *gorm.DB) error { ids := []int{preOrder.Pid, preOrder.MainId} if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ? AND status =6 AND order_type=0", ids).Update("status", 9).Error; err != nil {