123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #!/usr/bin/env tsx
- /**
- * Modular Delta Neutral Strategy Entry Point
- * Clean, maintainable, and extensible
- */
- import { ModularDeltaNeutralStrategy } from '../src/strategies/ModularDeltaNeutralStrategy';
- interface RunOptions {
- /**
- * When true (CLI mode), the process will exit automatically after shutdown.
- */
- exitOnShutdown?: boolean;
- }
- let activeStrategy: ModularDeltaNeutralStrategy | null = null;
- let handlersRegistered = false;
- let shutdownInProgress = false;
- let exitAfterShutdown = false;
- const shutdownSignals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];
- function ensureProcessHandlers(): void {
- if (handlersRegistered) {
- return;
- }
- const requestShutdown = (source: string, exitCode = 0) => {
- void performShutdown(source, exitCode);
- };
- shutdownSignals.forEach((signal) => {
- process.on(signal, () => requestShutdown(signal, 0));
- });
- process.on('uncaughtException', (error: Error) => {
- console.error('❌ Uncaught Exception:', error);
- requestShutdown('uncaughtException', 1);
- });
- process.on('unhandledRejection', (reason: unknown, promise: Promise<unknown>) => {
- console.error('❌ Unhandled Rejection at:', promise, 'reason:', reason);
- requestShutdown('unhandledRejection', 1);
- });
- handlersRegistered = true;
- }
- async function performShutdown(source: string, exitCode: number): Promise<void> {
- if (shutdownInProgress) {
- console.log('\n⚠️ Shutdown already in progress...');
- return;
- }
- shutdownInProgress = true;
- console.log(`\n\n📡 Received ${source}, initiating graceful shutdown...`);
- const strategy = activeStrategy;
- try {
- if (strategy) {
- await strategy.stop();
- }
- console.log('👋 Shutdown complete.');
- } catch (error) {
- console.error('❌ Error during shutdown:', error);
- exitCode = exitCode || 1;
- } finally {
- activeStrategy = null;
- shutdownInProgress = false;
- if (exitAfterShutdown) {
- process.exit(exitCode);
- }
- }
- }
- /**
- * Main entry point
- */
- export async function main(options: RunOptions = {}): Promise<void> {
- console.log('╔═══════════════════════════════════════════════╗');
- console.log('║ Modular Delta Neutral Strategy ║');
- console.log('║ Clean Architecture | Maintainable | Scalable ║');
- console.log('╚═══════════════════════════════════════════════╝\n');
- const strategy = new ModularDeltaNeutralStrategy();
- activeStrategy = strategy;
- exitAfterShutdown = Boolean(options.exitOnShutdown);
- shutdownInProgress = false;
- ensureProcessHandlers();
- try {
- await strategy.initialize();
- await strategy.start();
- } catch (error) {
- console.error('❌ Failed to start strategy:', error);
- try {
- await strategy.stop();
- } catch (stopError) {
- console.error('❌ Failed to stop strategy after initialization error:', stopError);
- } finally {
- activeStrategy = null;
- }
- throw error;
- }
- }
- // Run the strategy when executed directly from the CLI
- if (require.main === module) {
- main({ exitOnShutdown: true })
- .then(() => {
- // keep process alive to allow the trading cycle to run; exit handled by signal shutdown
- })
- .catch((error) => {
- console.error('Fatal error:', error);
- process.exit(1);
- });
- }
|