추가수정
This commit is contained in:
@@ -157,7 +157,10 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
|||||||
onNewCandle: handleNewCandle,
|
onNewCandle: handleNewCandle,
|
||||||
enabled: enabled && useUpbit,
|
enabled: enabled && useUpbit,
|
||||||
source: chartRealtimeSource,
|
source: chartRealtimeSource,
|
||||||
deepObvHistory: needsDeepObv,
|
deepObvHistory: false,
|
||||||
|
// OBV 있을 때: 200봉만 가져오면 OBV가 0부터 시작 → 신호선과 시각적 발산 보장
|
||||||
|
// WARMUP_COUNT(600) 불필요 — 미니차트 지표(OBV SMA-9, W%R 등)는 짧은 웜업으로 충분
|
||||||
|
fetchCount: needsDeepObv ? 200 : undefined,
|
||||||
}), [handleTickUpdate, handleNewCandle, enabled, useUpbit, needsDeepObv, chartRealtimeSource]),
|
}), [handleTickUpdate, handleNewCandle, enabled, useUpbit, needsDeepObv, chartRealtimeSource]),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -300,7 +303,6 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
|||||||
candleOverlayToggles={candleOverlayToggles}
|
candleOverlayToggles={candleOverlayToggles}
|
||||||
onToggleCandleOverlay={handleToggleCandleOverlay}
|
onToggleCandleOverlay={handleToggleCandleOverlay}
|
||||||
crosshairInfoVisible={false}
|
crosshairInfoVisible={false}
|
||||||
resolveInitialDisplayCount={needsDeepObv ? () => 99999 : undefined}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ interface Options {
|
|||||||
onNewCandle: (bar: OHLCVBar) => void;
|
onNewCandle: (bar: OHLCVBar) => void;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
deepObvHistory?: boolean;
|
deepObvHistory?: boolean;
|
||||||
|
/** 직접 지정할 페치 봉 수 — UPBIT_DIRECT 전용 (deepObvHistory·WARMUP_COUNT 무시) */
|
||||||
|
fetchCount?: number;
|
||||||
source?: ChartRealtimeSource;
|
source?: ChartRealtimeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ export function useChartRealtimeData(
|
|||||||
onNewCandle: opts.onNewCandle,
|
onNewCandle: opts.onNewCandle,
|
||||||
enabled: opts.enabled !== false && !useStomp,
|
enabled: opts.enabled !== false && !useStomp,
|
||||||
deepObvHistory: opts.deepObvHistory,
|
deepObvHistory: opts.deepObvHistory,
|
||||||
|
fetchCount: opts.fetchCount,
|
||||||
});
|
});
|
||||||
return useStomp ? stomp : upbit;
|
return useStomp ? stomp : upbit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ interface UpbitDataOptions {
|
|||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
/** OBV 등 누적 지표: 상장 이력에 가깝게 장기 캔들 로드 */
|
/** OBV 등 누적 지표: 상장 이력에 가깝게 장기 캔들 로드 */
|
||||||
deepObvHistory?: boolean;
|
deepObvHistory?: boolean;
|
||||||
|
/** 직접 지정할 페치 봉 수 (deepObvHistory·WARMUP_COUNT 무시) */
|
||||||
|
fetchCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UseUpbitDataReturn {
|
interface UseUpbitDataReturn {
|
||||||
@@ -88,9 +90,8 @@ export function useUpbitData(
|
|||||||
const marketChanged = prevMarketRef.current !== '' && prevMarketRef.current !== market;
|
const marketChanged = prevMarketRef.current !== '' && prevMarketRef.current !== market;
|
||||||
prevMarketRef.current = market;
|
prevMarketRef.current = market;
|
||||||
|
|
||||||
const fetchCount = opts.deepObvHistory
|
const fetchCount = opts.fetchCount
|
||||||
? OBV_DEEP_HISTORY
|
?? (opts.deepObvHistory ? OBV_DEEP_HISTORY : DISPLAY_COUNT + WARMUP_COUNT);
|
||||||
: DISPLAY_COUNT + WARMUP_COUNT;
|
|
||||||
|
|
||||||
fetchUpbitCandlesCached(market, timeframe, fetchCount, marketChanged)
|
fetchUpbitCandlesCached(market, timeframe, fetchCount, marketChanged)
|
||||||
.then(newBars => {
|
.then(newBars => {
|
||||||
@@ -108,7 +109,7 @@ export function useUpbitData(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return () => { cancelled = true; };
|
return () => { cancelled = true; };
|
||||||
}, [market, timeframe, opts.enabled, opts.deepObvHistory]);
|
}, [market, timeframe, opts.enabled, opts.deepObvHistory, opts.fetchCount]);
|
||||||
|
|
||||||
// ── 2. WebSocket: 실시간 체결 구독 ────────────────────────────────────
|
// ── 2. WebSocket: 실시간 체결 구독 ────────────────────────────────────
|
||||||
const handleMessage = useCallback((msg: UpbitMessage) => {
|
const handleMessage = useCallback((msg: UpbitMessage) => {
|
||||||
|
|||||||
@@ -897,11 +897,8 @@ export class ChartManager {
|
|||||||
const fallbackColor = config.type === 'OBV' && plotDef.id === 'plot0'
|
const fallbackColor = config.type === 'OBV' && plotDef.id === 'plot0'
|
||||||
? (regPlot?.color ?? '#2196F3')
|
? (regPlot?.color ?? '#2196F3')
|
||||||
: (regPlot?.color ?? plotDef.color ?? '#2962FF');
|
: (regPlot?.color ?? plotDef.color ?? '#2962FF');
|
||||||
const resolvedColor = config.type === 'OBV' && plotDef.id === 'plot0'
|
|
||||||
? '#FFFF00'
|
|
||||||
: resolvePlotLineColor(plotDef.color, fallbackColor);
|
|
||||||
series = this.chart.addSeries(LineSeries, {
|
series = this.chart.addSeries(LineSeries, {
|
||||||
color: resolvedColor,
|
color: resolvePlotLineColor(plotDef.color, fallbackColor),
|
||||||
lineWidth: (config.type === 'OBV' && plotDef.id === 'plot0'
|
lineWidth: (config.type === 'OBV' && plotDef.id === 'plot0'
|
||||||
? Math.max(2, plotDef.lineWidth ?? regPlot?.lineWidth ?? 2)
|
? Math.max(2, plotDef.lineWidth ?? regPlot?.lineWidth ?? 2)
|
||||||
: Math.max(1, plotDef.lineWidth ?? 1)) as 1 | 2 | 3 | 4,
|
: Math.max(1, plotDef.lineWidth ?? 1)) as 1 | 2 | 3 | 4,
|
||||||
@@ -913,19 +910,6 @@ export class ChartManager {
|
|||||||
...(indicatorPriceFormat ? { priceFormat: indicatorPriceFormat } : {}),
|
...(indicatorPriceFormat ? { priceFormat: indicatorPriceFormat } : {}),
|
||||||
}, pane);
|
}, pane);
|
||||||
series.setData(filtered.map(p => ({ time: p.time as Time, value: p.value })));
|
series.setData(filtered.map(p => ({ time: p.time as Time, value: p.value })));
|
||||||
if (config.type === 'OBV') {
|
|
||||||
const p0 = result.plots['plot0'] as PlotData | undefined;
|
|
||||||
const p1 = result.plots['plot1'] as PlotData | undefined;
|
|
||||||
console.error(
|
|
||||||
`[OBV addIndicator] plotDef.id=${plotDef.id}`,
|
|
||||||
'| visible:', isPlotVisible,
|
|
||||||
'| filteredLen:', filtered.length,
|
|
||||||
'| first val:', filtered[0]?.value,
|
|
||||||
'| last val:', filtered[filtered.length - 1]?.value,
|
|
||||||
'| p0.length:', p0?.length, '| p1.length:', p1?.length,
|
|
||||||
'| pane:', pane,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
seriesMeta.push({ plotId: plotDef.id, isHistogram: false, color: plotDef.color });
|
seriesMeta.push({ plotId: plotDef.id, isHistogram: false, color: plotDef.color });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2903,12 +2887,7 @@ export class ChartManager {
|
|||||||
const fallbackColor = entry.type === 'OBV' && pid === 'plot0'
|
const fallbackColor = entry.type === 'OBV' && pid === 'plot0'
|
||||||
? (regPlot?.color ?? '#2196F3')
|
? (regPlot?.color ?? '#2196F3')
|
||||||
: (regPlot?.color ?? plot.color ?? '#aaa');
|
: (regPlot?.color ?? plot.color ?? '#aaa');
|
||||||
opts['color'] = (entry.type === 'OBV' && pid === 'plot0')
|
opts['color'] = resolvePlotLineColor(plot.color, fallbackColor);
|
||||||
? '#FFFF00'
|
|
||||||
: resolvePlotLineColor(plot.color, fallbackColor);
|
|
||||||
if (entry.type === 'OBV') {
|
|
||||||
console.error(`[OBV applyStyle] pid=${pid} visible=${visible} color=${opts['color']}`);
|
|
||||||
}
|
|
||||||
opts['lineWidth'] = entry.type === 'OBV' && pid === 'plot0'
|
opts['lineWidth'] = entry.type === 'OBV' && pid === 'plot0'
|
||||||
? Math.max(2, plot.lineWidth ?? regPlot?.lineWidth ?? 2)
|
? Math.max(2, plot.lineWidth ?? regPlot?.lineWidth ?? 2)
|
||||||
: Math.max(1, plot.lineWidth ?? regPlot?.lineWidth ?? 1);
|
: Math.max(1, plot.lineWidth ?? regPlot?.lineWidth ?? 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user