89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
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<void> {
|
|
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<void> {
|
|
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);
|
|
}
|