feat(domain/socket): 시장 데이터와 백테스트 소켓에 multi-timeframe 지원을 추가한다
packages/domain/market: timeframemap 타입 추가 및 테스트 services/api/internal/socket/market: multi-timeframe 소켓 메시지 지원 services/worker/internal/socket/backtest_mapping: 백테스트 매핑 함수에 multi-timeframe 반영
This commit is contained in:
parent
7c1e36cefa
commit
9d8dde6dc9
6 changed files with 40 additions and 5 deletions
|
|
@ -30,6 +30,7 @@ const (
|
|||
type Timeframe string
|
||||
|
||||
const (
|
||||
TimeframeMonthly Timeframe = "1mo"
|
||||
TimeframeDaily Timeframe = "1d"
|
||||
TimeframeMin1 Timeframe = "1m"
|
||||
TimeframeMin5 Timeframe = "5m"
|
||||
|
|
|
|||
|
|
@ -79,6 +79,23 @@ func TestMarketVenueMetadata(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTimeframeVocabulary(t *testing.T) {
|
||||
cases := []struct {
|
||||
timeframe Timeframe
|
||||
want string
|
||||
}{
|
||||
{TimeframeMonthly, "1mo"},
|
||||
{TimeframeDaily, "1d"},
|
||||
{TimeframeMin1, "1m"},
|
||||
{TimeframeMin5, "5m"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if string(c.timeframe) != c.want {
|
||||
t.Errorf("timeframe %q: got %q, want %q", c.want, string(c.timeframe), c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderCapabilityRequireDailyBars(t *testing.T) {
|
||||
// A KIS-like capability serving both KR and US daily bars.
|
||||
kis := ProviderCapability{
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ func validateImportDateRange(fromValue, toValue string) error {
|
|||
|
||||
func isValidTimeframe(t altv1.Timeframe) bool {
|
||||
switch t {
|
||||
case altv1.Timeframe_TIMEFRAME_DAILY, altv1.Timeframe_TIMEFRAME_MINUTE_1, altv1.Timeframe_TIMEFRAME_MINUTE_5:
|
||||
case altv1.Timeframe_TIMEFRAME_MONTHLY, altv1.Timeframe_TIMEFRAME_DAILY, altv1.Timeframe_TIMEFRAME_MINUTE_1, altv1.Timeframe_TIMEFRAME_MINUTE_5:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -167,6 +167,19 @@ func TestHandleListBarsValidation(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIsValidTimeframeAcceptsMonthlyAndMinuteBaseline(t *testing.T) {
|
||||
for _, tf := range []altv1.Timeframe{
|
||||
altv1.Timeframe_TIMEFRAME_MONTHLY,
|
||||
altv1.Timeframe_TIMEFRAME_DAILY,
|
||||
altv1.Timeframe_TIMEFRAME_MINUTE_1,
|
||||
altv1.Timeframe_TIMEFRAME_MINUTE_5,
|
||||
} {
|
||||
if !isValidTimeframe(tf) {
|
||||
t.Errorf("expected timeframe %v to be valid", tf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleListBarsNilWorker(t *testing.T) {
|
||||
resp, err := handleListBars(nil, validBarsRequest())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ func marketToProto(m market.Market) altv1.Market {
|
|||
|
||||
func timeframeFromProto(t altv1.Timeframe) (market.Timeframe, error) {
|
||||
switch t {
|
||||
case altv1.Timeframe_TIMEFRAME_MONTHLY:
|
||||
return market.TimeframeMonthly, nil
|
||||
case altv1.Timeframe_TIMEFRAME_DAILY:
|
||||
return market.TimeframeDaily, nil
|
||||
case altv1.Timeframe_TIMEFRAME_MINUTE_1:
|
||||
|
|
@ -115,6 +117,8 @@ func timeframeFromProto(t altv1.Timeframe) (market.Timeframe, error) {
|
|||
|
||||
func timeframeToProto(t market.Timeframe) altv1.Timeframe {
|
||||
switch t {
|
||||
case market.TimeframeMonthly:
|
||||
return altv1.Timeframe_TIMEFRAME_MONTHLY
|
||||
case market.TimeframeDaily:
|
||||
return altv1.Timeframe_TIMEFRAME_DAILY
|
||||
case market.TimeframeMin1:
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func TestMarketEnumRoundTrip(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTimeframeEnumRoundTrip(t *testing.T) {
|
||||
for _, tf := range []market.Timeframe{market.TimeframeDaily, market.TimeframeMin1, market.TimeframeMin5} {
|
||||
for _, tf := range []market.Timeframe{market.TimeframeMonthly, market.TimeframeDaily, market.TimeframeMin1, market.TimeframeMin5} {
|
||||
got, err := timeframeFromProto(timeframeToProto(tf))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for %q: %v", tf, err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue