1、重写
This commit is contained in:
@ -14,13 +14,9 @@ import (
|
||||
"go-admin/models/spot"
|
||||
"go-admin/pkg/httputils"
|
||||
"go-admin/pkg/utility"
|
||||
"go-admin/pkg/utility/snowflakehelper"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/shopspring/decimal"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@ -244,14 +240,6 @@ func (e SpotRestApi) OrderPlace(orm *gorm.DB, params OrderPlacementService) erro
|
||||
if err := sonic.Unmarshal(resp, &dataMap); err != nil {
|
||||
return fmt.Errorf("api_id:%d 交易对:%s 下单失败:%+v", apiUserInfo.Id, params.Symbol, err.Error())
|
||||
}
|
||||
//code, ok := dataMap["code"]
|
||||
//if !ok {
|
||||
// return fmt.Errorf("api_id:%d 交易对:%s 下单失败:%s", apiUserInfo.Id, params.Symbol, dataMap["message"])
|
||||
//
|
||||
//}
|
||||
//if code.(float64) != 200 {
|
||||
// return fmt.Errorf("api_id:%d 交易对:%s 下单失败:%s", apiUserInfo.Id, params.Symbol, dataMap["message"])
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -341,48 +329,6 @@ func (e SpotRestApi) CancelOpenOrderByOrderSn(apiUserInfo DbModels.LineApiUser,
|
||||
return nil
|
||||
}
|
||||
|
||||
// CalcEntryCashPriceByOrder 计算现货主单均价
|
||||
func CalcEntryCashPriceByOrder(orderInfo *DbModels.LinePreOrder, orm *gorm.DB) (EntryPriceResult, error) {
|
||||
//找到主单成交的记录
|
||||
var id int
|
||||
if orderInfo.Pid > 0 {
|
||||
id = orderInfo.Pid
|
||||
} else {
|
||||
id = orderInfo.Id
|
||||
}
|
||||
|
||||
orderLists := make([]DbModels.LinePreOrder, 0)
|
||||
orm.Model(&DbModels.LinePreOrder{}).Where(" symbol = ? AND site = 'BUY' AND order_type in ('1','8') AND status ='9' AND (id = ? OR pid = ?)", orderInfo.Symbol, id, id).Find(&orderLists)
|
||||
|
||||
var (
|
||||
totalNum decimal.Decimal //总成交数量
|
||||
totalMoney decimal.Decimal //总金额
|
||||
entryPrice decimal.Decimal //均价
|
||||
initPrice decimal.Decimal //主单下单价格
|
||||
firstId int //主单id
|
||||
)
|
||||
for _, list := range orderLists {
|
||||
num, _ := decimal.NewFromString(list.Num)
|
||||
totalNum = totalNum.Add(num)
|
||||
price, _ := decimal.NewFromString(list.Price)
|
||||
totalMoney = totalMoney.Add(num.Mul(price))
|
||||
if list.OrderType == "1" {
|
||||
firstId = list.Id
|
||||
initPrice, _ = decimal.NewFromString(list.Price)
|
||||
}
|
||||
}
|
||||
if totalNum.GreaterThan(decimal.Zero) {
|
||||
entryPrice = totalMoney.Div(totalNum)
|
||||
}
|
||||
return EntryPriceResult{
|
||||
TotalNum: totalNum,
|
||||
EntryPrice: entryPrice,
|
||||
FirstPrice: initPrice,
|
||||
FirstId: firstId,
|
||||
TotalMoney: totalMoney,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ClosePosition 平仓
|
||||
// symbol 交易对
|
||||
// orderSn 平仓单号
|
||||
@ -459,135 +405,15 @@ func GetClient(apiUserInfo *DbModels.LineApiUser) *helper.BinanceClient {
|
||||
return client
|
||||
}
|
||||
|
||||
/*
|
||||
重下止盈单
|
||||
*/
|
||||
func (e SpotRestApi) reTakeOrder(parentOrderInfo DbModels.LinePreOrder, orm *gorm.DB) {
|
||||
price, _ := decimal.NewFromString(parentOrderInfo.Price)
|
||||
num, _ := decimal.NewFromString(parentOrderInfo.Num)
|
||||
parentId := parentOrderInfo.Id
|
||||
|
||||
if parentOrderInfo.Pid > 0 {
|
||||
parentId = parentOrderInfo.Pid
|
||||
}
|
||||
|
||||
var takePrice decimal.Decimal
|
||||
holdeAKey := fmt.Sprintf(rediskey.HoldeA, parentId)
|
||||
holdeAVal, _ := helper.DefaultRedis.GetString(holdeAKey)
|
||||
holdeA := HoldeData{}
|
||||
|
||||
if holdeAVal != "" {
|
||||
sonic.Unmarshal([]byte(holdeAVal), &holdeA)
|
||||
}
|
||||
|
||||
//查询持仓失败
|
||||
if holdeA.Id == 0 {
|
||||
log.Error("查询A账号持仓失败")
|
||||
return
|
||||
}
|
||||
|
||||
//加仓次数大于0 就需要使用均价
|
||||
if holdeA.PositionIncrementCount > 0 {
|
||||
price = holdeA.AveragePrice
|
||||
num = holdeA.TotalQuantity
|
||||
}
|
||||
|
||||
if parentOrderInfo.Site == "BUY" {
|
||||
takePrice = price.Mul(decimal.NewFromInt(100).Add(parentOrderInfo.ProfitRate)).Div(decimal.NewFromInt(100))
|
||||
} else {
|
||||
takePrice = price.Mul(decimal.NewFromInt(100).Sub(parentOrderInfo.ProfitRate)).Div(decimal.NewFromInt(100))
|
||||
}
|
||||
var takeOrder, oldTakeOrder DbModels.LinePreOrder
|
||||
|
||||
if err := orm.Model(&oldTakeOrder).Where("pid= ? AND order_type ='5'", parentId).First(&oldTakeOrder).Error; err != nil {
|
||||
log.Error("查询止盈单失败")
|
||||
return
|
||||
}
|
||||
|
||||
tradeset, _ := GetTradeSet(oldTakeOrder.Symbol, 0)
|
||||
|
||||
if tradeset.Coin == "" {
|
||||
log.Error("查询交易对失败")
|
||||
return
|
||||
}
|
||||
copier.Copy(&takeOrder, &oldTakeOrder)
|
||||
|
||||
takeOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
|
||||
takeOrder.Price = takePrice.Truncate(int32(tradeset.PriceDigit)).String()
|
||||
takeOrder.Num = num.Mul(decimal.NewFromFloat(0.995)).Truncate(int32(tradeset.AmountDigit)).String()
|
||||
takeOrder.Desc = ""
|
||||
takeOrder.Status = 0
|
||||
takeOrder.Id = 0
|
||||
|
||||
if err := orm.Create(&takeOrder).Error; err != nil {
|
||||
log.Error("创建新止盈单失败")
|
||||
return
|
||||
}
|
||||
|
||||
params := OrderPlacementService{
|
||||
ApiId: parentOrderInfo.ApiId,
|
||||
Symbol: parentOrderInfo.Symbol,
|
||||
Price: utility.StrToDecimal(takeOrder.Price),
|
||||
Quantity: utility.StringToDecimal(takeOrder.Num),
|
||||
Side: "SELL",
|
||||
Type: "TAKE_PROFIT_LIMIT",
|
||||
TimeInForce: "GTC",
|
||||
StopPrice: utility.StrToDecimal(takeOrder.Price),
|
||||
NewClientOrderId: takeOrder.OrderSn,
|
||||
}
|
||||
|
||||
apiUserInfo, _ := GetApiInfo(parentOrderInfo.ApiId)
|
||||
|
||||
if apiUserInfo.Id == 0 {
|
||||
log.Error("获取用户api失败")
|
||||
return
|
||||
}
|
||||
|
||||
if err := CancelSpotOrder(parentOrderInfo.Symbol, &apiUserInfo, "SELL"); err != nil {
|
||||
log.Error("取消旧止盈失败 err:", err)
|
||||
} else {
|
||||
if err := orm.Model(&DbModels.LinePreOrder{}).Where("pid = ? AND order_type =5 AND status in ('0','1','5') AND order_sn !=?", parentId, takeOrder.OrderSn).Update("status", "4").Error; err != nil {
|
||||
log.Error("更新旧止盈单取消状态失败 err:", err)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
for x := 1; x <= 4; x++ {
|
||||
err = e.OrderPlace(orm, params)
|
||||
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
log.Error("下止盈单失败 第", utility.IntToString(x), "次", " err:", err)
|
||||
time.Sleep(2 * time.Second * time.Duration(x))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error("重新下单止盈失败 err:", err)
|
||||
|
||||
if err1 := orm.Model(&DbModels.LinePreOrder{}).Where("order_sn =?", takeOrder.OrderSn).
|
||||
Updates(map[string]interface{}{"status": "2", "desc": err.Error()}).Error; err1 != nil {
|
||||
log.Error("重新下单止盈 修改订单失败 pid:", parentId, " takePrice:", takePrice, " err:", err1)
|
||||
}
|
||||
}
|
||||
|
||||
//修改止盈单信息
|
||||
if err := orm.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type ='5'", parentId).
|
||||
Updates(map[string]interface{}{"price": takePrice, "rate": parentOrderInfo.ProfitRate}).Error; err != nil {
|
||||
log.Error("重新下单止盈 修改订单失败 pid:", parentId, " takePrice:", takePrice, " rate:", parentOrderInfo.ProfitRate, " err:", err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
判断是否触发
|
||||
*/
|
||||
func JudgeSpotPrice(trade models.TradeSet) {
|
||||
preOrderVal, _ := helper.DefaultRedis.GetAllList(rediskey.PreSpotOrderList)
|
||||
key := fmt.Sprintf(rediskey.PreSpotOrderList, global.EXCHANGE_BINANCE)
|
||||
preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
|
||||
db := GetDBConnection()
|
||||
|
||||
if len(preOrderVal) == 0 {
|
||||
// log.Debug("没有现货预下单")
|
||||
return
|
||||
}
|
||||
|
||||
@ -622,35 +448,20 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S
|
||||
} else if ok {
|
||||
defer lock.Release()
|
||||
|
||||
key := fmt.Sprintf(rediskey.UserHolding, v.ApiId)
|
||||
symbols, err := helper.DefaultRedis.GetAllList(key)
|
||||
|
||||
if err != nil && err != redis.Nil {
|
||||
log.Error("获取用户持仓失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
key := fmt.Sprintf(rediskey.PreSpotOrderList, global.EXCHANGE_BINANCE)
|
||||
preOrder := DbModels.LinePreOrder{}
|
||||
if err := db.Where("id = ?", v.Id).First(&preOrder).Error; err != nil {
|
||||
log.Error("获取预下单失败", err)
|
||||
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
log.Error("不存在待触发主单", item)
|
||||
helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, item)
|
||||
helper.DefaultRedis.LRem(key, item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//获取代币 是否已有持仓
|
||||
coin := utility.ReplaceSuffix(preOrder.Symbol, preOrder.QuoteSymbol, "")
|
||||
|
||||
if utility.ContainsStr(symbols, coin) {
|
||||
log.Debug("已有持仓")
|
||||
return
|
||||
}
|
||||
|
||||
hasrecord, _ := helper.DefaultRedis.IsElementInList(rediskey.PreSpotOrderList, item)
|
||||
hasrecord, _ := helper.DefaultRedis.IsElementInList(key, item)
|
||||
|
||||
if !hasrecord {
|
||||
log.Error("不存在待触发主单", item)
|
||||
@ -673,14 +484,14 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S
|
||||
|
||||
if err := spotApi.OrderPlace(db, params); err != nil {
|
||||
log.Error("下单失败", v.Symbol, " err:", err)
|
||||
err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Updates(map[string]interface{}{"status": "2", "desc": err.Error()}).Error
|
||||
err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status =0", preOrder.Id).Updates(map[string]interface{}{"status": "2", "desc": err.Error()}).Error
|
||||
|
||||
if err != nil {
|
||||
log.Error("下单失败后修改订单失败")
|
||||
}
|
||||
|
||||
if preOrderVal != "" {
|
||||
if _, err := helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, preOrderVal); err != nil {
|
||||
if _, err := helper.DefaultRedis.LRem(key, preOrderVal); err != nil {
|
||||
log.Error("删除redis 预下单失败:", err)
|
||||
}
|
||||
}
|
||||
@ -689,31 +500,14 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S
|
||||
}
|
||||
|
||||
if preOrderVal != "" {
|
||||
if _, err := helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, preOrderVal); err != nil {
|
||||
if _, err := helper.DefaultRedis.LRem(key, preOrderVal); err != nil {
|
||||
log.Error("删除redis 预下单失败:", err)
|
||||
}
|
||||
|
||||
// spotPreOrders, _ := helper.DefaultRedis.GetAllList(rediskey.PreSpotOrderList)
|
||||
// futuresPreOrders, _ := helper.DefaultRedis.GetAllList(rediskey.PreFutOrderList)
|
||||
// var order dto.PreOrderRedisList
|
||||
|
||||
// for _, item := range spotPreOrders {
|
||||
// sonic.Unmarshal([]byte(item), &order)
|
||||
|
||||
// if order.QuoteSymbol == "" {
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Update("status", "1").Error; err != nil {
|
||||
log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1")
|
||||
}
|
||||
|
||||
if err := helper.DefaultRedis.RPushList(key, coin); err != nil {
|
||||
log.Error("写入用户持仓失败", v.Symbol)
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
log.Error("获取锁失败")
|
||||
|
||||
Reference in New Issue
Block a user