mobile download

This commit is contained in:
Macbook
2026-05-28 14:44:19 +09:00
parent e2816b037f
commit 3503ef33f5
152 changed files with 11021 additions and 687 deletions
+49 -69
View File
@@ -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 */