feat: 接入 CoinGlass 清算热力图隔离链路
Some checks failed
ci / build + vet + guard + race (push) Has been cancelled

This commit is contained in:
dela
2026-05-25 16:57:22 +08:00
parent e5fb54cb72
commit 1b61541ff5
32 changed files with 2550 additions and 70 deletions

View File

@@ -15,6 +15,7 @@ import (
"cryptoHermes/internal/controller/restapi"
"cryptoHermes/internal/repo/persistent/postgres"
"cryptoHermes/internal/repo/webapi/binance"
coinglassapi "cryptoHermes/internal/repo/webapi/coinglass"
"cryptoHermes/internal/usecase"
"cryptoHermes/internal/worker"
pgpkg "cryptoHermes/pkg/postgres"
@@ -47,6 +48,7 @@ func Run(cfg *config.Config, log *slog.Logger) error {
oiRepo := postgres.NewOpenInterestRepo(pool)
lsRepo := postgres.NewLongShortRatioRepo(pool)
takerRepo := postgres.NewTakerVolumeRepo(pool)
cgLiqRepo := postgres.NewCoinglassLiqHeatMapRepo(pool)
contextUC := usecase.NewMarketContextUsecase(
binanceClient,
@@ -67,23 +69,56 @@ func Run(cfg *config.Config, log *slog.Logger) error {
lsRepo,
)
collector := worker.NewCollector(worker.Deps{
MarketData: binanceClient,
Derivatives: binanceClient,
KlineRepo: klineRepo,
FundingRepo: fundingRepo,
OIRepo: oiRepo,
LSRepo: lsRepo,
TakerRepo: takerRepo,
Symbols: cfg.Collector.Symbols,
Intervals: cfg.Collector.Intervals,
Limit: cfg.Collector.DefaultLimit,
Logger: log,
})
cgQueryUC := usecase.NewCoinglassQueryUsecase(cgLiqRepo)
var collector *worker.Collector
if cfg.Collector.Enabled {
collector = worker.NewCollector(worker.Deps{
MarketData: binanceClient,
Derivatives: binanceClient,
KlineRepo: klineRepo,
FundingRepo: fundingRepo,
OIRepo: oiRepo,
LSRepo: lsRepo,
TakerRepo: takerRepo,
Symbols: cfg.Collector.Symbols,
Intervals: cfg.Collector.Intervals,
Limit: cfg.Collector.DefaultLimit,
Logger: log,
})
}
var cgCollector *worker.CoinglassCollector
if cfg.Coinglass.Enabled {
cgClient, err := coinglassapi.NewClient(coinglassapi.ClientOptions{
BaseURL: cfg.Coinglass.BaseURL,
TOTPSecret: cfg.Coinglass.TOTPSecret,
DataAESKey: cfg.Coinglass.DataAESKey,
Timeout: cfg.Coinglass.Timeout,
FakeSuccessRetry: cfg.Coinglass.FakeSuccessRetry,
FakeSuccessRetryWait: cfg.Coinglass.FakeSuccessRetryWait,
})
if err != nil {
return fmt.Errorf("coinglass client: %w", err)
}
cgCollector = worker.NewCoinglassCollector(worker.CoinglassCollectorDeps{
Provider: cgClient,
LiqHeatMapRepo: cgLiqRepo,
Symbols: cfg.Collector.Symbols,
LiqHeatMapInterval: cfg.Coinglass.LiqHeatMapInterval,
LiqHeatMapLimit: cfg.Coinglass.LiqHeatMapLimit,
BackoffInitial: cfg.Coinglass.BackoffInitial,
BackoffMax: cfg.Coinglass.BackoffMax,
Logger: log,
})
}
var sched *Scheduler
if cfg.Collector.Enabled {
if collector != nil || cgCollector != nil {
sched = NewScheduler(collector, log)
if cgCollector != nil {
sched.WithCoinglass(cgCollector, cfg.Coinglass.LiqHeatMapCron, cfg.Coinglass.StartupJitterMax)
}
sched.Start(rootCtx)
defer sched.Stop()
}
@@ -97,11 +132,13 @@ func Run(cfg *config.Config, log *slog.Logger) error {
})
restapi.Register(fiberApp, restapi.Deps{
Logger: log,
MarketContext: contextUC,
MarketQuery: queryUC,
MarketData: binanceClient,
KlineRepo: klineRepo,
Logger: log,
MarketContext: contextUC,
MarketQuery: queryUC,
CoinglassQuery: cgQueryUC,
CoinglassEnabled: cfg.Coinglass.Enabled,
MarketData: binanceClient,
KlineRepo: klineRepo,
})
listenErr := make(chan error, 1)