1
This commit is contained in:
@ -353,31 +353,34 @@ type LineTreeOrder struct {
|
|||||||
|
|
||||||
// LineBatchAddPreOrderReq 批量添加订单请求参数
|
// LineBatchAddPreOrderReq 批量添加订单请求参数
|
||||||
type LineBatchAddPreOrderReq struct {
|
type LineBatchAddPreOrderReq struct {
|
||||||
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
||||||
SymbolType int `json:"symbol_type"` //主单交易对类型 0-现货 1-合约
|
SymbolType int `json:"symbol_type"` //主单交易对类型 0-现货 1-合约
|
||||||
OrderType int `json:"order_type"` //订单类型
|
OrderType int `json:"order_type"` //订单类型
|
||||||
SymbolGroupId string `json:"symbol_group_id"` //交易对组id
|
SymbolGroupId string `json:"symbol_group_id"` //交易对组id
|
||||||
Symbol string `json:"symbol"` //交易对
|
Symbol string `json:"symbol"` //交易对
|
||||||
ApiUserId string `json:"api_id"` //下单用户
|
ApiUserId string `json:"api_id"` //下单用户
|
||||||
Site string `json:"site"` //购买方向
|
Site string `json:"site"` //购买方向
|
||||||
BuyPrice string `json:"buy_price"` //购买金额 U
|
BuyPrice string `json:"buy_price"` //购买金额 U
|
||||||
PricePattern string `json:"price_pattern"` //价格模式
|
PricePattern string `json:"price_pattern"` //价格模式
|
||||||
Price string `json:"price"` //下单价百分比
|
Price string `json:"price"` //下单价百分比
|
||||||
Profit string `json:"profit"` //止盈价
|
ProfitNumRatio decimal.Decimal `json:"profit_num_ratio"` //止盈数量百分比
|
||||||
StopPrice string `json:"stop_price"` //止损价
|
ProfitTpTpPriceRatio decimal.Decimal `json:"profit_tp_tp_price_ratio"` //止盈后止盈价百分比
|
||||||
PriceType string `json:"price_type"` //价格类型
|
ProfitTpSlPriceRatio decimal.Decimal `json:"profit_tp_sl_price_ratio"` //止盈后止损价百分比
|
||||||
SaveTemplate string `json:"save_template"` //是否保存模板
|
Profit string `json:"profit"` //止盈价
|
||||||
TemplateName string `json:"template_name"` //模板名字
|
StopPrice string `json:"stop_price"` //止损价
|
||||||
OrderNum int `json:"order_num"` //脚本运行次数
|
PriceType string `json:"price_type"` //价格类型
|
||||||
Script string `json:"script"` //是否是脚本运行 1 = 是 0= 否
|
SaveTemplate string `json:"save_template"` //是否保存模板
|
||||||
CoverType int `json:"cover_type"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
|
TemplateName string `json:"template_name"` //模板名字
|
||||||
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
|
OrderNum int `json:"order_num"` //脚本运行次数
|
||||||
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
|
Script string `json:"script"` //是否是脚本运行 1 = 是 0= 否
|
||||||
ReducePriceRatio decimal.Decimal `json:"reduce_price"` //主单减仓价格百分比
|
CoverType int `json:"cover_type"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
|
||||||
ReduceNumRatio decimal.Decimal `json:"reduce_num"` //主单减仓数量百分比
|
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
|
||||||
ReduceTakeProfitRatio decimal.Decimal `json:"reduce_take_profit"` //主单减仓后止盈价百分比
|
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
|
||||||
ReduceStopLossRatio decimal.Decimal `json:"reduce_stop_price"` //主单减仓后止损价百分比
|
ReducePriceRatio decimal.Decimal `json:"reduce_price"` //主单减仓价格百分比
|
||||||
Ext []LineAddPreOrderExtReq `json:"ext"` //拓展字段
|
ReduceNumRatio decimal.Decimal `json:"reduce_num"` //主单减仓数量百分比
|
||||||
|
ReduceTakeProfitRatio decimal.Decimal `json:"reduce_take_profit"` //主单减仓后止盈价百分比
|
||||||
|
ReduceStopLossRatio decimal.Decimal `json:"reduce_stop_price"` //主单减仓后止损价百分比
|
||||||
|
Ext []LineAddPreOrderExtReq `json:"ext"` //拓展字段
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req LineBatchAddPreOrderReq) CheckParams() error {
|
func (req LineBatchAddPreOrderReq) CheckParams() error {
|
||||||
|
|||||||
@ -244,7 +244,49 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
|
|||||||
}
|
}
|
||||||
|
|
||||||
positions := map[string]positiondto.LinePreOrderPositioinDelReq{}
|
positions := map[string]positiondto.LinePreOrderPositioinDelReq{}
|
||||||
|
addPosition := binanceservice.AddPositionList{}
|
||||||
|
reduceItem := binanceservice.ReduceListItem{}
|
||||||
|
futAddPosition := map[int]string{}
|
||||||
|
spotAddPosition := map[int]string{}
|
||||||
|
futReduces := map[int]string{}
|
||||||
|
spotRedces := map[int]string{}
|
||||||
|
|
||||||
|
futAddPositionKey := fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BINANCE)
|
||||||
|
spotAddPositionKey := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
|
||||||
|
futReduceKey := fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BINANCE)
|
||||||
|
spotReduceKey := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
|
||||||
|
futAddPositionVal, _ := helper.DefaultRedis.GetAllList(futAddPositionKey)
|
||||||
|
futReduceVal, _ := helper.DefaultRedis.GetAllList(spotAddPositionKey)
|
||||||
|
spotAddPositionVal, _ := helper.DefaultRedis.GetAllList(futReduceKey)
|
||||||
|
spotReduceVal, _ := helper.DefaultRedis.GetAllList(spotReduceKey)
|
||||||
|
|
||||||
|
for _, v := range futAddPositionVal {
|
||||||
|
sonic.Unmarshal([]byte(v), &addPosition)
|
||||||
|
if addPosition.MainId > 0 {
|
||||||
|
futAddPosition[addPosition.MainId] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range spotAddPositionVal {
|
||||||
|
sonic.Unmarshal([]byte(v), &addPosition)
|
||||||
|
if addPosition.MainId > 0 {
|
||||||
|
spotAddPosition[addPosition.MainId] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range futReduceVal {
|
||||||
|
sonic.Unmarshal([]byte(v), &reduceItem)
|
||||||
|
if reduceItem.MainId > 0 {
|
||||||
|
futReduces[reduceItem.MainId] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range spotReduceVal {
|
||||||
|
sonic.Unmarshal([]byte(v), &reduceItem)
|
||||||
|
if reduceItem.MainId > 0 {
|
||||||
|
spotRedces[reduceItem.MainId] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
//删除的缓存
|
//删除的缓存
|
||||||
for _, order := range list {
|
for _, order := range list {
|
||||||
redisList := dto.PreOrderRedisList{
|
redisList := dto.PreOrderRedisList{
|
||||||
@ -261,6 +303,21 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
|
|||||||
apiIds = append(apiIds, order.ApiId)
|
apiIds = append(apiIds, order.ApiId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//清除待加仓、待减仓
|
||||||
|
if val, ok := futAddPosition[order.Id]; ok {
|
||||||
|
helper.DefaultRedis.LRem(futAddPositionKey, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := spotAddPosition[order.Id]; ok {
|
||||||
|
helper.DefaultRedis.LRem(spotAddPositionKey, val)
|
||||||
|
}
|
||||||
|
if val, ok := futReduces[order.Id]; ok {
|
||||||
|
helper.DefaultRedis.LRem(futReduceKey, val)
|
||||||
|
}
|
||||||
|
if val, ok := spotRedces[order.Id]; ok {
|
||||||
|
helper.DefaultRedis.LRem(spotReduceKey, val)
|
||||||
|
}
|
||||||
|
|
||||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
|
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
|
||||||
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
|
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||||
marshal, _ := sonic.Marshal(redisList)
|
marshal, _ := sonic.Marshal(redisList)
|
||||||
@ -483,6 +540,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
|||||||
defultExt2.TotalAfter = mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio)).Div(decimal.NewFromInt(100)).Truncate(int32(tradeSet.AmountDigit))
|
defultExt2.TotalAfter = mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio)).Div(decimal.NewFromInt(100)).Truncate(int32(tradeSet.AmountDigit))
|
||||||
defultExt2.ReTakeRatio = req.ReducePriceRatio.Div(decimal.NewFromInt(100).Sub(req.ReduceNumRatio).Div(decimal.NewFromInt(100))).Truncate(2)
|
defultExt2.ReTakeRatio = req.ReducePriceRatio.Div(decimal.NewFromInt(100).Sub(req.ReduceNumRatio).Div(decimal.NewFromInt(100))).Truncate(2)
|
||||||
preOrderExts = append(preOrderExts, defultExt)
|
preOrderExts = append(preOrderExts, defultExt)
|
||||||
|
preOrderExts = append(preOrderExts, defultExt2)
|
||||||
|
|
||||||
calculateResp := dto.CalculateBreakEvenRatioResp{}
|
calculateResp := dto.CalculateBreakEvenRatioResp{}
|
||||||
mainParam := dto.CalculateBreakEevenRatioReq{
|
mainParam := dto.CalculateBreakEevenRatioReq{
|
||||||
@ -550,7 +608,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
|||||||
|
|
||||||
//加仓、减仓状态
|
//加仓、减仓状态
|
||||||
tx.Model(&models.LinePreOrderStatus{}).Create(&preOrderStatus)
|
tx.Model(&models.LinePreOrderStatus{}).Create(&preOrderStatus)
|
||||||
|
preOrderExts[0].OrderId = AddOrder.Id
|
||||||
list := dto.PreOrderRedisList{
|
list := dto.PreOrderRedisList{
|
||||||
Id: AddOrder.Id,
|
Id: AddOrder.Id,
|
||||||
Symbol: AddOrder.Symbol,
|
Symbol: AddOrder.Symbol,
|
||||||
@ -626,7 +684,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
|||||||
stopOrder.Num = stopNum.Truncate(int32(tradeSet.AmountDigit)).String()
|
stopOrder.Num = stopNum.Truncate(int32(tradeSet.AmountDigit)).String()
|
||||||
|
|
||||||
tx.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&stopOrder)
|
tx.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&stopOrder)
|
||||||
|
preOrderExts[1].OrderId = stopOrder.Id
|
||||||
if req.ReduceNumRatio.Cmp(decimal.Zero) > 0 && req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) < 0 {
|
if req.ReduceNumRatio.Cmp(decimal.Zero) > 0 && req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) < 0 {
|
||||||
if newOrders, err := makeReduceTakeAndStoploss(&stopOrder, defultExt2, tradeSet, false); err != nil {
|
if newOrders, err := makeReduceTakeAndStoploss(&stopOrder, defultExt2, tradeSet, false); err != nil {
|
||||||
logger.Errorf("主单减仓生成止盈、减仓失败 err:%v", err)
|
logger.Errorf("主单减仓生成止盈、减仓失败 err:%v", err)
|
||||||
@ -643,10 +701,10 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
|||||||
//添加止盈单
|
//添加止盈单
|
||||||
for index, v := range preOrderExts {
|
for index, v := range preOrderExts {
|
||||||
preOrderExts[index].MainOrderId = AddOrder.Id
|
preOrderExts[index].MainOrderId = AddOrder.Id
|
||||||
// if index == 0 {
|
if index < 2 {
|
||||||
// preOrderExts[index].OrderId = AddOrder.Id
|
// preOrderExts[index].OrderId = AddOrder.Id
|
||||||
// continue
|
continue
|
||||||
// }
|
}
|
||||||
var newOrder models.LinePreOrder
|
var newOrder models.LinePreOrder
|
||||||
|
|
||||||
if v.AddType == 1 {
|
if v.AddType == 1 {
|
||||||
@ -801,10 +859,10 @@ func makeFuturesTakeAndReduce(preOrder *models.LinePreOrder, ext models.LinePreO
|
|||||||
orders := make([]models.LinePreOrder, 0)
|
orders := make([]models.LinePreOrder, 0)
|
||||||
var side string
|
var side string
|
||||||
|
|
||||||
if strings.ToUpper(preOrder.Site) == "BUY" {
|
if (preOrder.OrderType != 0 && strings.ToUpper(preOrder.Site) == "BUY") || (preOrder.OrderType == 0 && strings.ToUpper(preOrder.Site) == "SELL") {
|
||||||
side = "SELL"
|
|
||||||
} else {
|
|
||||||
side = "BUY"
|
side = "BUY"
|
||||||
|
} else {
|
||||||
|
side = "SELL"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
||||||
@ -1055,6 +1113,9 @@ func (e *LinePreOrder) AddBatchPreOrder(batchReq *dto.LineBatchAddPreOrderReq, p
|
|||||||
req.PricePattern = batchReq.PricePattern
|
req.PricePattern = batchReq.PricePattern
|
||||||
req.Price = batchReq.Price
|
req.Price = batchReq.Price
|
||||||
req.Profit = batchReq.Profit
|
req.Profit = batchReq.Profit
|
||||||
|
req.ProfitNumRatio = batchReq.ProfitNumRatio
|
||||||
|
req.ProfitTpTpPriceRatio = batchReq.ProfitTpSlPriceRatio
|
||||||
|
req.ProfitTpSlPriceRatio = batchReq.ProfitTpSlPriceRatio
|
||||||
req.Ext = batchReq.Ext
|
req.Ext = batchReq.Ext
|
||||||
req.SymbolType = batchReq.SymbolType
|
req.SymbolType = batchReq.SymbolType
|
||||||
// req.StopPrice = batchReq.StopPrice
|
// req.StopPrice = batchReq.StopPrice
|
||||||
@ -1663,8 +1724,10 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//撤销合约的委托
|
//撤销合约的委托(根据方向撤)
|
||||||
api.CancelAllFutOrder(apiUserInfo, list.Symbol)
|
orderSns, _ := binanceservice.GetOpenOrderSns(e.Orm, []int{list.Id})
|
||||||
|
api.CancelBatchFutOrder(apiUserInfo, list.Symbol, orderSns)
|
||||||
|
// api.CancelAllFutOrder(apiUserInfo, list.Symbol)
|
||||||
//side=BUY&positionSide=LONG是开多,
|
//side=BUY&positionSide=LONG是开多,
|
||||||
//side=SELL&positionSide=LONG是平多,
|
//side=SELL&positionSide=LONG是平多,
|
||||||
//side=SELL&positionSide=SHORT是开空,
|
//side=SELL&positionSide=SHORT是开空,
|
||||||
|
|||||||
@ -50,9 +50,10 @@ const (
|
|||||||
SpotReduceList = "spot_reduce_list:%s" //现货减仓待触发 {交易所类型code}
|
SpotReduceList = "spot_reduce_list:%s" //现货减仓待触发 {交易所类型code}
|
||||||
FuturesStopLossList = "futures_stoploss_list:%s" //合约止损待触发列表 {交易所类型code}
|
FuturesStopLossList = "futures_stoploss_list:%s" //合约止损待触发列表 {交易所类型code}
|
||||||
FuturesReduceList = "futures_reduce_list:%s" //合约减仓待触发 {交易所类型code}
|
FuturesReduceList = "futures_reduce_list:%s" //合约减仓待触发 {交易所类型code}
|
||||||
|
//现货加仓待触发 {交易所code}
|
||||||
SpotAddPositionList = "spot_add_position_list:%s" //现货加仓待触发 {交易所code}
|
SpotAddPositionList = "spot_add_position_list:%s"
|
||||||
FuturesAddPositionList = "futures_add_position_list:%s" //合约加仓待触发 {交易所code}
|
//合约加仓待触发 {交易所code}
|
||||||
|
FuturesAddPositionList = "futures_add_position_list:%s"
|
||||||
//现货持仓 {exchangeType,apiuserid,symbol,side}
|
//现货持仓 {exchangeType,apiuserid,symbol,side}
|
||||||
SpotPosition = "spot_position:%s:%v:%s_%s"
|
SpotPosition = "spot_position:%s:%v:%s_%s"
|
||||||
//合约持仓 {exchangeType,apiuserid,symbol,side}
|
//合约持仓 {exchangeType,apiuserid,symbol,side}
|
||||||
|
|||||||
@ -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{}
|
result := []string{}
|
||||||
|
|
||||||
//委托中的订单
|
//委托中的订单
|
||||||
|
|||||||
@ -201,8 +201,8 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
|||||||
return
|
return
|
||||||
} else if ok {
|
} else if ok {
|
||||||
defer lock.Release()
|
defer lock.Release()
|
||||||
takeOrder := DbModels.LinePreOrder{}
|
takeOrders := make([]DbModels.LinePreOrder, 0)
|
||||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type =1", reduceOrder.Pid).Find(&takeOrder).Error; err != nil {
|
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("查询止盈单失败")
|
log.Error("查询止盈单失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -214,18 +214,19 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
apiInfo, _ := GetApiInfo(reduceOrder.ApiId)
|
||||||
|
|
||||||
if apiInfo.Id == 0 {
|
if apiInfo.Id == 0 {
|
||||||
log.Error("现货减仓 查询api用户不存在")
|
log.Error("现货减仓 查询api用户不存在")
|
||||||
return
|
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)
|
||||||
if err != nil {
|
return
|
||||||
log.Error("合约止盈撤单失败", err)
|
}
|
||||||
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))
|
||||||
|
|||||||
@ -154,7 +154,6 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
|||||||
|
|
||||||
orderExt := models.LinePreOrderExt{}
|
orderExt := models.LinePreOrderExt{}
|
||||||
totalNum := getFuturesPositionAvailableQuantity(db, apiUserInfo, preOrder, tradeSet)
|
totalNum := getFuturesPositionAvailableQuantity(db, apiUserInfo, preOrder, tradeSet)
|
||||||
totalNum = totalNum.Truncate(int32(tradeSet.AmountDigit))
|
|
||||||
price := utility.StrToDecimal(preOrder.Price).Truncate(int32(tradeSet.PriceDigit))
|
price := utility.StrToDecimal(preOrder.Price).Truncate(int32(tradeSet.PriceDigit))
|
||||||
futApi := FutRestApi{}
|
futApi := FutRestApi{}
|
||||||
mainId := preOrder.Id
|
mainId := preOrder.Id
|
||||||
@ -199,7 +198,7 @@ func nextFuturesReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal,
|
|||||||
return
|
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)
|
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))
|
num = totalNum.Mul(nextExt.AddPositionVal.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||||
nextOrder.Num = num.String()
|
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)
|
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)
|
removeFutLossAndAddPosition(preOrder.MainId, preOrder.OrderSn)
|
||||||
removePosition(db, preOrder)
|
removePosition(db, preOrder)
|
||||||
|
|
||||||
spotApi := SpotRestApi{}
|
|
||||||
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
||||||
|
|
||||||
if apiUserInfo.Id > 0 {
|
if apiUserInfo.Id > 0 {
|
||||||
req := CancelOpenOrdersReq{
|
mainIds := []int{preOrder.MainId}
|
||||||
Symbol: preOrder.Symbol,
|
if err := cancelMainOrders(mainIds, db, apiUserInfo, preOrder.Symbol, false); err != nil {
|
||||||
ApiId: preOrder.ApiId,
|
logger.Errorf("止损单成功 取消其它订单失败 订单号:%s:", err)
|
||||||
}
|
|
||||||
if err := spotApi.CancelOpenOrders(db, req); err != nil {
|
|
||||||
logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,12 +352,12 @@ func handleTakeProfit(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
|||||||
removeFutLossAndAddPosition(preOrder.MainId, preOrder.OrderSn)
|
removeFutLossAndAddPosition(preOrder.MainId, preOrder.OrderSn)
|
||||||
removePosition(db, preOrder)
|
removePosition(db, preOrder)
|
||||||
|
|
||||||
futApi := FutRestApi{}
|
|
||||||
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
||||||
|
|
||||||
if apiUserInfo.Id > 0 {
|
if apiUserInfo.Id > 0 {
|
||||||
if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil {
|
mainOrder, _ := GetOrderById(db, preOrder.MainId)
|
||||||
logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err)
|
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)
|
logger.Errorf("处理主单加仓失败, 主单号:%s, 错误信息: %v", preOrder.MainId, err)
|
||||||
return
|
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)
|
logger.Errorf("取消主单相关订单失败, 订单号:%s, 错误信息: %v", preOrder.OrderSn, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -497,7 +496,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
|||||||
positionData := savePosition(db, preOrder)
|
positionData := savePosition(db, preOrder)
|
||||||
orderExt := models.LinePreOrderExt{}
|
orderExt := models.LinePreOrderExt{}
|
||||||
db.Model(&orderExt).Where("order_id =?", extOrderId).First(&orderExt)
|
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 {
|
for _, order := range orders {
|
||||||
@ -505,7 +504,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
|
|||||||
order.Price = price.String()
|
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 {
|
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)
|
mainOrders, err := getOpenPositionMainOrderId(db, preOrder.Id, preOrder.ApiId, preOrder.SymbolType, preOrder.ExchangeType, preOrder.Symbol, preOrder.Site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if len(mainIds) > 0 {
|
||||||
orderSns, err := getOpenOrderSns(db, mainIds)
|
orderSns, err := GetOpenOrderSns(db, mainIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量取消订单
|
|
||||||
orderArray := utility.SplitSlice(orderSns, 10)
|
orderArray := utility.SplitSlice(orderSns, 10)
|
||||||
futApi := FutRestApi{}
|
futApi := FutRestApi{}
|
||||||
for _, item := range orderArray {
|
for _, item := range orderArray {
|
||||||
err := futApi.CancelBatchFutOrder(apiUserInfo, preOrder.Symbol, item)
|
err := futApi.CancelBatchFutOrder(apiUserInfo, symbol, item)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("批量取消订单失败 orderSns:%v", item)
|
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
|
return nil
|
||||||
@ -633,7 +644,7 @@ func updateOrderQuantity(db *gorm.DB, order models.LinePreOrder, preOrder *model
|
|||||||
// order.Num = num.String()
|
// order.Num = num.String()
|
||||||
// } else
|
// } 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))
|
num = num.Mul(ext.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
|
||||||
order.Num = num.String()
|
order.Num = num.String()
|
||||||
|
|||||||
@ -308,8 +308,8 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
|||||||
return
|
return
|
||||||
} else if ok {
|
} else if ok {
|
||||||
defer lock.Release()
|
defer lock.Release()
|
||||||
takeOrder := DbModels.LinePreOrder{}
|
takeOrders := make([]DbModels.LinePreOrder, 0)
|
||||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type =1", reduceOrder.Pid).Find(&takeOrder).Error; err != nil {
|
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("查询止盈单失败")
|
log.Error("查询止盈单失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -320,18 +320,20 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
|
apiInfo, _ := GetApiInfo(reduceOrder.ApiId)
|
||||||
|
|
||||||
if apiInfo.Id == 0 {
|
if apiInfo.Id == 0 {
|
||||||
log.Error("现货减仓 查询api用户不存在")
|
log.Error("现货减仓 查询api用户不存在")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := CancelOpenOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
for _, takeOrder := range takeOrders {
|
||||||
|
err := CancelOpenOrderByOrderSnLoop(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("现货止盈撤单失败", err)
|
log.Error("现货止盈撤单失败", err)
|
||||||
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))
|
||||||
|
|
||||||
|
|||||||
@ -195,7 +195,7 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
|||||||
|
|
||||||
db.Model(&orderExt).Where("order_id =?", preOrder.Pid).Find(&orderExt)
|
db.Model(&orderExt).Where("order_id =?", preOrder.Pid).Find(&orderExt)
|
||||||
totalNum := getSpotPositionAvailableQuantity(db, apiUserInfo, preOrder, tradeSet) //getSpotTotalNum(apiUserInfo, preOrder, tradeSet)
|
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)
|
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 {
|
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
|
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)
|
logger.Errorf("获取下一个单失败 err:%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,12 +265,12 @@ func nextSpotReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal, tr
|
|||||||
//减仓配置 且减仓比例大于0小于100
|
//减仓配置 且减仓比例大于0小于100
|
||||||
if nextExt.Id > 0 && nextExt.AddType == 2 && nextExt.AddPositionVal.Cmp(decimal.Zero) > 0 && nextExt.AddPositionVal.Cmp(decimal.Zero) < 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))
|
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()
|
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)
|
processSpotReduceOrder(nextOrder)
|
||||||
@ -638,7 +638,7 @@ func parseOrderStatus(status interface{}, mapData map[string]interface{}) (int,
|
|||||||
return 5, reason
|
return 5, reason
|
||||||
case "FILLED": // 完全成交
|
case "FILLED": // 完全成交
|
||||||
return 6, reason
|
return 6, reason
|
||||||
case "CANCELED", "EXPIRED": // 取消
|
case "CANCELED", "EXPIRED", "EXPIRED_IN_MATCH": // 取消
|
||||||
return 4, reason
|
return 4, reason
|
||||||
default:
|
default:
|
||||||
return 0, reason
|
return 0, reason
|
||||||
@ -729,13 +729,17 @@ func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrd
|
|||||||
spotApi := SpotRestApi{}
|
spotApi := SpotRestApi{}
|
||||||
orderExt := models.LinePreOrderExt{}
|
orderExt := models.LinePreOrderExt{}
|
||||||
db.Model(&orderExt).Where("order_id =?", extOrderId).First(&orderExt)
|
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 {
|
for _, order := range orders {
|
||||||
order.Num = num.String()
|
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% 止盈数量
|
//主单第一次且止盈数量不是100% 止盈数量
|
||||||
order.Num = num.Mul(orderExt.TakeProfitNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
|
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
|
err = nil
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 300)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user