import numpy as np
import pandas as pd
from scipy import stats

# Load data
df = pd.read_csv("portfolio_returns.csv", parse_dates=["date"], index_col="date")
port_ret = df["portfolio_return"]
bench_ret = df["benchmark_return"]

rf_rate = 0.02
ann_factor = 252
n_days = len(port_ret)

# --- Returns ---
total_return = (1 + port_ret).prod() - 1
annual_return = (1 + port_ret).prod() ** (ann_factor / n_days) - 1
bench_total = (1 + bench_ret).prod() - 1
bench_annual = (1 + bench_ret).prod() ** (ann_factor / n_days) - 1

# --- Volatility ---
annual_vol = port_ret.std() * np.sqrt(ann_factor)
bench_vol = bench_ret.std() * np.sqrt(ann_factor)
downside = port_ret[port_ret < 0]
downside_dev = downside.std() * np.sqrt(ann_factor)

# --- Beta & Correlation ---
cov_matrix = np.cov(port_ret, bench_ret)
beta = cov_matrix[0, 1] / cov_matrix[1, 1]
correlation = port_ret.corr(bench_ret)

# --- VaR ---
var_95_hist = -np.percentile(port_ret, 5)
var_99_hist = -np.percentile(port_ret, 1)
z95 = stats.norm.ppf(0.95)
var_95_param = -(port_ret.mean() - z95 * port_ret.std())

# Cornish-Fisher VaR
z = z95
s = stats.skew(port_ret)
k = stats.kurtosis(port_ret)
z_cf = z + (z**2 - 1) * s / 6 + (z**3 - 3*z) * k / 24 - (2*z**3 - 5*z) * s**2 / 36
var_95_cf = -(port_ret.mean() + z_cf * port_ret.std())

# --- CVaR (Expected Shortfall) ---
cvar_95 = -port_ret[port_ret <= -var_95_hist].mean()

# --- Drawdown ---
cumulative = (1 + port_ret).cumprod()
running_max = cumulative.cummax()
drawdowns = (cumulative - running_max) / running_max
max_dd = drawdowns.min()
max_dd_date = drawdowns.idxmin()
avg_dd = drawdowns[drawdowns < 0].mean()

# Drawdown duration
in_dd = drawdowns < 0
durations = []
current = 0
for v in in_dd:
    if v:
        current += 1
    elif current > 0:
        durations.append(current)
        current = 0
if current > 0:
    durations.append(current)
max_dd_duration = max(durations) if durations else 0
avg_dd_duration = np.mean(durations) if durations else 0

# --- Risk-Adjusted Returns ---
excess = port_ret.mean() * ann_factor - rf_rate
sharpe = excess / annual_vol
sortino = excess / downside_dev
calmar = annual_return / abs(max_dd) if max_dd != 0 else 0

returns_above = port_ret[port_ret > 0]
returns_below = port_ret[port_ret <= 0]
omega = returns_above.sum() / (-returns_below.sum()) if returns_below.sum() != 0 else np.inf

# --- Benchmark-relative ---
active_ret = port_ret - bench_ret
tracking_error = active_ret.std() * np.sqrt(ann_factor)
active_annual = active_ret.mean() * ann_factor
info_ratio = active_annual / tracking_error if tracking_error > 0 else 0

# --- Distribution ---
skewness = stats.skew(port_ret)
kurt = stats.kurtosis(port_ret)

# --- Recent performance (last 5, 10, 20 days) ---
def period_stats(ret, n):
    r = ret.iloc[-n:]
    return {
        "return": (1 + r).prod() - 1,
        "vol_ann": r.std() * np.sqrt(252),
        "sharpe": (r.mean() * 252 - rf_rate) / (r.std() * np.sqrt(252)) if r.std() > 0 else 0,
    }

last5 = period_stats(port_ret, 5)
last10 = period_stats(port_ret, 10)
last20 = period_stats(port_ret, 20)

# ============ PRINT REPORT ============
print("=" * 62)
print("  FLAGSHIP ALLOCATION - RISK SNAPSHOT")
print(f"  Period: {port_ret.index[0].date()} to {port_ret.index[-1].date()} ({n_days} trading days)")
print(f"  Report date: 2026-04-11")
print("=" * 62)

