백테스팅 수정

This commit is contained in:
Macbook
2026-06-12 00:00:06 +09:00
parent eb6cf894da
commit d5338274d4
10 changed files with 151 additions and 72 deletions
+26 -29
View File
@@ -105,22 +105,16 @@ import ReactDOM from 'react-dom';
import { MarketSearchPanel } from './MarketSearchPanel';
import { getKoreanName } from '../utils/marketNameCache';
import type { Timeframe } from '../types';
import {
BACKTEST_STRATEGY_TIMEFRAME,
buildQuickRunTimeframeSelectOptions,
parseBacktestRunTimeframeChoice,
resolveBacktestExecTimeframe,
type BacktestRunTimeframeChoice,
} from '../utils/backtestRunTimeframe';
import '../styles/strategyEditor.css';
import '../styles/strategyEditorTheme.css';
const QUICK_RUN_TIMEFRAMES: { value: Timeframe; label: string }[] = [
{ value: '1m', label: '1분' },
{ value: '3m', label: '3분' },
{ value: '5m', label: '5분' },
{ value: '10m', label: '10분' },
{ value: '15m', label: '15분' },
{ value: '30m', label: '30분' },
{ value: '1h', label: '1시간' },
{ value: '4h', label: '4시간' },
{ value: '1D', label: '일봉' },
{ value: '1W', label: '주봉' },
];
const BACKTEST_FOCUS_KEY = 'backtest_focus_id';
const LEFT_PANEL_MIN = 220;
@@ -222,23 +216,13 @@ export default function StrategyEditorPage({ theme, onNavigateToBacktest }: Prop
// ── 빠른 백테스팅 실행 ────────────────────────────────────────────────────
const [qbMarket, setQbMarket] = useState('KRW-BTC');
const [qbTimeframe, setQbTimeframe] = useState<Timeframe>('1D');
const [qbTimeframe, setQbTimeframe] = useState<BacktestRunTimeframeChoice>(BACKTEST_STRATEGY_TIMEFRAME);
const [qbLoading, setQbLoading] = useState(false);
const [qbError, setQbError] = useState<string | null>(null);
const [qbMarketOpen, setQbMarketOpen] = useState(false);
const [qbMarketQ, setQbMarketQ] = useState('');
const qbMarketBtnRef = useRef<HTMLButtonElement>(null);
// 전략 선택/조건 변경 시 DSL 기준 시간봉으로 빠른 실행 TF 동기화
useEffect(() => {
if (selectedId == null) return;
const tf = resolveStrategyPrimaryTimeframe({
buyCondition: buyCondition,
sellCondition: sellCondition,
} as ApiStrategyDto);
setQbTimeframe(prev => (prev === tf ? prev : tf));
}, [selectedId, buyCondition, sellCondition]);
const [leftWidth, setLeftWidth] = useState(() => readStoredSize('se-left-width', LEFT_PANEL_DEFAULT));
const [terminalHeight, setTerminalHeight] = useState(() => readStoredSize('se-terminal-height', TERMINAL_DEFAULT));
const leftWidthRef = useRef(leftWidth);
@@ -1189,10 +1173,11 @@ export default function StrategyEditorPage({ theme, onNavigateToBacktest }: Prop
setQbError(null);
try {
const selectedStrategy = strategies.find(s => s.id === selectedId);
const execTimeframe = resolveStrategyPrimaryTimeframe({
const strategyTimeframe = resolveStrategyPrimaryTimeframe({
buyCondition: buyCondition,
sellCondition: sellCondition,
} as ApiStrategyDto);
const execTimeframe = resolveBacktestExecTimeframe(qbTimeframe, strategyTimeframe);
const [settings, indicatorParams, barsRes] = await Promise.all([
loadBacktestSettings(),
loadIndicatorSettings(),
@@ -1228,7 +1213,19 @@ export default function StrategyEditorPage({ theme, onNavigateToBacktest }: Prop
} finally {
setQbLoading(false);
}
}, [selectedId, strategies, qbMarket, buyCondition, sellCondition, onNavigateToBacktest]);
}, [selectedId, strategies, qbMarket, qbTimeframe, buyCondition, sellCondition, onNavigateToBacktest]);
const qbStrategyTimeframe = useMemo(
() => resolveStrategyPrimaryTimeframe({
buyCondition: buyCondition,
sellCondition: sellCondition,
} as ApiStrategyDto),
[buyCondition, sellCondition],
);
const qbTimeframeOptions = useMemo(
() => buildQuickRunTimeframeSelectOptions(qbStrategyTimeframe),
[qbStrategyTimeframe],
);
const operators = [
{ type: 'operator' as const, value: 'AND', label: 'AND', color: 'logic-and' },
@@ -1303,11 +1300,11 @@ export default function StrategyEditorPage({ theme, onNavigateToBacktest }: Prop
<select
className="se-qr-select"
value={qbTimeframe}
onChange={e => setQbTimeframe(e.target.value as Timeframe)}
onChange={e => setQbTimeframe(parseBacktestRunTimeframeChoice(e.target.value))}
disabled={qbLoading}
title="타임프레임"
title="백테스팅 실행 시간봉"
>
{QUICK_RUN_TIMEFRAMES.map(tf => (
{qbTimeframeOptions.map(tf => (
<option key={tf.value} value={tf.value}>{tf.label}</option>
))}
</select>