feat: strategy builder

This commit is contained in:
OpenSquared
2026-07-29 20:57:45 +02:00
parent 7e03c9c301
commit ad3f599082

View File

@@ -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<string | null>(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)