백테스팅 목록 아이템 삭제 기능추가
This commit is contained in:
@@ -29,8 +29,19 @@ interface Props {
|
||||
selectedLiveId: string | null;
|
||||
onSelectBacktest: (r: BacktestResultRecord) => void;
|
||||
onSelectLive: (item: LiveExecutionItem) => void;
|
||||
onDeleteBacktest?: (r: BacktestResultRecord) => void;
|
||||
onDeleteLive?: (item: LiveExecutionItem) => void;
|
||||
}
|
||||
|
||||
const IcTrash = () => (
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
function parseBacktestSpark(r: BacktestResultRecord) {
|
||||
try {
|
||||
const signals = r.signalsJson ? JSON.parse(r.signalsJson) : [];
|
||||
@@ -55,6 +66,8 @@ export default function BacktestExecutionList({
|
||||
selectedLiveId,
|
||||
onSelectBacktest,
|
||||
onSelectLive,
|
||||
onDeleteBacktest,
|
||||
onDeleteLive,
|
||||
}: Props) {
|
||||
const [sort, setSort] = useState<BacktestListSort>('return');
|
||||
const [query, setQuery] = useState('');
|
||||
@@ -197,20 +210,36 @@ export default function BacktestExecutionList({
|
||||
const ko = getKoreanName(market);
|
||||
const strategy = r.strategyName || '전략 없음';
|
||||
return (
|
||||
<button type="button" className={`btd-history-card${active ? ' btd-history-card--active' : ''}`} onClick={() => onSelectBacktest(r)}>
|
||||
<div className="btd-history-card-row">
|
||||
<div className="btd-history-card-main">
|
||||
<span className="btd-history-ko">{ko}</span>
|
||||
<span className="btd-history-strategy">{strategy} · {formatTimeframeKo(resolveBacktestRecordExecTimeframe(r))}</span>
|
||||
<span className="btd-history-date">{fmtListTimestamp(r.createdAt)}</span>
|
||||
<div className={`btd-history-card${active ? ' btd-history-card--active' : ''}`}>
|
||||
<button type="button" className="btd-history-card-body" onClick={() => onSelectBacktest(r)}>
|
||||
<div className="btd-history-card-row">
|
||||
<div className="btd-history-card-main">
|
||||
<span className="btd-history-ko">{ko}</span>
|
||||
<span className="btd-history-strategy">{strategy} · {formatTimeframeKo(resolveBacktestRecordExecTimeframe(r))}</span>
|
||||
<span className="btd-history-date">{fmtListTimestamp(r.createdAt)}</span>
|
||||
</div>
|
||||
<div className="btd-history-card-side">
|
||||
<BacktestSparkline curve={parseBacktestSpark(r)} positive={positive} width={56} height={22} />
|
||||
<span className="btd-history-win">승률 {pctAbs(r.winRate ?? 0)}</span>
|
||||
<span className={`btd-history-roi${positive ? ' up' : ' down'}`}>총 수익률 {pct(ret)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="btd-history-card-side">
|
||||
<BacktestSparkline curve={parseBacktestSpark(r)} positive={positive} width={56} height={22} />
|
||||
<span className="btd-history-win">승률 {pctAbs(r.winRate ?? 0)}</span>
|
||||
<span className={`btd-history-roi${positive ? ' up' : ' down'}`}>총 수익률 {pct(ret)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</button>
|
||||
{onDeleteBacktest && r.id != null && (
|
||||
<button
|
||||
type="button"
|
||||
className="btd-history-card-delete"
|
||||
title="백테스팅 결과 삭제"
|
||||
aria-label="백테스팅 결과 삭제"
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onDeleteBacktest(r);
|
||||
}}
|
||||
>
|
||||
<IcTrash />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</VirtualScroll>
|
||||
@@ -241,24 +270,40 @@ export default function BacktestExecutionList({
|
||||
const market = toUpbitMarket(item.symbol);
|
||||
const ko = getKoreanName(market);
|
||||
return (
|
||||
<button type="button" className={`btd-history-card${active ? ' btd-history-card--active' : ''}`} onClick={() => onSelectLive(item)}>
|
||||
<div className="btd-history-card-row">
|
||||
<div className="btd-history-card-main">
|
||||
<span className="btd-history-ko">{ko}</span>
|
||||
<span className="btd-history-strategy">
|
||||
{item.strategyLabel}
|
||||
{item.timeframe !== 'unknown' ? ` · ${formatTimeframeKo(item.timeframe)}` : ''}
|
||||
{item.sourceLabel !== '자동' ? ` · ${item.sourceLabel}` : ''}
|
||||
</span>
|
||||
<span className="btd-history-date">{fmtShortTimestamp(item.createdAt)}</span>
|
||||
<div className={`btd-history-card${active ? ' btd-history-card--active' : ''}`}>
|
||||
<button type="button" className="btd-history-card-body" onClick={() => onSelectLive(item)}>
|
||||
<div className="btd-history-card-row">
|
||||
<div className="btd-history-card-main">
|
||||
<span className="btd-history-ko">{ko}</span>
|
||||
<span className="btd-history-strategy">
|
||||
{item.strategyLabel}
|
||||
{item.timeframe !== 'unknown' ? ` · ${formatTimeframeKo(item.timeframe)}` : ''}
|
||||
{item.sourceLabel !== '자동' ? ` · ${item.sourceLabel}` : ''}
|
||||
</span>
|
||||
<span className="btd-history-date">{fmtShortTimestamp(item.createdAt)}</span>
|
||||
</div>
|
||||
<div className="btd-history-card-side">
|
||||
<BacktestSparkline curve={parseLiveSpark(item)} positive={positive} width={56} height={22} />
|
||||
<span className="btd-history-win">라운드 {item.roundTripCount} · 체결 {item.tradeCount}건</span>
|
||||
<span className={`btd-history-roi${positive ? ' up' : ' down'}`}>{pct(item.totalReturnPct)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="btd-history-card-side">
|
||||
<BacktestSparkline curve={parseLiveSpark(item)} positive={positive} width={56} height={22} />
|
||||
<span className="btd-history-win">라운드 {item.roundTripCount} · 체결 {item.tradeCount}건</span>
|
||||
<span className={`btd-history-roi${positive ? ' up' : ' down'}`}>{pct(item.totalReturnPct)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</button>
|
||||
{onDeleteLive && item.trades.some(t => t.id > 0) && (
|
||||
<button
|
||||
type="button"
|
||||
className="btd-history-card-delete"
|
||||
title="실시간 매매 이력 삭제"
|
||||
aria-label="실시간 매매 이력 삭제"
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onDeleteLive(item);
|
||||
}}
|
||||
>
|
||||
<IcTrash />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</VirtualScroll>
|
||||
|
||||
Reference in New Issue
Block a user