#!/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) => { console.error('āŒ Unhandled Rejection at:', promise, 'reason:', reason); requestShutdown('unhandledRejection', 1); }); handlersRegistered = true; } async function performShutdown(source: string, exitCode: number): Promise { 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 { 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); }); }