diff --git a/frontend/src/utils/strategyEditorShared.tsx b/frontend/src/utils/strategyEditorShared.tsx index 54c2905..5b010e7 100644 --- a/frontend/src/utils/strategyEditorShared.tsx +++ b/frontend/src/utils/strategyEditorShared.tsx @@ -105,7 +105,7 @@ import { isThresholdSymbol, resolveInheritedThresholdField, } from '../utils/thresholdSymbols'; -import { STRATEGY_CANDLE_TYPE_OPTIONS } from '../utils/strategyStartNodes'; +import { STRATEGY_CANDLE_TYPE_OPTIONS, formatStrategyCandleLabel } from '../utils/strategyStartNodes'; import type { StrategyFlowLayoutStore } from './strategyEditorLayoutStorage'; import { genId } from './strategyNodeIds'; @@ -982,24 +982,48 @@ export const nodeToText = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string const c = node.children?.[0]; return c ? `NOT (${nodeToText(c, DEF)})` : '(NOT 그룹)'; } + if (node.type === 'TIMEFRAME') { + const inner = node.children?.[0]; + const types = node.candleTypes?.length + ? node.candleTypes + : [node.candleType ?? '1m']; + const tfLabel = types.map(formatStrategyCandleLabel).join(' · '); + if (!inner) return `[${tfLabel}] (빈 조건)`; + const innerText = nodeToText(inner, DEF); + return `[${tfLabel}] ${innerText}`; + } return ''; }; +function formulaParts(nodes: LogicNode[], DEF: DefType): string[] { + return nodes.map(c => nodeToFormula(c, DEF)).filter(p => p.length > 0); +} + export const nodeToFormula = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string => { if (!node) return ''; if (node.type === 'CONDITION') return `(${nodeToText(node, DEF)})`; if (node.type === 'AND') { - const parts = (node.children ?? []).map(c => nodeToFormula(c, DEF)); + const parts = formulaParts(node.children ?? [], DEF); return parts.length === 0 ? '(빈 AND)' : `(${parts.join(' AND ')})`; } if (node.type === 'OR') { - const parts = (node.children ?? []).map(c => nodeToFormula(c, DEF)); + const parts = formulaParts(node.children ?? [], DEF); return parts.length === 0 ? '(빈 OR)' : `(${parts.join(' OR ')})`; } if (node.type === 'NOT') { const c = node.children?.[0]; return c ? `NOT ${nodeToFormula(c, DEF)}` : '(빈 NOT)'; } + if (node.type === 'TIMEFRAME') { + const inner = node.children?.[0]; + const types = node.candleTypes?.length + ? node.candleTypes + : [node.candleType ?? '1m']; + const tfLabel = types.map(formatStrategyCandleLabel).join('·'); + if (!inner) return `[${tfLabel}]`; + const innerFormula = nodeToFormula(inner, DEF); + return innerFormula ? `[${tfLabel}] ${innerFormula}` : `[${tfLabel}]`; + } return ''; };