Portfolio Risk Engine
Problem Description
Given N assets with portfolio weights and D days of historical returns, compute comprehensive portfolio risk metrics. Calculate portfolio volatility, Sharpe ratio, Value-at-Risk (VaR) and Conditional VaR (CVaR) at 95% and 99% confidence levels, maximum drawdown, and the full asset correlation matrix.
Output 7 scalar metrics followed by the upper triangle of the N x N correlation matrix.
Tier System & Performance Targets
| LANGUAGE | GOLD | SILVER | BRONZE |
|---|---|---|---|
| C++ / Rust | < 500ms | < 2000ms | < 8000ms |
| Java | < 1000ms | < 4000ms | < 15000ms |
| Python | < 5000ms | < 15000ms | < 60000ms |
Evaluation Criteria
Correctness: The first 7 scalar metrics are compared with tolerance 0.001. Correlation matrix values use tolerance 0.01. All values must be within tolerance to pass.
Performance: Wall-clock time to compute all metrics determines tier placement.
Input Format
Read from stdin. The first line contains two integers N D (number of assets and number of days). The second line contains N space-separated portfolio weights. The next D lines each contain N space-separated daily returns:
N D
w1 w2 ... wN
r1_1 r1_2 ... r1_N
r2_1 r2_2 ... r2_N
...
rD_1 rD_2 ... rD_N
Where:
N: Number of assets in the portfolioD: Number of historical trading daysw1..wN: Portfolio weights (floats, sum to 1.0)r_d_n: Daily return for asset n on day d (float)
Output Format
Output 7 scalar metrics (one per line, 6 decimal places), followed by the upper triangle of the N x N correlation matrix (one row per line, space-separated, 6 decimal places):
PORTFOLIO_VOLATILITY
SHARPE_RATIO
VAR_95
VAR_99
CVAR_95
CVAR_99
MAX_DRAWDOWN
corr_1_1 corr_1_2 ... corr_1_N
corr_2_2 corr_2_3 ... corr_2_N
...
corr_N_N
Where:
PORTFOLIO_VOLATILITY: Annualized portfolio volatilitySHARPE_RATIO: Annualized Sharpe ratioVAR_95, VAR_99: Value-at-Risk at 95% and 99% confidenceCVAR_95, CVAR_99: Conditional VaR at 95% and 99%MAX_DRAWDOWN: Maximum peak-to-trough drawdown- Correlation matrix: upper triangle of the N x N asset correlation matrix
Example
Input
3 5
0.4 0.35 0.25
0.01 0.02 -0.005
-0.005 0.01 0.015
0.02 -0.01 0.005
-0.01 0.005 0.02
0.015 0.008 -0.01
Output
0.145200
1.250000
-0.012500
-0.018000
-0.015000
-0.020000
0.008500
1.000000 -0.650000 0.120000
1.000000 -0.350000
1.000000
Lines 1-7: Portfolio volatility, Sharpe, VaR95, VaR99, CVaR95, CVaR99, max drawdown. Lines 8-10: Upper triangle of the 3x3 correlation matrix.
Submission Rules
- Your program receives input via stdin
- Output 7 metric lines + correlation matrix to stdout (all values to 6 decimal places)
- Program must complete within 120 seconds
- Memory usage must not exceed 2GB
- Single-file solutions only
- Java class must be named
Solution
Starter Templates
C++
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
int main() {
int N, D;
scanf("%d %d", &N, &D);
std::vector<double> weights(N);
for (int i = 0; i < N; i++) scanf("%lf", &weights[i]);
std::vector<std::vector<double>> returns(D, std::vector<double>(N));
for (int d = 0; d < D; d++)
for (int n = 0; n < N; n++)
scanf("%lf", &returns[d][n]);
// Compute portfolio daily returns
// Calculate volatility, Sharpe, VaR, CVaR, max drawdown
// Build correlation matrix
double vol = 0, sharpe = 0, var95 = 0, var99 = 0;
double cvar95 = 0, cvar99 = 0, max_dd = 0;
printf("%.6f\n", vol);
printf("%.6f\n", sharpe);
printf("%.6f\n", var95);
printf("%.6f\n", var99);
printf("%.6f\n", cvar95);
printf("%.6f\n", cvar99);
printf("%.6f\n", max_dd);
// Output upper triangle of correlation matrix
// Each row i outputs corr[i][i], corr[i][i+1], ..., corr[i][N-1]
return 0;
}
Python
import sys
import math
line1 = input().split()
N, D = int(line1[0]), int(line1[1])
weights = list(map(float, input().split()))
returns = []
for _ in range(D):
row = list(map(float, input().split()))
returns.append(row)
# Compute portfolio daily returns: port_ret[d] = sum(w[i] * ret[d][i])
port_returns = []
for d in range(D):
pr = sum(weights[i] * returns[d][i] for i in range(N))
port_returns.append(pr)
# Calculate: volatility, Sharpe, VaR95, VaR99, CVaR95, CVaR99, max drawdown
# Build NxN correlation matrix from asset returns
vol = 0.0
sharpe = 0.0
var95 = 0.0
var99 = 0.0
cvar95 = 0.0
cvar99 = 0.0
max_dd = 0.0
print(f"{vol:.6f}")
print(f"{sharpe:.6f}")
print(f"{var95:.6f}")
print(f"{var99:.6f}")
print(f"{cvar95:.6f}")
print(f"{cvar99:.6f}")
print(f"{max_dd:.6f}")
# Output upper triangle of correlation matrix
# Row i: corr[i][i], corr[i][i+1], ..., corr[i][N-1]
Rust
use std::io::{self, BufRead, Write, BufWriter};
fn main() {
let stdin = io::stdin();
let stdout = io::stdout();
let mut out = BufWriter::new(stdout.lock());
let mut lines = stdin.lock().lines();
let first: Vec<usize> = lines.next().unwrap().unwrap().trim()
.split_whitespace().map(|x| x.parse().unwrap()).collect();
let (n, d) = (first[0], first[1]);
let weights: Vec<f64> = lines.next().unwrap().unwrap().trim()
.split_whitespace().map(|x| x.parse().unwrap()).collect();
let mut returns = Vec::with_capacity(d);
for _ in 0..d {
let row: Vec<f64> = lines.next().unwrap().unwrap().trim()
.split_whitespace().map(|x| x.parse().unwrap()).collect();
returns.push(row);
}
// Compute portfolio returns, risk metrics, correlation matrix
let (vol, sharpe, var95, var99, cvar95, cvar99, max_dd) = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
writeln!(out, "{:.6}", vol).unwrap();
writeln!(out, "{:.6}", sharpe).unwrap();
writeln!(out, "{:.6}", var95).unwrap();
writeln!(out, "{:.6}", var99).unwrap();
writeln!(out, "{:.6}", cvar95).unwrap();
writeln!(out, "{:.6}", cvar99).unwrap();
writeln!(out, "{:.6}", max_dd).unwrap();
// Output upper triangle of correlation matrix
}
Java
import java.util.*;
import java.io.*;
public class Solution {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int D = Integer.parseInt(st.nextToken());
double[] weights = new double[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) weights[i] = Double.parseDouble(st.nextToken());
double[][] returns = new double[D][N];
for (int d = 0; d < D; d++) {
st = new StringTokenizer(br.readLine());
for (int n = 0; n < N; n++) returns[d][n] = Double.parseDouble(st.nextToken());
}
// Compute portfolio returns, risk metrics, correlation matrix
double vol = 0, sharpe = 0, var95 = 0, var99 = 0;
double cvar95 = 0, cvar99 = 0, maxDd = 0;
System.out.printf("%.6f%n", vol);
System.out.printf("%.6f%n", sharpe);
System.out.printf("%.6f%n", var95);
System.out.printf("%.6f%n", var99);
System.out.printf("%.6f%n", cvar95);
System.out.printf("%.6f%n", cvar99);
System.out.printf("%.6f%n", maxDd);
// Output upper triangle of correlation matrix
}
}