messy work. backtests / mock-data
This commit is contained in:
parent
4e4a048988
commit
fa70ada2bb
51 changed files with 2576 additions and 887 deletions
|
|
@ -1,8 +1,7 @@
|
|||
import { Hono } from 'hono';
|
||||
import { z } from 'zod';
|
||||
import { logger } from '@stock-bot/logger';
|
||||
import { IServiceContainer } from '@stock-bot/di';
|
||||
import { AnalyticsService } from '../../services/AnalyticsService';
|
||||
import { container } from '../../container';
|
||||
|
||||
const DateRangeSchema = z.object({
|
||||
startDate: z.string().datetime(),
|
||||
|
|
@ -20,9 +19,9 @@ const OptimizationRequestSchema = z.object({
|
|||
}).optional()
|
||||
});
|
||||
|
||||
export function createAnalyticsRoutes(): Hono {
|
||||
export function createAnalyticsRoutes(container: IServiceContainer): Hono {
|
||||
const app = new Hono();
|
||||
const analyticsService = container.get('AnalyticsService') as AnalyticsService;
|
||||
const analyticsService = container.custom?.AnalyticsService as AnalyticsService;
|
||||
|
||||
// Get performance metrics
|
||||
app.get('/performance/:portfolioId', async (c) => {
|
||||
|
|
@ -50,7 +49,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error getting performance metrics:', error);
|
||||
container.logger.error('Error getting performance metrics:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get performance metrics'
|
||||
}, 500);
|
||||
|
|
@ -77,7 +76,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error optimizing portfolio:', error);
|
||||
container.logger.error('Error optimizing portfolio:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to optimize portfolio'
|
||||
}, 500);
|
||||
|
|
@ -92,7 +91,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
|
||||
return c.json(metrics);
|
||||
} catch (error) {
|
||||
logger.error('Error getting risk metrics:', error);
|
||||
container.logger.error('Error getting risk metrics:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get risk metrics'
|
||||
}, 500);
|
||||
|
|
@ -109,7 +108,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error detecting market regime:', error);
|
||||
container.logger.error('Error detecting market regime:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to detect market regime'
|
||||
}, 500);
|
||||
|
|
@ -138,7 +137,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error calculating correlation:', error);
|
||||
container.logger.error('Error calculating correlation:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to calculate correlation'
|
||||
}, 500);
|
||||
|
|
@ -169,7 +168,7 @@ export function createAnalyticsRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error making prediction:', error);
|
||||
container.logger.error('Error making prediction:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to make prediction'
|
||||
}, 500);
|
||||
|
|
|
|||
|
|
@ -1,21 +1,48 @@
|
|||
import { Hono } from 'hono';
|
||||
import { z } from 'zod';
|
||||
import { logger } from '@stock-bot/logger';
|
||||
import { IServiceContainer } from '@stock-bot/di';
|
||||
import { BacktestConfigSchema } from '../../types';
|
||||
import { BacktestEngine } from '../../backtest/BacktestEngine';
|
||||
import { ModeManager } from '../../core/ModeManager';
|
||||
import { container } from '../../container';
|
||||
|
||||
const BacktestIdSchema = z.object({
|
||||
backtestId: z.string()
|
||||
});
|
||||
|
||||
export function createBacktestRoutes(): Hono {
|
||||
export function createBacktestRoutes(container: IServiceContainer): Hono {
|
||||
const app = new Hono();
|
||||
const backtestEngine = container.get('BacktestEngine') as BacktestEngine;
|
||||
const modeManager = container.get('ModeManager') as ModeManager;
|
||||
const backtestEngine = container.custom?.BacktestEngine as BacktestEngine;
|
||||
const modeManager = container.custom?.ModeManager as ModeManager;
|
||||
|
||||
// Run new backtest
|
||||
// Default POST to / is the same as /run for backward compatibility
|
||||
app.post('/', async (c) => {
|
||||
try {
|
||||
const body = await c.req.json();
|
||||
const config = BacktestConfigSchema.parse(body);
|
||||
|
||||
// Initialize backtest mode
|
||||
await modeManager.initializeMode(config);
|
||||
|
||||
// Run backtest
|
||||
const result = await backtestEngine.runBacktest(config);
|
||||
|
||||
return c.json(result, 201);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return c.json({
|
||||
error: 'Invalid backtest configuration',
|
||||
details: error.errors
|
||||
}, 400);
|
||||
}
|
||||
|
||||
container.logger.error('Error running backtest:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to run backtest'
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Run new backtest (same as above but at /run)
|
||||
app.post('/run', async (c) => {
|
||||
try {
|
||||
const body = await c.req.json();
|
||||
|
|
@ -36,7 +63,7 @@ export function createBacktestRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error running backtest:', error);
|
||||
container.logger.error('Error running backtest:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to run backtest'
|
||||
}, 500);
|
||||
|
|
@ -53,7 +80,7 @@ export function createBacktestRoutes(): Hono {
|
|||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error stopping backtest:', error);
|
||||
container.logger.error('Error stopping backtest:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to stop backtest'
|
||||
}, 500);
|
||||
|
|
@ -72,7 +99,7 @@ export function createBacktestRoutes(): Hono {
|
|||
currentTime: new Date().toISOString()
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting backtest progress:', error);
|
||||
container.logger.error('Error getting backtest progress:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get progress'
|
||||
}, 500);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
import { Hono } from 'hono';
|
||||
import { z } from 'zod';
|
||||
import { logger } from '@stock-bot/logger';
|
||||
import { IServiceContainer } from '@stock-bot/di';
|
||||
import { OrderRequestSchema } from '../../types';
|
||||
import { ExecutionService } from '../../services/ExecutionService';
|
||||
import { container } from '../../container';
|
||||
|
||||
const OrderIdSchema = z.object({
|
||||
orderId: z.string()
|
||||
});
|
||||
|
||||
export function createOrderRoutes(): Hono {
|
||||
export function createOrderRoutes(container: IServiceContainer): Hono {
|
||||
const app = new Hono();
|
||||
const executionService = container.get('ExecutionService') as ExecutionService;
|
||||
const executionService = container.custom?.ExecutionService as ExecutionService;
|
||||
|
||||
// Submit new order
|
||||
app.post('/', async (c) => {
|
||||
|
|
@ -30,7 +29,7 @@ export function createOrderRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error submitting order:', error);
|
||||
container.logger.error('Error submitting order:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to submit order'
|
||||
}, 500);
|
||||
|
|
@ -50,7 +49,7 @@ export function createOrderRoutes(): Hono {
|
|||
return c.json({ error: 'Order not found or already filled' }, 404);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error cancelling order:', error);
|
||||
container.logger.error('Error cancelling order:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to cancel order'
|
||||
}, 500);
|
||||
|
|
@ -70,7 +69,7 @@ export function createOrderRoutes(): Hono {
|
|||
return c.json({ error: 'Order not found' }, 404);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error getting order status:', error);
|
||||
container.logger.error('Error getting order status:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get order status'
|
||||
}, 500);
|
||||
|
|
@ -101,7 +100,7 @@ export function createOrderRoutes(): Hono {
|
|||
}, 400);
|
||||
}
|
||||
|
||||
logger.error('Error submitting batch orders:', error);
|
||||
container.logger.error('Error submitting batch orders:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to submit batch orders'
|
||||
}, 500);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import { Hono } from 'hono';
|
||||
import { z } from 'zod';
|
||||
import { logger } from '@stock-bot/logger';
|
||||
import { IServiceContainer } from '@stock-bot/di';
|
||||
import { ModeManager } from '../../core/ModeManager';
|
||||
import { container } from '../../container';
|
||||
|
||||
const SymbolSchema = z.object({
|
||||
symbol: z.string()
|
||||
});
|
||||
|
||||
export function createPositionRoutes(): Hono {
|
||||
export function createPositionRoutes(container: IServiceContainer): Hono {
|
||||
const app = new Hono();
|
||||
const modeManager = container.get('ModeManager') as ModeManager;
|
||||
const modeManager = container.custom?.ModeManager as ModeManager;
|
||||
|
||||
// Get all positions
|
||||
app.get('/', async (c) => {
|
||||
|
|
@ -23,7 +22,7 @@ export function createPositionRoutes(): Hono {
|
|||
positions
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting positions:', error);
|
||||
container.logger.error('Error getting positions:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get positions'
|
||||
}, 500);
|
||||
|
|
@ -41,7 +40,7 @@ export function createPositionRoutes(): Hono {
|
|||
positions
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting open positions:', error);
|
||||
container.logger.error('Error getting open positions:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get open positions'
|
||||
}, 500);
|
||||
|
|
@ -69,7 +68,7 @@ export function createPositionRoutes(): Hono {
|
|||
}, 404);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error getting position:', error);
|
||||
container.logger.error('Error getting position:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get position'
|
||||
}, 500);
|
||||
|
|
@ -92,7 +91,7 @@ export function createPositionRoutes(): Hono {
|
|||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting P&L:', error);
|
||||
container.logger.error('Error getting P&L:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get P&L'
|
||||
}, 500);
|
||||
|
|
@ -111,7 +110,7 @@ export function createPositionRoutes(): Hono {
|
|||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting risk metrics:', error);
|
||||
container.logger.error('Error getting risk metrics:', error);
|
||||
return c.json({
|
||||
error: error instanceof Error ? error.message : 'Failed to get risk metrics'
|
||||
}, 500);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { Server as SocketIOServer, Socket } from 'socket.io';
|
||||
import { logger } from '@stock-bot/logger';
|
||||
import { z } from 'zod';
|
||||
import { IServiceContainer } from '@stock-bot/di';
|
||||
import { MarketDataService } from '../../services/MarketDataService';
|
||||
import { ExecutionService } from '../../services/ExecutionService';
|
||||
import { ModeManager } from '../../core/ModeManager';
|
||||
import { Container } from '@stock-bot/di';
|
||||
|
||||
const SubscribeSchema = z.object({
|
||||
symbols: z.array(z.string()),
|
||||
|
|
@ -15,16 +14,16 @@ const UnsubscribeSchema = z.object({
|
|||
symbols: z.array(z.string())
|
||||
});
|
||||
|
||||
export function setupWebSocketHandlers(io: SocketIOServer, container: Container): void {
|
||||
const marketDataService = container.get('MarketDataService') as MarketDataService;
|
||||
const executionService = container.get('ExecutionService') as ExecutionService;
|
||||
const modeManager = container.get('ModeManager') as ModeManager;
|
||||
export function setupWebSocketHandlers(io: SocketIOServer, container: IServiceContainer): void {
|
||||
const marketDataService = container.custom?.MarketDataService as MarketDataService;
|
||||
const executionService = container.custom?.ExecutionService as ExecutionService;
|
||||
const modeManager = container.custom?.ModeManager as ModeManager;
|
||||
|
||||
// Track client subscriptions
|
||||
const clientSubscriptions = new Map<string, Set<string>>();
|
||||
|
||||
io.on('connection', (socket: Socket) => {
|
||||
logger.info(`WebSocket client connected: ${socket.id}`);
|
||||
container.logger.info(`WebSocket client connected: ${socket.id}`);
|
||||
clientSubscriptions.set(socket.id, new Set());
|
||||
|
||||
// Send initial connection info
|
||||
|
|
@ -44,13 +43,13 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
subscriptions.add(symbol);
|
||||
}
|
||||
|
||||
logger.debug(`Client ${socket.id} subscribed to: ${symbols.join(', ')}`);
|
||||
container.logger.debug(`Client ${socket.id} subscribed to: ${symbols.join(', ')}`);
|
||||
|
||||
if (callback) {
|
||||
callback({ success: true, symbols });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Subscription error:', error);
|
||||
container.logger.error('Subscription error:', error);
|
||||
if (callback) {
|
||||
callback({
|
||||
success: false,
|
||||
|
|
@ -83,13 +82,13 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
}
|
||||
}
|
||||
|
||||
logger.debug(`Client ${socket.id} unsubscribed from: ${symbols.join(', ')}`);
|
||||
container.logger.debug(`Client ${socket.id} unsubscribed from: ${symbols.join(', ')}`);
|
||||
|
||||
if (callback) {
|
||||
callback({ success: true, symbols });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Unsubscribe error:', error);
|
||||
container.logger.error('Unsubscribe error:', error);
|
||||
if (callback) {
|
||||
callback({
|
||||
success: false,
|
||||
|
|
@ -107,7 +106,7 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
callback({ success: true, result });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Order submission error:', error);
|
||||
container.logger.error('Order submission error:', error);
|
||||
if (callback) {
|
||||
callback({
|
||||
success: false,
|
||||
|
|
@ -127,7 +126,7 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
callback({ success: true, positions });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error getting positions:', error);
|
||||
container.logger.error('Error getting positions:', error);
|
||||
if (callback) {
|
||||
callback({
|
||||
success: false,
|
||||
|
|
@ -139,7 +138,7 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
|
||||
// Handle disconnection
|
||||
socket.on('disconnect', async () => {
|
||||
logger.info(`WebSocket client disconnected: ${socket.id}`);
|
||||
container.logger.info(`WebSocket client disconnected: ${socket.id}`);
|
||||
|
||||
// Unsubscribe from all symbols for this client
|
||||
const subscriptions = clientSubscriptions.get(socket.id);
|
||||
|
|
@ -191,5 +190,5 @@ export function setupWebSocketHandlers(io: SocketIOServer, container: Container)
|
|||
});
|
||||
});
|
||||
|
||||
logger.info('WebSocket handlers initialized');
|
||||
container.logger.info('WebSocket handlers initialized');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue