전략평가 화면 전랸선택드롭다운 추가
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user