为什么:先把测试与骨架同时落地,让"红灯先行"作为 commit 3 实现的
靶子。骨架函数全部返回零值,所有断言失败但无编译错误也无 panic。
变更:
- ports.go 新增 IndicatorComputer 接口;接收已 fetch 的 slice、
避免与 MarketContextUsecase 重复 IO(G1 + G12)
- internal/usecase/indicator.go:常量、pivotPoint、9 个 helper +
Compute 全部签名就位,实现先返零值
- internal/usecase/indicator_test.go:parsePrice/formatPrice/
percentile/medianFloat/pivot{Highs,Lows}/clusterLevels/
rangeHighLow/longShortCrossings/Compute 全部 table-driven
覆盖(含 V-shape、双顶 0.18%/0.45%、三聚类、N=1/2/20 percentile、
穿越保留 N、malformed 跳过等)
- go.mod 把 stretchr/testify v1.8.1 从 indirect 提升为 direct
65 lines
2.7 KiB
Go
65 lines
2.7 KiB
Go
package usecase
|
||
|
||
import (
|
||
"context"
|
||
|
||
"cryptoHermes/internal/entity"
|
||
)
|
||
|
||
type MarketDataProvider interface {
|
||
GetKlines(ctx context.Context, symbol, interval string, limit int) ([]entity.Kline, error)
|
||
GetKlinesRange(ctx context.Context, symbol, interval string, startMs, endMs int64, limit int) ([]entity.Kline, error)
|
||
GetTicker24h(ctx context.Context, symbol string) (*entity.Ticker24h, error)
|
||
}
|
||
|
||
type DerivativesProvider interface {
|
||
GetCurrentFunding(ctx context.Context, symbol string) (*entity.FundingRate, error)
|
||
GetFundingHistory(ctx context.Context, symbol string, limit int) ([]entity.FundingRate, error)
|
||
|
||
GetCurrentOpenInterest(ctx context.Context, symbol string) (*entity.OpenInterest, error)
|
||
GetOpenInterestHistory(ctx context.Context, symbol, period string, limit int) ([]entity.OpenInterest, error)
|
||
|
||
GetGlobalLongShortRatio(ctx context.Context, symbol, period string, limit int) ([]entity.LongShortRatio, error)
|
||
GetTopTraderPositionRatio(ctx context.Context, symbol, period string, limit int) ([]entity.LongShortRatio, error)
|
||
|
||
GetTakerBuySellVolume(ctx context.Context, symbol, period string, limit int) ([]entity.TakerBuySellVolume, error)
|
||
}
|
||
|
||
type KlineRepository interface {
|
||
UpsertMany(ctx context.Context, items []entity.Kline) error
|
||
FindRecent(ctx context.Context, symbol, interval string, limit int) ([]entity.Kline, error)
|
||
}
|
||
|
||
type FundingRepository interface {
|
||
UpsertMany(ctx context.Context, items []entity.FundingRate) error
|
||
FindRecent(ctx context.Context, symbol string, limit int) ([]entity.FundingRate, error)
|
||
}
|
||
|
||
type OpenInterestRepository interface {
|
||
UpsertMany(ctx context.Context, items []entity.OpenInterest) error
|
||
FindRecent(ctx context.Context, symbol, period string, limit int) ([]entity.OpenInterest, error)
|
||
}
|
||
|
||
type LongShortRatioRepository interface {
|
||
UpsertMany(ctx context.Context, items []entity.LongShortRatio) error
|
||
FindRecent(ctx context.Context, symbol, period, ratioType string, limit int) ([]entity.LongShortRatio, error)
|
||
}
|
||
|
||
type TakerVolumeRepository interface {
|
||
UpsertMany(ctx context.Context, items []entity.TakerBuySellVolume) error
|
||
FindRecent(ctx context.Context, symbol, period string, limit int) ([]entity.TakerBuySellVolume, error)
|
||
}
|
||
|
||
// IndicatorComputer 纯函数式接口:接收已经被上层 fetch 的 slice,
|
||
// 返回填充好的 TechnicalStructure。
|
||
//
|
||
// 不持有任何 repo 引用——保住 G1(usecase 不依赖 repo 实现)和
|
||
// G12(indicator 包零 repo 导入)。MarketContextUsecase 已经并发 fetch
|
||
// 过 kline 与 long-short ratio,复用结果即可,二次注入仓库引用会
|
||
// 重复 IO。
|
||
//
|
||
// 实现可见 internal/usecase/indicator.go。
|
||
type IndicatorComputer interface {
|
||
Compute(klines []entity.Kline, longShort []entity.LongShortRatio) entity.TechnicalStructure
|
||
}
|