평가로직 오류 수정
This commit is contained in:
@@ -21,14 +21,28 @@ import {
|
||||
} from './thresholdSymbols';
|
||||
import { repairPriceExtremePairForest } from './priceExtremeBreakoutPair';
|
||||
|
||||
function coerceTargetValue(raw: unknown): number | null {
|
||||
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 isConditionCarrier(node: LogicNode): node is LogicNode & { condition: ConditionDSL } {
|
||||
return !!node.condition && (node.type === 'CONDITION' || node.type == null || node.type === undefined);
|
||||
}
|
||||
|
||||
function migrateConditionThreshold(
|
||||
cond: ConditionDSL,
|
||||
def: DefType,
|
||||
signalType: 'buy' | 'sell',
|
||||
): ConditionDSL {
|
||||
if (isThresholdOverridden(cond)) {
|
||||
const val = cond.targetValue ?? parseThresholdField(cond.rightField);
|
||||
if (val != null && Number.isFinite(val)) {
|
||||
const val = coerceTargetValue(cond.targetValue) ?? parseThresholdField(cond.rightField);
|
||||
if (val != null) {
|
||||
const role = inferThresholdRoleForValue(val, cond.indicatorType, def.hlThresh);
|
||||
if (role != null) {
|
||||
const { targetValue: _t, ...rest } = cond;
|
||||
@@ -92,12 +106,20 @@ function migrateLogicNode(
|
||||
signalType: 'buy' | 'sell',
|
||||
): LogicNode {
|
||||
let next = node;
|
||||
if (node.type === 'CONDITION' && node.condition) {
|
||||
next = { ...node, condition: migrateConditionForEditor(node.condition, def, signalType) };
|
||||
if (isConditionCarrier(node)) {
|
||||
next = {
|
||||
...node,
|
||||
type: node.type ?? 'CONDITION',
|
||||
condition: migrateConditionForEditor(node.condition, def, signalType),
|
||||
};
|
||||
}
|
||||
if (next.children?.length) {
|
||||
next = { ...next, children: next.children.map(c => migrateLogicNode(c, def, signalType)) };
|
||||
}
|
||||
const legacyChild = (next as LogicNode & { child?: LogicNode }).child;
|
||||
if (legacyChild) {
|
||||
next = { ...next, child: migrateLogicNode(legacyChild, def, signalType) } as LogicNode;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -115,13 +137,17 @@ export function migrateLogicRootForEditor(
|
||||
return repairPriceExtremePairForest(migrated.root, migrated.orphans);
|
||||
}
|
||||
|
||||
/** 저장 직전 — 상속 모드는 숫자 스냅샷·targetValue 제거; 직접입력도 hline 역할과 일치하면 HL_* 로 통일 */
|
||||
/** 저장·표시·평가 공통 — K_50 등을 HL_MID 로 접기 */
|
||||
export function normalizeConditionForPersistence(cond: ConditionDSL): ConditionDSL {
|
||||
let next: ConditionDSL = { ...cond };
|
||||
let next: ConditionDSL = {
|
||||
...cond,
|
||||
indicatorType: cond.indicatorType?.toUpperCase?.() ?? cond.indicatorType,
|
||||
};
|
||||
const targetNum = coerceTargetValue(next.targetValue);
|
||||
|
||||
if (isThresholdOverridden(next)) {
|
||||
if (next.targetValue != null && Number.isFinite(next.targetValue)) {
|
||||
const role = inferThresholdRoleForValue(next.targetValue, next.indicatorType, {});
|
||||
if (targetNum != null) {
|
||||
const role = inferThresholdRoleForValue(targetNum, next.indicatorType, {});
|
||||
if (role != null) {
|
||||
const { targetValue: _t, ...rest } = next;
|
||||
next = { ...rest, rightField: role, thresholdOverride: false };
|
||||
@@ -168,13 +194,21 @@ export function normalizeConditionForPersistence(cond: ConditionDSL): ConditionD
|
||||
}
|
||||
|
||||
function normalizeLogicNode(node: LogicNode): LogicNode {
|
||||
let next = node;
|
||||
if (node.type === 'CONDITION' && node.condition) {
|
||||
next = { ...node, condition: normalizeConditionForPersistence(node.condition) };
|
||||
let next: LogicNode = node;
|
||||
if (isConditionCarrier(node)) {
|
||||
next = {
|
||||
...node,
|
||||
type: node.type ?? 'CONDITION',
|
||||
condition: normalizeConditionForPersistence(node.condition),
|
||||
};
|
||||
}
|
||||
if (next.children?.length) {
|
||||
next = { ...next, children: next.children.map(normalizeLogicNode) };
|
||||
}
|
||||
const legacyChild = (next as LogicNode & { child?: LogicNode }).child;
|
||||
if (legacyChild) {
|
||||
next = { ...next, child: normalizeLogicNode(legacyChild) } as LogicNode;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user