diff --git a/packages/domain/market/types.go b/packages/domain/market/types.go index ea0f485..1367496 100644 --- a/packages/domain/market/types.go +++ b/packages/domain/market/types.go @@ -30,9 +30,10 @@ const ( type Timeframe string const ( - TimeframeDaily Timeframe = "1d" - TimeframeMin1 Timeframe = "1m" - TimeframeMin5 Timeframe = "5m" + TimeframeMonthly Timeframe = "1mo" + TimeframeDaily Timeframe = "1d" + TimeframeMin1 Timeframe = "1m" + TimeframeMin5 Timeframe = "5m" ) type InstrumentID string diff --git a/packages/domain/market/types_test.go b/packages/domain/market/types_test.go index 60d227e..fce1d76 100644 --- a/packages/domain/market/types_test.go +++ b/packages/domain/market/types_test.go @@ -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{ diff --git a/services/api/internal/socket/market.go b/services/api/internal/socket/market.go index afce715..5d5f196 100644 --- a/services/api/internal/socket/market.go +++ b/services/api/internal/socket/market.go @@ -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 diff --git a/services/api/internal/socket/market_test.go b/services/api/internal/socket/market_test.go index 9a8d617..659ee2f 100644 --- a/services/api/internal/socket/market_test.go +++ b/services/api/internal/socket/market_test.go @@ -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 { diff --git a/services/worker/internal/socket/backtest_mapping.go b/services/worker/internal/socket/backtest_mapping.go index e33463a..4a57ece 100644 --- a/services/worker/internal/socket/backtest_mapping.go +++ b/services/worker/internal/socket/backtest_mapping.go @@ -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: diff --git a/services/worker/internal/socket/backtest_mapping_test.go b/services/worker/internal/socket/backtest_mapping_test.go index 39a2f3d..e12fa52 100644 --- a/services/worker/internal/socket/backtest_mapping_test.go +++ b/services/worker/internal/socket/backtest_mapping_test.go @@ -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)