1、主单增加减仓、加仓状态
2、bug修复
This commit is contained in:
@ -625,6 +625,10 @@ func (e LinePreOrder) CalculateBreakEevenRatio(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.Symbol == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// data := dto.CalculateBreakEvenRatioResp{}
|
||||
_, err = s.GenerateOrder(&req)
|
||||
if err != nil {
|
||||
|
||||
@ -183,7 +183,7 @@ func (s *LinePreOrderDeleteReq) GetId() interface{} {
|
||||
type LineAddPreOrderReq struct {
|
||||
ExchangeType string `json:"exchange_type" vd:"len($)>0"` //交易所类型
|
||||
OrderType int `json:"order_type"` //订单类型
|
||||
Symbol string `json:"symbol" vd:"len($)>0"` //交易对
|
||||
Symbol string `json:"symbol"` //交易对
|
||||
ApiUserId string `json:"api_id" ` //下单用户
|
||||
Site string `json:"site" ` //购买方向
|
||||
BuyPrice string `json:"buy_price" vd:"$>0"` //购买金额 U
|
||||
@ -341,15 +341,15 @@ func (req LineBatchAddPreOrderReq) CheckParams() error {
|
||||
return errors.New("加仓单下跌价格不能为空")
|
||||
}
|
||||
|
||||
if v.ReduceNumRatio.IsZero() || v.ReduceNumRatio.Cmp(decimal.Zero) > 0 {
|
||||
if v.ReduceNumRatio.IsZero() || v.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) > 0 {
|
||||
return errors.New("减仓数量不正确")
|
||||
}
|
||||
|
||||
if v.ReducePriceRatio.IsZero() || v.ReducePriceRatio.Cmp(decimal.Zero) > 0 {
|
||||
if v.ReducePriceRatio.IsZero() || v.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) > 0 {
|
||||
return errors.New("减仓下跌价格不正确")
|
||||
}
|
||||
|
||||
if v.ReduceTakeProfitRatio.IsZero() || v.ReduceTakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
||||
if v.ReduceTakeProfitRatio.IsZero() || v.ReduceTakeProfitRatio.Cmp(decimal.NewFromInt(100)) > 0 {
|
||||
return errors.New("减仓后止盈价格不正确")
|
||||
}
|
||||
}
|
||||
@ -372,7 +372,7 @@ type LeverReq struct {
|
||||
Leverage int `json:"leverage"`
|
||||
GroupId int `json:"group_id"`
|
||||
IsAll int `json:"is_all"` // 1= 全部 0=不是全部
|
||||
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
||||
ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
|
||||
}
|
||||
|
||||
func (c LeverReq) CheckParams() error {
|
||||
@ -391,7 +391,7 @@ type MarginTypeReq struct {
|
||||
MarginType string `json:"margin_type"` //全仓 CROSSED 逐仓 ISOLATED
|
||||
GroupId int `json:"group_id"` // 交易对组id
|
||||
IsAll int `json:"is_all"` // 1= 全部 0=不是全部
|
||||
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
||||
ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
|
||||
}
|
||||
|
||||
type CancelOpenOrderReq struct {
|
||||
@ -399,7 +399,7 @@ type CancelOpenOrderReq struct {
|
||||
Symbol string `json:"symbol"`
|
||||
OrderSn string `json:"order_sn"`
|
||||
OrderType int `json:"order_type"`
|
||||
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
||||
ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
|
||||
}
|
||||
|
||||
type GetChildOrderReq struct {
|
||||
|
||||
@ -323,7 +323,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
||||
|
||||
//获取交易对
|
||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
|
||||
orderCount := e.CheckRepeatOrder(req.OrderType, id, req.Site, tradeSet.Coin)
|
||||
orderCount := e.CheckRepeatOrder(req.SymbolType, id, req.Site, tradeSet.Coin)
|
||||
if orderCount > 0 {
|
||||
*errs = append(*errs, fmt.Errorf("api_id:%s 获取交易对:%s 该交易对已存在,请勿重复下单", id, req.Symbol))
|
||||
continue
|
||||
@ -571,6 +571,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
|
||||
stopOrder.MainId = AddOrder.Id
|
||||
stopOrder.OrderType = 4
|
||||
stopOrder.Status = 0
|
||||
stopOrder.BuyPrice = "0"
|
||||
stopOrder.Rate = req.ReducePriceRatio.String()
|
||||
stopNum := utility.StrToDecimal(AddOrder.Num).Mul(req.ReduceNumRatio.Div(decimal.NewFromInt(100)).Truncate(4))
|
||||
stopOrder.Num = stopNum.Truncate(int32(tradeSet.AmountDigit)).String()
|
||||
@ -807,9 +808,9 @@ func makeReduceTakeAndStoploss(parentOrder *models.LinePreOrder, ext models.Line
|
||||
}
|
||||
|
||||
// CheckRepeatOrder 检查重复下单 检查基础货币
|
||||
func (e *LinePreOrder) CheckRepeatOrder(orderType int, apiUserId, site, baseCoin string) int64 {
|
||||
func (e *LinePreOrder) CheckRepeatOrder(symbolType int, apiUserId, site, baseCoin string) int64 {
|
||||
var count int64
|
||||
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND pid=0 AND symbol like ? AND order_type = ? AND site = ? AND `status` IN (1,5,6)", apiUserId, baseCoin+"%", orderType, site).Count(&count)
|
||||
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND pid=0 AND symbol like ? AND symbol_type = ? AND site = ? AND `status` IN (1,5,6)", apiUserId, baseCoin+"%", symbolType, site).Count(&count)
|
||||
return count
|
||||
}
|
||||
|
||||
@ -897,6 +898,7 @@ func (e *LinePreOrder) AddBatchPreOrder(batchReq *dto.LineBatchAddPreOrderReq, p
|
||||
req.Price = batchReq.Price
|
||||
req.Profit = batchReq.Profit
|
||||
req.Ext = batchReq.Ext
|
||||
req.SymbolType = batchReq.SymbolType
|
||||
// req.StopPrice = batchReq.StopPrice
|
||||
req.ReducePriceRatio = batchReq.ReducePriceRatio
|
||||
req.PriceType = batchReq.PriceType
|
||||
@ -1176,6 +1178,8 @@ func (e *LinePreOrder) ClearAll() error {
|
||||
"stop_loss_markt",
|
||||
"_PreSpotOrderList_",
|
||||
"_PreFutOrderList_",
|
||||
"spot_reduce_list",
|
||||
"futures_reduce_list",
|
||||
}
|
||||
err = helper.DefaultRedis.DeleteKeysByPrefix(prefixs...)
|
||||
if err != nil {
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/shopspring/decimal"
|
||||
"gorm.io/driver/mysql"
|
||||
|
||||
"github.com/go-admin-team/go-admin-core/sdk"
|
||||
@ -225,19 +226,28 @@ func (t LimitOrderTimeoutDuration) ReSpotOrderPlace(db *gorm.DB, order models.Li
|
||||
logger.Error(fmt.Sprintf("取消现货委托失败:order_sn:%s err:%+v", order.OrderSn, err))
|
||||
return err
|
||||
} else {
|
||||
var remainingQuantity decimal.Decimal
|
||||
spotOrder, err := spotApi.GetOrderByOrderSnLoop(order.Symbol, order.OrderSn, apiUserinfo, 4)
|
||||
|
||||
if err == nil {
|
||||
origQty := utility.StrToDecimal(spotOrder.OrigQuoteOrderQty)
|
||||
excuteQty := utility.StrToDecimal(spotOrder.ExecutedQty)
|
||||
remainingQuantity = origQty.Sub(excuteQty).Abs()
|
||||
}
|
||||
|
||||
if remainingQuantity.Cmp(decimal.Zero) <= 0 {
|
||||
logger.Errorf("剩余数量为0 无需重新下市价单mainid:%v", order.MainId)
|
||||
return nil
|
||||
}
|
||||
|
||||
tradeSet, _ := binanceservice.GetTradeSet(order.Symbol, 0)
|
||||
newClientOrderId := snowflakehelper.GetOrderId()
|
||||
|
||||
order.Num = remainingQuantity.Truncate(int32(tradeSet.AmountDigit)).String()
|
||||
order.Desc = fmt.Sprintf("取消限价单,重下市价单源订单号:%s ", order.OrderSn)
|
||||
order.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
|
||||
order.MainOrderType = "MARKET"
|
||||
// var newOrder models.LinePreOrder
|
||||
// copier.Copy(&newOrder, order)
|
||||
// newOrder.Id = 0
|
||||
// newOrder.OrderSn = utility.Int64ToString(newClientOrderId)
|
||||
// newOrder.CreatedAt = time.Now()
|
||||
// newOrder.MainOrderType = "MARKET"
|
||||
// err = db.Model(&models.LinePreOrder{}).Create(&newOrder).Error
|
||||
err := db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn, "main_order_type": order.MainOrderType}).Error
|
||||
err = db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn, "main_order_type": order.MainOrderType}).Error
|
||||
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("生成新市价单失败 err:%+v", err))
|
||||
@ -251,7 +261,7 @@ func (t LimitOrderTimeoutDuration) ReSpotOrderPlace(db *gorm.DB, order models.Li
|
||||
TimeInForce: "GTC",
|
||||
Price: utility.StringToDecimal(order.Price),
|
||||
StopPrice: utility.StrToDecimal(order.Price),
|
||||
Quantity: utility.StringToDecimal(order.Num),
|
||||
Quantity: remainingQuantity,
|
||||
NewClientOrderId: utility.Int64ToString(newClientOrderId),
|
||||
}
|
||||
if err := spotApi.OrderPlace(db, params); err != nil {
|
||||
@ -281,8 +291,24 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin
|
||||
logger.Error(fmt.Sprintf("取消现货委托失败:order_sn:%s err:%+v", order.OrderSn, err))
|
||||
return err
|
||||
} else {
|
||||
var remainingQuantity decimal.Decimal
|
||||
spotOrder, err := futApi.GetOrderByOrderSnLoop(order.Symbol, order.OrderSn, apiUserinfo, 4)
|
||||
|
||||
if err == nil {
|
||||
origQty := utility.StrToDecimal(spotOrder.OrigQty)
|
||||
excuteQty := utility.StrToDecimal(spotOrder.ExecutedQty)
|
||||
remainingQuantity = origQty.Sub(excuteQty).Abs()
|
||||
}
|
||||
|
||||
if remainingQuantity.Cmp(decimal.Zero) <= 0 {
|
||||
logger.Errorf("剩余数量为0 无需重新下市价单mainid:%v", order.MainId)
|
||||
return nil
|
||||
}
|
||||
|
||||
tradeSet, _ := binanceservice.GetTradeSet(order.Symbol, 0)
|
||||
|
||||
newClientOrderId := snowflakehelper.GetOrderId()
|
||||
orderType := "MARKET"
|
||||
order.Num = remainingQuantity.Truncate(int32(tradeSet.AmountDigit)).String()
|
||||
order.Desc = fmt.Sprintf("取消限价单,重下市价单 源订单号:%s", order.OrderSn)
|
||||
order.OrderSn = utility.Int64ToString(newClientOrderId)
|
||||
|
||||
@ -294,31 +320,32 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin
|
||||
// newOrder.MainOrderType = "MARKET"
|
||||
// err = db.Model(&models.LinePreOrder{}).Create(&newOrder).Error
|
||||
|
||||
var positionSide string
|
||||
|
||||
if order.Site == "BUY" {
|
||||
positionSide = "SHORT"
|
||||
} else {
|
||||
positionSide = "LONG"
|
||||
}
|
||||
err = db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn}).Error
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("生成合约新市价单失败 err:%+v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
if order.OrderType == 4 {
|
||||
orderType = "STOP_MARKET"
|
||||
}
|
||||
// params := binanceservice.FutOrderPlace{
|
||||
// ApiId: order.ApiId,
|
||||
// Symbol: order.Symbol,
|
||||
// Side: order.Site,
|
||||
// Quantity: remainingQuantity,
|
||||
// Price: utility.StringToDecimal(order.Price),
|
||||
// SideType: "MARKET",
|
||||
// OpenOrder: 0,
|
||||
// OrderType: "MARKET",
|
||||
// NewClientOrderId: utility.Int64ToString(newClientOrderId),
|
||||
// }
|
||||
|
||||
params := binanceservice.FutOrderPlace{
|
||||
ApiId: order.ApiId,
|
||||
Symbol: order.Symbol,
|
||||
Side: order.Site,
|
||||
Quantity: utility.StringToDecimal(order.Num),
|
||||
Price: utility.StringToDecimal(order.Price),
|
||||
SideType: "MARKET",
|
||||
OpenOrder: 0,
|
||||
StopPrice: utility.StringToDecimal(order.Price),
|
||||
Profit: utility.StringToDecimal(order.Price),
|
||||
OrderType: orderType,
|
||||
NewClientOrderId: utility.Int64ToString(newClientOrderId),
|
||||
}
|
||||
|
||||
if err := futApi.OrderPlace(db, params); err != nil {
|
||||
if err := futApi.ClosePositionLoop(order.Symbol, order.OrderSn, remainingQuantity, order.Site, positionSide, apiUserinfo, "MARKET", "0", decimal.Zero, 3); err != nil {
|
||||
logger.Error(fmt.Sprintf("重新下合约市价单失败 err:%+v", err))
|
||||
err := db.Model(&order).Updates(map[string]interface{}{"status": "2", "desc": order.Desc + " err:" + err.Error()}).Error
|
||||
if err != nil {
|
||||
|
||||
@ -22,3 +22,55 @@ type StoplossMarket struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Type int `json:"type" comment:"对冲类型 1-现货 2-合约"`
|
||||
}
|
||||
|
||||
type BinanceSpotOrder struct {
|
||||
Symbol string `json:"symbol"` // 交易对
|
||||
OrderID int64 `json:"orderId"` // 系统的订单ID
|
||||
OrderListID int64 `json:"orderListId"` // 除非此单是订单列表的一部分, 否则此值为 -1
|
||||
ClientOrderID string `json:"clientOrderId"` // 客户自己设置的ID
|
||||
Price string `json:"price"` // 订单价格
|
||||
OrigQty string `json:"origQty"` // 用户设置的原始订单数量
|
||||
ExecutedQty string `json:"executedQty"` // 交易的订单数量
|
||||
OrigQuoteOrderQty string `json:"origQuoteOrderQty"` // 原始的交易金额
|
||||
CummulativeQuoteQty string `json:"cummulativeQuoteQty"` // 累计交易的金额
|
||||
Status string `json:"status"` // 订单状态
|
||||
TimeInForce string `json:"timeInForce"` // 订单的时效方式
|
||||
Type string `json:"type"` // 订单类型,比如市价单,现价单等
|
||||
Side string `json:"side"` // 订单方向,买还是卖
|
||||
StopPrice string `json:"stopPrice"` // 止损价格
|
||||
IcebergQty string `json:"icebergQty"` // 冰山数量
|
||||
Time int64 `json:"time"` // 订单时间
|
||||
UpdateTime int64 `json:"updateTime"` // 最后更新时间
|
||||
IsWorking bool `json:"isWorking"` // 订单是否出现在orderbook中
|
||||
WorkingTime int64 `json:"workingTime"` // 订单添加到 order book 的时间
|
||||
SelfTradePreventionMode string `json:"selfTradePreventionMode"` // 如何处理自我交易模式
|
||||
}
|
||||
|
||||
type BinanceFutureOrder struct {
|
||||
AvgPrice string `json:"avgPrice"` // 平均成交价
|
||||
ClientOrderID string `json:"clientOrderId"` // 用户自定义的订单号
|
||||
CumQuote string `json:"cumQuote"` // 成交金额
|
||||
ExecutedQty string `json:"executedQty"` // 成交量
|
||||
OrderID int64 `json:"orderId"` // 系统订单号
|
||||
OrigQty string `json:"origQty"` // 原始委托数量
|
||||
OrigType string `json:"origType"` // 触发前订单类型
|
||||
Price string `json:"price"` // 委托价格
|
||||
ReduceOnly bool `json:"reduceOnly"` // 是否仅减仓
|
||||
Side string `json:"side"` // 买卖方向
|
||||
PositionSide string `json:"positionSide"` // 持仓方向
|
||||
Status string `json:"status"` // 订单状态
|
||||
StopPrice string `json:"stopPrice"` // 触发价,对`TRAILING_STOP_MARKET`无效
|
||||
ClosePosition bool `json:"closePosition"` // 是否条件全平仓
|
||||
Symbol string `json:"symbol"` // 交易对
|
||||
Time int64 `json:"time"` // 订单时间
|
||||
TimeInForce string `json:"timeInForce"` // 有效方法
|
||||
Type string `json:"type"` // 订单类型
|
||||
ActivatePrice string `json:"activatePrice"` // 跟踪止损激活价格, 仅`TRAILING_STOP_MARKET` 订单返回此字段
|
||||
PriceRate string `json:"priceRate"` // 跟踪止损回调比例, 仅`TRAILING_STOP_MARKET` 订单返回此字段
|
||||
UpdateTime int64 `json:"updateTime"` // 更新时间
|
||||
WorkingType string `json:"workingType"` // 条件价格触发类型
|
||||
PriceProtect bool `json:"priceProtect"` // 是否开启条件单触发保护
|
||||
PriceMatch string `json:"priceMatch"` // 盘口价格下单模式
|
||||
SelfTradePreventionMode string `json:"selfTradePreventionMode"` // 订单自成交保护模式
|
||||
GoodTillDate int64 `json:"goodTillDate"` // 订单TIF为GTD时的自动取消时间
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"go-admin/common/global"
|
||||
"go-admin/common/helper"
|
||||
"go-admin/models"
|
||||
"go-admin/models/binancedto"
|
||||
"go-admin/models/spot"
|
||||
"go-admin/pkg/httputils"
|
||||
"go-admin/pkg/utility"
|
||||
@ -529,3 +530,61 @@ func (e SpotRestApi) GetSpotSymbolLastPrice(targetSymbol string) (lastPrice deci
|
||||
// }
|
||||
return lastPrice
|
||||
}
|
||||
|
||||
func (e SpotRestApi) GetOrderByOrderSn(symbol, orderSn string, apiUserInfo DbModels.LineApiUser) (order binancedto.BinanceSpotOrder, err error) {
|
||||
result := binancedto.BinanceSpotOrder{}
|
||||
params := map[string]string{
|
||||
"symbol": symbol,
|
||||
"origClientOrderId": orderSn,
|
||||
}
|
||||
|
||||
client := GetClient(&apiUserInfo)
|
||||
|
||||
body, code, err := client.SendSpotAuth("/api/v3/order", "GET", params)
|
||||
if err != nil || code != 200 {
|
||||
log.Error("查询现货委托 参数:", params)
|
||||
log.Error("查询现货委托失败 code:", code)
|
||||
log.Error("查询现货委托失败 err:", err)
|
||||
dataMap := make(map[string]interface{})
|
||||
if err.Error() != "" {
|
||||
if err := sonic.Unmarshal([]byte(err.Error()), &dataMap); err != nil {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
code, ok := dataMap["code"]
|
||||
if ok {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%s", apiUserInfo.Id, symbol, ErrorMaps[code.(float64)])
|
||||
}
|
||||
if strings.Contains(err.Error(), "Unknown order sent.") {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, ErrorMaps[-2011])
|
||||
}
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error())
|
||||
}
|
||||
|
||||
sonic.Unmarshal(body, &result)
|
||||
|
||||
if result.OrderID == 0 {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, "订单不存在")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
/*
|
||||
查询现货委托
|
||||
*/
|
||||
func (e SpotRestApi) GetOrderByOrderSnLoop(symbol, ordersn string, apiUserInfo DbModels.LineApiUser, retryCount int) (order binancedto.BinanceSpotOrder, err error) {
|
||||
result, err := e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo)
|
||||
|
||||
if err != nil {
|
||||
for x := 1; x < retryCount; x++ {
|
||||
result, err = e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
@ -215,3 +215,35 @@ func TestFutOrderPlace(t *testing.T) {
|
||||
fmt.Println("err:", err)
|
||||
|
||||
}
|
||||
|
||||
func TestFutureQueryOrder(t *testing.T) {
|
||||
futureApi := FutRestApi{}
|
||||
// dsn := "root:root@tcp(192.168.1.12:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||
// db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
|
||||
helper.InitDefaultRedis("192.168.1.12:6379", "", 2)
|
||||
apiUserInfo, _ := GetApiInfo(49)
|
||||
order, err := futureApi.GetOrderByOrderSnLoop("TRUMPUSDT", "380211842506555392", apiUserInfo, 3)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("err:", err)
|
||||
}
|
||||
|
||||
fmt.Println("future order:", order)
|
||||
}
|
||||
|
||||
func TestSpotQueryOrder(t *testing.T) {
|
||||
spotApi := SpotRestApi{}
|
||||
// dsn := "root:root@tcp(192.168.1.12:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||
// db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
|
||||
helper.InitDefaultRedis("192.168.1.12:6379", "", 2)
|
||||
apiUserInfo, _ := GetApiInfo(49)
|
||||
order, err := spotApi.GetOrderByOrderSnLoop("ADAUSDT", "380577197825458177", apiUserInfo, 3)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("err:", err)
|
||||
}
|
||||
|
||||
fmt.Println("spot order:", order)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"go-admin/common/global"
|
||||
"go-admin/common/helper"
|
||||
"go-admin/models"
|
||||
"go-admin/models/binancedto"
|
||||
"go-admin/models/futuresdto"
|
||||
"go-admin/pkg/httputils"
|
||||
"go-admin/pkg/utility"
|
||||
@ -936,3 +937,66 @@ func (e FutRestApi) GetFutSymbolLastPrice(targetSymbol string) (lastPrice decima
|
||||
// }
|
||||
return lastPrice
|
||||
}
|
||||
|
||||
func (e FutRestApi) GetOrderByOrderSn(symbol, orderSn string, apiUserInfo DbModels.LineApiUser) (order binancedto.BinanceFutureOrder, err error) {
|
||||
result := binancedto.BinanceFutureOrder{}
|
||||
params := map[string]string{
|
||||
"symbol": symbol,
|
||||
"origClientOrderId": orderSn,
|
||||
}
|
||||
|
||||
client := GetClient(&apiUserInfo)
|
||||
|
||||
body, code, err := client.SendFuturesAuth("/fapi/v1/order", "GET", params)
|
||||
if err != nil || code != 200 {
|
||||
log.Error("查询合约委托 参数:", params)
|
||||
log.Error("查询合约委托失败 code:", code)
|
||||
log.Error("查询合约委托失败 err:", err)
|
||||
dataMap := make(map[string]interface{})
|
||||
if err.Error() != "" {
|
||||
if err := sonic.Unmarshal([]byte(err.Error()), &dataMap); err != nil {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
code, ok := dataMap["code"]
|
||||
if ok {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%s", apiUserInfo.Id, symbol, ErrorMaps[code.(float64)])
|
||||
}
|
||||
if strings.Contains(err.Error(), "Unknown order sent.") {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, ErrorMaps[-2011])
|
||||
}
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error())
|
||||
}
|
||||
|
||||
sonic.Unmarshal(body, &result)
|
||||
|
||||
if result.OrderID == 0 {
|
||||
return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, "订单不存在")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
/*
|
||||
查询现货委托
|
||||
*/
|
||||
// 根据订单号获取订单信息,如果获取失败,则进行重试
|
||||
func (e FutRestApi) GetOrderByOrderSnLoop(symbol, ordersn string, apiUserInfo DbModels.LineApiUser, retryCount int) (order binancedto.BinanceFutureOrder, err error) {
|
||||
result, err := e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo)
|
||||
// 如果获取失败,则进行重试
|
||||
|
||||
if err != nil {
|
||||
// 调用GetOrderByOrderSn方法获取订单信息
|
||||
for x := 1; x < retryCount; x++ {
|
||||
// 如果获取成功,则跳出循环
|
||||
result, err = e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 返回订单信息和错误信息
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ func futTriggerOrder(db *gorm.DB, v *dto.PreOrderRedisList, item string, futApi
|
||||
}
|
||||
|
||||
//判断是否有已触发交易对
|
||||
count, _ := GetSymbolTriggerCount(db, v.Symbol, 2)
|
||||
count, _ := GetSymbolTriggerCount(db, v.Symbol, v.ApiId, 2)
|
||||
|
||||
if count > 0 {
|
||||
return
|
||||
@ -316,7 +316,7 @@ func FutAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, futApi
|
||||
defer lock.Release()
|
||||
|
||||
setting, _ := GetSystemSetting(db)
|
||||
tradeSet, _ := GetTradeSet(v.Symbol, 0)
|
||||
tradeSet, _ := GetTradeSet(v.Symbol, 1)
|
||||
|
||||
if tradeSet.LastPrice == "" {
|
||||
log.Errorf("合约加仓触发 查询交易对失败 交易对:%s ordersn:%s", v.Symbol, v.OrderSn)
|
||||
|
||||
@ -111,16 +111,20 @@ func handleFutOrderByType(db *gorm.DB, preOrder *DbModels.LinePreOrder, orderSta
|
||||
|
||||
// 减仓回调
|
||||
func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id =? ", preOrder.MainId).Update("reduce_status", 1).Error; err != nil {
|
||||
logger.Errorf("handleReduceFilled 更新主单减仓状态失败,订单号:%s", preOrder.OrderSn)
|
||||
}
|
||||
|
||||
apiUserInfo, _ := GetApiInfo(preOrder.ApiId)
|
||||
if apiUserInfo.Id == 0 {
|
||||
logger.Errorf("handleMainReduceFilled 获取api信息失败,订单号:%s", preOrder.OrderSn)
|
||||
logger.Errorf("handleReduceFilled 获取api信息失败,订单号:%s", preOrder.OrderSn)
|
||||
return
|
||||
}
|
||||
|
||||
tradeSet, err := GetTradeSet(preOrder.Symbol, 1)
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("handleMainReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn)
|
||||
logger.Errorf("handleReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn)
|
||||
return
|
||||
}
|
||||
|
||||
@ -128,7 +132,7 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
parentOrder, err := GetOrderById(db, preOrder.Pid)
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("handleMainReduceFilled 获取主单失败,订单号:%s", preOrder.OrderSn)
|
||||
logger.Errorf("handleReduceFilled 获取主单失败,订单号:%s", preOrder.OrderSn)
|
||||
return
|
||||
}
|
||||
parentPrice := utility.StrToDecimal(parentOrder.Price)
|
||||
@ -353,7 +357,7 @@ func removeFutLossAndAddPosition(preOrder *DbModels.LinePreOrder) {
|
||||
// preOrder 主单
|
||||
func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
|
||||
orders := []models.LinePreOrder{}
|
||||
tradeSet, _ := GetTradeSet(preOrder.Symbol, 0)
|
||||
tradeSet, _ := GetTradeSet(preOrder.Symbol, 1)
|
||||
|
||||
if tradeSet.Coin == "" {
|
||||
logger.Error("获取交易对失败")
|
||||
@ -366,6 +370,10 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
|
||||
}
|
||||
|
||||
if preOrder.OrderCategory == 3 {
|
||||
if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id = ?", preOrder.MainId).Update("add_position_status", 1).Error; err != nil {
|
||||
logger.Errorf("更新主单加仓状态失败, 主单号:%s, 错误信息:%v", preOrder.MainId, err)
|
||||
}
|
||||
|
||||
if err := cancelSymbolTakeAndStop(db, preOrder.MainId, preOrder.SymbolType); err != nil {
|
||||
logger.Errorf("取消止盈止损订单失败 orderSn:%s err:%v", preOrder.OrderSn, err)
|
||||
}
|
||||
|
||||
@ -144,10 +144,10 @@ func GetSymbolTakeAndStop(db *gorm.DB, mainId int, symbolType int) ([]models.Lin
|
||||
// 获取交易对触发数量
|
||||
// symbol 交易对
|
||||
// symbolType 交易对类型 1-现货 2-合约
|
||||
func GetSymbolTriggerCount(db *gorm.DB, symbol string, symbolType int) (int64, error) {
|
||||
func GetSymbolTriggerCount(db *gorm.DB, symbol string, apiId, symbolType int) (int64, error) {
|
||||
var count int64
|
||||
|
||||
if err := db.Model(&models.LinePreOrder{}).Where("symbol =? AND symbol_type =? AND order_type =0 AND pid=0 AND status IN (1,5,6)", symbol, symbolType).Count(&count).Error; err != nil {
|
||||
if err := db.Model(&models.LinePreOrder{}).Where("symbol =? AND api_id =? AND symbol_type =? AND order_type =0 AND pid=0 AND status IN (1,5,6)", symbol, apiId, symbolType).Count(&count).Error; err != nil {
|
||||
logger.Error("查询交易对触发数量失败:", err)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S
|
||||
}
|
||||
|
||||
//判断是否有已触发交易对
|
||||
count, _ := GetSymbolTriggerCount(db, v.Symbol, 2)
|
||||
count, _ := GetSymbolTriggerCount(db, v.Symbol, v.ApiId, 1)
|
||||
|
||||
if count > 0 {
|
||||
return
|
||||
|
||||
@ -158,6 +158,10 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
orders := make([]models.LinePreOrder, 0)
|
||||
rate := utility.StringAsFloat(preOrder.Rate)
|
||||
|
||||
if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id =? ", preOrder.MainId).Update("reduce_status", 1).Error; err != nil {
|
||||
logger.Errorf("handleMainReduceFilled 更新主单减仓状态失败,订单号:%s", preOrder.OrderSn)
|
||||
}
|
||||
|
||||
// 100%减仓 终止流程
|
||||
if rate >= 100 {
|
||||
removeSpotLossAndAddPosition(preOrder)
|
||||
@ -436,6 +440,12 @@ func removeSpotLossAndAddPosition(preOrder *DbModels.LinePreOrder) {
|
||||
|
||||
// 主单成交
|
||||
func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
|
||||
if preOrder.OrderCategory == 3 {
|
||||
if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id = ?", preOrder.MainId).Update("add_position_status", 1).Error; err != nil {
|
||||
logger.Errorf("更新主单加仓状态失败, 主单号:%s, 错误信息:%v", preOrder.MainId, err)
|
||||
}
|
||||
}
|
||||
|
||||
processTakeProfitAndStopLossOrders(db, preOrder)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user