백테스팅 종목 선택란을 MarketSearchPanel 한글 검색 드롭다운으로 교체
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
*/
|
||||
import '../styles/backtestDashboard.css';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { MarketSearchPanel } from './MarketSearchPanel';
|
||||
import {
|
||||
loadBacktestResults,
|
||||
deleteBacktestResult,
|
||||
@@ -17,7 +19,6 @@ import {
|
||||
type BacktestSignal,
|
||||
type StrategyDto,
|
||||
} from '../utils/backendApi';
|
||||
import { UPBIT_MARKETS } from '../utils/upbitApi';
|
||||
import { timeframeToCandleType } from '../utils/chartCandleType';
|
||||
import type { Theme, Timeframe } from '../types';
|
||||
import { buildEquityFromSignals } from '../utils/backtestEquity';
|
||||
@@ -101,6 +102,9 @@ export function BacktestHistoryPage({ theme = 'dark' }: Props) {
|
||||
const [runStrategyId, setRunStrategyId] = useState<number | null>(null);
|
||||
const [runLoading, setRunLoading] = useState(false);
|
||||
const [runError, setRunError] = useState<string | null>(null);
|
||||
const [showMarketSearch, setShowMarketSearch] = useState(false);
|
||||
const [marketQuery, setMarketQuery] = useState('');
|
||||
const marketBtnRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const [leftWidth, setLeftWidth] = useState(() => readMinWidth(LEFT_KEY, LEFT_DEFAULT));
|
||||
const [rightWidth, setRightWidth] = useState(() => readMinWidth(RIGHT_KEY, RIGHT_DEFAULT));
|
||||
@@ -372,17 +376,42 @@ export function BacktestHistoryPage({ theme = 'dark' }: Props) {
|
||||
|
||||
{/* 빠른 실행 툴바 */}
|
||||
<div className="btd-header-run">
|
||||
<select
|
||||
className="btd-run-select"
|
||||
value={runMarket}
|
||||
onChange={e => setRunMarket(e.target.value)}
|
||||
<button
|
||||
ref={marketBtnRef}
|
||||
type="button"
|
||||
className="btd-run-market-btn"
|
||||
disabled={runLoading}
|
||||
title="종목"
|
||||
title="종목 검색"
|
||||
onClick={() => {
|
||||
setMarketQuery('');
|
||||
setShowMarketSearch(v => !v);
|
||||
}}
|
||||
>
|
||||
{UPBIT_MARKETS.map(m => (
|
||||
<option key={m} value={m}>{m.replace('KRW-', '')}</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="btd-run-market-ko">{getKoreanName(runMarket)}</span>
|
||||
<span className="btd-run-market-sym">{runMarket.replace('KRW-', '')}</span>
|
||||
<svg className="btd-run-market-caret" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="6 9 12 15 18 9"/>
|
||||
</svg>
|
||||
</button>
|
||||
{showMarketSearch && ReactDOM.createPortal(
|
||||
<MarketSearchPanel
|
||||
currentMarket={runMarket}
|
||||
query={marketQuery}
|
||||
onQueryChange={setMarketQuery}
|
||||
onSelect={market => {
|
||||
setRunMarket(market);
|
||||
setShowMarketSearch(false);
|
||||
setMarketQuery('');
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowMarketSearch(false);
|
||||
setMarketQuery('');
|
||||
}}
|
||||
anchorRect={marketBtnRef.current?.getBoundingClientRect() ?? null}
|
||||
anchorPlacement="dropdown"
|
||||
/>,
|
||||
document.body,
|
||||
)}
|
||||
<select
|
||||
className="btd-run-select"
|
||||
value={runTimeframe}
|
||||
|
||||
Reference in New Issue
Block a user