initial charts / backtest

This commit is contained in:
Boki 2025-07-02 19:58:43 -04:00
parent 11c24b2280
commit 1b9010ebf4
37 changed files with 3888 additions and 23 deletions

View file

@ -0,0 +1,173 @@
import type { BacktestConfig, BacktestResult, BacktestStatus } from '../types';
const API_BASE = '/api/backtest';
export class BacktestService {
static async createBacktest(config: BacktestConfig): Promise<{ id: string }> {
const response = await fetch(`${API_BASE}/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...config,
startDate: config.startDate.toISOString(),
endDate: config.endDate.toISOString(),
}),
});
if (!response.ok) {
throw new Error('Failed to create backtest');
}
return response.json();
}
static async startBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}/start`, {
method: 'POST',
});
if (!response.ok) {
throw new Error('Failed to start backtest');
}
}
static async pauseBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}/pause`, {
method: 'POST',
});
if (!response.ok) {
throw new Error('Failed to pause backtest');
}
}
static async resumeBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}/resume`, {
method: 'POST',
});
if (!response.ok) {
throw new Error('Failed to resume backtest');
}
}
static async stopBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}/stop`, {
method: 'POST',
});
if (!response.ok) {
throw new Error('Failed to stop backtest');
}
}
static async stepBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}/step`, {
method: 'POST',
});
if (!response.ok) {
throw new Error('Failed to step backtest');
}
}
static async getBacktestStatus(id: string): Promise<{
status: BacktestStatus;
currentTime?: number;
progress?: number;
}> {
const response = await fetch(`${API_BASE}/${id}/status`);
if (!response.ok) {
throw new Error('Failed to get backtest status');
}
return response.json();
}
static async getBacktestResults(id: string): Promise<BacktestResult> {
const response = await fetch(`${API_BASE}/${id}/results`);
if (!response.ok) {
throw new Error('Failed to get backtest results');
}
const data = await response.json();
// Convert date strings back to Date objects
return {
...data,
config: {
...data.config,
startDate: new Date(data.config.startDate),
endDate: new Date(data.config.endDate),
},
};
}
static async listBacktests(): Promise<BacktestResult[]> {
const response = await fetch(`${API_BASE}/list`);
if (!response.ok) {
throw new Error('Failed to list backtests');
}
const data = await response.json();
// Convert date strings back to Date objects
return data.map((backtest: any) => ({
...backtest,
config: {
...backtest.config,
startDate: new Date(backtest.config.startDate),
endDate: new Date(backtest.config.endDate),
},
}));
}
static async deleteBacktest(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}`, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error('Failed to delete backtest');
}
}
// Helper method to poll for updates
static async pollBacktestUpdates(
id: string,
onUpdate: (status: BacktestStatus, progress?: number, currentTime?: number) => void,
interval: number = 1000
): Promise<() => void> {
let isPolling = true;
const poll = async () => {
while (isPolling) {
try {
const { status, progress, currentTime } = await this.getBacktestStatus(id);
onUpdate(status, progress, currentTime);
if (status === 'completed' || status === 'error' || status === 'stopped') {
isPolling = false;
break;
}
} catch (error) {
console.error('Polling error:', error);
}
await new Promise(resolve => setTimeout(resolve, interval));
}
};
poll();
// Return cleanup function
return () => {
isPolling = false;
};
}
}