import type { VirtualTargetItem, VirtualSessionConfig } from './virtualTradingStorage'; /** 종목 전략 셀렉트 — 기본(전역) 전략 옵션 값 */ export const VIRTUAL_DEFAULT_STRATEGY_VALUE = '__default__'; /** * 종목별 실효 전략 ID. * strategyId 가 있으면 그대로 사용하고, null 이면 globalStrategyId(레거시·미설정)만 참조. * 상단 기본전략 변경은 기존 null 종목을 freezeTargetsBeforeGlobalStrategyChange 로 고정한 뒤 session 만 갱신. */ export function resolveVirtualTargetStrategyId( target: Pick, globalStrategyId: number | null, /** gc_app_settings.liveStrategyId — ui_preferences.globalStrategyId 미동기화 시 폴백 */ appLiveStrategyId: number | null = null, ): number | null { if (target.strategyId != null) return target.strategyId; if (globalStrategyId != null) return globalStrategyId; if (appLiveStrategyId != null && appLiveStrategyId > 0) return appLiveStrategyId; return null; } /** 기본전략 변경 직전 — null(기본 따름) 종목을 이전 기본전략 ID 로 고정 */ export function freezeTargetsBeforeGlobalStrategyChange( targets: VirtualTargetItem[], previousGlobalStrategyId: number | null, ): VirtualTargetItem[] { if (previousGlobalStrategyId == null) return targets; let changed = false; const next = targets.map(t => { if (t.strategyId != null) return t; changed = true; return { ...t, strategyId: previousGlobalStrategyId }; }); return changed ? next : targets; } export function usesDefaultStrategy(target: Pick): boolean { return target.strategyId == null; } export function targetStrategySelectValue(target: Pick): string { return target.strategyId != null ? String(target.strategyId) : VIRTUAL_DEFAULT_STRATEGY_VALUE; } export function parseTargetStrategySelectValue(value: string): number | null { if (!value || value === VIRTUAL_DEFAULT_STRATEGY_VALUE) return null; const n = Number(value); return Number.isFinite(n) ? n : null; } /** 전략 목록 첫 항목 ID (가상매매 기본 전략) */ export function pickDefaultGlobalStrategyId( strategies: Array<{ id?: number | null }>, ): number | null { for (const s of strategies) { const id = s.id; if (id != null && id > 0) return id; } return null; } /** 저장된 globalStrategyId 가 유효하면 유지, 아니면 목록 첫 항목 */ export function ensureDefaultGlobalStrategyId( globalStrategyId: number | null, strategies: Array<{ id?: number | null }>, ): number | null { const validIds = new Set( strategies.map(s => s.id).filter((id): id is number => id != null && id > 0), ); if (globalStrategyId != null && validIds.has(globalStrategyId)) { return globalStrategyId; } return pickDefaultGlobalStrategyId(strategies); } /** 신규 종목 추가·세션 초기화 — 상단 기본전략 (없으면 목록 첫 항목) */ export function resolveStrategyIdForNewTarget( globalStrategyId: number | null, strategies: Array<{ id?: number | null }>, ): number | null { return ensureDefaultGlobalStrategyId(globalStrategyId, strategies); } /** 전략 목록 로드 후 — 상단 기본전략을 첫 항목으로 자동 설정 */ export function applyDefaultGlobalStrategyToSession( session: VirtualSessionConfig, strategies: Array<{ id?: number | null }>, appLiveStrategyId: number | null = null, ): VirtualSessionConfig { let gid = ensureDefaultGlobalStrategyId(session.globalStrategyId, strategies); if (gid == null && appLiveStrategyId != null && appLiveStrategyId > 0) { gid = appLiveStrategyId; } if (gid === session.globalStrategyId) return session; return { ...session, globalStrategyId: gid }; } /** 종목 셀렉트 — 기본 전략(전역) 옵션 라벨 (신규 추가 시 적용되는 템플릿) */ export function defaultStrategyOptionLabel( globalStrategyId: number | null, strategies: Array<{ id?: number; name?: string }>, ): string { if (globalStrategyId == null) return '기본 전략 (미설정)'; const name = strategies.find(s => s.id === globalStrategyId)?.name; return name ? `기본 전략 (${name})` : '기본 전략'; }