백테스팅 적용

This commit is contained in:
Macbook
2026-05-25 20:23:54 +09:00
parent 02d14e4b2b
commit cae1c3a624
33 changed files with 3399 additions and 385 deletions
+53
View File
@@ -0,0 +1,53 @@
import type { OHLCVBar, Timeframe } from '../types';
import { API_BASE } from './backendApi';
import { timeframeToCandleType } from './chartCandleType';
import { fetchUpbitCandlesBeforeCached } from './requestCache';
import { normalizeEpochSec } from './backtestUiUtils';
/** 백엔드·업비트 history API용 ISO (Z 접미사 없음 — 서버에서 추가) */
export function toHistoryApiIso(epochSec: number): string {
return new Date(epochSec * 1000).toISOString().replace(/\.\d{3}Z$/, '');
}
/** 백테스팅·실매매 분석용 과거 캔들 로드 */
export async function loadAnalysisCandles(
market: string,
timeframe: Timeframe,
toTimeSec: number,
count: number,
): Promise<OHLCVBar[]> {
const type = timeframeToCandleType(timeframe);
const toSec = normalizeEpochSec(toTimeSec);
const to = toHistoryApiIso(toSec);
const safeCount = Math.max(50, Math.min(count, 500));
const params = new URLSearchParams({
market,
type,
to,
count: String(safeCount),
});
let data: OHLCVBar[] = [];
try {
const res = await fetch(`${API_BASE}/candles/history?${params.toString()}`);
if (res.ok) {
const raw: Array<Record<string, number>> = await res.json();
data = raw.map(d => ({
time: d.time,
open: d.open,
high: d.high,
low: d.low,
close: d.close,
volume: d.volume,
}));
}
} catch { /* backend fallback below */ }
if (data.length === 0) {
try {
data = await fetchUpbitCandlesBeforeCached(market, timeframe, safeCount, to);
} catch { /* ignore */ }
}
return data.sort((a, b) => a.time - b.time);
}