import { putPaperAllocationsBulk, saveLiveStrategySettings } from './backendApi'; import { pinStrategyEvaluationTimeframes } from './strategyTimeframePin'; import type { VirtualSessionConfig, VirtualTargetItem } from './virtualTradingStorage'; import { resolveVirtualTargetStrategyId } from './virtualTargetStrategy'; /** * 가상투자 대상 → 백엔드 live strategy·모의 한도 동기화. * 전략 평가·모의 자동 체결은 BarClose/LiveStrategyScheduler → OrderExecutionQueue 에서만 수행. */ export async function syncVirtualTargetsToBackend( targets: VirtualTargetItem[], session: VirtualSessionConfig, isLiveCheck: boolean, ): Promise { if (targets.length === 0) return; const shared = { isLiveCheck, executionType: session.executionType, positionMode: session.positionMode, skipWatchlistSync: true, } as const; if (isLiveCheck && session.globalStrategyId != null) { await saveLiveStrategySettings({ market: targets[0].market, strategyId: session.globalStrategyId, isLiveCheck: true, executionType: session.executionType, positionMode: session.positionMode, skipWatchlistSync: true, }); } const pinJobs = targets.map(async t => { const strategyId = resolveVirtualTargetStrategyId(t, session.globalStrategyId); if (strategyId == null) return; await pinStrategyEvaluationTimeframes(t.market, strategyId); }); await Promise.all(pinJobs); await Promise.all( targets.map(t => saveLiveStrategySettings({ market: t.market, strategyId: resolveVirtualTargetStrategyId(t, session.globalStrategyId), isPinned: !!t.pinned, skipGlobalTemplate: true, ...shared, }), ), ); try { await putPaperAllocationsBulk( targets.map((t, i) => ({ symbol: t.market, koreanName: t.koreanName, strategyId: resolveVirtualTargetStrategyId(t, session.globalStrategyId), pinned: !!t.pinned, sortOrder: i, isActive: true, })), ); } catch { /* paper allocation sync best-effort */ } } /** 가상투자 중지 — 대상 종목 체크 해제 + 전역 liveStrategyCheck OFF */ export async function stopVirtualLiveOnBackend( targets: VirtualTargetItem[], session: VirtualSessionConfig, ): Promise { if (targets.length === 0) { await saveLiveStrategySettings({ market: 'KRW-BTC', strategyId: session.globalStrategyId, isLiveCheck: false, executionType: session.executionType, positionMode: session.positionMode, skipWatchlistSync: true, }); return; } await syncVirtualTargetsToBackend(targets, session, false); }