전략편집기 저장오휴 수정
This commit is contained in:
@@ -83,4 +83,21 @@ function migrateK(cond) {
|
|||||||
const migrated = migrateK({ indicatorType: 'RSI', rightField: 'K_55', thresholdOverride: false });
|
const migrated = migrateK({ indicatorType: 'RSI', rightField: 'K_55', thresholdOverride: false });
|
||||||
assertOk('migrate K_55 stays K_55', migrated.rightField === 'K_55' && migrated.targetValue === 55);
|
assertOk('migrate K_55 stays K_55', migrated.rightField === 'K_55' && migrated.targetValue === 55);
|
||||||
|
|
||||||
|
// 비-임계값 rightField (RSI 신호선 등) — 로드 시 기본 과열선으로 되돌리지 않음
|
||||||
|
function migrateRightField(cond, signalType = 'buy') {
|
||||||
|
if (cond.thresholdOverride === true) return cond;
|
||||||
|
let rightField = cond.rightField;
|
||||||
|
if (rightField?.startsWith('K_')) return cond;
|
||||||
|
const THRESHOLD = new Set(['HL_OVER', 'HL_MID', 'HL_UNDER']);
|
||||||
|
const RSI_RIGHT_OPTS = ['RSI_SIGNAL', 'NONE', 'HL_OVER', 'HL_MID', 'HL_UNDER'];
|
||||||
|
if (!rightField) {
|
||||||
|
rightField = 'HL_OVER';
|
||||||
|
} else if (!THRESHOLD.has(rightField) && !rightField.startsWith('K_')) {
|
||||||
|
if (!RSI_RIGHT_OPTS.includes(rightField)) rightField = 'HL_OVER';
|
||||||
|
}
|
||||||
|
return { ...cond, rightField, thresholdOverride: false };
|
||||||
|
}
|
||||||
|
const rsiSignal = migrateRightField({ indicatorType: 'RSI', rightField: 'RSI_SIGNAL', conditionType: 'CROSS_UP' });
|
||||||
|
assertOk('RSI_SIGNAL preserved on load', rsiSignal.rightField === 'RSI_SIGNAL');
|
||||||
|
|
||||||
process.exit(failed > 0 ? 1 : 0);
|
process.exit(failed > 0 ? 1 : 0);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** 전략 조건 DSL — 보조지표 DB 설정과 임계값·기간 상inherit 정규화 */
|
/** 전략 조건 DSL — 보조지표 DB 설정과 임계값·기간 상inherit 정규화 */
|
||||||
import type { ConditionDSL, LogicNode } from './strategyTypes';
|
import type { ConditionDSL, LogicNode } from './strategyTypes';
|
||||||
import type { DefType } from './strategyEditorShared';
|
import type { DefType } from './strategyEditorShared';
|
||||||
import { getDefaultConditionFields } from './strategyEditorShared';
|
import { getDefaultConditionFields, getRightFieldOpts } from './strategyEditorShared';
|
||||||
import {
|
import {
|
||||||
ensureDirectThresholdSnapshot,
|
ensureDirectThresholdSnapshot,
|
||||||
isThresholdOverridden,
|
isThresholdOverridden,
|
||||||
@@ -10,9 +10,7 @@ import {
|
|||||||
VALUE_FIELD_PREFIX,
|
VALUE_FIELD_PREFIX,
|
||||||
} from './conditionPeriods';
|
} from './conditionPeriods';
|
||||||
import {
|
import {
|
||||||
defaultInheritedThresholdField,
|
|
||||||
inferThresholdSymbolFromLegacyExact,
|
inferThresholdSymbolFromLegacyExact,
|
||||||
isThresholdFieldOrSymbol,
|
|
||||||
isThresholdSymbol,
|
isThresholdSymbol,
|
||||||
} from './thresholdSymbols';
|
} from './thresholdSymbols';
|
||||||
import { parseThresholdField, setDirectThreshold } from './conditionPeriods';
|
import { parseThresholdField, setDirectThreshold } from './conditionPeriods';
|
||||||
@@ -45,10 +43,13 @@ function migrateConditionThreshold(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rightField || (!isThresholdSymbol(rightField) && !rightField.startsWith('K_'))) {
|
if (!rightField) {
|
||||||
const defaults = getDefaultConditionFields(cond.indicatorType, signalType, def);
|
rightField = getDefaultConditionFields(cond.indicatorType, signalType, def).r;
|
||||||
if (isThresholdFieldOrSymbol(defaults.r)) {
|
} else if (!isThresholdSymbol(rightField) && !rightField.startsWith('K_')) {
|
||||||
rightField = defaults.r;
|
const rightOpts = getRightFieldOpts(cond.indicatorType, signalType, def, cond);
|
||||||
|
const isValidRight = rightOpts.some(o => o.value === rightField);
|
||||||
|
if (!isValidRight) {
|
||||||
|
rightField = getDefaultConditionFields(cond.indicatorType, signalType, def).r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user