가상 수정
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
pinCandleWatch,
|
||||
type LiveConditionRowDto,
|
||||
} from '../utils/backendApi';
|
||||
import { formatIndicatorDisplayLabel } from '../utils/indicatorRegistry';
|
||||
import {
|
||||
extractVirtualConditions,
|
||||
type VirtualConditionRow,
|
||||
@@ -29,7 +30,26 @@ function rowFallbackKey(row: Pick<VirtualConditionRow, 'side' | 'timeframe' | 'i
|
||||
}
|
||||
|
||||
function liveFallbackKey(r: LiveConditionRowDto): string {
|
||||
return `${r.side}:${r.timeframe}:${r.indicatorType}:${r.conditionType}:${r.targetValue ?? ''}:${r.indicatorType}`;
|
||||
const plotKey = r.plotKey ?? r.indicatorType;
|
||||
return `${r.side}:${r.timeframe}:${r.indicatorType}:${r.conditionType}:${r.targetValue ?? ''}:${plotKey}`;
|
||||
}
|
||||
|
||||
function liveRowToVirtual(r: LiveConditionRowDto): VirtualConditionRow & { currentValue: number | null } {
|
||||
const plotKey = r.plotKey ?? r.indicatorType;
|
||||
return {
|
||||
id: r.id,
|
||||
indicatorType: r.indicatorType,
|
||||
displayName: formatIndicatorDisplayLabel(r.indicatorType),
|
||||
conditionType: r.conditionType,
|
||||
conditionLabel: r.conditionLabel,
|
||||
targetValue: r.targetValue,
|
||||
timeframe: r.timeframe,
|
||||
side: r.side,
|
||||
plotKey,
|
||||
satisfied: r.satisfied,
|
||||
thresholdLabel: r.thresholdLabel,
|
||||
currentValue: r.currentValue,
|
||||
};
|
||||
}
|
||||
|
||||
function mergeRows(
|
||||
@@ -44,26 +64,13 @@ function mergeRows(
|
||||
}
|
||||
|
||||
if (base.length === 0) {
|
||||
return live.map(r => ({
|
||||
id: r.id,
|
||||
indicatorType: r.indicatorType,
|
||||
displayName: r.displayName,
|
||||
conditionType: r.conditionType,
|
||||
conditionLabel: r.conditionLabel,
|
||||
targetValue: r.targetValue,
|
||||
timeframe: r.timeframe,
|
||||
side: r.side,
|
||||
plotKey: r.indicatorType,
|
||||
satisfied: r.satisfied,
|
||||
thresholdLabel: r.thresholdLabel,
|
||||
currentValue: r.currentValue,
|
||||
}));
|
||||
return live.map(liveRowToVirtual);
|
||||
}
|
||||
|
||||
return base.map(row => {
|
||||
const liveRow = liveById.get(row.id) ?? liveByKey.get(rowFallbackKey(row));
|
||||
if (!liveRow) {
|
||||
return { ...row, currentValue: null as number | null };
|
||||
return { ...row, currentValue: null as number | null, satisfied: null };
|
||||
}
|
||||
return {
|
||||
...row,
|
||||
@@ -89,20 +96,20 @@ async function buildSnapshot(
|
||||
market,
|
||||
strategyId,
|
||||
timeframe: [...new Set(baseRows.map(r => r.timeframe))].join(', '),
|
||||
rows: baseRows.map(r => ({ ...r, currentValue: null })),
|
||||
rows: baseRows.map(r => ({ ...r, currentValue: null, satisfied: null })),
|
||||
updatedAt: Date.now(),
|
||||
matchRate: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const status = await fetchLiveConditionStatus(market, strategyId);
|
||||
if (!status || status.market !== market) {
|
||||
if (!status || status.market !== market || status.strategyId !== strategyId) {
|
||||
if (baseRows.length === 0) return null;
|
||||
return {
|
||||
market,
|
||||
strategyId,
|
||||
timeframe: [...new Set(baseRows.map(r => r.timeframe))].join(', '),
|
||||
rows: baseRows.map(r => ({ ...r, currentValue: null })),
|
||||
rows: baseRows.map(r => ({ ...r, currentValue: null, satisfied: null })),
|
||||
updatedAt: Date.now(),
|
||||
matchRate: 0,
|
||||
};
|
||||
@@ -133,6 +140,7 @@ export function useVirtualIndicatorSnapshots(
|
||||
const strategiesRef = useRef(strategies);
|
||||
strategiesRef.current = strategies;
|
||||
const pinnedRef = useRef<Set<string>>(new Set());
|
||||
const refreshGenRef = useRef<Record<string, number>>({});
|
||||
const targetsKey = targets.map(t => `${t.market}:${t.strategyId ?? ''}`).join('|');
|
||||
|
||||
const pinTargets = useCallback(async () => {
|
||||
@@ -173,16 +181,17 @@ export function useVirtualIndicatorSnapshots(
|
||||
const jobs = targets
|
||||
.filter(t => t.strategyId != null)
|
||||
.map(async t => {
|
||||
const gen = (refreshGenRef.current[t.market] ?? 0) + 1;
|
||||
refreshGenRef.current[t.market] = gen;
|
||||
const strat = strats.find(s => s.id === t.strategyId);
|
||||
const snap = await buildSnapshot(t.market, t.strategyId!, strat, running);
|
||||
if (snap) {
|
||||
setSnapshots(prev => ({ ...prev, [snap.market]: snap }));
|
||||
}
|
||||
if (!snap || refreshGenRef.current[t.market] !== gen) return snap;
|
||||
if (snap.strategyId !== t.strategyId) return snap;
|
||||
setSnapshots(prev => ({ ...prev, [snap.market]: snap }));
|
||||
return snap;
|
||||
});
|
||||
await Promise.all(jobs);
|
||||
|
||||
// 제거된 종목 스냅샷 정리
|
||||
const activeMarkets = new Set(targets.map(t => t.market));
|
||||
setSnapshots(prev => {
|
||||
const next = { ...prev };
|
||||
@@ -201,6 +210,7 @@ export function useVirtualIndicatorSnapshots(
|
||||
if (targets.length === 0) {
|
||||
setSnapshots({});
|
||||
pinnedRef.current.clear();
|
||||
refreshGenRef.current = {};
|
||||
return;
|
||||
}
|
||||
void refresh();
|
||||
|
||||
Reference in New Issue
Block a user