--- id: "ET-PFM-003" title: "Motor de Stress Testing" type: "Technical Specification" status: "Done" priority: "Alta" epic: "OQI-008" project: "trading-platform" version: "1.0.0" created_date: "2025-12-05" updated_date: "2026-01-04" --- # ET-PFM-003: Motor de Stress Testing **Épica:** OQI-008 - Portfolio Manager **Versión:** 1.0 **Fecha:** 2025-12-05 **Estado:** Planificado --- ## Escenarios Predefinidos ```typescript const STRESS_SCENARIOS = { market_crash: { name: 'Market Crash', description: 'Caída del mercado tipo 2008/2020', impacts: { stocks: -0.30, crypto: -0.50, bonds: 0.05, gold: 0.10, }, }, recession: { name: 'Recesión Económica', description: 'Recesión prolongada', impacts: { stocks: -0.25, crypto: -0.40, bonds: 0.08, gold: 0.15, }, }, crypto_winter: { name: 'Crypto Winter', description: 'Caída prolongada de criptomonedas', impacts: { stocks: -0.05, crypto: -0.70, bonds: 0.02, gold: 0.05, }, }, rate_hike: { name: 'Subida de Tasas', description: 'Aumento agresivo de tasas de interés', impacts: { stocks: -0.15, crypto: -0.25, bonds: -0.10, gold: 0.00, }, }, }; ``` --- ## Servicio de Stress Testing ```typescript @Injectable() export class StressTestService { async runScenario( portfolioId: string, scenarioId: string ): Promise { const positions = await this.portfolioService.getPositions(portfolioId); const scenario = STRESS_SCENARIOS[scenarioId]; let totalImpact = 0; const positionImpacts = []; for (const position of positions) { const assetType = this.getAssetType(position.symbol); const impact = scenario.impacts[assetType] || -0.20; const positionImpact = position.marketValue * impact; totalImpact += positionImpact; positionImpacts.push({ symbol: position.symbol, currentValue: position.marketValue, impact: positionImpact, impactPercent: impact * 100, projectedValue: position.marketValue + positionImpact, }); } return { scenario: scenario.name, totalPortfolioValue: this.getCurrentValue(positions), totalImpact, totalImpactPercent: (totalImpact / this.getCurrentValue(positions)) * 100, projectedValue: this.getCurrentValue(positions) + totalImpact, positionImpacts: positionImpacts.sort((a, b) => a.impact - b.impact), timestamp: new Date().toISOString(), }; } } ``` --- ## Referencias - [RF-PFM-002: Análisis de Riesgo](../requerimientos/RF-PFM-002-analisis-riesgo.md) --- *Especificación técnica - Sistema NEXUS*