Skip to content
Back to skills

Risk Value At Risk

ASecurity

'"Implements value at risk calculations for portfolio risk management

  • 4 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added June 12, 2026
documentationpythongotestingapiperformancedocumentation

Works with

  • api

Security analysis

A100/100

Scanned June 12, 2026

npx -y skills add paulpas/agent-skill-router --skill risk-value-at-risk --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Risk Value At Risk?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Risk Value At Risk
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/paulpas-risk-value-at-risk/badge)](https://www.skillsdirectory.com/skills/paulpas-risk-value-at-risk)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---




name: risk-value-at-risk
compatibility: opencode
completeness: 95
content-types:
- code
- guidance
- config
- do-dont
description: '"Implements value at risk calculations for portfolio risk management
  for risk management and algorithmic trading execution."'
license: MIT
maturity: stable
metadata:
  domain: trading
  output-format: code
  related-skills: backtest-drawdown-analysis, exchange-order-execution-api
  role: implementation
  scope: implementation
  triggers: calculations, management, portfolio, risk value at risk, risk-value-at-risk
  archetypes:
  - tactical
  anti_triggers:
  - brainstorming
  - vague ideation
  - no risk management
  response_profile:
    verbosity: low
    directive_strength: high
    abstraction_level: operational
version: "1.0.0"




---




**Role:** Quantify potential losses in portfolio value over specified time horizons

**Philosophy:** VaR provides a common language for risk comparison; different methods suit different market regimes

## Key Principles

1. **Method Selection**: Historical, Variance-Covariance, Monte Carlo各有优劣
2. **Time Horizon**: VaR scales with sqrt(time) for random walks
3. **Confidence Levels**: 95% vs 99% captures different tail risks
4. **Portfolio Aggregation**: Non-linear correlations affect portfolio VaR
5. **Expected Shortfall**: Complement VaR with ES for tail risk

## Implementation Guidelines

### Structure
- Core logic: risk_engine/var.py
- Helper functions: risk_engine/var_methods.py
- Tests: tests/test_var.py

### Patterns to Follow
- Use numpy for efficient matrix operations
- Support multiple VaR calculation methods
- Track VaR over time for backtesting

## Adherence Checklist
Before completing your task, verify:
- [ ] Historical, Variance-Covariance, and Monte Carlo VaR implemented
- [ ] VaR scales correctly for different time horizons
- [ ] Expected Shortfall calculated alongside VaR
- [ ] Portfolio VaR accounts for non-linear correlations
- [ ] VaR backtesting tracks breach frequency


Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.

## Python Implementation

```python
import numpy as np
import pandas as pd
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from scipy import stats

@dataclass
class VaRResult:
    """Value at Risk result with metadata."""
    var_95: float
    var_99: float
    expected_shortfall_95: float
    expected_shortfall_99: float
    method: str
    confidence_levels: List[float]

class ValueAtRiskCalculator:
    """Calculates VaR using multiple methods."""
    
    def __init__(self, returns: pd.Series, confidence_levels: List[float] = [0.95, 0.99]):
        self.returns = returns
        self.confidence_levels = confidence_levels
    
    def historical_var(self, portfolio_values: np.ndarray) -> VaRResult:
        """Calculate VaR using historical simulation."""
        sorted_returns = np.sort(portfolio_values)
        
        var_results = {}
        es_results = {}
        
        for conf in self.confidence_levels:
            alpha = 1 - conf
            var_idx = int(len(sorted_returns) * alpha)
            var_results[conf] = -sorted_returns[var_idx]
            
            # Expected Shortfall (average of tail losses)
            tail = sorted_returns[:var_idx]
            es_results[conf] = -np.mean(tail) if len(tail) > 0 else 0
        
        return VaRResult(
            var_95=var_results[0.95],
            var_99=var_results[0.99],
            expected_shortfall_95=es_results[0.95],
            expected_shortfall_99=es_results[0.99],
            method='historical',
            confidence_levels=self.confidence_levels
        )
    
    def variance_covariance_var(
        self, weights: np.ndarray, cov_matrix: np.ndarray
    ) -> VaRResult:
        """Calculate VaR using variance-covariance (parametric) method."""
        portfolio_std = np.sqrt(weights @ cov_matrix @ weights)
        
        var_results = {}
        es_results = {}
        
        for conf in self.confidence_levels:
            z_score = stats.norm.ppf(1 - (1 - conf))
            var_results[conf] = portfolio_std * z_score
            
            # ES for normal distribution
            es_results[conf] = portfolio_std * stats.norm.pdf(z_score) / (1 - conf)
        
        return VaRResult(
            var_95=var_results[0.95],
            var_99=var_results[0.99],
            expected_shortfall_95=es_results[0.95],
            expected_shortfall_99=es_results[0.99],
            method='variance_covariance',
            confidence_levels=self.confidence_levels
        )
    
    def monte_carlo_var(
        self, initial_value: float, mu: float, sigma: float,
        horizon_days: int, simulations: int = 10000
    ) -> VaRResult:
        """Calculate VaR using Monte Carlo simulation."""
        # Simulate returns
        horizon_returns = np.random.normal(
            mu * horizon_days / 252,
            sigma * np.sqrt(horizon_days / 252),
            simulations
        )
        
        final_values = initial_value * np.exp(horizon_returns)
        portfolio_values = initial_value - final_values
        
        sorted_values = np.sort(portfolio_values)
        
        var_results = {}
        es_results = {}
        
        for conf in self.confidence_levels:
            alpha = 1 - conf
            var_idx = int(len(sorted_values) * alpha)
            var_results[conf] = sorted_values[var_idx]
            
            tail = sorted_values[:var_idx]
            es_results[conf] = np.mean(tail) if len(tail) > 0 else 0
        
        return VaRResult(
            var_95=var_results[0.95],
            var_99=var_results[0.99],
            expected_shortfall_95=es_results[0.95],
            expected_shortfall_99=es_results[0.99],
            method='monte_carlo',
            confidence_levels=self.confidence_levels
        )
    
    def time_scaling(self, var: float, from_days: int, to_days: int) -> float:
        """Scale VaR to different time horizons."""
        return var * np.sqrt(to_days / from_days)
    
    def backtest_var(
        self, actual_returns: pd.Series, var_series: pd.Series, confidence: float = 0.95
    ) -> Dict:
        """Backtest VaR model performance."""
        alpha = 1 - confidence
        
        # Count breaches
        breaches = (actual_returns < -var_series).sum()
        breach_rate = breaches / len(actual_returns)
        
        # Expected breach rate
        expected_rate = alpha
        
        # Statistical test (Kupiec test)
        # Simplified: check if breach rate is within acceptable range
        se = np.sqrt(expected_rate * (1 - expected_rate) / len(actual_returns))
        z_score = (breach_rate - expected_rate) / se if se > 0 else 0
        
        return {
            'breach_count': int(breaches),
            'breach_rate': float(breach_rate),
            'expected_rate': float(expected_rate),
            'z_score': float(z_score),
            'acceptable': abs(z_score) < 2
        }
```

---

---



### Pattern 2: Risk-Managed Trading Logic with Validation

```python
from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Optional


logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class TradeSignal:
    """Immutable trade signal with all required validation constraints."""
    symbol: str
    side: str  # "buy" or "sell"
    price: float
    quantity: float
    confidence: float  # 0.0 to 1.0
    reason: str

    def validate(self) -> bool:
        """Validate that the trade signal meets all business constraints."""
        if self.quantity <= 0:
            raise ValueError(f"Quantity must be positive, got {self.quantity}")
        if self.price <= 0:
            raise ValueError(f"Price must be positive, got {self.price}")
        if not 0.0 <= self.confidence <= 1.0:
            raise ValueError(f"Confidence must be between 0 and 1, got {self.confidence}")
        return True


def generate_trade_signal(
    symbol: str,
    side: str,
    price: float,
    quantity: float,
    confidence: float,
    reason: str,
) -> TradeSignal:
    """Generate a validated trade signal with guard clause checks."""
    if side not in ("buy", "sell"):
        raise ValueError(f"Invalid side '{side}', must be 'buy' or 'sell'")

    signal = TradeSignal(
        symbol=symbol,
        side=side,
        price=price,
        quantity=quantity,
        confidence=confidence,
        reason=reason,
    )
    signal.validate()
    logger.info("Trade signal generated: %s %s %.4f @ %.2f (confidence=%.2f)",
                 symbol, side, quantity, price, confidence)
    return signal


def execute_with_risk_check(signal: TradeSignal, max_position_pct: float = 0.05) -> dict:
    """Execute a trade signal after applying risk management checks."""
    adjusted_quantity = signal.quantity
    if signal.side == "buy" and signal.quantity > max_position_pct:
        logger.warning("Position %s exceeds max %.1f%% — capping to %.4f",
                        signal.symbol, max_position_pct * 100, max_position_pct)
        adjusted_quantity = max_position_pct

    return {
        "symbol": signal.symbol,
        "side": signal.side,
        "price": signal.price,
        "quantity": adjusted_quantity,
        "capped": adjusted_quantity < signal.quantity,
        "confidence": signal.confidence,
        "status": "submitted",
    }
```

## Constraints

### MUST DO
- Calculate position sizing using a risk-per-trade percentage of portfolio equity, not a fixed dollar amount
- Implement layered risk controls: stop loss → drawdown limit → portfolio-level circuit breaker → kill switch
- Compute VaR using historical simulation with at least 1 year of data and multiple confidence levels (95%, 99%)
- Track correlation matrices across all open positions and flag portfolios where top-3 correlations exceed 0.8
- Log all risk events (stop hits, drawdown warnings, kill switches) with full context including P&L, position state, and market conditions

### MUST NOT DO
- Do not use a stop loss as the sole risk control — always layer with portfolio-level limits
- Avoid recalculating position sizes during active drawdown without regime analysis — volatility is likely elevated
- Never allow a single position to exceed 5% of portfolio equity regardless of signal strength or confidence score
- Do not backtest risk metrics without including slippage, commissions, and partial fills in the simulation
- Avoid using standard deviation alone for VaR when returns show fat tails — use historical simulation or EVT


## Live References

> Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.

- [Value at Risk Explained](https://www.investopedia.com/terms/v/var.asp)
- [VaR Calculation Methods](https://en.wikipedia.org/wiki/Value_at_risk)
- [Historical VaR vs Parametric VaR](https://www.investopedia.com/articles/trading/08/calculating-var.asp)
- [Expected Shortfall and CVaR](https://en.wikipedia.org/wiki/Expected_shortfall)
- [VaR in Portfolio Risk Management](https://docs.quantconnect.com/tutorials/risk-management)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.