Files
cryptoHermes/internal/usecase/ports.go
dela 21b3078094 feat(indicator): per-interval S/R + Range + LSLine + Donchian 箱体(ADR-0003)
按 ADR-0003 把 Support / Resistance / Range / LSLine 从顶层下沉进
IntervalTechnicals,每个周期独立计算;顶层 5 字段保留为 Intervals[primary]
镜像(单一来源,不双写)以维持向后兼容的 JSON shape。

新增 BoxBreak(Donchian 风格,lookback=20 根不含当前根,K 线 < 21 → nil),
落到 IntervalTechnicals.Box。

IndicatorComputer.Compute 签名升级到 longShortByInterval map:
market_context 改为并发拉取 15m/1h/4h/1d 的全局 LSR,1w 不在 Binance LSR
支持列表 → 加 warning lsr_unsupported_interval:1w。

测试:boxBreak 6 个 case(inside/break_up/break_down/insufficient/2 个 parse
失败)+ per-interval Support/Resistance/Range 跨周期断言 + 镜像不变量 +
缺 LSR key → LongShortLine nil。indicator.go 平均覆盖 97.26%(boxBreak 100%)。
2026-05-25 10:44:33 +08:00

93 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 引用——保住 G1usecase 不依赖 repo 实现)和
// G12indicator 包零 repo 导入。MarketContextUsecase 已经并发 fetch
// 过 kline 与 long-short ratio复用结果即可二次注入仓库引用会
// 重复 IO。
//
// klinesByInterval 是按周期分组的 K 线 map每周期一份升序切片
// primaryInterval 决定顶层 TechnicalStructure 镜像哪个周期;所有周期
// 都会独立填充进 Intervals。longShortByInterval 按周期分组的 LSR map
// (某周期缺失时,该周期 IntervalTechnicals.LongShortLine 为 nil
// 实现可见 internal/usecase/indicator.go。
type IndicatorComputer interface {
Compute(
klinesByInterval map[string][]entity.Kline,
primaryInterval string,
longShortByInterval map[string][]entity.LongShortRatio,
) entity.TechnicalStructure
}
// DerivativesSignalComputer 把 funding/OI/LSR 的原始数据翻译成
// 可读语义crowded_long、long_building 之类)。
//
// 与 IndicatorComputer 一样是纯函数式接口、零 repo 依赖。
//
// primaryKlines 是用来给 OI 信号做"价格方向"判定的OI 在涨时,配合
// 价格涨 → long_building价格跌 → short_buildingfunding 不参与 OI
// 判定,避免价格下跌但 funding 仍为正时被误判)。
//
// 返回 warnings 用来告诉调用方"哪一项数据不够、对应字段为什么留空"
// 由调用方合并到 DataQuality.Warnings。signal 整体不可判时返回 nil。
type DerivativesSignalComputer interface {
Compute(
currentFunding *entity.FundingRate,
oiHistory []entity.OpenInterest,
globalLSR []entity.LongShortRatio,
primaryKlines []entity.Kline,
) (*entity.DerivativesSignal, []string)
}