1、订单增加策略模板
This commit is contained in:
@ -9,38 +9,40 @@ import (
|
||||
|
||||
type LinePreOrder struct {
|
||||
models.Model
|
||||
ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"`
|
||||
Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"`
|
||||
MainId int `json:"mainId" gorm:"type:int;comment:主单id"`
|
||||
ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"`
|
||||
GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"`
|
||||
Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"`
|
||||
QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"`
|
||||
SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"`
|
||||
SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"`
|
||||
SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
|
||||
Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"`
|
||||
Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"`
|
||||
Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"`
|
||||
BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"`
|
||||
SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"`
|
||||
OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"`
|
||||
Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"`
|
||||
OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"`
|
||||
OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"`
|
||||
Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"`
|
||||
Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
|
||||
CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"`
|
||||
ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"`
|
||||
MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"`
|
||||
LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"`
|
||||
TriggerTime *time.Time `json:"triggerTime" gorm:"type:datetime;comment:触发时间"`
|
||||
Child []LinePreOrder `json:"child" gorm:"-"`
|
||||
ApiName string `json:"api_name" gorm:"->"`
|
||||
ChildNum int64 `json:"child_num" gorm:"->"`
|
||||
AddPositionStatus int `json:"add_position_status" gorm:"->"`
|
||||
ReduceStatus int `json:"reduce_status" gorm:"->"`
|
||||
Childs []LinePreOrder `json:"childs" gorm:"foreignKey:pid;references:id"`
|
||||
ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"`
|
||||
StrategyTemplateType int `json:"strategyTemplateType" gorm:"type:tinyint;comment:策略类型 0-无 1-波段涨跌幅"`
|
||||
StrategyTemplateId int `json:"strategyTemplateId" gorm:"type:bigint;comment:策略模板id"`
|
||||
Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"`
|
||||
MainId int `json:"mainId" gorm:"type:int;comment:主单id"`
|
||||
ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"`
|
||||
GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"`
|
||||
Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"`
|
||||
QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"`
|
||||
SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"`
|
||||
SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"`
|
||||
SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
|
||||
Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"`
|
||||
Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"`
|
||||
Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"`
|
||||
BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"`
|
||||
SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"`
|
||||
OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"`
|
||||
Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"`
|
||||
OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"`
|
||||
OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"`
|
||||
Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"`
|
||||
Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
|
||||
CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"`
|
||||
ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"`
|
||||
MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"`
|
||||
LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"`
|
||||
TriggerTime *time.Time `json:"triggerTime" gorm:"type:datetime;comment:触发时间"`
|
||||
Child []LinePreOrder `json:"child" gorm:"-"`
|
||||
ApiName string `json:"api_name" gorm:"->"`
|
||||
ChildNum int64 `json:"child_num" gorm:"->"`
|
||||
AddPositionStatus int `json:"add_position_status" gorm:"->"`
|
||||
ReduceStatus int `json:"reduce_status" gorm:"->"`
|
||||
Childs []LinePreOrder `json:"childs" gorm:"foreignKey:pid;references:id"`
|
||||
// LinePreOrder 线上预埋单\
|
||||
models.ModelTime
|
||||
models.ControlBy
|
||||
|
||||
@ -186,6 +186,8 @@ func (s *LinePreOrderDeleteReq) GetId() interface{} {
|
||||
|
||||
type LineAddPreOrderReq struct {
|
||||
ExchangeType string `json:"exchange_type" vd:"len($)>0"` //交易所类型
|
||||
StrategyTemplateType int `json:"strategy_template_type"` //策略类型 0-无 1-波段涨跌幅
|
||||
StrategyTemplateId int `json:"strategy_template_id"` //策略id
|
||||
OrderType int `json:"order_type"` //订单类型
|
||||
Symbol string `json:"symbol"` //交易对
|
||||
ApiUserId string `json:"api_id" ` //下单用户
|
||||
@ -283,6 +285,10 @@ func (req LineAddPreOrderReq) Valid() error {
|
||||
return errors.New("主单减仓价格百分比不能为空")
|
||||
}
|
||||
|
||||
if req.StrategyTemplateType == 1 && req.StrategyTemplateId == 0 {
|
||||
return errors.New("请选择策略")
|
||||
}
|
||||
|
||||
if req.ReduceNumRatio.IsZero() {
|
||||
return errors.New("主单减仓数量百分比不能为空")
|
||||
}
|
||||
@ -367,6 +373,8 @@ type LineTreeOrder struct {
|
||||
// LineBatchAddPreOrderReq 批量添加订单请求参数
|
||||
type LineBatchAddPreOrderReq struct {
|
||||
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
|
||||
StrategyTemplateType int `json:"strategy_template_type"` //策略类型 0-无 1-波段涨跌幅
|
||||
StrategyTemplateId int `json:"strategy_template_id"` //策略id
|
||||
SymbolType int `json:"symbol_type"` //主单交易对类型 0-现货 1-合约
|
||||
OrderType int `json:"order_type"` //订单类型
|
||||
SymbolGroupId string `json:"symbol_group_id"` //交易对组id
|
||||
@ -404,6 +412,10 @@ func (req LineBatchAddPreOrderReq) CheckParams() error {
|
||||
return errors.New("请选择交易所")
|
||||
}
|
||||
|
||||
if req.StrategyTemplateType == 1 && req.StrategyTemplateId == 0 {
|
||||
return errors.New("请选择策略")
|
||||
}
|
||||
|
||||
if req.ApiUserId == "" {
|
||||
return errors.New("选择下单用户")
|
||||
}
|
||||
|
||||
@ -74,6 +74,13 @@ const (
|
||||
AveRequestToken = "ave_request_token" // AVE请求token
|
||||
)
|
||||
|
||||
const (
|
||||
//现货最后成交价 sort set {exchangeType,symbol}
|
||||
SpotTickerLastPrice = "spot_ticker_last_price:%s:%s"
|
||||
//合约最后成交价 sort set {exchangeType,symbol}
|
||||
FutureTickerLastPrice = "fut_ticker_last_price:%s:%s"
|
||||
)
|
||||
|
||||
// 用户下单
|
||||
const (
|
||||
MemberShipPre = "member_ship_pre:%v" //用户开通会员预下单 单价缓存{payable_amount}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
@ -609,7 +610,7 @@ func (e *RedisHelper) SignelAdd(key string, score float64, member string) error
|
||||
_, err := e.client.ZRemRangeByScore(e.ctx, key, scoreStr, scoreStr).Result()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("删除score失败", err.Error())
|
||||
fmt.Printf("删除score失败,err:%s", err.Error())
|
||||
}
|
||||
_, err = e.client.ZAdd(e.ctx, key, &redis.Z{
|
||||
Score: score,
|
||||
@ -642,6 +643,46 @@ func (e *RedisHelper) DelSortSet(key, member string) error {
|
||||
return e.client.ZRem(e.ctx, key, member).Err()
|
||||
}
|
||||
|
||||
// RemoveBeforeScore 移除 Sorted Set 中分数小于等于指定值的数据
|
||||
// key: Sorted Set 的键
|
||||
// score: 分数上限,所有小于等于此分数的元素将被移除
|
||||
// 返回值: 移除的元素数量和可能的错误
|
||||
func (e *RedisHelper) RemoveBeforeScore(key string, score float64) (int64, error) {
|
||||
if key == "" {
|
||||
return 0, errors.New("key 不能为空")
|
||||
}
|
||||
if math.IsNaN(score) || math.IsInf(score, 0) {
|
||||
return 0, errors.New("score 必须是有效数字")
|
||||
}
|
||||
|
||||
// 使用 ZRemRangeByScore 移除数据
|
||||
count, err := e.client.ZRemRangeByScore(e.ctx, key, "-inf", strconv.FormatFloat(score, 'f', -1, 64)).Result()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("移除 Sorted Set 数据失败, key: %s, score: %f, err: %v", key, score, err)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// GetNextAfterScore 获取指定分数及之后的第一条数据(包含指定分数)
|
||||
func (e *RedisHelper) GetNextAfterScore(key string, score float64) (string, error) {
|
||||
// 使用 ZRangeByScore 获取大于等于 score 的第一条数据
|
||||
zs, err := e.client.ZRangeByScoreWithScores(e.ctx, key, &redis.ZRangeBy{
|
||||
Min: fmt.Sprintf("%f", score), // 包含指定分数
|
||||
Max: "+inf", // 上限为正无穷
|
||||
Offset: 0, // 从第 0 条开始
|
||||
Count: 1, // 只取 1 条
|
||||
}).Result()
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("获取数据失败: %v", err)
|
||||
}
|
||||
if len(zs) == 0 {
|
||||
return "", nil // 没有符合条件的元素
|
||||
}
|
||||
return zs[0].Member.(string), nil
|
||||
}
|
||||
|
||||
/*
|
||||
获取sort set 所有数据
|
||||
*/
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go-admin/common/const/rediskey"
|
||||
"go-admin/common/global"
|
||||
"go-admin/common/helper"
|
||||
"go-admin/config"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
"go-admin/models"
|
||||
|
||||
log "github.com/go-admin-team/go-admin-core/logger"
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"go.uber.org/zap"
|
||||
@ -133,7 +135,19 @@ func handleTickerAllMessage(msg []byte) {
|
||||
// log.Debug(symbol, "ticker@all ws处理失败", err)
|
||||
continue
|
||||
}
|
||||
tradeSet.LastPrice = utility.StringFloat64Cut(data["c"].(string), int32(tradeSet.PriceDigit))
|
||||
var utcTime int64
|
||||
var lastPrice decimal.Decimal
|
||||
lastPriceKey := fmt.Sprintf(rediskey.FutureTickerLastPrice, global.EXCHANGE_BINANCE, symbol)
|
||||
|
||||
if e, ok := data["E"]; ok {
|
||||
utcTime = utility.ToInt64(e)
|
||||
}
|
||||
|
||||
if e, ok := data["c"]; ok {
|
||||
lastPrice = utility.StrToDecimal(e.(string)).Truncate(int32(tradeSet.PriceDigit))
|
||||
}
|
||||
|
||||
tradeSet.LastPrice = lastPrice.String()
|
||||
tradeSet.OpenPrice = utility.StrToFloatCut(data["o"].(string), int32(tradeSet.PriceDigit))
|
||||
tradeSet.HighPrice = utility.StringFloat64Cut(data["h"].(string), int32(tradeSet.PriceDigit))
|
||||
tradeSet.LowPrice = utility.StringFloat64Cut(data["l"].(string), int32(tradeSet.PriceDigit))
|
||||
@ -147,6 +161,16 @@ func handleTickerAllMessage(msg []byte) {
|
||||
log.Error(symbol, "ticker@all ws处理失败", err)
|
||||
}
|
||||
}
|
||||
|
||||
//行情存储时间
|
||||
lastUtc := utcTime - 1000*60*60
|
||||
if _, err := helper.DefaultRedis.RemoveBeforeScore(lastPriceKey, float64(lastUtc)); err != nil {
|
||||
log.Errorf("移除 合约交易对:%s %d之前的最新成交价失败,err:%v", symbol, lastUtc, err)
|
||||
}
|
||||
|
||||
if err := helper.DefaultRedis.AddSortSet(lastPriceKey, float64(utcTime), lastPrice.String()); err != nil {
|
||||
log.Errorf("添加 合约交易对:%s %d之前的最新成交价失败,err:%v", symbol, lastUtc, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(trades) > 0 {
|
||||
|
||||
@ -204,6 +204,7 @@ func handleTickerMessage(msg []byte) {
|
||||
}
|
||||
|
||||
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbolName)
|
||||
lastPriceKey := fmt.Sprintf(rediskey.SpotTickerLastPrice, global.EXCHANGE_BINANCE, symbolName)
|
||||
tcVal, _ := helper.DefaultRedis.GetString(key)
|
||||
tradeSet := models.TradeSet{}
|
||||
if err := sonic.UnmarshalString(tcVal, &tradeSet); err != nil {
|
||||
@ -212,7 +213,19 @@ func handleTickerMessage(msg []byte) {
|
||||
}
|
||||
continue
|
||||
}
|
||||
tradeSet.LastPrice = utility.StringFloat64Cut(dataMap["c"].(string), int32(tradeSet.PriceDigit))
|
||||
|
||||
var utcTime int64
|
||||
var lastPrice decimal.Decimal
|
||||
|
||||
if e, ok := dataMap["E"]; ok {
|
||||
utcTime = utility.ToInt64(e)
|
||||
}
|
||||
|
||||
if e, ok := dataMap["c"]; ok {
|
||||
lastPrice = utility.StrToDecimal(e.(string)).Truncate(int32(tradeSet.PriceDigit))
|
||||
}
|
||||
|
||||
tradeSet.LastPrice = lastPrice.String()
|
||||
tradeSet.OpenPrice = utility.StrToFloatCut(dataMap["o"].(string), int32(tradeSet.PriceDigit))
|
||||
tradeSet.HighPrice = utility.StringFloat64Cut(dataMap["h"].(string), int32(tradeSet.PriceDigit))
|
||||
tradeSet.LowPrice = utility.StringFloat64Cut(dataMap["l"].(string), int32(tradeSet.PriceDigit))
|
||||
@ -236,6 +249,17 @@ func handleTickerMessage(msg []byte) {
|
||||
log.Error("redis保存交易对失败", tradeSet.Coin, tradeSet.Currency)
|
||||
}
|
||||
}
|
||||
|
||||
//行情存储时间
|
||||
lastUtc := utcTime - 1000*60*60
|
||||
|
||||
if _, err := helper.DefaultRedis.RemoveBeforeScore(lastPriceKey, float64(lastUtc)); err != nil {
|
||||
log.Errorf("移除 现货交易对:%s %d之前的最新成交价失败,err:%v", symbolName, lastUtc, err)
|
||||
}
|
||||
|
||||
if err := helper.DefaultRedis.AddSortSet(lastPriceKey, float64(utcTime), lastPrice.String()); err != nil {
|
||||
log.Errorf("添加 现货交易对:%s %d之前的最新成交价失败,err:%v", symbolName, lastUtc, err)
|
||||
}
|
||||
}
|
||||
|
||||
//判断触发现货下单
|
||||
|
||||
Reference in New Issue
Block a user