messy work. backtests / mock-data
This commit is contained in:
parent
4e4a048988
commit
fa70ada2bb
51 changed files with 2576 additions and 887 deletions
|
|
@ -0,0 +1,121 @@
|
|||
import {
|
||||
BaseHandler,
|
||||
Handler,
|
||||
Operation,
|
||||
} from '@stock-bot/handlers';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
import type { OrchestratorServices } from '../../types';
|
||||
|
||||
const logger = getLogger('backtest-handler');
|
||||
|
||||
interface BacktestPayload {
|
||||
backtestId: string;
|
||||
strategy: string;
|
||||
symbols: string[];
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
initialCapital: number;
|
||||
config?: Record<string, any>;
|
||||
}
|
||||
|
||||
interface CancelBacktestPayload {
|
||||
backtestId: string;
|
||||
}
|
||||
|
||||
@Handler('orchestrator')
|
||||
export class BacktestHandler extends BaseHandler<OrchestratorServices> {
|
||||
|
||||
@Operation('run-backtest')
|
||||
async runBacktest(payload: BacktestPayload) {
|
||||
const { backtestId, strategy, symbols, startDate, endDate, initialCapital, config } = payload;
|
||||
|
||||
logger.info('Starting backtest', { backtestId, strategy, symbolCount: symbols.length });
|
||||
|
||||
try {
|
||||
// Update status in web-api (via Redis or direct DB update)
|
||||
await this.updateBacktestStatus(backtestId, 'running');
|
||||
|
||||
// TODO: Call Rust core via NAPI bindings
|
||||
// For now, we'll simulate the backtest
|
||||
const results = await this.simulateBacktest({
|
||||
strategy,
|
||||
symbols,
|
||||
startDate,
|
||||
endDate,
|
||||
initialCapital,
|
||||
config,
|
||||
});
|
||||
|
||||
// Store results
|
||||
await this.storeBacktestResults(backtestId, results);
|
||||
|
||||
// Update status to completed
|
||||
await this.updateBacktestStatus(backtestId, 'completed');
|
||||
|
||||
logger.info('Backtest completed', { backtestId });
|
||||
|
||||
return { success: true, backtestId, results };
|
||||
} catch (error) {
|
||||
logger.error('Backtest failed', { backtestId, error });
|
||||
|
||||
await this.updateBacktestStatus(backtestId, 'failed', error.message);
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@Operation('cancel-backtest')
|
||||
async cancelBacktest(payload: CancelBacktestPayload) {
|
||||
const { backtestId } = payload;
|
||||
|
||||
logger.info('Cancelling backtest', { backtestId });
|
||||
|
||||
// TODO: Implement actual cancellation logic
|
||||
// For now, just update the status
|
||||
await this.updateBacktestStatus(backtestId, 'cancelled');
|
||||
|
||||
return { success: true, backtestId };
|
||||
}
|
||||
|
||||
private async updateBacktestStatus(backtestId: string, status: string, error?: string) {
|
||||
// TODO: Update in MongoDB or notify web-api
|
||||
logger.info('Updating backtest status', { backtestId, status, error });
|
||||
}
|
||||
|
||||
private async storeBacktestResults(backtestId: string, results: any) {
|
||||
// TODO: Store in MongoDB
|
||||
logger.info('Storing backtest results', { backtestId });
|
||||
}
|
||||
|
||||
private async simulateBacktest(params: Omit<BacktestPayload, 'backtestId'>) {
|
||||
// Simulate some processing time
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Return mock results
|
||||
return {
|
||||
metrics: {
|
||||
totalReturn: 0.15,
|
||||
sharpeRatio: 1.2,
|
||||
maxDrawdown: -0.08,
|
||||
winRate: 0.55,
|
||||
totalTrades: 150,
|
||||
profitFactor: 1.8,
|
||||
},
|
||||
equity: [
|
||||
{ date: params.startDate, value: params.initialCapital },
|
||||
{ date: params.endDate, value: params.initialCapital * 1.15 },
|
||||
],
|
||||
trades: [
|
||||
{
|
||||
symbol: params.symbols[0],
|
||||
entryDate: params.startDate,
|
||||
exitDate: params.endDate,
|
||||
entryPrice: 100,
|
||||
exitPrice: 115,
|
||||
quantity: 100,
|
||||
pnl: 1500,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue