가상수정2
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
coerceFiniteNumber,
|
||||
formatIndicatorValue,
|
||||
isConditionMet,
|
||||
type VirtualConditionRow,
|
||||
@@ -33,37 +34,39 @@ const PENDING_PROGRESS = 72;
|
||||
/** 목표값 대비 현재값 접근률 (0~100, 충족 시 100) */
|
||||
export function computeConditionProgress(
|
||||
conditionType: string,
|
||||
current: number | null,
|
||||
target: number | null,
|
||||
current: number | null | unknown,
|
||||
target: number | null | unknown,
|
||||
): number | null {
|
||||
if (current == null || target == null) return null;
|
||||
const met = isConditionMet(conditionType, current, target);
|
||||
const cur = coerceFiniteNumber(current);
|
||||
const tgt = coerceFiniteNumber(target);
|
||||
if (cur == null || tgt == null) return null;
|
||||
const met = isConditionMet(conditionType, cur, tgt);
|
||||
if (met === true) return 100;
|
||||
|
||||
const absTarget = Math.abs(target);
|
||||
const scale = absTarget > 1e-9 ? absTarget : Math.max(Math.abs(current), 1);
|
||||
const absTarget = Math.abs(tgt);
|
||||
const scale = absTarget > 1e-9 ? absTarget : Math.max(Math.abs(cur), 1);
|
||||
|
||||
switch (conditionType) {
|
||||
case 'LT':
|
||||
case 'CROSS_DOWN':
|
||||
case 'LTE': {
|
||||
if (current <= target) return 100;
|
||||
const gap = current - target;
|
||||
if (cur <= tgt) return 100;
|
||||
const gap = cur - tgt;
|
||||
return Math.min(99, Math.max(0, 100 - (gap / scale) * 100));
|
||||
}
|
||||
case 'GT':
|
||||
case 'CROSS_UP':
|
||||
case 'GTE': {
|
||||
if (current >= target) return 100;
|
||||
if (target <= 0 && current <= 0) return 0;
|
||||
return Math.min(99, Math.max(0, (current / scale) * 100));
|
||||
if (cur >= tgt) return 100;
|
||||
if (tgt <= 0 && cur <= 0) return 0;
|
||||
return Math.min(99, Math.max(0, (cur / scale) * 100));
|
||||
}
|
||||
case 'EQ': {
|
||||
const diff = Math.abs(current - target);
|
||||
const diff = Math.abs(cur - tgt);
|
||||
return Math.min(99, Math.max(0, 100 - (diff / scale) * 100));
|
||||
}
|
||||
default:
|
||||
return Math.min(99, Math.max(0, 100 - (Math.abs(current - target) / scale) * 100));
|
||||
return Math.min(99, Math.max(0, 100 - (Math.abs(cur - tgt) / scale) * 100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,10 +171,11 @@ export function buildConditionMetrics(
|
||||
/** 전체 매매조건 일치율 — 백엔드 matchRate 우선 */
|
||||
export function computeMatchRate(
|
||||
metrics: ConditionMetric[],
|
||||
backendMatchRate?: number,
|
||||
backendMatchRate?: number | unknown,
|
||||
): number {
|
||||
if (backendMatchRate != null && Number.isFinite(backendMatchRate)) {
|
||||
return Math.round(Math.min(100, Math.max(0, backendMatchRate)));
|
||||
const backend = coerceFiniteNumber(backendMatchRate);
|
||||
if (backend != null) {
|
||||
return Math.round(Math.min(100, Math.max(0, backend)));
|
||||
}
|
||||
const evaluable = metrics.filter(m => m.status !== 'unknown');
|
||||
if (evaluable.length === 0) return 0;
|
||||
|
||||
Reference in New Issue
Block a user