diff --git a/frontend/src/pages/StrategyBuilder.tsx b/frontend/src/pages/StrategyBuilder.tsx index 01b41ec..58fd811 100644 --- a/frontend/src/pages/StrategyBuilder.tsx +++ b/frontend/src/pages/StrategyBuilder.tsx @@ -8,15 +8,13 @@ import { useOptionChainSlice, usePriceStrategy, useOptimizeStrategy, useSuggestedProfile, useScenarios, useSaveScenario, useDeleteScenario, useSavedStrategies, useSaveStrategyRecord, useDeleteSavedStrategy, - useWatchlistTickers, useSaxoCatalog, useIvForTrade, + useSaxoSymbols, useIvForTrade, type StrategyLeg, type StrategyScenario, type PriceCombo, type StrategyCandidate, type OptimizeConstraints, type SavedScenario, type GreekProfile, type GreekTarget, type GreekState, type GreekTolerance, DEFAULT_GREEK_PROFILE, } from '../hooks/useApi' import { fmtPrice, fmtAsOf } from '../lib/format' -type WatchlistEntry = { ticker: string; is_active: number | boolean; added_by: string } - const STRIKE_PCTS = [80, 85, 90, 95, 100, 105, 110, 115, 120] const DELTA_NEUTRAL_THRESHOLD = 0.15 @@ -758,12 +756,11 @@ export default function StrategyBuilder() { const [showAdvancedGreeks, setShowAdvancedGreeks] = useState(false) const [activeTemplate, setActiveTemplate] = useState(null) - const { data: watchlistData } = useWatchlistTickers() - const { data: saxoCatalog } = useSaxoCatalog(undefined, undefined, { enabled: true, limit: 500 }) - const watchlistTickers = Array.from(new Set([ - ...((watchlistData?.tickers ?? []) as WatchlistEntry[]).filter(t => t.is_active).map(t => t.ticker), - ...(saxoCatalog ?? []).map(c => c.symbol), - ])).sort() + // Only propose symbols that actually have accumulated Saxo History — a catalog/watchlist + // entry with no snapshot rows yet just leads to the same "no history" dead end this list + // is meant to prevent (see the commitSymbol comment above). + const { data: saxoSymbols } = useSaxoSymbols() + const watchlistTickers = (saxoSymbols ?? []).map(s => s.symbol).sort() const { data: chain, isLoading: chainLoading, isError: chainError, error: chainErrorObj, refetch: refetchChain, isFetching } = useOptionChainSlice(debouncedSymbol, horizonDays, 3, true, scenario.dte_min, scenario.dte_max)