print("\n--- RETURN SUMMARY ---")
print(f"  {'Metric':<30} {'Portfolio':>12} {'Benchmark':>12}")
print(f"  {'-'*54}")
print(f"  {'Total Return':<30} {total_return:>11.2%} {bench_total:>12.2%}")
print(f"  {'Annualized Return':<30} {annual_return:>11.2%} {bench_annual:>12.2%}")
print(f"  {'Active Return (ann.)':<30} {active_annual:>11.2%} {'':>12}")

print("\n--- VOLATILITY & MARKET SENSITIVITY ---")
print(f"  Annual Volatility:           {annual_vol:>10.2%}   (Bench: {bench_vol:.2%})")
print(f"  Downside Deviation:          {downside_dev:>10.2%}")
print(f"  Beta:                        {beta:>10.3f}")
print(f"  Correlation to Benchmark:    {correlation:>10.3f}")
print(f"  Tracking Error:              {tracking_error:>10.2%}")

print("\n--- VALUE AT RISK (daily) ---")
print(f"  Historical VaR (95%):        {var_95_hist:>10.2%}")
print(f"  Historical VaR (99%):        {var_99_hist:>10.2%}")
print(f"  Parametric VaR (95%):        {var_95_param:>10.2%}")
print(f"  Cornish-Fisher VaR (95%):    {var_95_cf:>10.2%}")
print(f"  CVaR / Expected Shortfall:   {cvar_95:>10.2%}")

print("\n--- DRAWDOWN ANALYSIS ---")
print(f"  Max Drawdown:                {max_dd:>10.2%}   (on {max_dd_date.date()})")
print(f"  Avg Drawdown:                {avg_dd:>10.2%}")
print(f"  Max DD Duration:             {max_dd_duration:>10d} days")
print(f"  Avg DD Duration:             {avg_dd_duration:>10.1f} days")
print(f"  Currently in Drawdown:       {'Yes' if drawdowns.iloc[-1] < 0 else 'No':>10}")
if drawdowns.iloc[-1] < 0:
    print(f"  Current Drawdown:            {drawdowns.iloc[-1]:>10.2%}")

print("\n--- RISK-ADJUSTED PERFORMANCE ---")
print(f"  Sharpe Ratio:                {sharpe:>10.3f}")
print(f"  Sortino Ratio:               {sortino:>10.3f}")
print(f"  Calmar Ratio:                {calmar:>10.3f}")
print(f"  Omega Ratio:                 {omega:>10.3f}")
print(f"  Information Ratio:           {info_ratio:>10.3f}")

print("\n--- RETURN DISTRIBUTION ---")
print(f"  Skewness:                    {skewness:>10.3f}")
print(f"  Excess Kurtosis:             {kurt:>10.3f}")
print(f"  Best Day:                    {port_ret.max():>10.2%}   ({port_ret.idxmax().date()})")
print(f"  Worst Day:                   {port_ret.min():>10.2%}   ({port_ret.idxmin().date()})")
print(f"  % Positive Days:             {(port_ret > 0).mean():>10.1%}")

print("\n--- RECENT WINDOWS ---")
print(f"  {'Window':<12} {'Return':>10} {'Vol (ann)':>12} {'Sharpe':>10}")
print(f"  {'-'*44}")
print(f"  {'Last 5d':<12} {last5['return']:>10.2%} {last5['vol_ann']:>12.2%} {last5['sharpe']:>10.3f}")
print(f"  {'Last 10d':<12} {last10['return']:>10.2%} {last10['vol_ann']:>12.2%} {last10['sharpe']:>10.3f}")
print(f"  {'Last 20d':<12} {last20['return']:>10.2%} {last20['vol_ann']:>12.2%} {last20['sharpe']:>10.3f}")
print(f"  {'Full Period':<12} {total_return:>10.2%} {annual_vol:>12.2%} {sharpe:>10.3f}")

print("\n" + "=" * 62)
