1
This commit is contained in:
@ -471,7 +471,7 @@ func getOpenPositionMainOrderId(db *gorm.DB, newId, apiId, symbolType int, excha
|
||||
}
|
||||
|
||||
// 获取需要取消的订单号
|
||||
func getOpenOrderSns(db *gorm.DB, mainIds []int) ([]string, error) {
|
||||
func GetOpenOrderSns(db *gorm.DB, mainIds []int) ([]string, error) {
|
||||
result := []string{}
|
||||
|
||||
//委托中的订单
|
||||
|
||||
@ -201,8 +201,8 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
||||
return
|
||||
} else if ok {
|
||||
defer lock.Release()
|
||||
takeOrder := DbModels.LinePreOrder{}
|
||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type =1", reduceOrder.Pid).Find(&takeOrder).Error; err != nil {
|
||||
takeOrders := make([]DbModels.LinePreOrder, 0)
|
||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND order_type =1 AND status IN (1,5)", reduceOrder.MainId).Find(&takeOrders).Error; err != nil {
|
||||
log.Error("查询止盈单失败")
|
||||
return
|
||||
}
|
||||
@ -214,18 +214,19 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
||||
return
|
||||
}
|
||||
|
||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
||||
apiInfo, _ := GetApiInfo(reduceOrder.ApiId)
|
||||
|
||||
if apiInfo.Id == 0 {
|
||||
log.Error("现货减仓 查询api用户不存在")
|
||||
return
|
||||
}
|
||||
for _, takeOrder := range takeOrders {
|
||||
err := CancelFutOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||
|
||||
err := CancelFutOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||
|
||||
if err != nil {
|
||||
log.Error("合约止盈撤单失败", err)
|
||||
return
|
||||
if err != nil {
|
||||
log.Error("合约止盈撤单失败", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
price := reduceOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.ReducePremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
|
||||
|
||||
@ -154,7 +154,6 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
|
||||
orderExt := models.LinePreOrderExt{}
|
||||
totalNum := getFuturesPositionAvailableQuantity(db, apiUserInfo, preOrder, tradeSet)
|
||||
totalNum = totalNum.Truncate(int32(tradeSet.AmountDigit))
|
||||
price := utility.StrToDecimal(preOrder.Price).Truncate(int32(tradeSet.PriceDigit))
|
||||
futApi := FutRestApi{}
|
||||
mainId := preOrder.Id
|
||||
@ -199,7 +198,7 @@ func nextFuturesReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal,
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Model(&models.LinePreOrderExt{}).Where("id =?", nextOrder.Id).First(&nextExt).Error; err != nil {
|
||||
if err := db.Model(&models.LinePreOrderExt{}).Where("order_id =? and add_type =2", nextOrder.Id).First(&nextExt).Error; err != nil {
|
||||
logger.Errorf("获取下一个单失败 err:%v", err)
|
||||
}
|
||||
|
||||
@ -223,6 +222,10 @@ func nextFuturesReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal,
|
||||
// 计算减仓数量
|
||||
num = totalNum.Mul(nextExt.AddPositionVal.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||
nextOrder.Num = num.String()
|
||||
|
||||
if err := db.Model(&nextOrder).Update("num", nextOrder.Num).Error; err != nil {
|
||||
logger.Errorf("更新减仓单数量失败 err:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
processFutReduceOrder(nextOrder, utility.StrToDecimal(nextOrder.Price).Truncate(int32(tradeSet.PriceDigit)), num)
|
||||
@ -321,16 +324,12 @@ func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
removeFutLossAndAddPosition(preOrder.MainId, preOrder.OrderSn)
|
||||
removePosition(db, 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)
|
||||
mainIds := []int{preOrder.MainId}
|
||||
if err := cancelMainOrders(mainIds, db, apiUserInfo, preOrder.Symbol, false); err != nil {
|
||||
logger.Errorf("止损单成功 取消其它订单失败 订单号:%s:", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,12 +352,12 @@ func handleTakeProfit(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
removeFutLossAndAddPosition(preOrder.MainId, preOrder.OrderSn)
|
||||
removePosition(db, preOrder)
|
||||
|
||||
futApi := FutRestApi{}
|
||||
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
||||
|
||||
if apiUserInfo.Id > 0 {
|
||||
if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil {
|
||||
logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err)
|
||||
mainOrder, _ := GetOrderById(db, preOrder.MainId)
|
||||
if err := cancelPositionOtherOrders(apiUserInfo, db, &mainOrder, false); err != nil {
|
||||
logger.Errorf("止损单成功 取消其它订单失败 订单号:%s:", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,9 +444,9 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
||||
logger.Errorf("处理主单加仓失败, 主单号:%s, 错误信息: %v", preOrder.MainId, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
} else if first {
|
||||
// 处理其他主单逻辑
|
||||
if err := cancelPositionOtherOrders(apiInfo, db, preOrder); err != nil {
|
||||
if err := cancelPositionOtherOrders(apiInfo, db, preOrder, true); err != nil {
|
||||
logger.Errorf("取消主单相关订单失败, 订单号:%s, 错误信息: %v", preOrder.OrderSn, err)
|
||||
return
|
||||
}
|
||||
@ -497,7 +496,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
||||
positionData := savePosition(db, preOrder)
|
||||
orderExt := models.LinePreOrderExt{}
|
||||
db.Model(&orderExt).Where("order_id =?", extOrderId).First(&orderExt)
|
||||
num := getFuturesPositionAvailableQuantity(db, apiInfo, preOrder, tradeSet).Truncate(int32(tradeSet.AmountDigit))
|
||||
totalNum := getFuturesPositionAvailableQuantity(db, apiInfo, preOrder, tradeSet).Truncate(int32(tradeSet.AmountDigit))
|
||||
|
||||
// 更新订单数量并处理止盈、止损、减仓
|
||||
for _, order := range orders {
|
||||
@ -505,7 +504,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
||||
order.Price = price.String()
|
||||
|
||||
// 更新止盈止损订单数量
|
||||
num = updateOrderQuantity(db, order, preOrder, &orderExt, num, first, tradeSet)
|
||||
num := updateOrderQuantity(db, order, preOrder, &orderExt, totalNum, first, tradeSet)
|
||||
|
||||
// 根据订单类型处理
|
||||
switch order.OrderType {
|
||||
@ -552,7 +551,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
||||
}
|
||||
}
|
||||
|
||||
nextFuturesReduceTrigger(db, mainId, num, tradeSet)
|
||||
nextFuturesReduceTrigger(db, mainId, totalNum, tradeSet)
|
||||
}
|
||||
|
||||
// 处理主单加仓
|
||||
@ -569,7 +568,8 @@ func handleMainOrderAddPosition(db *gorm.DB, preOrder *models.LinePreOrder) erro
|
||||
}
|
||||
|
||||
// 取消主单相关订单
|
||||
func cancelPositionOtherOrders(apiUserInfo DbModels.LineApiUser, db *gorm.DB, preOrder *models.LinePreOrder) error {
|
||||
// changeMainOrderStatus 是否修改主单状态
|
||||
func cancelPositionOtherOrders(apiUserInfo DbModels.LineApiUser, db *gorm.DB, preOrder *models.LinePreOrder, changeMainOrderStatus bool) error {
|
||||
mainOrders, err := getOpenPositionMainOrderId(db, preOrder.Id, preOrder.ApiId, preOrder.SymbolType, preOrder.ExchangeType, preOrder.Symbol, preOrder.Site)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -589,25 +589,36 @@ func cancelPositionOtherOrders(apiUserInfo DbModels.LineApiUser, db *gorm.DB, pr
|
||||
}
|
||||
}
|
||||
|
||||
// 批量取消订单
|
||||
err = cancelMainOrders(mainIds, db, apiUserInfo, preOrder.Symbol, changeMainOrderStatus)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// 根据mainid 取消订单
|
||||
// @changeMainOrderStatus 是否更新主单状态
|
||||
func cancelMainOrders(mainIds []int, db *gorm.DB, apiUserInfo DbModels.LineApiUser, symbol string, changeMainOrderStatus bool) error {
|
||||
if len(mainIds) > 0 {
|
||||
orderSns, err := getOpenOrderSns(db, mainIds)
|
||||
orderSns, err := GetOpenOrderSns(db, mainIds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量取消订单
|
||||
orderArray := utility.SplitSlice(orderSns, 10)
|
||||
futApi := FutRestApi{}
|
||||
for _, item := range orderArray {
|
||||
err := futApi.CancelBatchFutOrder(apiUserInfo, preOrder.Symbol, item)
|
||||
err := futApi.CancelBatchFutOrder(apiUserInfo, symbol, item)
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("批量取消订单失败 orderSns:%v", item)
|
||||
}
|
||||
}
|
||||
|
||||
if err := db.Exec("UPDATE line_pre_order SET `status`=4, `desc`=CONCAT(`desc`, ' 新单触发取消') WHERE id IN ? AND `status` =6", mainIds).Error; err != nil {
|
||||
logger.Errorf("合约 新下单成功后更新主单取消状态失败, 新主单号:%s, 错误信息:%v", preOrder.MainId, err)
|
||||
//需要修改主单状态
|
||||
if changeMainOrderStatus {
|
||||
if err := db.Exec("UPDATE line_pre_order SET `status`=4, `desc`=CONCAT(`desc`, ' 新单触发取消') WHERE id IN ? AND `status` =6", mainIds).Error; err != nil {
|
||||
logger.Errorf("合约 新下单成功后更新主单取消状态失败, 交易对:%s, 错误信息:%v", symbol, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -633,7 +644,7 @@ func updateOrderQuantity(db *gorm.DB, order models.LinePreOrder, preOrder *model
|
||||
// order.Num = num.String()
|
||||
// } else
|
||||
|
||||
if first && order.OrderCategory == 1 && ext.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 && ext.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) != 0 {
|
||||
if first && (order.OrderCategory == 1 || order.OrderCategory == 3) && order.OrderType == 1 && ext.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 && ext.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) != 0 {
|
||||
// 计算止盈数量
|
||||
num = num.Mul(ext.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||
order.Num = num.String()
|
||||
|
||||
@ -308,8 +308,8 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
||||
return
|
||||
} else if ok {
|
||||
defer lock.Release()
|
||||
takeOrder := DbModels.LinePreOrder{}
|
||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type =1", reduceOrder.Pid).Find(&takeOrder).Error; err != nil {
|
||||
takeOrders := make([]DbModels.LinePreOrder, 0)
|
||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND order_type =1 AND status IN (1,5)", reduceOrder.MainId).Find(&takeOrders).Error; err != nil {
|
||||
log.Error("查询止盈单失败")
|
||||
return
|
||||
}
|
||||
@ -320,18 +320,20 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
||||
return
|
||||
}
|
||||
|
||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
||||
apiInfo, _ := GetApiInfo(reduceOrder.ApiId)
|
||||
|
||||
if apiInfo.Id == 0 {
|
||||
log.Error("现货减仓 查询api用户不存在")
|
||||
return
|
||||
}
|
||||
|
||||
err := CancelOpenOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||
for _, takeOrder := range takeOrders {
|
||||
err := CancelOpenOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||
|
||||
if err != nil {
|
||||
log.Error("现货止盈撤单失败", err)
|
||||
return
|
||||
if err != nil {
|
||||
log.Error("现货止盈撤单失败", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
price := reduceOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.ReducePremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
|
||||
|
||||
|
||||
@ -195,7 +195,7 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
|
||||
db.Model(&orderExt).Where("order_id =?", preOrder.Pid).Find(&orderExt)
|
||||
totalNum := getSpotPositionAvailableQuantity(db, apiUserInfo, preOrder, tradeSet) //getSpotTotalNum(apiUserInfo, preOrder, tradeSet)
|
||||
totalNum = totalNum.Truncate(int32(tradeSet.AmountDigit))
|
||||
totalNum = totalNum.Mul(decimal.NewFromFloat(0.998)).Truncate(int32(tradeSet.AmountDigit))
|
||||
price := utility.StrToDecimal(preOrder.Price)
|
||||
|
||||
if err := db.Model(&models.LinePreOrder{}).Where("pid =? AND order_type IN (1,2) AND status=0", preOrder.Id).Find(&orders).Error; err != nil {
|
||||
@ -244,7 +244,7 @@ func nextSpotReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal, tr
|
||||
return true
|
||||
}
|
||||
|
||||
if err := db.Model(&models.LinePreOrderExt{}).Where("id =?", nextOrder.Id).First(&nextExt).Error; err != nil {
|
||||
if err := db.Model(&models.LinePreOrderExt{}).Where("order_id =? and add_type =2", nextOrder.Id).First(&nextExt).Error; err != nil {
|
||||
logger.Errorf("获取下一个单失败 err:%v", err)
|
||||
}
|
||||
|
||||
@ -265,12 +265,12 @@ func nextSpotReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal, tr
|
||||
//减仓配置 且减仓比例大于0小于100
|
||||
if nextExt.Id > 0 && nextExt.AddType == 2 && nextExt.AddPositionVal.Cmp(decimal.Zero) > 0 && nextExt.AddPositionVal.Cmp(decimal.Zero) < 100 {
|
||||
num := totalNum.Mul(nextExt.AddPositionVal.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||
// percentag = positionData.TotalLoss.Div(num).Div(price).Mul(decimal.NewFromInt(100)).Truncate(2)
|
||||
nextOrder.Num = num.String()
|
||||
|
||||
if err := db.Model(&nextOrder).Update("num", nextOrder.Num).Error; err != nil {
|
||||
logger.Errorf("更新减仓单数量失败 err:%v", err)
|
||||
}
|
||||
}
|
||||
// percentag = nextExt.PriceRatio.Add(percentag)
|
||||
// nextOrder.Rate = percentag.String()
|
||||
// nextOrder.Price = price.Mul(decimal.NewFromInt(1).Add(percentag.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||
|
||||
//减仓待触发
|
||||
processSpotReduceOrder(nextOrder)
|
||||
@ -638,7 +638,7 @@ func parseOrderStatus(status interface{}, mapData map[string]interface{}) (int,
|
||||
return 5, reason
|
||||
case "FILLED": // 完全成交
|
||||
return 6, reason
|
||||
case "CANCELED", "EXPIRED": // 取消
|
||||
case "CANCELED", "EXPIRED", "EXPIRED_IN_MATCH": // 取消
|
||||
return 4, reason
|
||||
default:
|
||||
return 0, reason
|
||||
@ -729,13 +729,17 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd
|
||||
spotApi := SpotRestApi{}
|
||||
orderExt := models.LinePreOrderExt{}
|
||||
db.Model(&orderExt).Where("order_id =?", extOrderId).First(&orderExt)
|
||||
num = num.Mul(decimal.NewFromFloat(0.998)).Truncate(int32(tradeSet.AmountDigit))
|
||||
totalNum := num.Mul(decimal.NewFromFloat(0.998)).Truncate(int32(tradeSet.AmountDigit))
|
||||
num = totalNum
|
||||
|
||||
// if orderExt.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 && orderExt.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) < 0 {
|
||||
// num = num.Mul(orderExt.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||
// }
|
||||
//止盈止损
|
||||
for _, order := range orders {
|
||||
order.Num = num.String()
|
||||
|
||||
if fist && order.OrderCategory == 1 && orderExt.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 && orderExt.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) != 0 {
|
||||
if fist && order.OrderCategory == 1 && order.OrderType == 1 && orderExt.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 && orderExt.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) != 0 {
|
||||
//主单第一次且止盈数量不是100% 止盈数量
|
||||
order.Num = num.Mul(orderExt.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
|
||||
}
|
||||
@ -777,7 +781,7 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd
|
||||
}
|
||||
|
||||
//待触发减仓单
|
||||
nextSpotReduceTrigger(db, mainId, num, tradeSet)
|
||||
nextSpotReduceTrigger(db, mainId, totalNum, tradeSet)
|
||||
}
|
||||
|
||||
// 根据下单百分比计算价格
|
||||
@ -947,6 +951,8 @@ func CancelOpenOrderByOrderSnLoop(apiInfo DbModels.LineApiUser, symbol string, o
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * 300)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user