109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
import { resolveVirtualTargetNames } from './virtualTargetNames';
|
|
import { getUiPreferences, patchUiPreferences } from './uiPreferencesDb';
|
|
import {
|
|
DEFAULT_TRADE_NOTIFICATION_GRID_PRESET,
|
|
normalizeTradeNotificationGridPreset,
|
|
type TradeNotificationGridPresetId,
|
|
} from './tradeNotificationGridPresets';
|
|
|
|
/** 가상투자 대상 종목·세션 설정 (DB ui_preferences + per-market live settings) */
|
|
|
|
export interface VirtualTargetItem {
|
|
market: string;
|
|
strategyId: number | null;
|
|
koreanName?: string;
|
|
englishName?: string;
|
|
/** 투자대상 고정 — 추세검색 자동삭제 등에서 보호 (수동 삭제는 가능, gc_live_strategy_settings.is_pinned) */
|
|
pinned?: boolean;
|
|
}
|
|
|
|
export interface VirtualSessionConfig {
|
|
globalStrategyId: number | null;
|
|
executionType: 'CANDLE_CLOSE' | 'REALTIME_TICK';
|
|
/** LONG_ONLY = 보유 자산 기준, SIGNAL_ONLY = 순수 지표 기준 */
|
|
positionMode: 'LONG_ONLY' | 'SIGNAL_ONLY';
|
|
running: boolean;
|
|
}
|
|
|
|
/** 카드 표시: summary=이퀄라이저·신호등·푸터만, detail=지표 테이블 포함 전체 */
|
|
export type VirtualCardViewMode = 'summary' | 'detail';
|
|
|
|
function defaultSession(): VirtualSessionConfig {
|
|
return {
|
|
globalStrategyId: null,
|
|
executionType: 'CANDLE_CLOSE',
|
|
positionMode: 'LONG_ONLY',
|
|
running: false,
|
|
};
|
|
}
|
|
|
|
/** 레거시 ui_preferences.virtual.targets.candleType 제거 */
|
|
function normalizeTargets(items: VirtualTargetItem[]): VirtualTargetItem[] {
|
|
return items.map(t => {
|
|
const { koreanName, englishName } = resolveVirtualTargetNames(
|
|
t.market,
|
|
t.koreanName,
|
|
t.englishName,
|
|
);
|
|
return {
|
|
market: t.market,
|
|
strategyId: t.strategyId ?? null,
|
|
koreanName,
|
|
englishName,
|
|
pinned: t.pinned,
|
|
};
|
|
});
|
|
}
|
|
|
|
export function loadVirtualTargets(): VirtualTargetItem[] {
|
|
const raw = getUiPreferences().virtual?.targets;
|
|
if (!raw?.length) return [];
|
|
return normalizeTargets(raw);
|
|
}
|
|
|
|
export function saveVirtualTargets(items: VirtualTargetItem[]): void {
|
|
patchUiPreferences({ virtual: { targets: normalizeTargets(items) } });
|
|
notifyVirtualSessionChanged();
|
|
}
|
|
|
|
export function loadVirtualSession(): VirtualSessionConfig {
|
|
const parsed = getUiPreferences().virtual?.session;
|
|
if (!parsed) return defaultSession();
|
|
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,
|
|
};
|
|
}
|
|
|
|
export function saveVirtualSession(cfg: VirtualSessionConfig): void {
|
|
patchUiPreferences({ virtual: { session: cfg } });
|
|
notifyVirtualSessionChanged();
|
|
}
|
|
|
|
export const VIRTUAL_SESSION_CHANGED_EVENT = 'gc_virtual_session_changed';
|
|
|
|
export function notifyVirtualSessionChanged(): void {
|
|
window.dispatchEvent(new CustomEvent(VIRTUAL_SESSION_CHANGED_EVENT));
|
|
}
|
|
|
|
export function loadVirtualCardViewMode(): VirtualCardViewMode {
|
|
const mode = getUiPreferences().virtual?.cardViewMode;
|
|
return mode === 'detail' ? 'detail' : 'summary';
|
|
}
|
|
|
|
export function saveVirtualCardViewMode(mode: VirtualCardViewMode): void {
|
|
patchUiPreferences({ virtual: { cardViewMode: mode } });
|
|
}
|
|
|
|
export function loadVirtualGridPreset(): TradeNotificationGridPresetId {
|
|
return normalizeTradeNotificationGridPreset(
|
|
getUiPreferences().virtual?.gridPreset ?? DEFAULT_TRADE_NOTIFICATION_GRID_PRESET,
|
|
);
|
|
}
|
|
|
|
export function saveVirtualGridPreset(preset: TradeNotificationGridPresetId): void {
|
|
patchUiPreferences({ virtual: { gridPreset: preset } });
|
|
}
|