import { ExecutionManager } from '../src/services/executionManager.js'; import { TradeMonitor } from '../src/services/tradeMonitor.js'; import { SignalDirection, MarketContext, RuleResult } from '../src/strategies/rules/types.js'; import { IExchangeConnector } from '../src/connectors/types.js'; async function testTrailAndHold() { console.log('--- Trailing Guard & Signal Exit Test Start ---'); // 1. Mock Exchange const mockExchange: any = { getPosition: async () => ({ side: 'long', qty: '1', avg_entry_price: '10000' }), placeOrder: async (sym: string, side: string) => { console.log(`[Mock] Order Placed: ${side} for ${sym}`); return { id: 'test-exit-id' }; }, fetchOHLCV: async () => [{ close: 10150 }] // 1.5% profit mock price }; const manager = new ExecutionManager(mockExchange as any); const monitor = new TradeMonitor(mockExchange as any, manager); const symbol = 'BTC/USD'; const entryPrice = 10000; // --- TEST 1: Signal Reversal Exit --- console.log('\n--- Scenario 1: Signal Reversal ---'); (manager as any).activeTraders.set(symbol, { side: SignalDirection.BUY, entryPrice: entryPrice, size: 1, stopLoss: 9000, takeProfit: 10100, // 1% target peakPrice: entryPrice }); const sellSignal: RuleResult = { ruleName: 'ReverseSignal', signal: SignalDirection.SELL, passed: true, reason: 'Trend flipped' }; const context: MarketContext = { currentPrice: 10050, candles4h: [], candles1h: [], candles15m: [], change24h: 0, changeToday: 0, session: 'NY', isMajorSession: true, volatility: 'Low', latestSignal: SignalDirection.BUY }; console.log('Action: Sending SELL signal while in BUY trade...'); await manager.handleSignal(symbol, sellSignal, context); if (!(manager as any).activeTraders.has(symbol)) { console.log('✅ PASS: Trade exited on Signal Flip.'); } else { console.log('❌ FAIL: Trade still active after Signal Flip.'); } // --- TEST 2: Trailing Profit Guard --- console.log('\n--- Scenario 2: Trailing Profit Guard ---'); // Reset state (manager as any).activeTraders.set(symbol, { side: SignalDirection.BUY, entryPrice: entryPrice, size: 1, stopLoss: 9000, takeProfit: 10100, // 1% target peakPrice: 10150, // Peak reached profitGuardActive: true }); // Mock price pullback (0.2% pullback from 10150 peak -> 10129) mockExchange.fetchOHLCV = async () => [{ close: 10120 }]; console.log('Action: Simulating price pullback (0.3%) after 1.5% run...'); await (monitor as any).checkOpenPositions(); if (!(manager as any).activeTraders.has(symbol)) { console.log('✅ PASS: Trailing guard triggered exit on pullback.'); } else { console.log('❌ FAIL: Trailing guard failed to trigger exit.'); } console.log('\n--- Trailing Guard & Signal Exit Test End ---'); } testTrailAndHold().catch(console.error);