From 2764111556c90f1b0207b68e5fdbf588c1b8ebe4 Mon Sep 17 00:00:00 2001 From: strange Date: Mon, 9 Feb 2026 18:27:05 +0800 Subject: [PATCH] grid strategy --- api/pub.proto | 8 +- cmd/test/test.go | 12 +-- internal/admin/repoitory/user_repository.go | 11 +-- internal/admin/service/auth_service.go | 37 ++++---- internal/exchange/exchange_service.go | 6 +- internal/trading/backtest/trade_account.go | 6 +- internal/trading/trading_grpc_server.go | 6 +- internal/trading/trading_service.go | 8 +- pkg/data/entity/user.go | 17 ++-- pkg/session/session.go | 4 +- pkg/strategy/bollgrid.go | 97 +++++++++++++++++++++ pkg/strategy/grid.go | 87 ++++++++++++++++++ pkg/strategy/sig_strategy_registry.go | 2 + pkg/strategy/strategy.go | 4 +- pkg/strategy/super_trend_bos_waves.go | 6 +- pkg/types/signal.go | 3 +- pkg/utils/{lang => misc}/concurrent.go | 2 +- pkg/utils/{lang => misc}/condition.go | 2 +- pkg/utils/{lang => misc}/tuple.go | 2 +- 19 files changed, 255 insertions(+), 65 deletions(-) create mode 100644 pkg/strategy/bollgrid.go create mode 100644 pkg/strategy/grid.go rename pkg/utils/{lang => misc}/concurrent.go (95%) rename pkg/utils/{lang => misc}/condition.go (96%) rename pkg/utils/{lang => misc}/tuple.go (79%) diff --git a/api/pub.proto b/api/pub.proto index 3d1cb36..cbcb434 100644 --- a/api/pub.proto +++ b/api/pub.proto @@ -248,6 +248,10 @@ message RpcSubject { int64 uid = 1; string account = 2; int64 time = 3; // ms - map extra = 4; + Role role = 4; + map extra = 15; +} +enum Role { + User = 0; // 普通用户 + Admin = 1; // 管理员 } - diff --git a/cmd/test/test.go b/cmd/test/test.go index 44bb6b9..9f1fec1 100644 --- a/cmd/test/test.go +++ b/cmd/test/test.go @@ -1,10 +1,7 @@ package main import ( - "fmt" - "path/filepath" "sig-pub/pkg/zlog" - "strings" "github.com/govalues/decimal" ) @@ -12,14 +9,7 @@ import ( func main() { // curl -H 'Content-Type: application/json' --data-binary "@vmdata.json" -X POST http://localhost:8428/api/v1/import - // testDecimalScale() - file := "config.toml" - ext := filepath.Ext(file) - filename, _ := strings.CutSuffix(file, ext) - filename2 := strings.Replace(file, ext, "", -1) - fmt.Println(ext) - fmt.Println(filename) - fmt.Println(filename2) + testDecimalScale() } type BTC struct { diff --git a/internal/admin/repoitory/user_repository.go b/internal/admin/repoitory/user_repository.go index 6cda0c0..bf7e488 100644 --- a/internal/admin/repoitory/user_repository.go +++ b/internal/admin/repoitory/user_repository.go @@ -29,16 +29,17 @@ func (dao *UserRepository) FindByAccount(account string) (user *entity.User, err } func (dao *UserRepository) NextUid() (nextUid int64, err error) { - maxUid := int64(0) - err = dao.db.Select(&maxUid, "uid=(select userid from t_user)") + var maxUid *int64 + err = dao.db.Select(&maxUid, "select max(userid) from t_user") if err != nil { return } - if maxUid == 0 { - maxUid = 10000 + if maxUid == nil || *maxUid == 0 { + maxUid = new(int64) + *maxUid = 10000 } - nextUid = maxUid + rands.RandN(10) + nextUid = *maxUid + rands.RandN(10) return } diff --git a/internal/admin/service/auth_service.go b/internal/admin/service/auth_service.go index 289969b..3b9db4e 100644 --- a/internal/admin/service/auth_service.go +++ b/internal/admin/service/auth_service.go @@ -2,21 +2,24 @@ package service import ( "encoding/base64" + "fmt" "net/http" + "sig-pub/api/pb" "sig-pub/internal/admin/args" repository "sig-pub/internal/admin/repoitory" "sig-pub/pkg/config" "sig-pub/pkg/data/entity" "sig-pub/pkg/resp" "sig-pub/pkg/session" + "strconv" "time" "github.com/gin-gonic/gin" ) type AuthService struct { - repo *repository.UserRepository - aesKeyBytes []byte + repo *repository.UserRepository + aesKey []byte } func NewAuthService(repo *repository.UserRepository) *AuthService { @@ -30,10 +33,12 @@ func (svc *AuthService) Route(group *gin.RouterGroup) { if err != nil { panic(err) } - svc.aesKeyBytes, err = base64.StdEncoding.DecodeString(aesKey) + svc.aesKey, err = base64.StdEncoding.DecodeString(aesKey) if err != nil { panic(err) } + + group.POST("login", svc.Login) // 登录接口 } func (s *AuthService) Login(ctx *gin.Context) { @@ -51,12 +56,8 @@ func (s *AuthService) Login(ctx *gin.Context) { ctx.JSON(http.StatusInternalServerError, resp.Fail(err.Error())) return } - if len(req.Password) < 6 { - ctx.JSON(http.StatusBadRequest, gin.H{"error": "password length must be at least 6"}) - return - } - if user == nil { + if user == nil || user.UserId == 0 { // 不存在注册 now := time.Now().UnixMilli() uid, err := s.repo.NextUid() @@ -67,8 +68,9 @@ func (s *AuthService) Login(ctx *gin.Context) { user = &entity.User{ UserId: uid, Account: req.Account, - Username: req.Account, + Username: fmt.Sprintf("sig-%s", strconv.FormatInt(uid, 36)), Password: req.Password, + Role: pb.Role_User, CreateAt: now, UpdateAt: now, } @@ -77,7 +79,6 @@ func (s *AuthService) Login(ctx *gin.Context) { ctx.JSON(http.StatusInternalServerError, resp.Fail(err.Error())) return } - // return nil, errors.New("not found account " + req.Account) } // verify password login if req.Password != user.Password { @@ -86,10 +87,14 @@ func (s *AuthService) Login(ctx *gin.Context) { } // generate token - rpcSubject := session.NewRpcSubject(user.UserId, user.Account, nil) - _ = rpcSubject - // session.RpcSubjectGenToken() - - // res := &auth.ResLogin{Token: token, Subject: subject} - return + rpcSubject := session.NewRpcSubject(user.UserId, user.Account, user.Role, nil) + token, err := session.RpcSubjectGenToken(s.aesKey, rpcSubject) + if err != nil { + ctx.JSON(http.StatusInternalServerError, resp.Fail(err.Error())) + return + } + ctx.JSON(http.StatusOK, resp.Success(resp.H{ + "token": token, + "subject": rpcSubject, + })) } diff --git a/internal/exchange/exchange_service.go b/internal/exchange/exchange_service.go index 3d612d6..b70b318 100644 --- a/internal/exchange/exchange_service.go +++ b/internal/exchange/exchange_service.go @@ -13,7 +13,7 @@ import ( "sig-pub/pkg/publish" "sig-pub/pkg/types" "sig-pub/pkg/utils/collect" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" "sig-pub/pkg/utils/retry" "sig-pub/pkg/utils/times" "sig-pub/pkg/zlog" @@ -815,8 +815,8 @@ func (svc *ExchangeService) HistoryKline(arg *pb.SeriesRange, recvBranch int, re // 检查k线是否连续进行补齐 if err = svc.paddingKlinesIfNotSeries(exchange, arg.InstId, interval, klines, - lang.Ternary(arg.Desc, nil, prevLastK), - lang.Ternary(arg.Desc, prevFirstK, nil), + misc.Ternary(arg.Desc, nil, prevLastK), + misc.Ternary(arg.Desc, prevFirstK, nil), ); err != nil { return } diff --git a/internal/trading/backtest/trade_account.go b/internal/trading/backtest/trade_account.go index 7353822..0543d6f 100644 --- a/internal/trading/backtest/trade_account.go +++ b/internal/trading/backtest/trade_account.go @@ -7,7 +7,7 @@ import ( "sig-pub/pkg/types/decimals" "sig-pub/pkg/utils/collect" "sig-pub/pkg/utils/conver" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" "sig-pub/pkg/zlog" "time" @@ -200,8 +200,8 @@ func (a *BacktestTradeAccount) CloseTradeOrder(ticket trade.TradeTicket) (err er entryTrades++ entryPxs += trade.Price order.EntryFee += trade.Fee - order.EntryTime = lang.Ternary(order.EntryTime == 0, trade.Ctime, min(order.EntryTime, trade.Ctime)) - order.PeakPx = lang.Ternary( + order.EntryTime = misc.Ternary(order.EntryTime == 0, trade.Ctime, min(order.EntryTime, trade.Ctime)) + order.PeakPx = misc.Ternary( trade.Side == types.SideLong, max(order.PeakPx, trade.PeakPx), min(order.PeakPx, trade.PeakPx), diff --git a/internal/trading/trading_grpc_server.go b/internal/trading/trading_grpc_server.go index ff349b0..e06ac25 100644 --- a/internal/trading/trading_grpc_server.go +++ b/internal/trading/trading_grpc_server.go @@ -6,7 +6,7 @@ import ( "sig-pub/api/pb" "sig-pub/pkg/types" "sig-pub/pkg/utils/collect" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" "sig-pub/pkg/utils/times" "sig-pub/pkg/zlog" @@ -58,7 +58,7 @@ func (svr *TradingGrpcServer) IndicatorMetas(ctx context.Context, req *pb.ReqInd Name: input.Name, Desc: input.Desc, Type: int32(input.Type), - Default: lang.Ternary(input.Default == nil, "", fmt.Sprintf("%v", input.Default)), + Default: misc.Ternary(input.Default == nil, "", fmt.Sprintf("%v", input.Default)), Options: collect.Mapping(input.Options, func(opt types.InputOption) *pb.InputOption { return &pb.InputOption{ Name: opt.Name, @@ -191,7 +191,7 @@ func (svr *TradingGrpcServer) BacktestLog(ctx context.Context, req *pb.ReqBackte // BacktestRace 交易计划参数调试回测 func (svr *TradingGrpcServer) BacktestRace(ctx context.Context, req *pb.ReqBacktestRace) (rsp *pb.RspBacktestRace, err error) { rsp = new(pb.RspBacktestRace) - lang.SafeGo(func() { + misc.SafeGo(func() { c := context.Background() err := svr.tradingService.BacktestRace(c, req) if err != nil { diff --git a/internal/trading/trading_service.go b/internal/trading/trading_service.go index 0075f28..6a1adf1 100644 --- a/internal/trading/trading_service.go +++ b/internal/trading/trading_service.go @@ -15,7 +15,7 @@ import ( "sig-pub/pkg/trade" "sig-pub/pkg/types" "sig-pub/pkg/utils/collect" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" "sig-pub/pkg/utils/times" "sig-pub/pkg/zlog" "sort" @@ -285,7 +285,7 @@ func (svc *TradingService) IndicatorSeries(ctx context.Context, indicatorName st sr.WindowExtra = uint32(max(0, candlePeriods-1)) + uint32(appros) indicatorStates := indicator.Meta().State // 指标导出状态 - digit = lang.Ternary(digit > 0 && digit <= 10, digit, 6) // 保留小数位数 + digit = misc.Ternary(digit > 0 && digit <= 10, digit, 6) // 保留小数位数 pow := math.Pow(10, float64(digit)) matrix = make([]float64, 0, 200) times = make([]int64, 0, 200) @@ -358,9 +358,9 @@ func (svc *TradingService) StrategySeries(ctx context.Context, req *pb.ReqStrate // todo 多币种回测 return } - side := lang.Ternary(sigSide == types.SideLong, pb.Side_BUY, pb.Side_SELL) + side := misc.Ternary(sigSide == types.SideLong, pb.Side_BUY, pb.Side_SELL) rsp.Signal = append(rsp.Signal, int32(side)) - rsp.Direction = append(rsp.Direction, lang.Ternary[int32](k.OpenF64() > k.CloseF64(), 1, 2)) + rsp.Direction = append(rsp.Direction, misc.Ternary[int32](k.OpenF64() > k.CloseF64(), 1, 2)) rsp.Prices = append(rsp.Prices, k.CloseF64()) // 处理k线时间 ktime := k.Ts diff --git a/pkg/data/entity/user.go b/pkg/data/entity/user.go index b4b7b77..8007f25 100644 --- a/pkg/data/entity/user.go +++ b/pkg/data/entity/user.go @@ -1,14 +1,17 @@ package entity +import "sig-pub/api/pb" + // User 用户 type User struct { - UserId int64 `gorm:"column:userid;primaryKey;" json:"userId"` // 用户id - Account string `gorm:"column:account" json:"account"` // 登录账号 - Username string `gorm:"column:username" json:"username"` // 用户名 - Password string `gorm:"column:password" json:"password"` // 密码 - Avatar string `gorm:"column:avatar" json:"avatar"` // 头像 - CreateAt int64 `gorm:"column:create_at" json:"createAt"` // 创建时间 - UpdateAt int64 `gorm:"column:update_at" json:"updateAt"` // 更新时间 + UserId int64 `gorm:"column:userid;primaryKey;" json:"userId"` // 用户id + Account string `gorm:"column:account" json:"account"` // 登录账号 + Username string `gorm:"column:username" json:"username"` // 用户名 + Password string `gorm:"column:password" json:"password"` // 密码 + Avatar string `gorm:"column:avatar" json:"avatar"` // 头像 + Role pb.Role `gorm:"column:role" json:"role"` // 角色 0:普通用户 1:管理员 + CreateAt int64 `gorm:"column:create_at" json:"createAt"` // 创建时间 + UpdateAt int64 `gorm:"column:update_at" json:"updateAt"` // 更新时间 } func (User) TableName() string { diff --git a/pkg/session/session.go b/pkg/session/session.go index 7614183..c7d6341 100644 --- a/pkg/session/session.go +++ b/pkg/session/session.go @@ -9,8 +9,8 @@ import ( "google.golang.org/protobuf/proto" ) -func NewRpcSubject(userId int64, account string, extra map[string]string) (subject *pb.RpcSubject) { - subject = &pb.RpcSubject{Uid: userId, Account: account, Time: time.Now().UnixMilli(), Extra: extra} +func NewRpcSubject(userId int64, account string, role pb.Role, extra map[string]string) (subject *pb.RpcSubject) { + subject = &pb.RpcSubject{Uid: userId, Account: account, Role: role, Time: time.Now().UnixMilli(), Extra: extra} return } diff --git a/pkg/strategy/bollgrid.go b/pkg/strategy/bollgrid.go new file mode 100644 index 0000000..0f8e037 --- /dev/null +++ b/pkg/strategy/bollgrid.go @@ -0,0 +1,97 @@ +package strategy + +import ( + "sig-pub/pkg/types" +) + +// BollGrid 布林带网格策略 +// 基于布林带中轨(SMA)和标准差(StdDev)构建动态网格 +// 利用布林带指标计算出的中轨和上轨反推标准差 +// 当价格下穿下方网格线时做多 +// 当价格上穿上方网格线时做空 +type BollGrid struct { + period int16 // 布林带周期 + gridStep float64 // 网格间距(标准差倍数) + gridSize int16 // 单侧网格数量 +} + +func (s *BollGrid) New() ISigStrategy { + return &BollGrid{} +} + +func (s *BollGrid) Meta() StrategyMeta { + return StrategyMeta{ + Name: "BollGrid", + Desc: "基于布林带标准差的动态网格策略", + Input: []types.InputArg{ + {Name: "period", Type: types.InputTypeUInt, Desc: "布林带周期", Default: 20}, + {Name: "gridStep", Type: types.InputTypeUFloat, Desc: "网格间距(标准差倍数)", Default: 1.0}, + {Name: "gridSize", Type: types.InputTypeUInt, Desc: "单侧网格数量", Default: 3}, + }, + } +} + +func (s *BollGrid) Init(input types.Input) (err error) { + s.period = input.Int16("period") + s.gridStep = input.Float("gridStep") + s.gridSize = input.Int16("gridSize") + return +} + +func (s *BollGrid) CandlePeriods(ctx ISingleSigStrategyContext) int16 { + return max( + ctx.Indicator("BOLL", s.period).CandlePeriods(), + 2, // 需要前一根K线判断交叉 + ) +} + +func (s *BollGrid) Update(ctx ISingleSigStrategyContext) (side types.Side) { + // 获取指标数据 + // BOLL指标 Calculate 返回值为 mb (中轨) + bollInd := ctx.Indicator("BOLL", s.period) + mb := bollInd.Get(0) + ub := bollInd.State("ub", 0) // 上轨 (mb + 2*sigma) + + // 计算标准差 sigma + // 默认 BOLL 实现中,ub = mb + 2 * sigma + sigma := (ub - mb) / 2.0 + if sigma == 0 { + return types.SideNone + } + + // 获取前一根指标数据用于判断交叉 + mbPrev := bollInd.Get(1) + ubPrev := bollInd.State("ub", 1) + sigmaPrev := (ubPrev - mbPrev) / 2.0 + + // 获取K线收盘价 + closeP := ctx.Get(0).CloseF64() + closePrev := ctx.Get(1).CloseF64() + + // 遍历网格层级 + for i := int16(1); i <= s.gridSize; i++ { + stepMul := float64(i) * s.gridStep + + // 下方网格线: MB - i * step * sigma + lower := mb - sigma*stepMul + lowerPrev := mbPrev - sigmaPrev*stepMul + + // 价格下穿下方网格线 -> 买入信号 + // Close[1] >= Lower[1] && Close[0] < Lower[0] + if closePrev >= lowerPrev && closeP < lower { + return types.SideLong + } + + // 上方网格线: MB + i * step * sigma + upper := mb + sigma*stepMul + upperPrev := mbPrev + sigmaPrev*stepMul + + // 价格上穿上方网格线 -> 卖出信号 + // Close[1] <= Upper[1] && Close[0] > Upper[0] + if closePrev <= upperPrev && closeP > upper { + return types.SideShort + } + } + + return +} diff --git a/pkg/strategy/grid.go b/pkg/strategy/grid.go new file mode 100644 index 0000000..78c9424 --- /dev/null +++ b/pkg/strategy/grid.go @@ -0,0 +1,87 @@ +package strategy + +import ( + "sig-pub/pkg/types" +) + +// Grid 网格策略 +// 基于均线和ATR构建动态网格 +// 当价格下穿下方网格线时做多 +// 当价格上穿上方网格线时做空 +type Grid struct { + period int16 // 均线和ATR周期 + gridStep float64 // 网格间距(ATR倍数) + gridSize int16 // 单侧网格数量 +} + +func (s *Grid) New() ISigStrategy { + return &Grid{} +} + +func (s *Grid) Meta() StrategyMeta { + return StrategyMeta{ + Name: "Grid", + Desc: "基于ATR的动态网格策略", + Input: []types.InputArg{ + {Name: "period", Type: types.InputTypeUInt, Desc: "EMA和ATR周期", Default: 20}, + {Name: "gridStep", Type: types.InputTypeUFloat, Desc: "网格间距(ATR倍数)", Default: 1.0}, + {Name: "gridSize", Type: types.InputTypeUInt, Desc: "单侧网格数量", Default: 5}, + }, + } +} + +func (s *Grid) Init(input types.Input) (err error) { + s.period = input.Int16("period") + s.gridStep = input.Float("gridStep") + s.gridSize = input.Int16("gridSize") + return +} + +func (s *Grid) CandlePeriods(ctx ISingleSigStrategyContext) int16 { + return max( + ctx.Indicator("EMA", s.period).CandlePeriods(), + ctx.Indicator("ATR", s.period).CandlePeriods(), + 2, // 需要前一根K线判断交叉 + ) +} + +func (s *Grid) Update(ctx ISingleSigStrategyContext) (side types.Side) { + // 获取指标数据 + ema := ctx.Indicator("EMA", s.period).Get(0) + atr := ctx.Indicator("ATR", s.period).Get(0) + + // 获取前一根指标数据用于判断交叉 + emaPrev := ctx.Indicator("EMA", s.period).Get(1) + atrPrev := ctx.Indicator("ATR", s.period).Get(1) + + // 获取K线收盘价 + closeP := ctx.Get(0).CloseF64() + closePrev := ctx.Get(1).CloseF64() + + // 遍历网格层级 + for i := int16(1); i <= s.gridSize; i++ { + step := float64(i) * s.gridStep + + // 下方网格线 + lower := ema - atr*step + lowerPrev := emaPrev - atrPrev*step + + // 价格下穿下方网格线 -> 买入信号 + // Close[1] >= Lower[1] && Close[0] < Lower[0] + if closePrev >= lowerPrev && closeP < lower { + return types.SideLong + } + + // 上方网格线 + upper := ema + atr*step + upperPrev := emaPrev + atrPrev*step + + // 价格上穿上方网格线 -> 卖出信号 + // Close[1] <= Upper[1] && Close[0] > Upper[0] + if closePrev <= upperPrev && closeP > upper { + return types.SideShort + } + } + + return +} diff --git a/pkg/strategy/sig_strategy_registry.go b/pkg/strategy/sig_strategy_registry.go index de1d960..77438cc 100644 --- a/pkg/strategy/sig_strategy_registry.go +++ b/pkg/strategy/sig_strategy_registry.go @@ -29,6 +29,8 @@ func (r *SigStrategyRegistry) Init() (err error) { r.MustRegistStrategy(&SuperTrend2Macd{}) r.MustRegistStrategy(&SuperTrendMacdRSI{}) r.MustRegistStrategy(&TrendTrackV1{}) + r.MustRegistStrategy(&Grid{}) + r.MustRegistStrategy(&BollGrid{}) return } diff --git a/pkg/strategy/strategy.go b/pkg/strategy/strategy.go index bc058f4..3ee8d9a 100644 --- a/pkg/strategy/strategy.go +++ b/pkg/strategy/strategy.go @@ -5,7 +5,7 @@ import ( "sig-pub/api/pb" "sig-pub/pkg/types" "sig-pub/pkg/utils/collect" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" "strings" ) @@ -34,7 +34,7 @@ const ( func DriverIntervalKey(instId string, exchange pb.ExchangeType, completed bool, intervals ...types.Interval) string { types.IntervalsSort(intervals) strIntervals := collect.Mapping(intervals, func(interval types.Interval) string { return string(interval) }) - pubKey := fmt.Sprintf("/interval/%s/%s/%s/%d", instId, exchange.String(), strings.Join(strIntervals, ","), lang.Ternary(completed, 1, 0)) + pubKey := fmt.Sprintf("/interval/%s/%s/%s/%d", instId, exchange.String(), strings.Join(strIntervals, ","), misc.Ternary(completed, 1, 0)) return pubKey } diff --git a/pkg/strategy/super_trend_bos_waves.go b/pkg/strategy/super_trend_bos_waves.go index e1d8fbb..8b69bed 100644 --- a/pkg/strategy/super_trend_bos_waves.go +++ b/pkg/strategy/super_trend_bos_waves.go @@ -2,7 +2,7 @@ package strategy import ( "sig-pub/pkg/types" - "sig-pub/pkg/utils/lang" + "sig-pub/pkg/utils/misc" ) type SupertrendBOSWaves struct { @@ -77,9 +77,9 @@ func (s *SupertrendBOSWaves) Update(ctx ISingleSigStrategyContext) (side types.S // Standard supertrend logic prevSupertrend := supertrend if direction == 1 { - supertrend = lang.Ternary(close < prevSupertrend, upperBand, max(lowerBand, prevSupertrend)) + supertrend = misc.Ternary(close < prevSupertrend, upperBand, max(lowerBand, prevSupertrend)) } else { - supertrend = lang.Ternary(close > prevSupertrend, lowerBand, min(upperBand, prevSupertrend)) + supertrend = misc.Ternary(close > prevSupertrend, lowerBand, min(upperBand, prevSupertrend)) } s.prevDirection = direction diff --git a/pkg/types/signal.go b/pkg/types/signal.go index abe064f..9a80e79 100644 --- a/pkg/types/signal.go +++ b/pkg/types/signal.go @@ -3,6 +3,7 @@ package types type Side int32 const ( + SideNone Side = 0 // NONE SideLong Side = 1 // LONG SideShort Side = 2 // SHORT ) @@ -19,7 +20,7 @@ func (side Side) Opposite() Side { case SideShort: return SideLong default: - return 0 + return SideNone } } diff --git a/pkg/utils/lang/concurrent.go b/pkg/utils/misc/concurrent.go similarity index 95% rename from pkg/utils/lang/concurrent.go rename to pkg/utils/misc/concurrent.go index 34e8828..f740905 100644 --- a/pkg/utils/lang/concurrent.go +++ b/pkg/utils/misc/concurrent.go @@ -1,4 +1,4 @@ -package lang +package misc import ( "runtime/debug" diff --git a/pkg/utils/lang/condition.go b/pkg/utils/misc/condition.go similarity index 96% rename from pkg/utils/lang/condition.go rename to pkg/utils/misc/condition.go index 5d4e771..50803de 100644 --- a/pkg/utils/lang/condition.go +++ b/pkg/utils/misc/condition.go @@ -1,4 +1,4 @@ -package lang +package misc // Ternary is a 1 line if/else statement. func Ternary[T any](condition bool, ifOutput T, elseOutput T) T { diff --git a/pkg/utils/lang/tuple.go b/pkg/utils/misc/tuple.go similarity index 79% rename from pkg/utils/lang/tuple.go rename to pkg/utils/misc/tuple.go index a06e4a8..86b8987 100644 --- a/pkg/utils/lang/tuple.go +++ b/pkg/utils/misc/tuple.go @@ -1,4 +1,4 @@ -package lang +package misc type Tuple2[V0, V1 any] struct { V0 V0