feat: saxo price

This commit is contained in:
OpenSquared
2026-07-23 17:09:53 +02:00
parent 7267443d5b
commit d04aeace1c
2 changed files with 34 additions and 8 deletions

View File

@@ -341,6 +341,25 @@ function RiskProfilesCard() {
// Asset-type filters matching backend services.saxo_client.OPTION_ASSET_TYPES /
// UNDERLYING_ASSET_TYPES — keeps each picker's search scoped to the catalog rows that
// are actually relevant, instead of both searching the same undifferentiated list.
// Saxo has no shared naming convention with yfinance — its catalog search matches on
// Saxo's own instrument description text ("Brent Crude"), not the yfinance ticker code
// ("BZ=F"). This maps the common yfinance futures-root/index tickers to the plain-English
// name worth searching for, so opening a picker pre-fills something useful instead of an
// empty box the user has to guess into. Not exhaustive — anything not listed here (most
// FX pairs, where the Saxo symbol IS the yfinance root, e.g. "EURUSD=X" -> "EURUSD") falls
// back to a best-effort strip of yfinance's own suffix/prefix decoration.
const YFINANCE_SEARCH_HINTS: Record<string, string> = {
'BZ=F': 'Brent', 'CL=F': 'WTI Crude', 'NG=F': 'Natural Gas',
'GC=F': 'Gold', 'SI=F': 'Silver', 'HG=F': 'Copper', 'PL=F': 'Platinum',
'^GSPC': 'S&P 500', '^NDX': 'Nasdaq 100', '^DJI': 'Dow Jones', '^RUT': 'Russell 2000',
'^VIX': 'VIX',
}
function guessSaxoSearchHint(ticker: string): string {
if (YFINANCE_SEARCH_HINTS[ticker]) return YFINANCE_SEARCH_HINTS[ticker]
return ticker.replace(/=F$|=X$|^\^/g, '')
}
const SAXO_LINK_KIND_META = {
option: {
label: 'Option', placeholder: 'Search Saxo option symbol…',
@@ -350,7 +369,7 @@ const SAXO_LINK_KIND_META = {
quote: {
label: 'Quote', placeholder: 'Search Saxo spot/futures symbol…',
activeCls: 'text-sky-400 hover:text-sky-300 bg-sky-900/20 border-sky-700/30',
assetTypes: 'ContractFutures,FxSpot,StockIndex',
assetTypes: 'ContractFutures,CfdOnFutures,FxSpot,StockIndex',
},
} as const
@@ -375,7 +394,7 @@ function SaxoLinkPicker({ ticker, kind, saxoSymbol }: { ticker: string; kind: ke
<Link2 className="w-2.5 h-2.5" /> {meta.label}: {saxoSymbol}
</button>
) : (
<button onClick={() => setEditing(true)} className="flex items-center gap-1 text-[9px] text-slate-500 hover:text-slate-300 border border-slate-700/40 px-1.5 py-0.5 rounded">
<button onClick={() => { setEditing(true); setValue(guessSaxoSearchHint(ticker)); setShowDropdown(true) }} className="flex items-center gap-1 text-[9px] text-slate-500 hover:text-slate-300 border border-slate-700/40 px-1.5 py-0.5 rounded">
<Unlink className="w-2.5 h-2.5" /> {meta.label}
</button>
)
@@ -780,6 +799,7 @@ function SaxoConnectionCard() {
<option value="Stock">Stock</option>
<option value="StockIndex">StockIndex</option>
<option value="ContractFutures">ContractFutures</option>
<option value="CfdOnFutures">CfdOnFutures</option>
</select>
<button
onClick={() => testQuote.mutate({ symbol: quoteSymbol, assetType: quoteAssetType })}