/** * 지표 설정 화면 라벨 — 한글명 (영문명) 형식 */ type LabelPair = { ko: string; en: string }; function bilingual({ ko, en }: LabelPair): string { return `${ko} (${en})`; } /** 입력값(파라미터) 키 라벨 */ const PARAM_LABELS: Record = { len: { ko: '기간', en: 'Length' }, length: { ko: '기간', en: 'Length' }, src: { ko: '소스', en: 'Source' }, fastLength: { ko: '단기 기간', en: 'Fast Length' }, slowLength: { ko: '장기 기간', en: 'Slow Length' }, signalLength: { ko: '신호선 기간', en: 'Signal Length' }, mult: { ko: '승수', en: 'Multiplier' }, multiplier: { ko: '승수', en: 'Multiplier' }, offset: { ko: '오프셋', en: 'Offset' }, sigma: { ko: '시그마', en: 'Sigma' }, increment: { ko: '증가값', en: 'Increment' }, maximum: { ko: '최대값', en: 'Maximum' }, start: { ko: '시작값', en: 'Start' }, factor: { ko: '계수', en: 'Factor' }, atrPeriod: { ko: 'ATR 기간', en: 'ATR Period' }, displacement: { ko: '이동 기간', en: 'Displacement' }, chikouDisplacement: { ko: '후행 기간', en: 'Chikou Displacement' }, senkouDisplacement: { ko: '선행 기간', en: 'Senkou Displacement' }, conversionPeriods: { ko: '전환선 기간', en: 'Conversion Periods' }, basePeriods: { ko: '기준선 기간', en: 'Base Periods' }, laggingSpan2Periods: { ko: '선행스팬2 기간', en: 'Lagging Span 2 Periods' }, kLength: { ko: '%K 기간', en: '%K Length' }, dSmoothing: { ko: '%D 스무딩', en: '%D Smoothing' }, smooth: { ko: '스무딩', en: 'Smooth' }, lengthRSI: { ko: 'RSI 기간', en: 'RSI Length' }, lengthStoch: { ko: '스토캐 기간', en: 'Stoch Length' }, smoothK: { ko: '%K 스무딩', en: '%K Smooth' }, smoothD: { ko: '%D 스무딩', en: '%D Smooth' }, length1: { ko: '기간 1', en: 'Length 1' }, length2: { ko: '기간 2', en: 'Length 2' }, length3: { ko: '기간 3', en: 'Length 3' }, rsiLength: { ko: 'RSI 기간', en: 'RSI Length' }, upDownLength: { ko: '상하 기간', en: 'Up/Down Length' }, rocLength: { ko: 'ROC 기간', en: 'ROC Length' }, longLength: { ko: '장기', en: 'Long Length' }, shortLength: { ko: '단기', en: 'Short Length' }, adxSmoothing: { ko: 'ADX 스무딩', en: 'ADX Smoothing' }, diLength: { ko: 'DI 길이', en: 'DI Length' }, percent: { ko: '비율', en: 'Percent' }, deviation: { ko: '편차', en: 'Deviation' }, depth: { ko: '깊이', en: 'Depth' }, backstep: { ko: '되돌림', en: 'Backstep' }, p: { ko: 'P', en: 'P' }, q: { ko: 'Q', en: 'Q' }, x: { ko: 'X', en: 'X' }, annualBars: { ko: '연간 봉 수', en: 'Annual Bars' }, smoothing: { ko: '스무딩', en: 'Smoothing' }, maType: { ko: '신호선', en: 'Signal Type' }, maLength: { ko: '신호선 기간', en: 'Signal Length' }, ultraLength: { ko: '초단기 기간', en: 'Ultra Length' }, midLength: { ko: '중기 기간', en: 'Mid Length' }, sessionType: { ko: '세션 유형', en: 'Session Type' }, ccilength: { ko: 'CCI 기간', en: 'CCI Length' }, turbolen: { ko: '터보 기간', en: 'Turbo Length' }, stdevLength: { ko: '표준편차 기간', en: 'Stdev Length' }, period1: { ko: 'MA1 기간', en: 'MA1 Period' }, period2: { ko: 'MA2 기간', en: 'MA2 Period' }, period3: { ko: 'MA3 기간', en: 'MA3 Period' }, period4: { ko: 'MA4 기간', en: 'MA4 Period' }, period5: { ko: 'MA5 기간', en: 'MA5 Period' }, period6: { ko: 'MA6 기간', en: 'MA6 Period' }, period7: { ko: 'MA7 기간', en: 'MA7 Period' }, period8: { ko: 'MA8 기간', en: 'MA8 Period' }, period9: { ko: 'MA9 기간', en: 'MA9 Period' }, period10: { ko: 'MA10 기간', en: 'MA10 Period' }, period11: { ko: 'MA11 기간', en: 'MA11 Period' }, }; /** 플롯(선) 타이틀 라벨 */ const PLOT_LABELS: Record = { SMA: { ko: '단순이동평균', en: 'SMA' }, EMA: { ko: '지수이동평균', en: 'EMA' }, WMA: { ko: '가중이동평균', en: 'WMA' }, HMA: { ko: '헐이동평균', en: 'HMA' }, VWMA: { ko: '거래량가중이동평균', en: 'VWMA' }, DEMA: { ko: '이중지수이동평균', en: 'DEMA' }, TEMA: { ko: '삼중지수이동평균', en: 'TEMA' }, LSMA: { ko: '최소제곱이동평균', en: 'LSMA' }, ALMA: { ko: '아르노-레구이동평균', en: 'ALMA' }, RMA: { ko: '윌더스무딩이동평균', en: 'RMA' }, SMMA: { ko: '스무딩이동평균', en: 'SMMA' }, MGD: { ko: '맥긴리다이나믹', en: 'MGD' }, Median: { ko: '중간값', en: 'Median' }, TWAP: { ko: '시간가중평균가격', en: 'TWAP' }, Fast: { ko: '단기', en: 'Fast' }, Slow: { ko: '장기', en: 'Slow' }, Upper: { ko: '상단', en: 'Upper' }, Lower: { ko: '하단', en: 'Lower' }, Middle: { ko: '중간', en: 'Middle' }, Basis: { ko: '기준', en: 'Basis' }, 중앙값: { ko: '중앙값', en: 'Basis' }, 어퍼: { ko: '어퍼', en: 'Upper' }, 로우어: { ko: '로우어', en: 'Lower' }, Tenkan: { ko: '전환선', en: 'Tenkan' }, Kijun: { ko: '기준선', en: 'Kijun' }, SpanA: { ko: '선행스팬1', en: 'SpanA' }, SpanB: { ko: '선행스팬2', en: 'SpanB' }, Lagging: { ko: '후행스팬', en: 'Lagging' }, RSI: { ko: '상대강도지수', en: 'RSI' }, '%K': { ko: '스토캐스틱 %K', en: '%K' }, '%D': { ko: '스토캐스틱 %D', en: '%D' }, '%R': { ko: '윌리엄스 %R', en: '%R' }, '%B': { ko: '볼린저 %B', en: '%B' }, CCI: { ko: '상품채널지수', en: 'CCI' }, 'CCI MA': { ko: 'CCI 이동평균', en: 'CCI MA' }, AO: { ko: '어썸오실레이터', en: 'AO' }, CMO: { ko: '챈드모멘텀', en: 'CMO' }, DPO: { ko: '비트렌드가격', en: 'DPO' }, RVI: { ko: '상대활력지수', en: 'RVI' }, Fisher: { ko: '피셔변환', en: 'Fisher' }, Signal: { ko: '신호선', en: 'Signal' }, UO: { ko: '울티메이트', en: 'UO' }, CRSI: { ko: '코너스RSI', en: 'CRSI' }, SMI: { ko: 'SMI', en: 'SMI' }, SMIO: { ko: 'SMI 오실레이터', en: 'SMIO' }, Turbo: { ko: '터보', en: 'Turbo' }, MACD: { ko: 'MACD', en: 'MACD' }, Histogram: { ko: '히스토그램', en: 'Histogram' }, MOM: { ko: '모멘텀', en: 'MOM' }, ROC: { ko: '가격변화율', en: 'ROC' }, TSI: { ko: '참강도지수', en: 'TSI' }, TRIX: { ko: 'TRIX', en: 'TRIX' }, KST: { ko: 'KST', en: 'KST' }, Coppock: { ko: '콥독커브', en: 'Coppock' }, BBP: { ko: '매수매도세력', en: 'BBP' }, EFI: { ko: '엘더강도지수', en: 'EFI' }, PPO: { ko: '가격오실레이터', en: 'PPO' }, EOM: { ko: '이동용이성', en: 'EOM' }, ADX: { ko: '평균방향성지수', en: 'ADX' }, '+DI': { ko: '+방향지표', en: '+DI' }, '-DI': { ko: '-방향지표', en: '-DI' }, DX: { ko: '방향지수', en: 'DX' }, ADXR: { ko: 'ADX 등급', en: 'ADXR' }, Up: { ko: '상승', en: 'Up' }, Down: { ko: '하락', en: 'Down' }, ST: { ko: '슈퍼트렌드', en: 'ST' }, SAR: { ko: '파라볼릭SAR', en: 'SAR' }, CHOP: { ko: '불규칙성지수', en: 'CHOP' }, MI: { ko: '매스인덱스', en: 'MI' }, 'VI+': { ko: '보텍스+', en: 'VI+' }, 'VI-': { ko: '보텍스-', en: 'VI-' }, Jaw: { ko: '턱', en: 'Jaw' }, Teeth: { ko: '이', en: 'Teeth' }, Lips: { ko: '입술', en: 'Lips' }, BBTrend: { ko: '볼린저추세', en: 'BBTrend' }, 'Stop+': { ko: '스탑+', en: 'Stop+' }, 'Stop-': { ko: '스탑-', en: 'Stop-' }, ZZ: { ko: '지그재그', en: 'ZZ' }, RCI9: { ko: 'RCI 9', en: 'RCI9' }, RCI26: { ko: 'RCI 26', en: 'RCI26' }, ATR: { ko: '평균실제범위', en: 'ATR' }, ADR: { ko: '평균일일범위', en: 'ADR' }, StdDev: { ko: '표준편차', en: 'StdDev' }, HV: { ko: '역사적변동성', en: 'HV' }, OBV: { ko: '잔량균형', en: 'OBV' }, 심리도: { ko: '심리도', en: 'Psychological' }, 신심리도: { ko: '신심리도', en: 'New Psychological' }, 투자심리도: { ko: '투자심리도', en: 'Invest Psychological' }, MFI: { ko: '자금흐름지수', en: 'MFI' }, CMF: { ko: '차이킨자금흐름', en: 'CMF' }, CO: { ko: '차이킨오실레이터', en: 'CO' }, PVT: { ko: '가격거래량추세', en: 'PVT' }, NV: { ko: '순거래량', en: 'NV' }, VD: { ko: '거래량델타', en: 'VD' }, CVD: { ko: '누적거래량델타', en: 'CVD' }, VO: { ko: '거래량오실레이터', en: 'VO' }, KVO: { ko: '클링거오실레이터', en: 'KVO' }, RVAT: { ko: '시간대별상대거래량', en: 'RVAT' }, BBW: { ko: '볼린저밴드폭', en: 'BBW' }, MA1: { ko: 'MA1', en: 'MA1' }, MA2: { ko: 'MA2', en: 'MA2' }, MA3: { ko: 'MA3', en: 'MA3' }, MA4: { ko: 'MA4', en: 'MA4' }, MA5: { ko: 'MA5', en: 'MA5' }, MA6: { ko: 'MA6', en: 'MA6' }, MA7: { ko: 'MA7', en: 'MA7' }, MA8: { ko: 'MA8', en: 'MA8' }, MA9: { ko: 'MA9', en: 'MA9' }, MA10: { ko: 'MA10', en: 'MA10' }, MA11: { ko: 'MA11', en: 'MA11' }, }; /** 소스(src) 선택 옵션 라벨 */ const SRC_LABELS: Record = { close: { ko: '종가', en: 'close' }, open: { ko: '시가', en: 'open' }, high: { ko: '고가', en: 'high' }, low: { ko: '저가', en: 'low' }, hl2: { ko: '고저평균', en: 'hl2' }, hlc3: { ko: '고저종평균', en: 'hlc3' }, ohlc4: { ko: 'OHLC평균', en: 'ohlc4' }, Regular:{ ko: '정규장', en: 'Regular' }, RMA: { ko: 'RMA', en: 'RMA' }, }; /** camelCase → 공백 구분 영문 (미매핑 키 폴백) */ function humanizeKey(key: string): string { return key .replace(/([A-Z])/g, ' $1') .replace(/^./, s => s.toUpperCase()) .trim(); } export function getParamLabel(key: string, indicatorType?: string): string { if (indicatorType === 'BollingerBands') { if (key === 'length') return bilingual({ ko: '길이', en: 'Length' }); if (key === 'mult') return bilingual({ ko: '곱', en: 'Multiplier' }); if (key === 'offset') return bilingual({ ko: '오프셋', en: 'Offset' }); } if (key === 'maType' && indicatorType === 'OBV') { return bilingual({ ko: '잔량균형(OBV)', en: 'OBV Smoothing' }); } if (key === 'maLength' && indicatorType === 'OBV') { return bilingual({ ko: '신호선 기간', en: 'Signal Length' }); } const pair = PARAM_LABELS[key]; if (pair) return bilingual(pair); return bilingual({ ko: humanizeKey(key), en: key }); } export function getPlotLabel(title: string): string { if (/^MA\d+일$/.test(title) || /^EMA\d+일$/.test(title)) return title; const pair = PLOT_LABELS[title]; if (pair) return bilingual(pair); return bilingual({ ko: title, en: title }); } export function getSrcOptionLabel(value: string): string { const pair = SRC_LABELS[value]; if (pair) return bilingual(pair); return bilingual({ ko: value, en: value }); }