전략편집기 수정, 보조지표 설정 수정

This commit is contained in:
Macbook
2026-05-27 23:59:30 +09:00
parent 8cc0d1c88c
commit 2713b2951d
17 changed files with 210 additions and 46 deletions
@@ -1,6 +1,6 @@
import React, { useEffect, useRef } from 'react';
import type { ConditionDSL } from '../../utils/strategyTypes';
import type { DefType } from '../../utils/strategyEditorShared';
import { getDefaultConditionFields, type DefType } from '../../utils/strategyEditorShared';
import {
getCompositeLeftCandleType,
getCompositeRightCandleType,
@@ -27,13 +27,19 @@ import ComboNumberInput from './ComboNumberInput';
interface Props {
condition: ConditionDSL;
def: DefType;
signalType?: 'buy' | 'sell';
onChange: (c: ConditionDSL) => void;
onClose: () => void;
popoverClassName?: string;
}
export default function ConditionNodeSettings({
condition, def, onChange, onClose, popoverClassName = 'se-flow-settings-pop',
condition,
def,
signalType = 'buy',
onChange,
onClose,
popoverClassName = 'se-flow-settings-pop',
}: Props) {
const ref = useRef<HTMLDivElement>(null);
@@ -45,7 +51,8 @@ export default function ConditionNodeSettings({
return () => document.removeEventListener('mousedown', onDoc);
}, [onClose]);
const rightThreshold = getConditionThreshold(condition, 'right');
const inheritedThreshold = getDefaultConditionFields(condition.indicatorType, signalType, def).r;
const rightThreshold = getConditionThreshold(condition, 'right', inheritedThreshold);
const showThreshold = hasEditableThreshold(condition) && rightThreshold != null;
const periodPresets = getPeriodPresetOptions(condition.indicatorType, def);
const thresholdPresets = getThresholdPresetOptions(condition.indicatorType);
@@ -283,6 +283,7 @@ export const ConditionFlowNode = memo(function ConditionFlowNode({ id, data, sel
<ConditionNodeSettings
condition={cond}
def={d.def}
signalType={d.signalTab ?? 'buy'}
onChange={handleSettingsChange}
onClose={() => setSettingsOpen(false)}
/>
@@ -105,6 +105,8 @@ interface Props {
extraStartIds?: string[];
extraRoots?: Record<string, LogicNode | null>;
onStartMetaChange?: (meta: Record<string, StartNodeMeta>) => void;
/** START 체크박스 — startMeta + 조건 트리 분봉 동기화 */
onStartCandleTypesChange?: (startId: string, candleTypes: string[]) => void;
onExtraStartIdsChange?: (ids: string[]) => void;
onExtraRootsChange?: (roots: Record<string, LogicNode | null>) => void;
}
@@ -268,6 +270,7 @@ function StrategyEditorCanvasInner({
extraStartIds = [],
extraRoots = {},
onStartMetaChange,
onStartCandleTypesChange,
onExtraStartIdsChange,
onExtraRootsChange,
}: Props) {
@@ -372,13 +375,17 @@ function StrategyEditorCanvasInner({
}, [emitLayoutChange]);
const handleStartCandleTypesChange = useCallback((startId: string, candleTypes: string[]) => {
if (onStartCandleTypesChange) {
onStartCandleTypesChange(startId, candleTypes);
return;
}
const types = candleTypes.length > 0 ? candleTypes : [DEFAULT_START_CANDLE];
const normalized = types.map(normalizeStartCandleType);
onStartMetaChange?.({
...startMeta,
[startId]: { candleTypes: normalized, candleType: normalized[0] },
});
}, [startMeta, onStartMetaChange]);
}, [startMeta, onStartMetaChange, onStartCandleTypesChange]);
const handleDeleteStart = useCallback((startId: string) => {
if (startId === START_NODE_ID) return;
@@ -149,6 +149,7 @@ const TreeNodeComp: React.FC<TreeNodeProps> = ({
<ConditionNodeSettings
condition={node.condition}
def={def}
signalType={signalType}
onChange={handleCondChange}
onClose={() => setSettingsOpen(false)}
popoverClassName="sp-node-settings-pop"