직접입력값 평가오류 수정

This commit is contained in:
Macbook
2026-06-18 00:15:18 +09:00
parent 9c832a3ab8
commit ea8576d756
9 changed files with 128 additions and 90 deletions
+39 -27
View File
@@ -22,36 +22,26 @@ function inferFromK(field, indicatorType) {
const val = parseFloat(field.slice(2));
return inferThresholdRoleForValue(val, indicatorType);
}
function coerceTargetValue(raw) {
if (raw == null) return null;
if (typeof raw === 'number') return Number.isFinite(raw) ? raw : null;
if (typeof raw === 'string') {
const n = parseFloat(raw.trim());
return Number.isFinite(n) ? n : null;
}
return null;
}
function normalizeCondition(cond) {
function canonicalizeCondition(cond) {
let next = { ...cond, indicatorType: cond.indicatorType?.toUpperCase?.() ?? cond.indicatorType };
const targetNum = coerceTargetValue(next.targetValue);
if (isThresholdOverridden(next)) {
if (targetNum != null) {
const role = inferThresholdRoleForValue(targetNum, next.indicatorType);
if (role) {
const { targetValue, ...rest } = next;
next = { ...rest, rightField: role, thresholdOverride: false };
}
} else if (next.rightField?.startsWith('K_')) {
const role = inferFromK(next.rightField, next.indicatorType);
if (role) {
const { targetValue, ...rest } = next;
next = { ...rest, rightField: role, thresholdOverride: false };
}
const targetNum = typeof next.targetValue === 'number' && Number.isFinite(next.targetValue)
? next.targetValue
: null;
const fromField = parseThresholdField(next.rightField);
const val = targetNum ?? fromField;
if (val != null && Number.isFinite(val)) {
const role = inferThresholdRoleForValue(val, next.indicatorType);
if (role) {
const { targetValue, ...rest } = next;
return { ...rest, rightField: role, thresholdOverride: false };
}
}
if (!isThresholdOverridden(next) && next.rightField?.startsWith('K_')) {
if (next.rightField?.startsWith('K_')) {
const role = inferFromK(next.rightField, next.indicatorType);
if (role) next = { ...next, rightField: role, thresholdOverride: false };
if (role) {
const { targetValue, ...rest } = next;
return { ...rest, rightField: role, thresholdOverride: false };
}
}
return next;
}
@@ -61,7 +51,7 @@ function isConditionCarrier(node) {
function normalizeNode(node) {
let next = { ...node };
if (isConditionCarrier(node)) {
next = { ...node, type: node.type ?? 'CONDITION', condition: normalizeCondition(node.condition) };
next = { ...node, type: node.type ?? 'CONDITION', condition: canonicalizeCondition(node.condition) };
}
if (next.children?.length) {
next.children = next.children.map(normalizeNode);
@@ -69,6 +59,17 @@ function normalizeNode(node) {
return next;
}
/** 차트 hline mid=48 이어도 직접입력 50 → HL_MID (Ta4j 기본값 기준) */
function setConditionThreshold(cond, value) {
const role = inferThresholdRoleForValue(value, cond.indicatorType);
if (role) {
const { targetValue, ...rest } = cond;
return { ...rest, rightField: role, thresholdOverride: false };
}
return { ...cond, rightField: `K_${value}`, targetValue: value, thresholdOverride: true };
}
let failed = 0;
const cases = [
{ type: 'CONDITION', condition: { indicatorType: 'RSI', rightField: 'K_50', thresholdOverride: true, targetValue: 50 } },
{ condition: { indicatorType: 'RSI', rightField: 'K_50', thresholdOverride: true, targetValue: 50 } },
@@ -78,5 +79,16 @@ for (const c of cases) {
const r = normalizeNode(c);
const cond = r.condition ?? r.children?.[0]?.condition;
const ok = cond?.rightField === 'HL_MID' && cond?.thresholdOverride === false;
if (!ok) failed++;
console.log(ok ? 'PASS' : 'FAIL', JSON.stringify(c).slice(0, 60), '=>', cond?.rightField, cond?.thresholdOverride);
}
const direct = setConditionThreshold(
{ indicatorType: 'RSI', rightField: 'HL_OVER', thresholdOverride: false },
50,
);
const directOk = direct.rightField === 'HL_MID' && direct.thresholdOverride === false;
if (!directOk) failed++;
console.log(directOk ? 'PASS' : 'FAIL', 'setConditionThreshold(50) with chart mid≠50 =>', direct.rightField);
process.exit(failed > 0 ? 1 : 0);