분석레포트 로직 수정
This commit is contained in:
@@ -6,41 +6,17 @@ import type {
|
||||
} from './backendApi';
|
||||
import type { BacktestAnalysisReportModel } from '../components/backtest/BacktestAnalysisReportModal';
|
||||
import type { LiveExecutionItem } from './liveExecutionGroups';
|
||||
import { buildAnalysisFromPaperTrades } from './paperMetrics';
|
||||
import { fmtListTimestamp, toUpbitMarket } from './backtestUiUtils';
|
||||
import { getKoreanName } from './marketNameCache';
|
||||
import { repairUtf8Mojibake } from './textEncoding';
|
||||
|
||||
/** 실시간 매매 탭 — KPI만 있는 경우 최소 분석 객체 */
|
||||
/** 실시간 매매 탭 — 체결 이력 기반 분석 */
|
||||
export function buildAnalysisFromLive(
|
||||
item: LiveExecutionItem,
|
||||
initialCapital = 10_000_000,
|
||||
): BacktestAnalysis {
|
||||
const finalEquity = initialCapital * (1 + item.totalReturnPct);
|
||||
const winCount = Math.round(item.tradeCount * item.winRatePct);
|
||||
return {
|
||||
initialCapital,
|
||||
finalEquity,
|
||||
totalReturnPct: item.totalReturnPct,
|
||||
totalProfitLoss: finalEquity - initialCapital,
|
||||
grossProfit: 0,
|
||||
grossLoss: 0,
|
||||
avgReturnPct: item.tradeCount > 0 ? item.totalReturnPct / item.tradeCount : 0,
|
||||
profitLossRatio: item.profitFactor,
|
||||
numberOfPositions: item.tradeCount,
|
||||
numberOfWinning: winCount,
|
||||
numberOfLosing: Math.max(0, item.tradeCount - winCount),
|
||||
numberOfBreakEven: 0,
|
||||
winRate: item.winRatePct,
|
||||
maxDrawdownPct: item.mddPct,
|
||||
maxRunupPct: 0,
|
||||
sharpeRatio: item.sharpeRatio,
|
||||
sortinoRatio: 0,
|
||||
calmarRatio: 0,
|
||||
valueAtRisk95: 0,
|
||||
expectedShortfall: 0,
|
||||
buyAndHoldReturnPct: 0,
|
||||
vsBuyAndHold: 0,
|
||||
};
|
||||
return buildAnalysisFromPaperTrades(item.trades, initialCapital);
|
||||
}
|
||||
|
||||
function buildAnalysisFromStats(s: BacktestStats): BacktestAnalysis {
|
||||
@@ -101,14 +77,11 @@ export function buildBacktestReportModel(
|
||||
record: BacktestResultRecord,
|
||||
analysis: BacktestAnalysis,
|
||||
signals: BacktestSignal[],
|
||||
strategyNamesById: Record<number, string> = {},
|
||||
_strategyNamesById: Record<number, string> = {},
|
||||
): BacktestAnalysisReportModel {
|
||||
const market = toUpbitMarket(record.symbol);
|
||||
const freshName = record.strategyId != null
|
||||
? strategyNamesById[record.strategyId]
|
||||
: undefined;
|
||||
const strategyName = repairUtf8Mojibake(
|
||||
freshName || record.strategyName || '전략 없음',
|
||||
record.strategyName || '전략 없음',
|
||||
);
|
||||
return {
|
||||
analysis,
|
||||
@@ -126,10 +99,10 @@ export function buildBacktestReportModel(
|
||||
export function buildLiveReportModel(
|
||||
item: LiveExecutionItem,
|
||||
signals: BacktestSignal[],
|
||||
timeframe: string,
|
||||
initialCapital = 10_000_000,
|
||||
): BacktestAnalysisReportModel {
|
||||
const market = toUpbitMarket(item.symbol);
|
||||
const timeframe = item.timeframe !== 'unknown' ? item.timeframe : '—';
|
||||
return {
|
||||
analysis: buildAnalysisFromLive(item, initialCapital),
|
||||
signals,
|
||||
@@ -137,7 +110,7 @@ export function buildLiveReportModel(
|
||||
symbol: item.symbol,
|
||||
symbolKo: getKoreanName(market),
|
||||
timeframe,
|
||||
barCount: 300,
|
||||
barCount: item.trades.length,
|
||||
createdAt: item.createdAt ? fmtListTimestamp(item.createdAt) : undefined,
|
||||
reportKind: 'live',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user