diff --git a/config/exchange.toml b/config/exchange.toml index c0a42b7..4d567a5 100644 --- a/config/exchange.toml +++ b/config/exchange.toml @@ -18,8 +18,8 @@ receiveBuffer = 4096 marketSubscribeLimit = 16 consumeBatch = 1024 consumeLater = 2000 # 时间到达later或者数据累计到batch触发consume -httpProxy = "http://192.168.1.5:7890" -# httpProxy = "http://10.255.183.209:7890" +# httpProxy = "http://192.168.1.5:7890" +httpProxy = "http://10.255.183.209:7890" # 模拟盘API交易地址如下: # REST:https://www.okx.com diff --git a/internal/trading/trading_plan.go b/internal/trading/trading_plan.go index cb428ab..a732a87 100644 --- a/internal/trading/trading_plan.go +++ b/internal/trading/trading_plan.go @@ -15,7 +15,7 @@ type TradingPlan struct { StrategyName string `json:"strategyName"` } -func NewTradingPlan(plan entity.TradingPlan, strategy strategy.IStrategy) *TradingPlan { +func NewTradingPlan(plan entity.TradingPlan, strategy strategy.ISigStrategy) *TradingPlan { return &TradingPlan{} } diff --git a/internal/trading/trading_service.go b/internal/trading/trading_service.go index 1184824..da2923c 100644 --- a/internal/trading/trading_service.go +++ b/internal/trading/trading_service.go @@ -14,11 +14,11 @@ type TradingService struct { marketClientAside *client.TradeInstanceAside exchangeClient pb.ExchangeServiceClient - klineStore *KlineStore - windowIndicators *collect.SyncMap[string, indicator.IWindowIndicator] - strategies *collect.SyncMap[string, strategy.IStrategy] - publisher publish.Publisher[int64, *TradingPlan] - tradingPlan chan *TradingPlan + klineStore *KlineStore + indicatorsW *collect.SyncMap[string, indicator.IWindowIndicator] // 注册窗口指标 + strategies *collect.SyncMap[string, strategy.ISigStrategy] // 注册信号策略 + publisher publish.Publisher[int64, *TradingPlan] + tradingPlan chan *TradingPlan } func NewTradingService( @@ -29,7 +29,8 @@ func NewTradingService( marketClientAside: marketClientAside, exchangeClient: exchangeClient, klineStore: NewKlineSeriesStore(exchangeClient), - windowIndicators: collect.NewSyncMap[string, indicator.IWindowIndicator](), + indicatorsW: collect.NewSyncMap[string, indicator.IWindowIndicator](), + strategies: collect.NewSyncMap[string, strategy.ISigStrategy](), } } @@ -55,7 +56,7 @@ func (svr *TradingService) Init() (err error) { // RegisterWindowIndicator func (svr *TradingService) RegisterWindowIndicator(ind indicator.IWindowIndicator) (err error) { indName := ind.Name() - _, loaded := svr.windowIndicators.LoadOrStore(indName, ind) + _, loaded := svr.indicatorsW.LoadOrStore(indName, ind) if loaded { err = fmt.Errorf("window indicator name %s already duplicated", indName) return @@ -70,7 +71,7 @@ func (svr *TradingService) MustRegisterWindowIndicator(ind indicator.IWindowIndi } // RegisterStrategy -func (svr *TradingService) RegisterStrategy(strategy strategy.IStrategy) (err error) { +func (svr *TradingService) RegisterStrategy(strategy strategy.ISigStrategy) (err error) { strategyName := strategy.Meta().Name _, loaded := svr.strategies.LoadOrStore(strategyName, strategy) if loaded { @@ -80,7 +81,7 @@ func (svr *TradingService) RegisterStrategy(strategy strategy.IStrategy) (err er return } -func (svr *TradingService) MustRegisterStrategy(strategy strategy.IStrategy) { +func (svr *TradingService) MustRegisterStrategy(strategy strategy.ISigStrategy) { if err := svr.RegisterStrategy(strategy); err != nil { panic(err) } diff --git a/pkg/backtrace/backtrace.go b/pkg/backtrace/backtrace.go index 5f3f4b6..92154fc 100644 --- a/pkg/backtrace/backtrace.go +++ b/pkg/backtrace/backtrace.go @@ -4,7 +4,7 @@ import "sig-pub/pkg/strategy" // 回测引擎 type BacktraceEngine struct { - strategy strategy.IStrategy + strategy strategy.ISigStrategy } // 多周期策略回测引擎 diff --git a/pkg/data/entity/trade_plan.go b/pkg/data/entity/trade_plan.go index 0c5e30e..3d991af 100644 --- a/pkg/data/entity/trade_plan.go +++ b/pkg/data/entity/trade_plan.go @@ -6,14 +6,14 @@ import ( ) type TradingPlan struct { - Id int64 `gorm:"column:id;primaryKey" json:"id"` // 交易计划id - Userid string `gorm:"column:userid" json:"userid"` // 所属用户id - Exchange pb.ExchangeType `gorm:"column:exchange" json:"exchange"` // 交易所 - InstId string `gorm:"column:instId" json:"instId"` // 交易产品 - Interval types.Interval `gorm:"column:interval" json:"interval"` // 交易周期 - StrategyName string `gorm:"column:strategy_name" json:"strategyName"` // 策略名称 - UpdateBy string `gorm:"column:update_by" json:"updateBy"` // 更新人 - UpdateTime int64 `gorm:"column:update_time" json:"updateTime"` // 更新时间戳毫秒 + Id int64 `gorm:"column:id;primaryKey" json:"id"` // 交易计划id + Userid string `gorm:"column:userid" json:"userid"` // 所属用户id + Exchange pb.ExchangeType `gorm:"column:exchange" json:"exchange"` // 交易所 + InstId string `gorm:"column:instId" json:"instId"` // 交易产品 + Interval types.Interval `gorm:"column:interval" json:"interval"` // 交易周期 + Strategy string `gorm:"column:strategy" json:"strategy"` // 策略名称 + UpdateBy string `gorm:"column:update_by" json:"updateBy"` // 更新人 + UpdateTime int64 `gorm:"column:update_time" json:"updateTime"` // 更新时间戳毫秒 } func (TradingPlan) TableName() string { diff --git a/pkg/strategy/buy_strategy.go b/pkg/strategy/buy_strategy.go new file mode 100644 index 0000000..bec1336 --- /dev/null +++ b/pkg/strategy/buy_strategy.go @@ -0,0 +1,5 @@ +package strategy + +// TradeStrategy 下单买入策略接口(控制滑点, 仓位管理) +type TradeStrategy interface { +} diff --git a/pkg/strategy/exit_strategy.go b/pkg/strategy/exit_strategy.go new file mode 100644 index 0000000..e2572a6 --- /dev/null +++ b/pkg/strategy/exit_strategy.go @@ -0,0 +1,13 @@ +package strategy + +import "github.com/govalues/decimal" + +// todo Exit 止盈止损策略(trading service 管理) +type IExitStrategy interface { + Name() string // 获取策略名称,便于日志 + Tick(ctx IExitStrategyContext) +} + +type IExitStrategyContext interface { + LastPrice() decimal.Decimal +} diff --git a/pkg/strategy/gold_x.go b/pkg/strategy/gold_x.go index 8817222..2f2e7b0 100644 --- a/pkg/strategy/gold_x.go +++ b/pkg/strategy/gold_x.go @@ -4,7 +4,7 @@ package strategy type GoldX struct { } -func (s *GoldX) New() IStrategy { +func (s *GoldX) New() ISigStrategy { return &GoldX{} } @@ -15,7 +15,7 @@ func (s *GoldX) Meta() StrategyMeta { } } -func (s *GoldX) Update(ctx IStrategyContext) { +func (s *GoldX) Update(ctx ISigStrategyContext) { sma14 := ctx.IndicatorW("sma", 14) sma28 := ctx.IndicatorW("sma", 28) // 包装方法 diff --git a/pkg/strategy/strategy.go b/pkg/strategy/sig_strategy.go similarity index 63% rename from pkg/strategy/strategy.go rename to pkg/strategy/sig_strategy.go index 172f9f9..3f54288 100644 --- a/pkg/strategy/strategy.go +++ b/pkg/strategy/sig_strategy.go @@ -10,16 +10,16 @@ import ( "strings" ) -// todo Exit 止盈止损策略(trading service 管理) -type IStrategy interface { - New() IStrategy +// ISigStrategy 交易信号策略接口 +type ISigStrategy interface { + New() ISigStrategy Meta() StrategyMeta - Update(ctx IStrategyContext) + Update(ctx ISigStrategyContext) } // todo Meta 策略调参, 回测引擎自动调参回测(最佳参数) argGenerator.next() (arg, ok) -type IStrategyAdjustable interface { - IStrategy +type ISigStrategyAdjustable interface { + ISigStrategy NextParams() map[string]any // 根据当前策略参数, 返回下一批策略参数(并行回测 stateless) AdjustParams(map[string]any) // 重置策略设置策略参数 } @@ -30,9 +30,9 @@ type StrategyMeta struct { Desc string } -// IStrategyContext 策略外部访问能力 +// ISigStrategyContext 策略外部访问能力 // klineSeries, Indicator -type IStrategyContext interface { +type ISigStrategyContext interface { Buy() // 发出多信号 Sell() // 发出空信号 @@ -45,11 +45,11 @@ type IStrategyContext interface { } // DriverIntervalKey 生成周期驱动事件key -// interval/okx/BTC_USDT/1m,3m,5m -func DriverIntervalKey(exchangeType pb.ExchangeType, instId string, intervals ...types.Interval) string { +// interval/BTC_USDT/OKX,BINANCE/1m,3m,5m +func DriverIntervalKey(instId string, intervals []types.Interval, exchanges ...pb.ExchangeType) string { types.IntervalsSort(intervals) strIntervals := collect.Mapping(intervals, func(_ int, interval types.Interval) string { return string(interval) }) - - pubKey := fmt.Sprintf("/interval/%s/%s/%s", exchangeType.String(), instId, strings.Join(strIntervals, ",")) + strExchanges := collect.Mapping(exchanges, func(_ int, exchange pb.ExchangeType) string { return exchange.String() }) + pubKey := fmt.Sprintf("/interval/%s/%s/%s", instId, strings.Join(strExchanges, ","), strings.Join(strIntervals, ",")) return pubKey } diff --git a/pkg/strategy/strategy_multi_interval.go b/pkg/strategy/strategy_multi_interval.go index 58dc952..b330951 100644 --- a/pkg/strategy/strategy_multi_interval.go +++ b/pkg/strategy/strategy_multi_interval.go @@ -4,15 +4,15 @@ import "sig-pub/pkg/types" // 多k线周期策略 type MultiIntervalStrategy interface { - IStrategy + ISigStrategy DriverInterval() types.Interval // 驱动k线周期, 当驱动周期k线更新时则判断调用Update方法 SubscribeIntervals() []types.Interval // 订阅k线周期, 当同一时间的订阅周期都更新时调用Update方法 } type MultiExchangeStrategy interface { - IStrategy + ISigStrategy } type MultiIntervalExchangeStrategy interface { - IStrategy + ISigStrategy }