Files
overnight-trading-bot/internal/instruments/registry.go
T
2026-06-07 21:01:40 +00:00

62 lines
1.9 KiB
Go

package instruments
import (
"context"
"fmt"
"strings"
"overnight-trading-bot/internal/domain"
"overnight-trading-bot/internal/repository"
"overnight-trading-bot/internal/tinvest"
)
type Registry struct {
repo repository.Repository
gateway tinvest.Gateway
}
func NewRegistry(repo repository.Repository, gateway tinvest.Gateway) Registry {
return Registry{repo: repo, gateway: gateway}
}
func (r Registry) SyncMetadata(ctx context.Context) error {
instruments, err := r.repo.ListInstruments(ctx, true)
if err != nil {
return err
}
for _, instrument := range instruments {
if strings.HasPrefix(instrument.InstrumentUID, "PENDING:") || !instrument.MetadataValid() {
remote, err := r.gateway.GetInstrument(ctx, instrument.Ticker, instrument.ClassCode)
if err != nil {
return fmt.Errorf("sync %s: %w", instrument.Ticker, err)
}
remote.Enabled = instrument.Enabled && remote.Enabled
remote.FundType = instrument.FundType
remote.ExpectedCommissionBpsPerSide = instrument.ExpectedCommissionBpsPerSide
remote.FreeOrderLimitPerDay = instrument.FreeOrderLimitPerDay
remote.Quarantine = instrument.Quarantine
remote.QuarantineReason = instrument.QuarantineReason
remote.ExcludeReason = instrument.ExcludeReason
if err := r.repo.ReplaceInstrument(ctx, instrument.InstrumentUID, remote); err != nil {
return fmt.Errorf("replace synced instrument %s: %w", instrument.Ticker, err)
}
}
}
return nil
}
func CheckInstrument(instrument domain.Instrument, status domain.TradingStatus) error {
switch {
case !instrument.Enabled:
return fmt.Errorf("%s disabled", instrument.Ticker)
case instrument.Quarantine:
return fmt.Errorf("%s quarantined: %s", instrument.Ticker, instrument.QuarantineReason)
case !instrument.MetadataValid():
return fmt.Errorf("%s invalid metadata", instrument.Ticker)
case status != domain.TradingStatusNormal:
return fmt.Errorf("%s trading status %s", instrument.Ticker, status)
default:
return nil
}
}