import { supabaseService } from '../src/services/SupabaseService.js'; import { AutoTrader } from '../src/services/AutoTrader.js'; import { TradeExecutor } from '../src/services/TradeExecutor.js'; import { AlpacaConnector } from '../src/connectors/alpaca.js'; import { config } from '../src/config/index.js'; import { SignalDirection, MarketContext, RuleResult } from '../src/strategies/rules/types.js'; import logger from '../src/utils/logger.js'; async function testProfileExecution() { logger.info('--- PROFILE-BASED E2E TEST STARTING ---'); const profiles = await supabaseService.getActiveProfiles(); if (profiles.length === 0) { logger.error('No profiles found.'); return; } const testProfile = profiles[0]; const user = testProfile.users; const symbols = testProfile.symbols ? testProfile.symbols.split(',').map(s => s.trim()).filter(s => s !== "") : ['BTC/USDT']; const testSymbol = symbols[0]; logger.info(`Profile: ${testProfile.name} | Symbol: ${testSymbol} | Capital: ${testProfile.allocated_capital}`); const userKey = config.PAPER_TRADING ? user.ALPACA_API_KEY : user.REAL_ALPACA_API_KEY; const userSecret = config.PAPER_TRADING ? user.ALPACA_SECRET_KEY : user.REAL_ALPACA_SECRET_KEY; const exchange = new AlpacaConnector(userKey, userSecret); const executor = new TradeExecutor(exchange, undefined, user.user_id, testProfile.id); // IMPORTANT: Inject global config for trading enabled config.ENABLE_TRADING = true; const trader = new AutoTrader( executor, exchange, parseFloat(testProfile.allocated_capital.toString()), parseFloat(testProfile.risk_per_trade_percent?.toString() || '1'), symbols ); const mockResult: RuleResult = { ruleName: 'TEST', passed: true, signal: SignalDirection.BUY, reason: 'E2E_TEST', metadata: {} }; const mockContext: MarketContext = { symbol: testSymbol, currentPrice: 50000, candles1h: [], candles15m: [], candles4h: [], rsi_1h: 40, ema20_1h: 49000, change24h: 2, changeToday: 1, volatility: 'Low', session: 'NY', isMajorSession: true, latestSignal: SignalDirection.NONE }; logger.info('Simulating Signal...'); await trader.handleSignal(testSymbol, mockResult, mockContext); const pos = executor.getActivePosition(testSymbol); if (pos) { logger.info(`✅ SUCCESS: Position found! ProfileID: ${pos.profileId} | Qty: ${pos.size}`); await executor.closePosition(testSymbol, 'E2E CLEANUP'); } else { logger.error('❌ FAILED: Position not created. Checking why...'); // Manually try openPosition to see exchange error const direct = await executor.openPosition(testSymbol, SignalDirection.BUY, 0.001); if (!direct.success) { logger.error(`Direct Open Error: ${direct.error}`); } else { logger.info('Direct open worked. Something is wrong in AutoTrader logic.'); } } } testProfileExecution().catch(console.error);