전략편집기 수정
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
/** 전략편집기 우측 팔레트 — 보조·복합 지표 목록 (localStorage) */
|
||||
import { COMPOSITE_INDICATOR_ITEMS } from './compositeIndicators';
|
||||
|
||||
export type PaletteItemKind = 'auxiliary' | 'composite';
|
||||
|
||||
export interface PaletteItem {
|
||||
id: string;
|
||||
kind: PaletteItemKind;
|
||||
/** 지표 타입 (RSI, CCI, …) */
|
||||
value: string;
|
||||
label: string;
|
||||
desc: string;
|
||||
/** 단일 보조지표 기간 */
|
||||
period?: number;
|
||||
/** 복합지표 단기·장기 기간 */
|
||||
shortPeriod?: number;
|
||||
longPeriod?: number;
|
||||
builtIn?: boolean;
|
||||
}
|
||||
|
||||
const STORAGE_AUX = 'se-palette-auxiliary-v1';
|
||||
const STORAGE_COMP = 'se-palette-composite-v1';
|
||||
|
||||
export const DEFAULT_AUXILIARY_ITEMS: Omit<PaletteItem, 'id' | 'kind'>[] = [
|
||||
{ value: 'RSI', label: 'RSI', desc: '상대강도지수', builtIn: true },
|
||||
{ value: 'MACD', label: 'MACD', desc: '이동평균 수렴확산', builtIn: true },
|
||||
{ value: 'STOCHASTIC', label: 'Stochastic', desc: '스토캐스틱', builtIn: true },
|
||||
{ value: 'CCI', label: 'CCI', desc: '상품채널지수', builtIn: true },
|
||||
{ value: 'ADX', label: 'ADX', desc: '평균방향지수', builtIn: true },
|
||||
{ value: 'DMI', label: 'DMI', desc: '방향성 지표', builtIn: true },
|
||||
{ value: 'OBV', label: 'OBV', desc: '거래량 균형', builtIn: true },
|
||||
{ value: 'WILLIAMS_R', label: 'Williams %R', desc: '윌리엄스 %R', builtIn: true },
|
||||
{ value: 'TRIX', label: 'TRIX', desc: '삼중지수이동평균', builtIn: true },
|
||||
{ value: 'VOLUME_OSC', label: 'Volume OSC', desc: '거래량 오실레이터', builtIn: true },
|
||||
{ value: 'VR', label: 'VR', desc: '거래량 비율', builtIn: true },
|
||||
{ value: 'DISPARITY', label: '이격도', desc: 'Disparity', builtIn: true },
|
||||
{ value: 'PSYCHOLOGICAL', label: '심리도', desc: 'Psychological', builtIn: true },
|
||||
{ value: 'INVEST_PSYCHOLOGICAL', label: '투자심리도', desc: 'Invest PSY', builtIn: true },
|
||||
{ value: 'VOLUME', label: '거래량', desc: 'Volume', builtIn: true },
|
||||
];
|
||||
|
||||
export const DEFAULT_COMPOSITE_ITEMS: Omit<PaletteItem, 'id' | 'kind'>[] =
|
||||
COMPOSITE_INDICATOR_ITEMS.map(i => ({
|
||||
value: i.value,
|
||||
label: i.label,
|
||||
desc: i.desc,
|
||||
builtIn: true,
|
||||
}));
|
||||
|
||||
export const AUXILIARY_TYPE_OPTIONS = DEFAULT_AUXILIARY_ITEMS.map(i => ({
|
||||
value: i.value,
|
||||
label: i.label,
|
||||
}));
|
||||
|
||||
export const COMPOSITE_TYPE_OPTIONS = DEFAULT_COMPOSITE_ITEMS.map(i => ({
|
||||
value: i.value,
|
||||
label: i.label,
|
||||
}));
|
||||
|
||||
function builtinId(kind: PaletteItemKind, value: string): string {
|
||||
return `builtin-${kind}-${value}`;
|
||||
}
|
||||
|
||||
function seedItems(
|
||||
kind: PaletteItemKind,
|
||||
defaults: Omit<PaletteItem, 'id' | 'kind'>[],
|
||||
): PaletteItem[] {
|
||||
return defaults.map(d => ({
|
||||
...d,
|
||||
id: builtinId(kind, d.value),
|
||||
kind,
|
||||
}));
|
||||
}
|
||||
|
||||
function parseStored(raw: string | null): PaletteItem[] | null {
|
||||
if (!raw) return null;
|
||||
try {
|
||||
const arr = JSON.parse(raw) as PaletteItem[];
|
||||
if (!Array.isArray(arr)) return null;
|
||||
return arr.filter(
|
||||
i => i && typeof i.id === 'string' && typeof i.value === 'string' && i.label,
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function loadPaletteItems(kind: PaletteItemKind): PaletteItem[] {
|
||||
const key = kind === 'auxiliary' ? STORAGE_AUX : STORAGE_COMP;
|
||||
const defaults = kind === 'auxiliary' ? DEFAULT_AUXILIARY_ITEMS : DEFAULT_COMPOSITE_ITEMS;
|
||||
try {
|
||||
const stored = parseStored(localStorage.getItem(key));
|
||||
if (stored && stored.length > 0) {
|
||||
return stored.map(i => ({ ...i, kind }));
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
return seedItems(kind, defaults);
|
||||
}
|
||||
|
||||
export function savePaletteItems(kind: PaletteItemKind, items: PaletteItem[]): void {
|
||||
const key = kind === 'auxiliary' ? STORAGE_AUX : STORAGE_COMP;
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(items));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
export function resetPaletteItems(kind: PaletteItemKind): PaletteItem[] {
|
||||
const defaults = kind === 'auxiliary' ? DEFAULT_AUXILIARY_ITEMS : DEFAULT_COMPOSITE_ITEMS;
|
||||
const items = seedItems(kind, defaults);
|
||||
savePaletteItems(kind, items);
|
||||
return items;
|
||||
}
|
||||
|
||||
export function createPaletteItemId(): string {
|
||||
return `custom-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
||||
}
|
||||
Reference in New Issue
Block a user