OBV 신호선 점선 처리로 본선과 시각 구분 보장
- 진단 로그로 두 시리즈가 정상 생성됨을 확인 (series:2, visible:true, color:#2196F3) - 미니차트는 800봉 누적 OBV 계산 → 마지막 200봉 구간에서 OBV와 SMA(9)가 수렴, 주황 신호선이 파란 본선을 덮어 1개 선처럼 보이는 것이 원인 - registry plot1에 lineStyle:'dashed' 추가 - normalizeSignalLineIndicatorPlots OBV 분기에서 plot0=solid, plot1=dashed 강제 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -928,23 +928,6 @@ export class ChartManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── OBV 진단 로그 (개발용) ────────────────────────────────────────────
|
|
||||||
if (config.type === 'OBV') {
|
|
||||||
const plotKeys = Object.keys(result.plots);
|
|
||||||
const seriesIds = seriesMeta.map(m => m.plotId);
|
|
||||||
const volSum = this.rawBars.reduce((s, b) => s + (Number(b.volume) || 0), 0);
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(
|
|
||||||
'[OBV Debug] series:', seriesList.length,
|
|
||||||
'| plotIds:', seriesIds,
|
|
||||||
'| resultKeys:', plotKeys,
|
|
||||||
'| plotVisibility:', JSON.stringify(config.plotVisibility),
|
|
||||||
'| plot0Color:', config.plots?.find(p => p.id === 'plot0')?.color,
|
|
||||||
'| bars:', this.rawBars.length,
|
|
||||||
'| volSum>0:', volSum > 0,
|
|
||||||
'| pane:', pane,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hlines(과열선/중앙선/침체선)는 첫 번째 시리즈에만 한 번 생성 (중복 방지)
|
// hlines(과열선/중앙선/침체선)는 첫 번째 시리즈에만 한 번 생성 (중복 방지)
|
||||||
const hlineRefs: IPriceLine[] = [];
|
const hlineRefs: IPriceLine[] = [];
|
||||||
@@ -2921,11 +2904,6 @@ export class ChartManager {
|
|||||||
} else {
|
} else {
|
||||||
opts['color'] = plot.color ?? '#aaa';
|
opts['color'] = plot.color ?? '#aaa';
|
||||||
}
|
}
|
||||||
// ── OBV plot0 스타일 진단 로그 ──────────────────────────────────────────
|
|
||||||
if (entry.type === 'OBV' && pid === 'plot0') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error('[OBV Style] plot0 opts:', JSON.stringify({ visible: opts['visible'], color: opts['color'], lineWidth: opts['lineWidth'] }));
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
series.applyOptions(opts as any);
|
series.applyOptions(opts as any);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ export const INDICATOR_REGISTRY: IndicatorDef[] = [
|
|||||||
{ type:'HistoricalVolatility',name:'Historical Volatility', koreanName:'역사적변동성', shortName:'HV', category:'Volatility', overlay:false, defaultParams:{length:20, annualBars:252}, plots:[{id:'plot0',title:'HV', color:'#E91E63',type:'line',lineWidth:2}], description:'역사적 변동성 (연화)' },
|
{ type:'HistoricalVolatility',name:'Historical Volatility', koreanName:'역사적변동성', shortName:'HV', category:'Volatility', overlay:false, defaultParams:{length:20, annualBars:252}, plots:[{id:'plot0',title:'HV', color:'#E91E63',type:'line',lineWidth:2}], description:'역사적 변동성 (연화)' },
|
||||||
|
|
||||||
// ── Volume ────────────────────────────────────────────────────────────────
|
// ── Volume ────────────────────────────────────────────────────────────────
|
||||||
{ type:'OBV', name:'On Balance Volume', koreanName:'잔량균형지수', shortName:'OBV', category:'Volume', overlay:false, defaultParams:{maType:'SMA', maLength:9}, plots:[{id:'plot0',title:'OBV', color:'#2196F3',type:'line',lineWidth:2},{id:'plot1',title:'Signal',color:'#FF9800',type:'line',lineWidth:1}], hlines:[], description:'잔량 균형 지수 (OBV + 이동평균 신호선)' },
|
{ type:'OBV', name:'On Balance Volume', koreanName:'잔량균형지수', shortName:'OBV', category:'Volume', overlay:false, defaultParams:{maType:'SMA', maLength:9}, plots:[{id:'plot0',title:'OBV', color:'#2196F3',type:'line',lineWidth:2},{id:'plot1',title:'Signal',color:'#FF9800',type:'line',lineWidth:1,lineStyle:'dashed'}], hlines:[], description:'잔량 균형 지수 (OBV + 이동평균 신호선)' },
|
||||||
{ type:'VR', name:'Volume Ratio', koreanName:'거래량비율', shortName:'VR', category:'Volume', overlay:false, defaultParams:{length:10}, plots:[{id:'plot0',title:'VR', color:'#AB47BC',type:'line',lineWidth:2}], hlines:[{price:200,color:'#EF5350'},{price:100,color:'#607D8B'},{price:50,color:'#4CAF50'}], description:'거래량 비율 (VR)' },
|
{ type:'VR', name:'Volume Ratio', koreanName:'거래량비율', shortName:'VR', category:'Volume', overlay:false, defaultParams:{length:10}, plots:[{id:'plot0',title:'VR', color:'#AB47BC',type:'line',lineWidth:2}], hlines:[{price:200,color:'#EF5350'},{price:100,color:'#607D8B'},{price:50,color:'#4CAF50'}], description:'거래량 비율 (VR)' },
|
||||||
{ type:'Disparity', name:'Disparity Index', koreanName:'이격도', shortName:'Disp', category:'Oscillators', overlay:false, defaultParams:{ultraLength:5, shortLength:10, midLength:20, longLength:60, src:'close'}, plots:[{id:'plot0',title:'초단기',color:'#E91E63',type:'line',lineWidth:1},{id:'plot1',title:'단기',color:'#FF9800',type:'line',lineWidth:1},{id:'plot2',title:'중기',color:'#4CAF50',type:'line',lineWidth:1},{id:'plot3',title:'장기',color:'#2196F3',type:'line',lineWidth:1}], hlines:[{price:100,color:'#607D8B'}], description:'이격도 (종가÷이평×100)' },
|
{ type:'Disparity', name:'Disparity Index', koreanName:'이격도', shortName:'Disp', category:'Oscillators', overlay:false, defaultParams:{ultraLength:5, shortLength:10, midLength:20, longLength:60, src:'close'}, plots:[{id:'plot0',title:'초단기',color:'#E91E63',type:'line',lineWidth:1},{id:'plot1',title:'단기',color:'#FF9800',type:'line',lineWidth:1},{id:'plot2',title:'중기',color:'#4CAF50',type:'line',lineWidth:1},{id:'plot3',title:'장기',color:'#2196F3',type:'line',lineWidth:1}], hlines:[{price:100,color:'#607D8B'}], description:'이격도 (종가÷이평×100)' },
|
||||||
{ type:'Psychological', name:'Psychological Line', koreanName:'심리도', shortName:'Psy', category:'Oscillators', overlay:false, defaultParams:{length:12}, plots:[{id:'plot0',title:'심리도',color:'#00BCD4',type:'line',lineWidth:2}], hlines:[{price:75,color:'#EF5350',label:'과열선'},{price:50,color:'#607D8B',label:'중앙선'},{price:25,color:'#4CAF50',label:'침체선'}], description:'심리도 (상승일 비율)' },
|
{ type:'Psychological', name:'Psychological Line', koreanName:'심리도', shortName:'Psy', category:'Oscillators', overlay:false, defaultParams:{length:12}, plots:[{id:'plot0',title:'심리도',color:'#00BCD4',type:'line',lineWidth:2}], hlines:[{price:75,color:'#EF5350',label:'과열선'},{price:50,color:'#607D8B',label:'중앙선'},{price:25,color:'#4CAF50',label:'침체선'}], description:'심리도 (상승일 비율)' },
|
||||||
@@ -481,6 +481,14 @@ function normalizeSignalLineIndicatorPlots(
|
|||||||
type: 'line' as const,
|
type: 'line' as const,
|
||||||
color: reg.color,
|
color: reg.color,
|
||||||
lineWidth: Math.max(2, normalized.lineWidth ?? reg.lineWidth ?? 2),
|
lineWidth: Math.max(2, normalized.lineWidth ?? reg.lineWidth ?? 2),
|
||||||
|
lineStyle: 'solid' as const,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// OBV 신호선 — 값이 본선과 거의 같더라도 점선으로 시각적 구분 보장
|
||||||
|
if (p.id === 'plot1') {
|
||||||
|
return {
|
||||||
|
...normalized,
|
||||||
|
lineStyle: 'dashed' as const,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return normalized;
|
return normalized;
|
||||||
|
|||||||
Reference in New Issue
Block a user