goldenChat base source add

This commit is contained in:
aidev
2026-05-23 15:11:48 +09:00
commit a4ea7762b5
2081 changed files with 1155760 additions and 0 deletions
@@ -0,0 +1,219 @@
/**
* 보조지표 설정 편집 — 개별 모달·일괄 설정 팝업 공통 직렬화/초기화
*/
import type { IndicatorConfig, HlinesBackground, Timeframe } from '../types';
import type { PlotDef, HLineDef } from './indicatorRegistry';
import {
getIndicatorDef,
mergePlotDefs,
normalizeHLines,
normalizeObvParams,
enrichIndicatorConfig,
} from './indicatorRegistry';
import {
normalizeBollingerParams,
DEFAULT_BB_BAND_BACKGROUND,
resolveBbBandBackground,
} from './bollingerConfig';
import { normalizeDmiParams } from './indicatorRegistry';
import {
normalizeSmaConfig,
createDefaultSmaParams,
createDefaultSmaPlots,
createDefaultSmaPlotVisibility,
} from './smaConfig';
import {
normalizeIchimokuConfig,
createDefaultIchimokuParams,
createDefaultIchimokuPlotVisibility,
mergeIchimokuPlots,
DEFAULT_ICHIMOKU_CLOUD_COLORS,
resolveIchimokuCloudColors,
type IchimokuCloudColors,
} from './ichimokuConfig';
export const DEFAULT_HLINES_BG: HlinesBackground = { visible: true, color: '#787B8640' };
export interface IndicatorSettingsEditorSnapshot {
params: Record<string, number | string | boolean>;
plots: PlotDef[];
plotVis: Record<string, boolean>;
hlines: HLineDef[];
hlinesBg: HlinesBackground;
lastValueVisible: boolean;
timeframeVis: Partial<Record<Timeframe, boolean>>;
cloudColors: IchimokuCloudColors;
bandBg: HlinesBackground;
}
/** 차트·DB 값으로 편집기 초기 config (개별 모달·일괄 팝업 동일) */
export function initializeIndicatorConfigForEditor(
raw: IndicatorConfig,
getParams?: (type: string, defaults: Record<string, number | string | boolean>) => Record<string, number | string | boolean>,
getVisualConfig?: (
type: string,
defaultPlots: PlotDef[],
defaultHlines?: HLineDef[],
) => { plots: PlotDef[]; hlines: HLineDef[]; cloudColors?: IchimokuCloudColors },
): IndicatorConfig {
const def = getIndicatorDef(raw.type);
if (!def) return enrichIndicatorConfig(raw);
const params = getParams
? { ...getParams(raw.type, def.defaultParams), ...raw.params }
: { ...raw.params };
const visual = getVisualConfig?.(raw.type, def.plots, def.hlines);
return enrichIndicatorConfig({
...raw,
params,
plots: raw.plots?.length ? raw.plots : visual?.plots,
hlines: raw.hlines?.length ? raw.hlines : visual?.hlines,
cloudColors: raw.cloudColors ?? visual?.cloudColors,
});
}
export function createEditorSnapshot(config: IndicatorConfig): IndicatorSettingsEditorSnapshot {
const normalized = config.type === 'SMA'
? normalizeSmaConfig(config)
: config.type === 'IchimokuCloud'
? normalizeIchimokuConfig(config)
: config;
const def = getIndicatorDef(config.type);
const baseParams = config.type === 'SMA' || config.type === 'IchimokuCloud'
? { ...normalized.params }
: { ...(def?.defaultParams ?? {}), ...normalized.params };
let params = baseParams;
if (config.type === 'OBV') params = normalizeObvParams(baseParams);
if (config.type === 'BollingerBands') params = normalizeBollingerParams(baseParams);
if (config.type === 'DMI') params = normalizeDmiParams(baseParams);
const basePlots: PlotDef[] = config.type === 'IchimokuCloud'
? mergeIchimokuPlots(normalized.plots, def?.plots ?? [])
: mergePlotDefs(normalized.plots, def?.plots ?? []);
const plotVis: Record<string, boolean> = { ...normalized.plotVisibility };
const mergedParams = { ...(def?.defaultParams ?? {}), ...normalized.params };
for (const p of basePlots) {
if (plotVis[p.id] === undefined) {
plotVis[p.id] = normalized.plotVisibility?.[p.id] !== false;
}
}
if ((config.type === 'CCI' || config.type === 'RSI') && mergedParams.maType === 'None') {
plotVis.plot1 = false;
}
const baseHLines: HLineDef[] = config.hlines ?? def?.hlines ?? [];
return {
params,
plots: basePlots.map(p => ({ ...p })),
plotVis,
hlines: normalizeHLines(
baseHLines.map(h => ({ ...h, visible: h.visible !== false })),
config.type,
def?.hlines,
),
hlinesBg: normalized.hlinesBackground ?? { ...DEFAULT_HLINES_BG },
lastValueVisible: normalized.lastValueVisible !== false,
timeframeVis: { ...normalized.timeframeVisibility },
cloudColors: resolveIchimokuCloudColors(normalized.cloudColors),
bandBg: resolveBbBandBackground(normalized.bandBackground),
};
}
/** 편집 스냅샷 → IndicatorConfig (저장·일괄 적용·실시간 onChange 공통) */
export function configFromEditorSnapshot(
base: IndicatorConfig,
snap: IndicatorSettingsEditorSnapshot,
): IndicatorConfig {
const def = getIndicatorDef(base.type);
const hasHLines = (def?.hlines ?? []).length > 0 || snap.hlines.length > 0;
const tfVis = Object.values(snap.timeframeVis).some(v => v === false)
? snap.timeframeVis
: undefined;
const draft: IndicatorConfig = {
...base,
params: snap.params,
plots: snap.plots,
plotVisibility: snap.plotVis,
hlines: snap.hlines,
hlinesBackground: hasHLines ? snap.hlinesBg : undefined,
lastValueVisible: snap.lastValueVisible,
timeframeVisibility: tfVis,
...(base.type === 'IchimokuCloud' ? { cloudColors: snap.cloudColors } : {}),
};
if (base.type === 'SMA') return normalizeSmaConfig(draft);
if (base.type === 'IchimokuCloud') return normalizeIchimokuConfig(draft);
if (base.type === 'BollingerBands') {
return enrichIndicatorConfig({
...draft,
params: normalizeBollingerParams(draft.params),
bandBackground: snap.bandBg,
});
}
return enrichIndicatorConfig(draft);
}
/** 지표별 기본값 (id·hidden 유지) */
export function resetConfigToDefaults(config: IndicatorConfig): IndicatorConfig {
const def = getIndicatorDef(config.type);
if (!def) return config;
if (config.type === 'SMA') {
return normalizeSmaConfig({
...config,
params: createDefaultSmaParams(),
plots: createDefaultSmaPlots(),
plotVisibility: createDefaultSmaPlotVisibility(),
hlines: [],
hlinesBackground: undefined,
lastValueVisible: true,
timeframeVisibility: undefined,
});
}
if (config.type === 'IchimokuCloud') {
return normalizeIchimokuConfig({
...config,
params: createDefaultIchimokuParams(),
plots: def.plots.map(p => ({ ...p })),
plotVisibility: createDefaultIchimokuPlotVisibility(),
cloudColors: DEFAULT_ICHIMOKU_CLOUD_COLORS,
hlines: [],
hlinesBackground: undefined,
lastValueVisible: true,
timeframeVisibility: undefined,
});
}
const baseParams = { ...(def.defaultParams as Record<string, number | string | boolean>) };
const plots = def.plots.map(p => ({ ...p }));
const plotVis: Record<string, boolean> = {};
for (const p of def.plots) plotVis[p.id] = true;
let params = config.type === 'BollingerBands'
? normalizeBollingerParams(baseParams)
: baseParams;
const draft: IndicatorConfig = {
...config,
params,
plots,
plotVisibility: plotVis,
hlines: normalizeHLines(
(def.hlines ?? []).map(h => ({ ...h, visible: h.visible !== false })),
config.type,
def.hlines,
),
hlinesBackground: { ...DEFAULT_HLINES_BG },
lastValueVisible: true,
timeframeVisibility: undefined,
cloudColors: undefined,
bandBackground: config.type === 'BollingerBands' ? { ...DEFAULT_BB_BAND_BACKGROUND } : undefined,
};
return enrichIndicatorConfig(draft);
}