그래프 수정
This commit is contained in:
@@ -63,6 +63,7 @@ import {
|
|||||||
type TradeNotificationGridPresetId,
|
type TradeNotificationGridPresetId,
|
||||||
} from '../utils/tradeNotificationGridPresets';
|
} from '../utils/tradeNotificationGridPresets';
|
||||||
import { sortTradeNotifications } from '../utils/tradeListSort';
|
import { sortTradeNotifications } from '../utils/tradeListSort';
|
||||||
|
import { getKoreanName } from '../utils/marketNameCache';
|
||||||
|
|
||||||
type RightTab = 'trade' | 'orderbook';
|
type RightTab = 'trade' | 'orderbook';
|
||||||
|
|
||||||
@@ -380,9 +381,14 @@ export const TradeNotificationListPage: React.FC<Props> = ({
|
|||||||
items = items.filter(n => {
|
items = items.filter(n => {
|
||||||
const mkt = n.market.toLowerCase();
|
const mkt = n.market.toLowerCase();
|
||||||
const sym = n.market.includes('-') ? n.market.split('-')[1].toLowerCase() : mkt;
|
const sym = n.market.includes('-') ? n.market.split('-')[1].toLowerCase() : mkt;
|
||||||
|
const ko = (
|
||||||
|
tickers?.get(n.market)?.koreanName ??
|
||||||
|
getKoreanName(n.market)
|
||||||
|
).toLowerCase();
|
||||||
const strat = (n.strategyName ?? '').toLowerCase();
|
const strat = (n.strategyName ?? '').toLowerCase();
|
||||||
const sigKo = n.signalType === 'BUY' ? '매수' : '매도';
|
const sigKo = n.signalType === 'BUY' ? '매수' : '매도';
|
||||||
return (
|
return (
|
||||||
|
ko.includes(normalizedQuery) ||
|
||||||
mkt.includes(normalizedQuery) ||
|
mkt.includes(normalizedQuery) ||
|
||||||
sym.includes(normalizedQuery) ||
|
sym.includes(normalizedQuery) ||
|
||||||
strat.includes(normalizedQuery) ||
|
strat.includes(normalizedQuery) ||
|
||||||
@@ -391,7 +397,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}, [allNotifications, filter, candleFilter, normalizedQuery]);
|
}, [allNotifications, filter, candleFilter, normalizedQuery, tickers]);
|
||||||
|
|
||||||
const sorted = useMemo(
|
const sorted = useMemo(
|
||||||
() => sortTradeNotifications(filtered, listSort),
|
() => sortTradeNotifications(filtered, listSort),
|
||||||
@@ -525,7 +531,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="tnl-search-input"
|
className="tnl-search-input"
|
||||||
placeholder="종목·전략 검색"
|
placeholder="한글 종목명·코드·전략 검색"
|
||||||
value={query}
|
value={query}
|
||||||
onChange={e => setQuery(e.target.value)}
|
onChange={e => setQuery(e.target.value)}
|
||||||
aria-label="알림 목록 검색"
|
aria-label="알림 목록 검색"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { DEFAULT_DISPLAY_TIMEZONE } from '../../utils/timezone';
|
|||||||
import { useIndicatorSettings } from '../../hooks/useIndicatorSettings';
|
import { useIndicatorSettings } from '../../hooks/useIndicatorSettings';
|
||||||
import { useSessionCandleOverlayControls } from '../../hooks/useSessionCandleOverlayControls';
|
import { useSessionCandleOverlayControls } from '../../hooks/useSessionCandleOverlayControls';
|
||||||
import { ensurePaperChartOverlays } from '../../utils/strategyToChartIndicators';
|
import { ensurePaperChartOverlays } from '../../utils/strategyToChartIndicators';
|
||||||
|
import { mergeGlobalDefaultsOntoChartIndicators } from '../../utils/indicatorMainConfig';
|
||||||
import { enrichIndicatorConfig } from '../../utils/indicatorRegistry';
|
import { enrichIndicatorConfig } from '../../utils/indicatorRegistry';
|
||||||
import {
|
import {
|
||||||
applyNotificationSignalMarkers,
|
applyNotificationSignalMarkers,
|
||||||
@@ -69,7 +70,11 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
|||||||
signalMarkerRef.current = signalMarker;
|
signalMarkerRef.current = signalMarker;
|
||||||
|
|
||||||
const baseIndicators = useMemo(
|
const baseIndicators = useMemo(
|
||||||
() => ensurePaperChartOverlays(indicators, getParams, getVisualConfig).map(enrichIndicatorConfig),
|
() => mergeGlobalDefaultsOntoChartIndicators(
|
||||||
|
ensurePaperChartOverlays(indicators, getParams, getVisualConfig),
|
||||||
|
getParams,
|
||||||
|
getVisualConfig,
|
||||||
|
).map(enrichIndicatorConfig),
|
||||||
[indicators, getParams, getVisualConfig],
|
[indicators, getParams, getVisualConfig],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,21 @@ function sortDualLinePlotDefs(plotDefs: PlotDef[]): PlotDef[] {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OBV 등 이중 plot — 설정 lineWidth 기준 굵은 선 먼저(하단), 가는 선 나중(상단).
|
||||||
|
* 값이 겹쳐도 점선·실선·색상(설정값)이 함께 보이도록 z-order만 조정.
|
||||||
|
*/
|
||||||
|
function sortPlotDefsForSeriesAdd(type: string, plotDefs: PlotDef[]): PlotDef[] {
|
||||||
|
const sorted = sortDualLinePlotDefs(plotDefs);
|
||||||
|
if (type !== 'OBV') return sorted;
|
||||||
|
return [...sorted].sort((a, b) => {
|
||||||
|
const wA = a.lineWidth ?? 1;
|
||||||
|
const wB = b.lineWidth ?? 1;
|
||||||
|
if (wA !== wB) return wB - wA;
|
||||||
|
return DUAL_LINE_PLOT_ORDER.indexOf(a.id) - DUAL_LINE_PLOT_ORDER.indexOf(b.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export class ChartManager {
|
export class ChartManager {
|
||||||
private chart: IChartApi;
|
private chart: IChartApi;
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
@@ -761,7 +776,7 @@ export class ChartManager {
|
|||||||
indicatorHidden: boolean,
|
indicatorHidden: boolean,
|
||||||
def: ReturnType<typeof getIndicatorDef>,
|
def: ReturnType<typeof getIndicatorDef>,
|
||||||
): void {
|
): void {
|
||||||
const plotDefs = sortDualLinePlotDefs(config.plots ?? def?.plots ?? []);
|
const plotDefs = sortPlotDefsForSeriesAdd(config.type, config.plots ?? def?.plots ?? []);
|
||||||
const existingIds = new Set(seriesMeta.map(m => m.plotId));
|
const existingIds = new Set(seriesMeta.map(m => m.plotId));
|
||||||
const indicatorPriceFormat = priceFormatForIndicatorPane(pane);
|
const indicatorPriceFormat = priceFormatForIndicatorPane(pane);
|
||||||
|
|
||||||
@@ -882,7 +897,7 @@ export class ChartManager {
|
|||||||
|
|
||||||
const plotDefsRaw = config.plots ?? def?.plots ?? [];
|
const plotDefsRaw = config.plots ?? def?.plots ?? [];
|
||||||
const plotDefs = DUAL_LINE_INDICATOR_TYPES.has(config.type)
|
const plotDefs = DUAL_LINE_INDICATOR_TYPES.has(config.type)
|
||||||
? sortDualLinePlotDefs(plotDefsRaw)
|
? sortPlotDefsForSeriesAdd(config.type, plotDefsRaw)
|
||||||
: plotDefsRaw;
|
: plotDefsRaw;
|
||||||
|
|
||||||
for (const plotDef of plotDefs) {
|
for (const plotDef of plotDefs) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
type HLineDef,
|
type HLineDef,
|
||||||
} from './indicatorRegistry';
|
} from './indicatorRegistry';
|
||||||
import { initializeIndicatorConfigForEditor } from './indicatorSettingsEditor';
|
import { initializeIndicatorConfigForEditor } from './indicatorSettingsEditor';
|
||||||
|
import { mergeGlobalDefaultsOntoChartIndicators } from './indicatorMainConfig';
|
||||||
import { buildMainIndicatorConfig } from './indicatorMainConfig';
|
import { buildMainIndicatorConfig } from './indicatorMainConfig';
|
||||||
import { normalizeSmaConfig, smaPeriodKey } from './smaConfig';
|
import { normalizeSmaConfig, smaPeriodKey } from './smaConfig';
|
||||||
import { normalizeIchimokuConfig } from './ichimokuConfig';
|
import { normalizeIchimokuConfig } from './ichimokuConfig';
|
||||||
@@ -266,7 +267,11 @@ export function buildStrategyChartIndicators(
|
|||||||
const cfg = buildOneIndicator(ref, getParams, getVisual);
|
const cfg = buildOneIndicator(ref, getParams, getVisual);
|
||||||
if (cfg) result.push(cfg);
|
if (cfg) result.push(cfg);
|
||||||
}
|
}
|
||||||
return result;
|
return mergeGlobalDefaultsOntoChartIndicators(
|
||||||
|
result,
|
||||||
|
getParams,
|
||||||
|
(type, defaultPlots, defaultHlines) => getVisual(type, defaultPlots ?? [], defaultHlines ?? []),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MA_OVERLAY_TYPES = new Set(['SMA', 'EMA']);
|
const MA_OVERLAY_TYPES = new Set(['SMA', 'EMA']);
|
||||||
|
|||||||
Reference in New Issue
Block a user