Quantitative risk modeling toolkit for hedge funds and asset managers
VaR calculations, scenario analysis, counterparty exposure, and regulatory reporting
- Overview
- Features
- Installation
- Quick Start
- Modules
- Examples
- Methodology
- Project Structure
- Contributing
A comprehensive credit risk analysis framework designed for:
- Hedge Funds - Portfolio-level credit exposure and VaR
- Asset Managers - Counterparty risk assessment
- Risk Teams - Regulatory stress testing (Basel III/IV alignment)
- Researchers - Quantitative risk modeling experimentation
Traditional risk systems are often black boxes. This framework provides:
- Transparency - Full visibility into risk calculations
- Flexibility - Modular design for custom risk metrics
- Reproducibility - Version-controlled, tested codebase
- Education - Well-documented methodology
| Module | Description |
|---|---|
| VaR Engine | Historical, Parametric, and Monte Carlo VaR |
| Scenario Analysis | Stress testing with custom shock scenarios |
| Counterparty Risk | PFE, CVA, and exposure-at-default calculations |
| Portfolio Analytics | Concentration risk, sector exposure, correlation |
| Reporting | Automated risk reports with visualizations |
- Python 3.9+
- pip or conda
# Clone the repository
git clone https://github.com/Leotaby/hedge-fund-credit-risk.git
cd hedge-fund-credit-risk
# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # Linux/Mac
# or
.\venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txtpandas>=1.5.0
numpy>=1.24.0
scipy>=1.10.0
matplotlib>=3.7.0
seaborn>=0.12.0
yfinance>=0.2.0
pytest>=7.0.0
from risk_engine import PortfolioRisk, VaRCalculator
from data_loader import load_portfolio
# Load sample portfolio
portfolio = load_portfolio("data/sample_portfolio.csv")
# Initialize risk calculator
risk = PortfolioRisk(portfolio)
# Calculate VaR at 95% confidence, 10-day horizon
var_95 = risk.calculate_var(confidence=0.95, horizon=10, method="historical")
print(f"10-day 95% VaR: ${var_95:,.2f}")
# Run stress test
stress_results = risk.stress_test(scenario="2008_financial_crisis")
print(f"Stress Loss: ${stress_results['total_loss']:,.2f}")
# Generate risk report
risk.generate_report(output_path="reports/risk_report.html")Three methodologies for Value-at-Risk:
from risk_engine.var import VaRCalculator
calc = VaRCalculator(returns_data)
# Historical VaR - uses actual return distribution
historical_var = calc.historical_var(confidence=0.99)
# Parametric VaR - assumes normal distribution
parametric_var = calc.parametric_var(confidence=0.99)
# Monte Carlo VaR - simulates price paths
monte_carlo_var = calc.monte_carlo_var(
confidence=0.99,
simulations=10000,
horizon=10
)Pre-built and custom stress scenarios:
from risk_engine.scenarios import ScenarioEngine
engine = ScenarioEngine(portfolio)
# Pre-built scenarios
results = engine.run_scenario("covid_march_2020")
results = engine.run_scenario("2008_financial_crisis")
results = engine.run_scenario("dot_com_bubble")
# Custom scenario
custom_shocks = {
"equity": -0.30, # 30% equity drop
"credit_spread": 200, # 200bps spread widening
"rates": -0.50, # 50bps rate cut
"fx_usd": 0.10 # 10% USD appreciation
}
results = engine.run_custom_scenario(custom_shocks)Exposure metrics for OTC derivatives:
from risk_engine.counterparty import CounterpartyRisk
cpty_risk = CounterpartyRisk(derivative_portfolio)
# Potential Future Exposure
pfe = cpty_risk.calculate_pfe(confidence=0.95, horizon=365)
# Credit Valuation Adjustment
cva = cpty_risk.calculate_cva(
counterparty_pd=0.02, # 2% probability of default
lgd=0.60 # 60% loss given default
)
# Exposure at Default
ead = cpty_risk.calculate_ead()Concentration and correlation analysis:
from risk_engine.analytics import PortfolioAnalytics
analytics = PortfolioAnalytics(portfolio)
# Sector concentration
sector_exposure = analytics.sector_concentration()
# Top N holdings
top_holdings = analytics.top_holdings(n=10)
# Correlation matrix
corr_matrix = analytics.correlation_matrix()
# Herfindahl-Hirschman Index (concentration)
hhi = analytics.calculate_hhi()from risk_engine import RiskReport
from datetime import date
report = RiskReport(portfolio, as_of_date=date.today())
# Generate comprehensive report
report.add_var_summary()
report.add_stress_tests()
report.add_concentration_analysis()
report.add_pnl_attribution()
report.export_html("reports/daily_risk_report.html")
report.export_pdf("reports/daily_risk_report.pdf")from risk_engine.backtest import VaRBacktest
backtest = VaRBacktest(
returns=historical_returns,
var_confidence=0.99,
lookback_window=250
)
results = backtest.run()
print(f"VaR Breaches: {results['breaches']}")
print(f"Breach Rate: {results['breach_rate']:.2%}")
print(f"Kupiec Test p-value: {results['kupiec_pvalue']:.4f}")
backtest.plot_breaches(save_path="reports/var_backtest.png")from risk_engine.simulation import MonteCarloSimulator
simulator = MonteCarloSimulator(
portfolio=portfolio,
num_simulations=10000,
horizon_days=252 # 1 year
)
paths = simulator.simulate()
# Analyze distribution of terminal values
terminal_values = paths[:, -1]
print(f"Expected Value: ${terminal_values.mean():,.2f}")
print(f"5th Percentile: ${np.percentile(terminal_values, 5):,.2f}")
print(f"95th Percentile: ${np.percentile(terminal_values, 95):,.2f}")
simulator.plot_paths(num_paths=100)Historical VaR:
VaR_Ξ± = -Percentile(returns, 1-Ξ±)
Parametric VaR:
VaR_Ξ± = ΞΌ - Ο Γ Ξ¦β»ΒΉ(Ξ±) Γ βt
Where Ξ¦β»ΒΉ is the inverse standard normal CDF.
Monte Carlo VaR:
1. Estimate return distribution parameters
2. Generate N simulated price paths
3. Calculate portfolio value for each path
4. VaR = percentile of simulated losses
CVA = LGD Γ Ξ£ EE(tα΅’) Γ PD(tα΅’ββ, tα΅’) Γ DF(tα΅’)
Where:
EE(t)= Expected Exposure at time tPD(tβ,tβ)= Probability of Default between tβ and tβDF(t)= Discount Factor to time tLGD= Loss Given Default
hedge-fund-credit-risk/
βββ README.md
βββ LICENSE
βββ requirements.txt
βββ setup.py
βββ risk_engine/
β βββ __init__.py
β βββ var.py # VaR calculations
β βββ scenarios.py # Stress testing
β βββ counterparty.py # Counterparty risk
β βββ analytics.py # Portfolio analytics
β βββ simulation.py # Monte Carlo
β βββ backtest.py # Model validation
β βββ report.py # Report generation
βββ data_loader/
β βββ __init__.py
β βββ portfolio.py # Portfolio loading
β βββ market_data.py # Market data fetching
βββ data/
β βββ sample_portfolio.csv
β βββ scenarios/
β βββ 2008_crisis.json
β βββ covid_2020.json
βββ tests/
β βββ test_var.py
β βββ test_scenarios.py
β βββ test_counterparty.py
βββ notebooks/
β βββ 01_var_analysis.ipynb
β βββ 02_stress_testing.ipynb
β βββ 03_cva_calculation.ipynb
βββ reports/
βββ .gitkeep
# Run all tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=risk_engine --cov-report=html
# Run specific test module
pytest tests/test_var.py -v- Historical VaR
- Parametric VaR
- Monte Carlo VaR
- Scenario Analysis
- Basic Reporting
- Expected Shortfall (ES/CVaR)
- Incremental VaR
- Component VaR
- Real-time risk streaming
- Integration with Bloomberg API
- FRTB-compliant calculations
- Hull, J.C. (2018). Risk Management and Financial Institutions
- Jorion, P. (2007). Value at Risk: The New Benchmark for Managing Financial Risk
- Gregory, J. (2020). The xVA Challenge: Counterparty Risk, Funding, Collateral, Capital and Initial Margin
- Basel Committee on Banking Supervision - Minimum capital requirements for market risk
Contributions welcome! Please read CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE for details.
Hatef Tabbakhian
MSc Economics & Finance | Risk & Quantitative Analysis