import { normalizeStartCandleType } from './strategyStartNodes'; /** 가상투자 대상 종목·세션 설정 localStorage */ export interface VirtualTargetItem { market: string; strategyId: number | null; /** 종목별 전략 평가 분봉 (gc_live_strategy_settings.candle_type) */ candleType?: string; koreanName?: string; englishName?: string; } export interface VirtualSessionConfig { globalStrategyId: number | null; executionType: 'CANDLE_CLOSE' | 'REALTIME_TICK'; /** LONG_ONLY = 보유 자산 기준, SIGNAL_ONLY = 순수 지표 기준 */ positionMode: 'LONG_ONLY' | 'SIGNAL_ONLY'; running: boolean; } const TARGETS_KEY = 'gc_virtual_targets_v1'; const SESSION_KEY = 'gc_virtual_session_v1'; const CARD_VIEW_KEY = 'gc_virtual_card_view_v1'; /** 카드 표시: summary=이퀄라이저·신호등·푸터만, detail=지표 테이블 포함 전체 */ export type VirtualCardViewMode = 'summary' | 'detail'; export function loadVirtualTargets(): VirtualTargetItem[] { try { const raw = localStorage.getItem(TARGETS_KEY); if (!raw) return []; const parsed = JSON.parse(raw) as VirtualTargetItem[]; return Array.isArray(parsed) ? parsed : []; } catch { return []; } } export function saveVirtualTargets(items: VirtualTargetItem[]): void { try { localStorage.setItem(TARGETS_KEY, JSON.stringify(items)); notifyVirtualSessionChanged(); } catch { /* ignore */ } } export function loadVirtualSession(): VirtualSessionConfig { try { const raw = localStorage.getItem(SESSION_KEY); if (!raw) return defaultSession(); const parsed = JSON.parse(raw) as Partial; return { globalStrategyId: parsed.globalStrategyId ?? null, executionType: parsed.executionType === 'REALTIME_TICK' ? 'REALTIME_TICK' : 'CANDLE_CLOSE', positionMode: parsed.positionMode === 'SIGNAL_ONLY' ? 'SIGNAL_ONLY' : 'LONG_ONLY', running: parsed.running === true, }; } catch { return defaultSession(); } } export function saveVirtualSession(cfg: VirtualSessionConfig): void { try { localStorage.setItem(SESSION_KEY, JSON.stringify(cfg)); notifyVirtualSessionChanged(); } catch { /* ignore */ } } export const VIRTUAL_SESSION_CHANGED_EVENT = 'gc_virtual_session_changed'; export function notifyVirtualSessionChanged(): void { window.dispatchEvent(new CustomEvent(VIRTUAL_SESSION_CHANGED_EVENT)); } function defaultSession(): VirtualSessionConfig { return { globalStrategyId: null, executionType: 'CANDLE_CLOSE', positionMode: 'LONG_ONLY', running: false, }; } export function loadVirtualCardViewMode(): VirtualCardViewMode { try { const raw = localStorage.getItem(CARD_VIEW_KEY); return raw === 'detail' ? 'detail' : 'summary'; } catch { return 'summary'; } } export function saveVirtualCardViewMode(mode: VirtualCardViewMode): void { try { localStorage.setItem(CARD_VIEW_KEY, mode); } catch { /* ignore */ } } /** 카드 시간봉 드롭다운 기본값 — 저장값 → 스냅샷 → 1m */ export function resolveTargetCandleType( item: Pick, snapshotTimeframe?: string | null, ): string { if (item.candleType) return normalizeStartCandleType(item.candleType); const raw = snapshotTimeframe?.split(',')[0]?.trim(); if (raw) return normalizeStartCandleType(raw); return '1m'; }