1、波段触发修改
This commit is contained in:
@ -14,7 +14,7 @@ type LineStrategyTemplate struct {
|
||||
Percentag decimal.Decimal `json:"percentag" gorm:"type:decimal(10,2);comment:涨跌点数"`
|
||||
CompareType int `json:"compareType" gorm:"type:tinyint;comment:比较类型 1-大于 2-大于等于 3-小于 4-小于等于 5等于 "`
|
||||
TimeSlotStart int `json:"timeSlotStart" gorm:"type:int;comment:时间段开始(分)"`
|
||||
TimeSlotEnd int `json:"timeSlotEnd" gorm:"type:int;comment:时间断截至(分)"`
|
||||
// TimeSlotEnd int `json:"timeSlotEnd" gorm:"type:int;comment:时间断截至(分)"`
|
||||
models.ModelTime
|
||||
models.ControlBy
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ type LineAddPreOrderReq struct {
|
||||
Site string `json:"site" ` //购买方向
|
||||
BuyPrice string `json:"buy_price" vd:"$>0"` //购买金额 U
|
||||
PricePattern string `json:"price_pattern"` //价格模式
|
||||
Price string `json:"price" vd:"$>0"` //下单价百分比
|
||||
Price string `json:"price"` //下单价百分比
|
||||
Profit string `json:"profit" vd:"$>0"` //止盈价
|
||||
ProfitNumRatio decimal.Decimal `json:"profit_num_ratio"` //止盈数量百分比
|
||||
ProfitTpTpPriceRatio decimal.Decimal `json:"profit_tp_tp_price_ratio"` //止盈后止盈价百分比
|
||||
|
||||
@ -41,8 +41,8 @@ type LineStrategyTemplateInsertReq struct {
|
||||
Direction int `json:"direction" comment:"涨跌方向 1-涨 2-跌"`
|
||||
Percentag decimal.Decimal `json:"percentag" comment:"涨跌点数"`
|
||||
CompareType int `json:"compareType" comment:"比较类型 1-大于 2-大于等于 3-小于 4-小于等于 5等于 "`
|
||||
TimeSlotStart int `json:"timeSlotStart" comment:"时间段开始(分)"`
|
||||
TimeSlotEnd int `json:"timeSlotEnd" comment:"时间断截至(分)"`
|
||||
TimeSlotStart int `json:"timeSlotStart" comment:"时间段(分)"`
|
||||
// TimeSlotEnd int `json:"timeSlotEnd" comment:"时间断截至(分)"`
|
||||
common.ControlBy
|
||||
}
|
||||
|
||||
@ -63,13 +63,13 @@ func (s *LineStrategyTemplateInsertReq) Valid() error {
|
||||
return errors.New("比较类型不合法")
|
||||
}
|
||||
|
||||
if s.TimeSlotStart < 0 || s.TimeSlotEnd > 59 {
|
||||
if s.TimeSlotStart < 0 {
|
||||
return errors.New("时间段不合法")
|
||||
}
|
||||
|
||||
if s.TimeSlotEnd < s.TimeSlotStart {
|
||||
return errors.New("时间段不合法")
|
||||
}
|
||||
// if s.TimeSlotEnd < s.TimeSlotStart {
|
||||
// return errors.New("时间段不合法")
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -83,7 +83,7 @@ func (s *LineStrategyTemplateInsertReq) Generate(model *models.LineStrategyTempl
|
||||
model.Percentag = s.Percentag
|
||||
model.CompareType = s.CompareType
|
||||
model.TimeSlotStart = s.TimeSlotStart
|
||||
model.TimeSlotEnd = s.TimeSlotEnd
|
||||
// model.TimeSlotEnd = s.TimeSlotEnd
|
||||
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
|
||||
}
|
||||
|
||||
@ -97,8 +97,8 @@ type LineStrategyTemplateUpdateReq struct {
|
||||
Direction int `json:"direction" comment:"涨跌方向 1-涨 2-跌"`
|
||||
Percentag decimal.Decimal `json:"percentag" comment:"涨跌点数"`
|
||||
CompareType int `json:"compareType" comment:"比较类型 1-大于 2-大于等于 3-小于 4-小于等于 5等于 "`
|
||||
TimeSlotStart int `json:"timeSlotStart" comment:"时间段开始(分)"`
|
||||
TimeSlotEnd int `json:"timeSlotEnd" comment:"时间断截至(分)"`
|
||||
TimeSlotStart int `json:"timeSlotStart" comment:"时间段(分)"`
|
||||
// TimeSlotEnd int `json:"timeSlotEnd" comment:"时间断截至(分)"`
|
||||
common.ControlBy
|
||||
}
|
||||
|
||||
@ -120,13 +120,13 @@ func (s *LineStrategyTemplateUpdateReq) Valid() error {
|
||||
return errors.New("比较类型不合法")
|
||||
}
|
||||
|
||||
if s.TimeSlotStart < 0 || s.TimeSlotEnd > 59 {
|
||||
if s.TimeSlotStart < 0 {
|
||||
return errors.New("时间段不合法")
|
||||
}
|
||||
|
||||
if s.TimeSlotEnd < s.TimeSlotStart {
|
||||
return errors.New("时间段不合法")
|
||||
}
|
||||
// if s.TimeSlotEnd < s.TimeSlotStart {
|
||||
// return errors.New("时间段不合法")
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -139,7 +139,7 @@ func (s *LineStrategyTemplateUpdateReq) Generate(model *models.LineStrategyTempl
|
||||
model.Percentag = s.Percentag
|
||||
model.CompareType = s.CompareType
|
||||
model.TimeSlotStart = s.TimeSlotStart
|
||||
model.TimeSlotEnd = s.TimeSlotEnd
|
||||
// model.TimeSlotEnd = s.TimeSlotEnd
|
||||
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
|
||||
}
|
||||
|
||||
|
||||
@ -279,6 +279,8 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
|
||||
futReduceVal, _ := helper.DefaultRedis.GetAllList(spotAddPositionKey)
|
||||
spotAddPositionVal, _ := helper.DefaultRedis.GetAllList(futReduceKey)
|
||||
spotReduceVal, _ := helper.DefaultRedis.GetAllList(spotReduceKey)
|
||||
spotStrategyMap := e.GetStrategyOrderListMap(1)
|
||||
futStrategyMap := e.GetStrategyOrderListMap(2)
|
||||
|
||||
for _, v := range futAddPositionVal {
|
||||
sonic.Unmarshal([]byte(v), &addPosition)
|
||||
@ -337,8 +339,14 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
|
||||
if val, ok := spotRedces[order.Id]; ok {
|
||||
helper.DefaultRedis.LRem(spotReduceKey, val)
|
||||
}
|
||||
var tradedSetKey string
|
||||
if order.SymbolType == 1 {
|
||||
tradedSetKey = fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol)
|
||||
} else {
|
||||
tradedSetKey = fmt.Sprintf(global.TICKER_FUTURES, order.ExchangeType, order.Symbol)
|
||||
}
|
||||
|
||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
|
||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, tradedSetKey)
|
||||
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||
marshal, _ := sonic.Marshal(redisList)
|
||||
if order.SymbolType == 1 {
|
||||
@ -349,6 +357,13 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
|
||||
helper.DefaultRedis.LRem(listKey, string(marshal))
|
||||
}
|
||||
|
||||
switch {
|
||||
case order.StrategyTemplateType == 1 && order.SymbolType == 1:
|
||||
e.RemoveStrategyOrderCache(order.Id, order.SymbolType, order.ExchangeType, &spotStrategyMap)
|
||||
case order.StrategyTemplateType == 1 && order.SymbolType == 2:
|
||||
e.RemoveStrategyOrderCache(order.Id, order.SymbolType, order.ExchangeType, &futStrategyMap)
|
||||
}
|
||||
|
||||
//会影响持仓的
|
||||
removeSymbolKey := fmt.Sprintf("%v_%s_%s_%s_%v", order.ApiId, order.ExchangeType, order.Symbol, order.Site, order.SymbolType)
|
||||
|
||||
@ -908,7 +923,6 @@ func saveOrderCache(req *dto.LineAddPreOrderReq, AddOrder models.LinePreOrder, l
|
||||
list.Percentag = linestrategyTemplate.Percentag
|
||||
list.CompareType = linestrategyTemplate.CompareType
|
||||
list.TimeSlotStart = linestrategyTemplate.TimeSlotStart
|
||||
list.TimeSlotEnd = linestrategyTemplate.TimeSlotEnd
|
||||
|
||||
marshal, _ = sonic.Marshal(&list)
|
||||
if AddOrder.SymbolType == global.SYMBOL_SPOT {
|
||||
@ -1995,6 +2009,8 @@ func (e *LinePreOrder) ClearUnTriggered() error {
|
||||
var orderLists []models.LinePreOrder
|
||||
positions := map[string]positiondto.LinePreOrderPositioinDelReq{}
|
||||
e.Orm.Model(&models.LinePreOrder{}).Where("main_id = 0 AND pid = 0 AND status = '0'").Find(&orderLists).Unscoped().Delete(&models.LinePreOrder{})
|
||||
spotStrategyMap := e.GetStrategyOrderListMap(1)
|
||||
futStrategyMap := e.GetStrategyOrderListMap(2)
|
||||
|
||||
for _, order := range orderLists {
|
||||
redisList := dto.PreOrderRedisList{
|
||||
@ -2006,17 +2022,35 @@ func (e *LinePreOrder) ClearUnTriggered() error {
|
||||
OrderSn: order.OrderSn,
|
||||
QuoteSymbol: order.QuoteSymbol,
|
||||
}
|
||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
|
||||
|
||||
var tradedSetKey string
|
||||
if order.SymbolType == 1 {
|
||||
tradedSetKey = fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol)
|
||||
} else {
|
||||
tradedSetKey = fmt.Sprintf(global.TICKER_FUTURES, order.ExchangeType, order.Symbol)
|
||||
}
|
||||
|
||||
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, tradedSetKey)
|
||||
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
|
||||
marshal, _ := sonic.Marshal(redisList)
|
||||
|
||||
if order.SymbolType == 1 {
|
||||
key := fmt.Sprintf(rediskey.PreFutOrderList, order.ExchangeType)
|
||||
|
||||
helper.DefaultRedis.LRem(key, string(marshal))
|
||||
} else {
|
||||
key := fmt.Sprintf(rediskey.PreSpotOrderList, order.ExchangeType)
|
||||
|
||||
helper.DefaultRedis.LRem(key, string(marshal))
|
||||
}
|
||||
|
||||
switch {
|
||||
case order.StrategyTemplateType == 1 && order.SymbolType == 1:
|
||||
e.RemoveStrategyOrderCache(order.Id, order.SymbolType, order.ExchangeType, &spotStrategyMap)
|
||||
case order.StrategyTemplateType == 1 && order.SymbolType == 2:
|
||||
e.RemoveStrategyOrderCache(order.Id, order.SymbolType, order.ExchangeType, &futStrategyMap)
|
||||
}
|
||||
|
||||
//会影响持仓的
|
||||
removeSymbolKey := fmt.Sprintf("%v_%s_%s_%s_%v", order.ApiId, order.ExchangeType, order.Symbol, order.Site, order.SymbolType)
|
||||
|
||||
@ -2056,6 +2090,60 @@ func (e *LinePreOrder) ClearUnTriggered() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 移除待策略待触发单
|
||||
func (e *LinePreOrder) RemoveStrategyOrderCache(orderId int, symbolType int, exchangeType string, caches *map[string][]dto.StrategyOrderRedisList) {
|
||||
strategys, _ := (*caches)[exchangeType]
|
||||
var strategyListKey string
|
||||
|
||||
if symbolType == 1 {
|
||||
strategyListKey = fmt.Sprintf(rediskey.StrategySpotOrderList, exchangeType)
|
||||
} else {
|
||||
strategyListKey = fmt.Sprintf(rediskey.StrategyFutOrderList, exchangeType)
|
||||
}
|
||||
|
||||
for _, strategy := range strategys {
|
||||
if strategy.Id == orderId {
|
||||
strategyVal, _ := sonic.MarshalString(strategy)
|
||||
helper.DefaultRedis.LRem(strategyListKey, strategyVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取策略订单缓存列表
|
||||
// symbolType 1现货 2合约
|
||||
func (e *LinePreOrder) GetStrategyOrderListMap(symbolType int) map[string][]dto.StrategyOrderRedisList {
|
||||
result := make(map[string][]dto.StrategyOrderRedisList)
|
||||
var key string
|
||||
exchanges := []string{global.EXCHANGE_BINANCE}
|
||||
|
||||
if symbolType == 1 {
|
||||
key = rediskey.StrategySpotOrderList
|
||||
} else {
|
||||
key = rediskey.StrategyFutOrderList
|
||||
}
|
||||
|
||||
for _, exchange := range exchanges {
|
||||
newKey := fmt.Sprintf(key, exchange)
|
||||
vals, _ := helper.DefaultRedis.GetAllList(newKey)
|
||||
itemData := make([]dto.StrategyOrderRedisList, 0)
|
||||
item := dto.StrategyOrderRedisList{}
|
||||
|
||||
for _, v := range vals {
|
||||
sonic.Unmarshal([]byte(v), &item)
|
||||
|
||||
if item.Id > 0 {
|
||||
itemData = append(itemData, item)
|
||||
}
|
||||
}
|
||||
|
||||
if len(itemData) > 0 {
|
||||
result[exchange] = itemData
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (e *LinePreOrder) QueryOrder(req *dto.QueryOrderReq) (res interface{}, err error) {
|
||||
var apiUserInfo models.LineApiUser
|
||||
e.Orm.Model(&models.LineApiUser{}).Where("id = ?", req.ApiId).Find(&apiUserInfo)
|
||||
|
||||
@ -3,6 +3,7 @@ package jobs
|
||||
import (
|
||||
"fmt"
|
||||
models2 "go-admin/app/jobs/models"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
log "github.com/go-admin-team/go-admin-core/logger"
|
||||
@ -43,7 +44,10 @@ type ExecJob struct {
|
||||
func (e *ExecJob) Run() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Errorf("脚本任务失败:%v", err)
|
||||
// 获取调用栈信息
|
||||
buf := make([]byte, 1<<16) // 64KB 缓冲区
|
||||
n := runtime.Stack(buf, false)
|
||||
log.Errorf("脚本任务失败: %v\n%s", err, buf[:n])
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
22
app/jobs/strategy_job_test.go
Normal file
22
app/jobs/strategy_job_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package jobs
|
||||
|
||||
import (
|
||||
"go-admin/common/helper"
|
||||
"testing"
|
||||
|
||||
"github.com/go-admin-team/go-admin-core/sdk"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestStrategyJob(t *testing.T) {
|
||||
dsn := "root:123456@tcp(127.0.0.1:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
sdk.Runtime.SetDb("default", db)
|
||||
helper.InitDefaultRedis("127.0.0.1:6379", "", 2)
|
||||
helper.InitLockRedisConn("127.0.0.1:6379", "", "2")
|
||||
|
||||
job := StrategyJob{}
|
||||
|
||||
job.Exec([]string{})
|
||||
}
|
||||
Reference in New Issue
Block a user