learning_ai_invt_trdg/backend/final_e2e_param_verification.ts

97 lines
4.1 KiB
TypeScript

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 { ProStrategyEngine } from '../src/strategies/ProStrategyEngine.js';
import { config } from '../src/config/index.js';
import { SignalDirection, MarketContext } from '../src/strategies/rules/types.js';
import logger from '../src/utils/logger.js';
config.ENABLE_TRADING = true;
config.PAPER_TRADING = true;
const SLEEP_MS = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
async function runParamVerification() {
logger.info('===================================================');
logger.info('🧪 STARTING PARAMETER-AWARE E2E VERIFICATION');
logger.info(' Testing contrast between High Risk and Low Risk settings.');
logger.info('===================================================');
// 1. Fetch our two distinct profiles
const profiles = await supabaseService.getActiveProfiles();
const highRisk = profiles.find(p => p.name.includes('High Risk'));
const lowRisk = profiles.find(p => p.name.includes('Low Risk'));
if (!highRisk || !lowRisk) {
logger.error('❌ Could not find both profiles (Scalper and Swing). Run create scripts first.');
process.exit(1);
}
const user = highRisk.users; // Both belong to same user in our setup
const exchange = new AlpacaConnector(user.ALPACA_API_KEY, user.ALPACA_SECRET_KEY);
const engine = new ProStrategyEngine(exchange);
// 2. Setup Traders
const executorHigh = new TradeExecutor(exchange, undefined, user.user_id, highRisk.id);
const traderHigh = new AutoTrader(executorHigh, exchange, highRisk, engine);
const executorLow = new TradeExecutor(exchange, undefined, user.user_id, lowRisk.id);
const traderLow = new AutoTrader(executorLow, exchange, lowRisk, engine);
// 3. Define Market Context with RSI = 75
// Scenario: RSI is 75.
// Low Risk Swing logic (default RSI 70) -> Should Trigger SELL
// High Risk Scalper logic (custom RSI 80) -> Should NOT Trigger (75 < 80)
const mockCandles = Array(100).fill({ close: 65000, high: 65100, low: 64900, open: 65000, volume: 100 });
const mockContext: MarketContext = {
symbol: 'BTC/USD',
currentPrice: 65000,
candles1h: mockCandles,
candles15m: mockCandles,
candles4h: mockCandles,
rsi_1h: 75, // THE MAGIC NUMBER
ema20_1h: 64000,
ema50_4h: 60000,
ema200_4h: 55000,
session: 'NY', isMajorSession: true,
volatility: 'Med', change24h: 1, changeToday: 0.5,
latestSignal: SignalDirection.NONE
};
const analysis: any = {
symbol: 'BTC/USD',
globalSignal: SignalDirection.NONE,
rules: {}, // Global results don't matter now as we re-evaluate
context: mockContext
};
logger.info('\n📊 Scenario: RSI is 75');
logger.info(` Profile [Low Risk]: Threshold 70 -> Expected: PASS`);
logger.info(` Profile [High Risk]: Threshold 80 -> Expected: FAIL`);
// 4. Test Execution
logger.info('\n⚡ Testing [Low Risk Swing]...');
await traderLow.handleSignal('BTC/USD', analysis);
logger.info('⚡ Testing [High Risk Scalper]...');
await traderHigh.handleSignal('BTC/USD', analysis);
// 5. Verification
logger.info('\n🏁 RESULTS:');
// We can't easily wait for orders in this fake test without mocking exchange,
// but we can look at the logs to see where "EXECUTING" appeared.
logger.info('===================================================');
logger.info('✅ VERIFICATION COMPLETE');
logger.info(' Please check the logs above for "EXECUTING" vs "Blocked" messages.');
logger.info('===================================================');
process.exit(0);
}
runParamVerification().catch(err => {
logger.error('Test Failed:', err);
process.exit(1);
});