/// Defaults for 4-hour slot market history ([MarketHistoryFourHourSlot]). /// Env overrides via [MarketHistoryEnv] in [ServerEnv.load]. abstract final class MarketHistoryConfig { /// Rolling window length in calendar days (UTC). static const int windowDays = 7; /// Alpaca bar aggregation for market-history backfill (six slots per UTC day). static const String barTimeframe = '4Hour'; /// Width of each history slot in hours (`24 / slotsPerDay`). static const int slotHours = 4; /// Symbols per Alpaca `GET /v2/stocks/bars` request (max ~100). static const int historySyncBatchSize = 100; /// Hard cap on symbols synced per run (Alpaca Basic rate-limit safety). static const int historySyncMaxSymbols = 2000; /// Minimum 4-hour bars required before a symbol is eligible for the /// guess-the-move question rule. static const int minBarsForGuess = 5; /// Hours before the same symbol can fire another guess question. static const int guessCooldownHours = 24; /// Rows deleted per cleanup loop iteration (Postgres batched DELETE). static const int retentionBatchSize = 5000; /// Max Alpaca HTTP calls per rolling minute during history backfill. static const int apiRequestsPerMinute = 200; /// Wait after HTTP 429 before retrying the same bars request. static const Duration rateLimitCooldown = Duration(minutes: 1); }