messy work. backtests / mock-data
This commit is contained in:
parent
4e4a048988
commit
fa70ada2bb
51 changed files with 2576 additions and 887 deletions
|
|
@ -1,4 +1,6 @@
|
|||
import { logger } from '@stock-bot/logger';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
|
||||
const logger = getLogger('DataManager');
|
||||
import { StorageService } from '../services/StorageService';
|
||||
import { MarketData, Bar } from '../types';
|
||||
import { EventEmitter } from 'events';
|
||||
|
|
@ -62,13 +64,19 @@ export class DataManager extends EventEmitter {
|
|||
for (const symbol of symbols) {
|
||||
try {
|
||||
// Load raw data
|
||||
const data = await this.storageService.getHistoricalBars(
|
||||
let data = await this.storageService.getHistoricalBars(
|
||||
symbol,
|
||||
startDate,
|
||||
endDate,
|
||||
resolution
|
||||
);
|
||||
|
||||
// If no data found, generate mock data
|
||||
if (!data || data.length === 0) {
|
||||
logger.warn(`No historical data found for ${symbol}, generating mock data`);
|
||||
data = this.generateMockBars(symbol, startDate, endDate, resolution);
|
||||
}
|
||||
|
||||
// Apply corporate actions
|
||||
const adjustedData = await this.applyCorporateActions(symbol, data, startDate, endDate);
|
||||
|
||||
|
|
@ -432,4 +440,62 @@ export class DataManager extends EventEmitter {
|
|||
this.aggregatedCache.clear();
|
||||
this.dataQualityIssues = [];
|
||||
}
|
||||
|
||||
private generateMockBars(
|
||||
symbol: string,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
resolution: string
|
||||
): any[] {
|
||||
const bars: any[] = [];
|
||||
const resolutionMs = DataManager.RESOLUTIONS[resolution]?.milliseconds || 86400000; // Default to 1 day
|
||||
|
||||
let currentTime = startDate.getTime();
|
||||
const endTime = endDate.getTime();
|
||||
|
||||
// Base price varies by symbol
|
||||
let basePrice = 100;
|
||||
if (symbol === 'AAPL') basePrice = 150;
|
||||
else if (symbol === 'GOOGL') basePrice = 140;
|
||||
else if (symbol === 'MSFT') basePrice = 380;
|
||||
else if (symbol === 'TSLA') basePrice = 250;
|
||||
|
||||
let price = basePrice;
|
||||
|
||||
while (currentTime <= endTime) {
|
||||
// Generate realistic intraday movement
|
||||
const volatility = 0.02; // 2% daily volatility
|
||||
const trend = 0.0001; // Slight upward trend
|
||||
|
||||
// Random walk with trend
|
||||
const changePercent = (Math.random() - 0.5) * volatility + trend;
|
||||
price = price * (1 + changePercent);
|
||||
|
||||
// Generate OHLC
|
||||
const open = price;
|
||||
const intraDayVolatility = volatility / 4;
|
||||
const high = price * (1 + Math.random() * intraDayVolatility);
|
||||
const low = price * (1 - Math.random() * intraDayVolatility);
|
||||
const close = low + Math.random() * (high - low);
|
||||
|
||||
// Volume with some randomness
|
||||
const baseVolume = 10000000; // 10M shares
|
||||
const volume = baseVolume * (0.5 + Math.random());
|
||||
|
||||
bars.push({
|
||||
timestamp: new Date(currentTime),
|
||||
open: Number(open.toFixed(2)),
|
||||
high: Number(high.toFixed(2)),
|
||||
low: Number(low.toFixed(2)),
|
||||
close: Number(close.toFixed(2)),
|
||||
volume: Math.floor(volume),
|
||||
vwap: Number(((high + low + close) / 3).toFixed(2))
|
||||
});
|
||||
|
||||
currentTime += resolutionMs;
|
||||
price = close; // Next bar opens at previous close
|
||||
}
|
||||
|
||||
return bars;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue