feat(cli): 백테스트 operator에 multi-timeframe 지원과 테스트를 추가한다

runner.go, scenario.go에 multi-timeframe 기능 추가
scenario_test.go에 테스트 Cases 추가
This commit is contained in:
toki 2026-06-17 21:33:01 +09:00
parent 91602a66c7
commit 9cdda549c2
3 changed files with 43 additions and 0 deletions

View file

@ -55,6 +55,7 @@ var marketByName = map[string]altv1.Market{
// timeframeByName maps scenario timeframe strings onto the contract enum.
var timeframeByName = map[string]altv1.Timeframe{
"monthly": altv1.Timeframe_TIMEFRAME_MONTHLY,
"daily": altv1.Timeframe_TIMEFRAME_DAILY,
"minute_1": altv1.Timeframe_TIMEFRAME_MINUTE_1,
"minute_5": altv1.Timeframe_TIMEFRAME_MINUTE_5,

View file

@ -161,6 +161,7 @@ var validVenues = map[string]bool{
// validTimeframes is the set of bar timeframe strings a list_bars request may
// use, mirroring the API's accepted Timeframe values.
var validTimeframes = map[string]bool{
"monthly": true,
"daily": true,
"minute_1": true,
"minute_5": true,

View file

@ -5,6 +5,8 @@ import (
"path/filepath"
"strings"
"testing"
altv1 "git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1"
)
func fixture(t *testing.T, name string) string {
@ -656,6 +658,45 @@ steps:
}
}
func TestTimeframeVocabularyIncludesMonthlyAndMinuteBaseline(t *testing.T) {
cases := []struct {
timeframe string
proto altv1.Timeframe
}{
{"monthly", altv1.Timeframe_TIMEFRAME_MONTHLY},
{"daily", altv1.Timeframe_TIMEFRAME_DAILY},
{"minute_1", altv1.Timeframe_TIMEFRAME_MINUTE_1},
{"minute_5", altv1.Timeframe_TIMEFRAME_MINUTE_5},
}
for _, c := range cases {
t.Run(c.timeframe, func(t *testing.T) {
if !validTimeframes[c.timeframe] {
t.Fatalf("validTimeframes[%q] = false", c.timeframe)
}
if got := timeframeByName[c.timeframe]; got != c.proto {
t.Fatalf("timeframeByName[%q] = %v, want %v", c.timeframe, got, c.proto)
}
yamlText := fmt.Sprintf(`
name: valid_%s_timeframe
steps:
- id: step1
action: start_backtest
request:
strategy_id: strat1
market: kr
timeframe: %s
from_unix_ms: 100
to_unix_ms: 200
symbols: ["005930"]
`, c.timeframe, c.timeframe)
if _, err := ParseScenario([]byte(yamlText)); err != nil {
t.Fatalf("ParseScenario(%q) returned error: %v", c.timeframe, err)
}
})
}
}
func TestValidatePaperTradingScenario(t *testing.T) {
yamlText := `
name: valid_paper