109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
import type { VirtualTargetItem, VirtualSessionConfig } from './virtualTradingStorage';
|
|
|
|
/** 종목 전략 셀렉트 — 기본(전역) 전략 옵션 값 */
|
|
export const VIRTUAL_DEFAULT_STRATEGY_VALUE = '__default__';
|
|
|
|
/**
|
|
* 종목별 실효 전략 ID.
|
|
* strategyId 가 있으면 그대로 사용하고, null 이면 globalStrategyId(레거시·미설정)만 참조.
|
|
* 상단 기본전략 변경은 기존 null 종목을 freezeTargetsBeforeGlobalStrategyChange 로 고정한 뒤 session 만 갱신.
|
|
*/
|
|
export function resolveVirtualTargetStrategyId(
|
|
target: Pick<VirtualTargetItem, 'strategyId'>,
|
|
globalStrategyId: number | null,
|
|
/** gc_app_settings.liveStrategyId — ui_preferences.globalStrategyId 미동기화 시 폴백 */
|
|
appLiveStrategyId: number | null = null,
|
|
): number | null {
|
|
if (target.strategyId != null) return target.strategyId;
|
|
if (globalStrategyId != null) return globalStrategyId;
|
|
if (appLiveStrategyId != null && appLiveStrategyId > 0) return appLiveStrategyId;
|
|
return null;
|
|
}
|
|
|
|
/** 기본전략 변경 직전 — null(기본 따름) 종목을 이전 기본전략 ID 로 고정 */
|
|
export function freezeTargetsBeforeGlobalStrategyChange(
|
|
targets: VirtualTargetItem[],
|
|
previousGlobalStrategyId: number | null,
|
|
): VirtualTargetItem[] {
|
|
if (previousGlobalStrategyId == null) return targets;
|
|
let changed = false;
|
|
const next = targets.map(t => {
|
|
if (t.strategyId != null) return t;
|
|
changed = true;
|
|
return { ...t, strategyId: previousGlobalStrategyId };
|
|
});
|
|
return changed ? next : targets;
|
|
}
|
|
|
|
export function usesDefaultStrategy(target: Pick<VirtualTargetItem, 'strategyId'>): boolean {
|
|
return target.strategyId == null;
|
|
}
|
|
|
|
export function targetStrategySelectValue(target: Pick<VirtualTargetItem, 'strategyId'>): string {
|
|
return target.strategyId != null ? String(target.strategyId) : VIRTUAL_DEFAULT_STRATEGY_VALUE;
|
|
}
|
|
|
|
export function parseTargetStrategySelectValue(value: string): number | null {
|
|
if (!value || value === VIRTUAL_DEFAULT_STRATEGY_VALUE) return null;
|
|
const n = Number(value);
|
|
return Number.isFinite(n) ? n : null;
|
|
}
|
|
|
|
/** 전략 목록 첫 항목 ID (가상매매 기본 전략) */
|
|
export function pickDefaultGlobalStrategyId(
|
|
strategies: Array<{ id?: number | null }>,
|
|
): number | null {
|
|
for (const s of strategies) {
|
|
const id = s.id;
|
|
if (id != null && id > 0) return id;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** 저장된 globalStrategyId 가 유효하면 유지, 아니면 목록 첫 항목 */
|
|
export function ensureDefaultGlobalStrategyId(
|
|
globalStrategyId: number | null,
|
|
strategies: Array<{ id?: number | null }>,
|
|
): number | null {
|
|
const validIds = new Set(
|
|
strategies.map(s => s.id).filter((id): id is number => id != null && id > 0),
|
|
);
|
|
if (globalStrategyId != null && validIds.has(globalStrategyId)) {
|
|
return globalStrategyId;
|
|
}
|
|
return pickDefaultGlobalStrategyId(strategies);
|
|
}
|
|
|
|
/** 신규 종목 추가·세션 초기화 — 상단 기본전략 (없으면 목록 첫 항목) */
|
|
export function resolveStrategyIdForNewTarget(
|
|
globalStrategyId: number | null,
|
|
strategies: Array<{ id?: number | null }>,
|
|
): number | null {
|
|
return ensureDefaultGlobalStrategyId(globalStrategyId, strategies);
|
|
}
|
|
|
|
/** 전략 목록 로드 후 — 상단 기본전략을 첫 항목으로 자동 설정 */
|
|
export function applyDefaultGlobalStrategyToSession(
|
|
session: VirtualSessionConfig,
|
|
strategies: Array<{ id?: number | null }>,
|
|
appLiveStrategyId: number | null = null,
|
|
): VirtualSessionConfig {
|
|
let gid = ensureDefaultGlobalStrategyId(session.globalStrategyId, strategies);
|
|
if (gid == null && appLiveStrategyId != null && appLiveStrategyId > 0) {
|
|
gid = appLiveStrategyId;
|
|
}
|
|
if (gid === session.globalStrategyId) return session;
|
|
return { ...session, globalStrategyId: gid };
|
|
}
|
|
|
|
/** 종목 셀렉트 — 기본 전략(전역) 옵션 라벨 (신규 추가 시 적용되는 템플릿) */
|
|
export function defaultStrategyOptionLabel(
|
|
globalStrategyId: number | null,
|
|
strategies: Array<{ id?: number; name?: string }>,
|
|
): string {
|
|
if (globalStrategyId == null) return '기본 전략 (미설정)';
|
|
const name = strategies.find(s => s.id === globalStrategyId)?.name;
|
|
return name ? `기본 전략 (${name})` : '기본 전략';
|
|
}
|
|
|