feat: instrument analysis

This commit is contained in:
OpenSquared
2026-06-30 17:03:36 +02:00
parent 9711f0921c
commit 7f3cce69b9

View File

@@ -1,7 +1,19 @@
import { createContext, useContext, useCallback, useState, useEffect, ReactNode } from 'react'
import { createContext, useContext, useCallback, useState, ReactNode } from 'react'
// Instruments that exist in instruments.json — used to validate localStorage
const VALID_INSTRUMENT_SUFFIX = /^[A-Z0-9]+=?[A-Z0-9-]*$/
// Forex tickers on Yahoo Finance require the =X suffix; migrate stale plain versions
const FOREX_MIGRATIONS: Record<string, string> = { 'EURUSD': 'EURUSD=X', 'GBPUSD': 'GBPUSD=X', 'USDJPY': 'USDJPY=X', 'USDCHF': 'USDCHF=X' }
function migrateInstrumentId(id: string): string {
return FOREX_MIGRATIONS[id] ?? id
}
// Apply once at module load so every localStorage read is already corrected
;(function migrateLastInstrument() {
const stored = localStorage.getItem('last_instrument')
if (stored && FOREX_MIGRATIONS[stored]) {
localStorage.setItem('last_instrument', FOREX_MIGRATIONS[stored])
}
})()
interface TabsCtx {
kept: ReadonlySet<string>
@@ -32,8 +44,9 @@ export function TabsProvider({ children }: { children: ReactNode }) {
setKept(p => { const n = new Set(p); n.delete(r); return n }), [])
const openInstrument = useCallback((id: string) => {
localStorage.setItem('last_instrument', id)
setInstrumentIds(p => p.includes(id) ? p : [...p, id])
const safe = migrateInstrumentId(id.toUpperCase())
localStorage.setItem('last_instrument', safe)
setInstrumentIds(p => p.includes(safe) ? p : [...p, safe])
}, [])
const closeInstrument = useCallback((id: string) =>