This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
@@ -72,6 +73,9 @@ func run() error {
|
||||
if *useMinuteModel && len(minuteCandles) == 0 {
|
||||
return fmt.Errorf("-minute-candles is required when -use-minute-model=true")
|
||||
}
|
||||
if err := validateMetadata(candles, metadata); err != nil {
|
||||
return err
|
||||
}
|
||||
entry, err := decimal.NewFromString(*entrySlip)
|
||||
if err != nil {
|
||||
return fmt.Errorf("entry slippage: %w", err)
|
||||
@@ -149,6 +153,20 @@ func run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateMetadata(candles map[string][]domain.Candle, metadata map[string]backtest.InstrumentMetadata) error {
|
||||
var missing []string
|
||||
for instrumentUID := range candles {
|
||||
meta := metadata[instrumentUID]
|
||||
if meta.Lot <= 0 || !meta.MinPriceIncrement.IsPositive() {
|
||||
missing = append(missing, instrumentUID)
|
||||
}
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("missing lot/min_price_increment metadata for instruments: %s", strings.Join(missing, ","))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeMetadata(dst, src map[string]backtest.InstrumentMetadata) {
|
||||
for uid, meta := range src {
|
||||
current := dst[uid]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
"overnight-trading-bot/internal/backtest"
|
||||
"overnight-trading-bot/internal/domain"
|
||||
)
|
||||
|
||||
func TestValidateMetadataRejectsMissingLotOrTick(t *testing.T) {
|
||||
candles := map[string][]domain.Candle{
|
||||
"uid": {{InstrumentUID: "uid", TradeDate: time.Date(2026, 6, 8, 0, 0, 0, 0, time.UTC)}},
|
||||
}
|
||||
err := validateMetadata(candles, map[string]backtest.InstrumentMetadata{
|
||||
"uid": {Lot: 10},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "missing lot/min_price_increment metadata") {
|
||||
t.Fatalf("err=%v, want missing metadata error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMetadataAcceptsCompleteMetadata(t *testing.T) {
|
||||
candles := map[string][]domain.Candle{
|
||||
"uid": {{InstrumentUID: "uid", TradeDate: time.Date(2026, 6, 8, 0, 0, 0, 0, time.UTC)}},
|
||||
}
|
||||
err := validateMetadata(candles, map[string]backtest.InstrumentMetadata{
|
||||
"uid": {Lot: 10, MinPriceIncrement: decimal.RequireFromString("0.01")},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user