전략알림 수정

This commit is contained in:
Macbook
2026-05-27 16:51:57 +09:00
parent d7ceb8cbfd
commit aca895e9fd
13 changed files with 701 additions and 123 deletions
+71 -5
View File
@@ -1,4 +1,4 @@
import type { LogicNode } from './strategyTypes';
import type { LogicNode, ConditionDSL } from './strategyTypes';
import { generateNodeId } from './strategyTypes';
import { subtreeToFlatOrphans } from './strategyFlowLayout';
import {
@@ -82,16 +82,79 @@ export function updateBranchRoot(
};
}
/** START 분봉 변경 시 조건 노드의 left/rightCandleType 동기화 */
function syncSubtreeCandleTypes(node: LogicNode | null, candleType: string): LogicNode | null {
if (!node) return null;
const ct = normalizeStartCandleType(candleType);
if (node.type === 'CONDITION' && node.condition) {
const cond = node.condition as ConditionDSL;
return {
...node,
condition: {
...cond,
leftCandleType: ct,
rightCandleType: ct,
},
};
}
if (node.children?.length) {
return {
...node,
children: node.children.map(c => syncSubtreeCandleTypes(c, ct)).filter(Boolean) as LogicNode[],
};
}
return node;
}
function collectExplicitCandleTypesFromTree(node: LogicNode | null, out: Set<string>): void {
if (!node) return;
if (node.type === 'TIMEFRAME' && node.candleType) {
out.add(normalizeStartCandleType(node.candleType));
}
if (node.type === 'CONDITION' && node.condition) {
const c = node.condition as ConditionDSL;
if (c.leftCandleType) out.add(normalizeStartCandleType(c.leftCandleType));
if (c.rightCandleType) out.add(normalizeStartCandleType(c.rightCandleType));
}
node.children?.forEach(ch => collectExplicitCandleTypesFromTree(ch, out));
}
function inferPrimaryCandleFromTree(root: LogicNode | null): string {
const set = new Set<string>();
collectExplicitCandleTypesFromTree(root, set);
const non1m = [...set].filter(ct => ct !== '1m');
if (non1m.length >= 1) return non1m[0];
if (set.size >= 1) return [...set][0];
return DEFAULT_START_CANDLE;
}
export function updateStartCandleType(
state: EditorConditionState,
startId: string,
candleType: string,
): EditorConditionState {
const ct = normalizeStartCandleType(candleType);
const nextMeta = {
...state.startMeta,
[startId]: { candleType: ct },
};
if (startId === START_NODE_ID) {
return {
...state,
startMeta: nextMeta,
root: syncSubtreeCandleTypes(state.root, ct),
};
}
return {
...state,
startMeta: {
...state.startMeta,
[startId]: { candleType: normalizeStartCandleType(candleType) },
startMeta: nextMeta,
extraRoots: {
...state.extraRoots,
[startId]: syncSubtreeCandleTypes(state.extraRoots[startId] ?? null, ct),
},
};
}
@@ -225,9 +288,12 @@ export function decodeConditionForEditor(dsl: LogicNode | null): EditorCondition
};
}
const inferred = inferPrimaryCandleFromTree(dsl);
return {
root: dsl,
startMeta: defaultStartMeta(),
startMeta: {
[START_NODE_ID]: { candleType: inferred },
},
extraStartIds: [],
extraRoots: {},
startCombineOp: DEFAULT_START_COMBINE_OP,