feat: saxo price
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useSources, useUpdateSources, useUpdateApiKeys, useConfig, useAiStatus, useAnalysisConfig, useSaveAnalysisConfig, useCycleStatus, useUpdateCycleConfig, useTriggerCycle, useCycleStepCatalog, useRiskProfiles, useUpsertProfile, useDeleteProfile, useExitDefaults, useSaveExitDefaults, useOptionsGate, useSaveOptionsGate, useTechIndicatorsConfig, useSaveTechIndicatorsConfig, useInstrumentsWatchlist, useAddWatchlistInstrument, useRemoveWatchlistInstrument, useSetWatchlistSaxoOptionLink, useSetWatchlistSaxoQuoteLink, validateTicker, useSaxoStatus, useDisconnectSaxo, useSaxoWatchlist, useUpdateSaxoWatchlist, useSnapshotSaxoNow, useValidateSaxoWatchlist, useSaxoCatalog, useSaxoCatalogSummary, useRefreshSaxoCatalog, useTestSaxoQuote, useSaxoSettings, useUpdateSaxoSettings, useSnapshotAllSaxoNow, useExpandSaxoWatchlist, type CycleStepDef } from '../hooks/useApi'
|
||||
import { useSources, useUpdateSources, useUpdateApiKeys, useConfig, useAiStatus, useAnalysisConfig, useSaveAnalysisConfig, useCycleStatus, useUpdateCycleConfig, useTriggerCycle, useCycleStepCatalog, useRiskProfiles, useUpsertProfile, useDeleteProfile, useExitDefaults, useSaveExitDefaults, useOptionsGate, useSaveOptionsGate, useTechIndicatorsConfig, useSaveTechIndicatorsConfig, useInstrumentsWatchlist, useAddWatchlistInstrument, useRemoveWatchlistInstrument, useSetWatchlistSaxoOptionLink, useSetWatchlistSaxoQuoteLink, useSaxoStatus, useDisconnectSaxo, useSaxoWatchlist, useUpdateSaxoWatchlist, useSnapshotSaxoNow, useValidateSaxoWatchlist, useSaxoCatalog, useSaxoCatalogSummary, useRefreshSaxoCatalog, useTestSaxoQuote, useSaxoSettings, useUpdateSaxoSettings, useSnapshotAllSaxoNow, useExpandSaxoWatchlist, type CycleStepDef } from '../hooks/useApi'
|
||||
import { Settings, Key, Globe, CheckCircle, XCircle, AlertCircle, Save, Eye, EyeOff, Brain, SlidersHorizontal, RefreshCw, Zap, Plus, Trash2, Pencil, X, Lock, Gauge, DollarSign, TrendingUp, ShieldAlert, DatabaseBackup, Radar, Link2, Unlink, Camera, ShieldCheck, ExternalLink } from 'lucide-react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
@@ -439,18 +439,21 @@ function WatchlistCard() {
|
||||
const { mutate: removeTicker } = useRemoveWatchlistInstrument()
|
||||
const [input, setInput] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
const [note, setNote] = useState('')
|
||||
|
||||
const handleAdd = async () => {
|
||||
const sym = input.trim().toUpperCase()
|
||||
if (!sym) return
|
||||
setError('')
|
||||
const check = await validateTicker(sym)
|
||||
if (!check.valid) {
|
||||
setError(check.reason ?? 'Ticker not found')
|
||||
return
|
||||
}
|
||||
setNote('')
|
||||
// yfinance recognition is informational only, not a gate — an instrument can be
|
||||
// entirely Saxo-sourced (link its Option/Quote symbols below) with no yfinance
|
||||
// equivalent at all.
|
||||
try {
|
||||
await addTicker(sym)
|
||||
const result = await addTicker(sym)
|
||||
if (!(result as any)?.yfinance_recognized) {
|
||||
setNote(`'${sym}' added, but yfinance doesn't recognize it — no fallback price until you link it to Saxo (Option/Quote below).`)
|
||||
}
|
||||
setInput('')
|
||||
} catch (e: unknown) {
|
||||
const msg = (e as any)?.response?.data?.detail ?? (e as { message?: string })?.message ?? 'Could not add ticker'
|
||||
@@ -487,6 +490,7 @@ function WatchlistCard() {
|
||||
</button>
|
||||
</div>
|
||||
{error && <div className="text-[10px] text-red-400 mb-3">{error}</div>}
|
||||
{note && <div className="text-[10px] text-amber-400 mb-3">{note}</div>}
|
||||
|
||||
{isLoading ? (
|
||||
<div className="text-xs text-slate-600">Loading…</div>
|
||||
|
||||
Reference in New Issue
Block a user