219 lines
7.0 KiB
Go
219 lines
7.0 KiB
Go
package jobs
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"go-admin/app/admin/models"
|
||
"go-admin/app/admin/service"
|
||
"go-admin/app/admin/service/dto"
|
||
"go-admin/common/const/rediskey"
|
||
"go-admin/common/global"
|
||
"go-admin/common/helper"
|
||
"go-admin/pkg/utility"
|
||
"go-admin/services/binanceservice"
|
||
"time"
|
||
|
||
"github.com/bytedance/sonic"
|
||
"github.com/go-admin-team/go-admin-core/logger"
|
||
"github.com/go-admin-team/go-admin-core/sdk"
|
||
sysservice "github.com/go-admin-team/go-admin-core/sdk/service"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// InitJob
|
||
// 需要将定义的struct 添加到字典中;
|
||
// 字典 key 可以配置到 自动任务 调用目标 中;
|
||
func InitJob() {
|
||
jobList = map[string]JobExec{
|
||
"ExamplesOne": ExamplesOne{},
|
||
// ...
|
||
"DeleteExpireOrder": DeleteExpireOrder{}, //定时删除过期数据
|
||
"UpRange": UpRange{}, //更新涨跌幅
|
||
"InitFuturesSymbol": InitFuturesSymbol{}, //定时更新合约交易对
|
||
"InitSpotSymbol": InitSpotSymbol{}, //定时更新现货交易对
|
||
"ClearLogJob": ClearLogJob{}, //定时清理日志
|
||
"AutoPlaceOrder": AutoPlaceOrder{}, //定时下单
|
||
"LimitOrderTimeoutDuration": LimitOrderTimeoutDuration{}, //定时取消限价单改下市价单
|
||
"ListenSymbol": ListenSymbol{}, //交易对监听
|
||
"MemberExpirationJob": MemberExpirationJob{}, //会员到期处理
|
||
"MemberRenwalOrderExpirationJob": MemberRenwalOrderExpirationJob{}, //会员续费订单过期处理
|
||
"TrxQueryJobs": TrxQueryJobs{}, //订单支付监听
|
||
"StrategyJob": StrategyJob{}, //下单策略触发
|
||
}
|
||
}
|
||
|
||
// ExamplesOne
|
||
// 新添加的job 必须按照以下格式定义,并实现Exec函数
|
||
type ExamplesOne struct {
|
||
}
|
||
|
||
func (t ExamplesOne) Exec(arg interface{}) error {
|
||
str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success"
|
||
// TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化;
|
||
switch arg.(type) {
|
||
|
||
case string:
|
||
if arg.(string) != "" {
|
||
fmt.Println("string", arg.(string))
|
||
fmt.Println(str, arg.(string))
|
||
} else {
|
||
fmt.Println("arg is nil")
|
||
fmt.Println(str, "arg is nil")
|
||
}
|
||
break
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// DeleteExpireOrder 清理过期订单
|
||
type DeleteExpireOrder struct {
|
||
}
|
||
|
||
func (receiver DeleteExpireOrder) Exec(arg interface{}) error {
|
||
dbs := sdk.Runtime.GetDb()
|
||
var db *gorm.DB
|
||
|
||
for _, item := range dbs {
|
||
db = item
|
||
break
|
||
}
|
||
orders := make([]models.LinePreOrder, 0)
|
||
err := db.Model(&models.LinePreOrder{}).Where("status = '0' AND expire_time <= ? AND order_type = 0 AND pid=0", time.Now()).Find(&orders).Error
|
||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return err
|
||
}
|
||
for _, order := range orders {
|
||
//删除止盈止损数据
|
||
db.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
|
||
//删除缓存
|
||
list := dto.PreOrderRedisList{
|
||
Id: order.Id,
|
||
Symbol: order.Symbol,
|
||
Price: order.Price,
|
||
Site: order.Site,
|
||
ApiId: order.ApiId,
|
||
OrderSn: order.OrderSn,
|
||
QuoteSymbol: order.QuoteSymbol,
|
||
}
|
||
marshal, _ := sonic.Marshal(&list)
|
||
if order.SymbolType == 1 {
|
||
helper.DefaultRedis.LRem(fmt.Sprintf(rediskey.PreSpotOrderList, order.ExchangeType), string(marshal))
|
||
} else {
|
||
helper.DefaultRedis.LRem(fmt.Sprintf(rediskey.PreFutOrderList, order.ExchangeType), string(marshal))
|
||
}
|
||
//删除主单
|
||
db.Model(&models.LinePreOrder{}).Where("id = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
|
||
}
|
||
|
||
//子订单 加仓、检查过期
|
||
childOrders := make([]models.LinePreOrder, 0)
|
||
err = db.Model(&models.LinePreOrder{}).Where("pid >0 AND order_type IN (0,4) AND status=0 AND expire_time <= ?", time.Now()).Select("id", "order_category", "order_type").Find(&childOrders).Error
|
||
|
||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return err
|
||
}
|
||
|
||
removeExpirateChildOrder(childOrders, db)
|
||
|
||
return nil
|
||
}
|
||
|
||
func removeExpirateChildOrder(childOrders []models.LinePreOrder, db *gorm.DB) {
|
||
childOrderId := make([]int, 0)
|
||
futAddKey := fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BINANCE)
|
||
spotAddKey := fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BINANCE)
|
||
futReduceKey := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
|
||
spotReduceKey := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
|
||
futAddPositionStr, _ := helper.DefaultRedis.GetAllList(futAddKey)
|
||
spotAdPositionStr, _ := helper.DefaultRedis.GetAllList(spotAddKey)
|
||
futReduceStr, _ := helper.DefaultRedis.GetAllList(futReduceKey)
|
||
spotReduceStr, _ := helper.DefaultRedis.GetAllList(spotReduceKey)
|
||
futAddPositionCache := binanceservice.AddPositionList{}
|
||
spotAddPositionCache := binanceservice.AddPositionList{}
|
||
futReduceCache := binanceservice.ReduceListItem{}
|
||
spotReduceCache := binanceservice.ReduceListItem{}
|
||
futAddPositionMap := map[int]string{}
|
||
spotAddPositionMap := map[int]string{}
|
||
futReduceMap := map[int]string{}
|
||
spotReduceMap := map[int]string{}
|
||
|
||
for _, item := range futAddPositionStr {
|
||
sonic.Unmarshal([]byte(item), &futAddPositionCache)
|
||
futAddPositionMap[futAddPositionCache.Id] = item
|
||
}
|
||
|
||
for _, item := range spotAdPositionStr {
|
||
sonic.Unmarshal([]byte(item), &spotAddPositionCache)
|
||
spotAddPositionMap[spotAddPositionCache.Id] = item
|
||
}
|
||
|
||
for _, item := range futReduceStr {
|
||
sonic.Unmarshal([]byte(item), &futReduceCache)
|
||
futReduceMap[futReduceCache.Id] = item
|
||
}
|
||
|
||
for _, item := range spotReduceStr {
|
||
sonic.Unmarshal([]byte(item), &spotReduceCache)
|
||
spotReduceMap[spotReduceCache.Id] = item
|
||
}
|
||
|
||
for _, childOrder := range childOrders {
|
||
switch {
|
||
//加仓单
|
||
case childOrder.OrderType == 0 && childOrder.OrderCategory == 3:
|
||
if val, ok := futAddPositionMap[childOrder.Id]; ok {
|
||
helper.DefaultRedis.LRem(futAddKey, val)
|
||
}
|
||
|
||
if val, ok := spotAddPositionMap[childOrder.Id]; ok {
|
||
helper.DefaultRedis.LRem(spotAddKey, val)
|
||
}
|
||
|
||
//减仓单
|
||
case childOrder.OrderType == 4 && childOrder.OrderCategory == 1:
|
||
if val, ok := futReduceMap[childOrder.Id]; ok {
|
||
helper.DefaultRedis.LRem(futReduceKey, val)
|
||
}
|
||
|
||
if val, ok := spotReduceMap[childOrder.Id]; ok {
|
||
helper.DefaultRedis.LRem(spotReduceKey, val)
|
||
}
|
||
default:
|
||
continue
|
||
}
|
||
childOrderId = append(childOrderId, childOrder.Id)
|
||
}
|
||
|
||
idArrays := utility.SplitSlice(childOrderId, 1000)
|
||
|
||
for _, idArray := range idArrays {
|
||
if err := db.Delete(&models.LinePreOrder{}, idArray).Error; err != nil {
|
||
logger.Errorf("删除过期子订单失败,err", err)
|
||
}
|
||
}
|
||
}
|
||
|
||
// UpRange 更新涨跌幅
|
||
type UpRange struct {
|
||
}
|
||
|
||
func (receiver UpRange) Exec(arg interface{}) error {
|
||
dbs := sdk.Runtime.GetDb()
|
||
var db *gorm.DB
|
||
|
||
for _, item := range dbs {
|
||
db = item
|
||
break
|
||
}
|
||
|
||
limit := service.LinePriceLimit{
|
||
Service: sysservice.Service{Orm: db},
|
||
}
|
||
err := limit.UpRange()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|