You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.5 KiB
101 lines
2.5 KiB
package trading |
|
|
|
import ( |
|
"fmt" |
|
"sig-pub/api/pb" |
|
"sig-pub/pkg/client" |
|
"sig-pub/pkg/indicator" |
|
"sig-pub/pkg/publish" |
|
"sig-pub/pkg/strategy" |
|
"sig-pub/pkg/utils/collect" |
|
) |
|
|
|
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 |
|
} |
|
|
|
func NewTradingService( |
|
marketClientAside *client.TradeInstanceAside, |
|
exchangeClient pb.ExchangeServiceClient, |
|
) *TradingService { |
|
return &TradingService{ |
|
marketClientAside: marketClientAside, |
|
exchangeClient: exchangeClient, |
|
klineStore: NewKlineSeriesStore(exchangeClient), |
|
windowIndicators: collect.NewSyncMap[string, indicator.IWindowIndicator](), |
|
} |
|
} |
|
|
|
// 初始化历史k线, 订阅实时k线 |
|
func (svr *TradingService) Init() (err error) { |
|
if err = svr.klineStore.Init(); err != nil { |
|
return |
|
} |
|
// indicator registry |
|
{ |
|
svr.MustRegisterWindowIndicator(&indicator.RSI{}) |
|
} |
|
// strategy registry |
|
{ |
|
svr.MustRegisterStrategy(&strategy.GoldX{}) |
|
} |
|
// strategy initial |
|
// 初始化策略执行器 64 |
|
|
|
return |
|
} |
|
|
|
// RegisterWindowIndicator |
|
func (svr *TradingService) RegisterWindowIndicator(ind indicator.IWindowIndicator) (err error) { |
|
indName := ind.Name() |
|
_, loaded := svr.windowIndicators.LoadOrStore(indName, ind) |
|
if loaded { |
|
err = fmt.Errorf("window indicator name %s already duplicated", indName) |
|
return |
|
} |
|
return |
|
} |
|
|
|
func (svr *TradingService) MustRegisterWindowIndicator(ind indicator.IWindowIndicator) { |
|
if err := svr.RegisterWindowIndicator(ind); err != nil { |
|
panic(err) |
|
} |
|
} |
|
|
|
// RegisterStrategy |
|
func (svr *TradingService) RegisterStrategy(strategy strategy.IStrategy) (err error) { |
|
strategyName := strategy.Meta().Name |
|
_, loaded := svr.strategies.LoadOrStore(strategyName, strategy) |
|
if loaded { |
|
err = fmt.Errorf("strategy name %s already duplicated", strategyName) |
|
return |
|
} |
|
return |
|
} |
|
|
|
func (svr *TradingService) MustRegisterStrategy(strategy strategy.IStrategy) { |
|
if err := svr.RegisterStrategy(strategy); err != nil { |
|
panic(err) |
|
} |
|
} |
|
|
|
// RunStrategy 运行策略 |
|
// todo 止盈止损... |
|
func (svr *TradingService) RunQuantPlan(plan TradingPlan) (err error) { |
|
strategy, ok := svr.strategies.Load(plan.StrategyName) |
|
if !ok { |
|
err = fmt.Errorf("strategy %s not exists", plan.StrategyName) |
|
return |
|
} |
|
runner := strategy.New() |
|
_ = runner |
|
runner.Update(nil) |
|
return |
|
}
|
|
|