mobile download
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { normalizeStartCandleType } from './strategyStartNodes';
|
||||
import { resolveVirtualTargetNames } from './virtualTargetNames';
|
||||
import { getUiPreferences, patchUiPreferences } from './uiPreferencesDb';
|
||||
|
||||
/** 가상투자 대상 종목·세션 설정 localStorage */
|
||||
/** 가상투자 대상 종목·세션 설정 (DB ui_preferences + per-market live settings) */
|
||||
|
||||
export interface VirtualTargetItem {
|
||||
market: string;
|
||||
@@ -22,68 +23,9 @@ export interface VirtualSessionConfig {
|
||||
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[];
|
||||
if (!Array.isArray(parsed)) return [];
|
||||
return parsed.map(t => {
|
||||
const { koreanName, englishName } = resolveVirtualTargetNames(
|
||||
t.market,
|
||||
t.koreanName,
|
||||
t.englishName,
|
||||
);
|
||||
return { ...t, koreanName, englishName };
|
||||
});
|
||||
} 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<VirtualSessionConfig>;
|
||||
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,
|
||||
@@ -93,19 +35,57 @@ function defaultSession(): VirtualSessionConfig {
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeTargets(items: VirtualTargetItem[]): VirtualTargetItem[] {
|
||||
return items.map(t => {
|
||||
const { koreanName, englishName } = resolveVirtualTargetNames(
|
||||
t.market,
|
||||
t.koreanName,
|
||||
t.englishName,
|
||||
);
|
||||
return { ...t, koreanName, englishName };
|
||||
});
|
||||
}
|
||||
|
||||
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: 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 {
|
||||
try {
|
||||
const raw = localStorage.getItem(CARD_VIEW_KEY);
|
||||
return raw === 'detail' ? 'detail' : 'summary';
|
||||
} catch {
|
||||
return 'summary';
|
||||
}
|
||||
const mode = getUiPreferences().virtual?.cardViewMode;
|
||||
return mode === 'detail' ? 'detail' : 'summary';
|
||||
}
|
||||
|
||||
export function saveVirtualCardViewMode(mode: VirtualCardViewMode): void {
|
||||
try {
|
||||
localStorage.setItem(CARD_VIEW_KEY, mode);
|
||||
} catch { /* ignore */ }
|
||||
patchUiPreferences({ virtual: { cardViewMode: mode } });
|
||||
}
|
||||
|
||||
/** 카드 시간봉 드롭다운 기본값 — 저장값 → 스냅샷 → 1m */
|
||||
|
||||
Reference in New Issue
Block a user