전략평가 화면 전랸선택드롭다운 추가

This commit is contained in:
Macbook
2026-06-12 14:42:12 +09:00
parent ae9266bd28
commit d80a854d5b
3 changed files with 49 additions and 0 deletions
@@ -183,9 +183,24 @@ export default function StrategyEvaluationPage({ theme = 'dark' }: Props) {
setSelectedStrategy(hydrateStrategyDto(s)); setSelectedStrategy(hydrateStrategyDto(s));
setAppliedIndicatorParams(null); setAppliedIndicatorParams(null);
setParamsRevision(v => v + 1); setParamsRevision(v => v + 1);
setTimeframeChoice(BACKTEST_STRATEGY_TIMEFRAME);
setLeftTab('strategy'); setLeftTab('strategy');
}, []); }, []);
const handleSelectStrategyById = useCallback((id: number) => {
const found = strategies.find(s => s.id === id);
if (found) {
handleSelectStrategy(found);
return;
}
setSelectedStrategyId(id);
setSelectedStrategy(null);
setAppliedIndicatorParams(null);
setParamsRevision(v => v + 1);
setTimeframeChoice(BACKTEST_STRATEGY_TIMEFRAME);
setLeftTab('strategy');
}, [strategies, handleSelectStrategy]);
const handleSaveIndicatorParams = useCallback((params: EvalIndicatorParams) => { const handleSaveIndicatorParams = useCallback((params: EvalIndicatorParams) => {
setAppliedIndicatorParams(params); setAppliedIndicatorParams(params);
setParamsRevision(v => v + 1); setParamsRevision(v => v + 1);
@@ -308,6 +323,9 @@ export default function StrategyEvaluationPage({ theme = 'dark' }: Props) {
timeframe={chartTimeframe} timeframe={chartTimeframe}
timeframeChoice={timeframeChoice} timeframeChoice={timeframeChoice}
tfOptions={tfOptions} tfOptions={tfOptions}
strategies={strategies}
selectedStrategyId={selectedStrategyId}
onStrategySelect={handleSelectStrategyById}
onMarketChange={setMarket} onMarketChange={setMarket}
onTimeframeChoiceChange={setTimeframeChoice} onTimeframeChoiceChange={setTimeframeChoice}
theme={theme} theme={theme}
@@ -19,6 +19,7 @@ import { loadBacktestSettings, runBacktest } from '../../utils/backendApi';
import { buildVirtualTradingChartIndicators } from '../../utils/strategyToChartIndicators'; import { buildVirtualTradingChartIndicators } from '../../utils/strategyToChartIndicators';
import { buildEvalParamsFromStrategy } from '../../utils/strategyEvaluationParams'; import { buildEvalParamsFromStrategy } from '../../utils/strategyEvaluationParams';
import { resolveEvaluationFromLoadedBars } from '../../utils/backtestWarmup'; import { resolveEvaluationFromLoadedBars } from '../../utils/backtestWarmup';
import { repairUtf8Mojibake } from '../../utils/textEncoding';
import StrategyEvaluationBarSelector from './StrategyEvaluationBarSelector'; import StrategyEvaluationBarSelector from './StrategyEvaluationBarSelector';
import { import {
parseBacktestRunTimeframeChoice, parseBacktestRunTimeframeChoice,
@@ -30,6 +31,9 @@ interface Props {
timeframe: Timeframe; timeframe: Timeframe;
timeframeChoice: BacktestRunTimeframeChoice; timeframeChoice: BacktestRunTimeframeChoice;
tfOptions: { value: string; label: string }[]; tfOptions: { value: string; label: string }[];
strategies: StrategyDto[];
selectedStrategyId: number | null;
onStrategySelect: (strategyId: number) => void;
onMarketChange: (market: string) => void; onMarketChange: (market: string) => void;
onTimeframeChoiceChange: (choice: BacktestRunTimeframeChoice) => void; onTimeframeChoiceChange: (choice: BacktestRunTimeframeChoice) => void;
theme?: Theme; theme?: Theme;
@@ -67,6 +71,9 @@ const StrategyEvaluationChart: React.FC<Props> = ({
timeframe, timeframe,
timeframeChoice, timeframeChoice,
tfOptions, tfOptions,
strategies,
selectedStrategyId,
onStrategySelect,
onMarketChange, onMarketChange,
onTimeframeChoiceChange, onTimeframeChoiceChange,
theme = 'dark', theme = 'dark',
@@ -326,6 +333,23 @@ const StrategyEvaluationChart: React.FC<Props> = ({
<option key={o.value} value={o.value}>{o.label}</option> <option key={o.value} value={o.value}>{o.label}</option>
))} ))}
</select> </select>
<select
className="btd-run-select btd-run-select--strategy seval-chart-strategy-select"
value={selectedStrategyId ?? ''}
onChange={e => {
const raw = e.target.value;
if (!raw) return;
onStrategySelect(Number(raw));
}}
title="전략"
>
<option value=""> </option>
{strategies.map(s => (
<option key={s.id} value={s.id ?? ''}>
{repairUtf8Mojibake(s.name ?? `전략 #${s.id}`)}
</option>
))}
</select>
{selectedBar && ( {selectedBar && (
<span className="seval-chart-bar-time"> <span className="seval-chart-bar-time">
{new Date(selectedBar.time * 1000).toLocaleString('ko-KR')} {new Date(selectedBar.time * 1000).toLocaleString('ko-KR')}
@@ -45,6 +45,13 @@
gap: 6px; gap: 6px;
flex-wrap: wrap; flex-wrap: wrap;
min-width: 0; min-width: 0;
flex: 1;
}
.seval-chart-strategy-select {
flex: 1 1 140px;
max-width: 220px;
min-width: 120px;
} }
.seval-chart-bar-time { .seval-chart-bar-time {