Value at Risk (VAR) system for crypto portfolio

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Value at Risk (VAR) system for crypto portfolio
Complex
~5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1218
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    853
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1047
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Development of VaR (Value at Risk) System for Crypto Portfolio

Value at Risk (VaR) is a statistical estimate of maximum portfolio loss over a specific time horizon with given probability. "VaR 95% on 1 day = $5,000" means: with 95% probability daily loss will not exceed $5,000 (and with 5% probability it will).

VaR Calculation Methods

Historical Simulation VaR — most common and intuitive:

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

class HistoricalVaR:
    def __init__(self, confidence_level=0.95, lookback_days=252):
        self.confidence = confidence_level
        self.lookback = lookback_days
    
    def calculate(self, portfolio_value, positions, price_history):
        """
        portfolio_value: current portfolio value
        positions: {symbol: qty}
        price_history: DataFrame with prices for lookback_days
        """
        # Calculate historical portfolio returns
        portfolio_returns = []
        for i in range(1, len(price_history)):
            daily_pnl = 0
            for symbol, qty in positions.items():
                if symbol in price_history.columns:
                    prev_price = price_history[symbol].iloc[i-1]
                    curr_price = price_history[symbol].iloc[i]
                    daily_pnl += qty * (curr_price - prev_price)
            portfolio_returns.append(daily_pnl / portfolio_value)
        
        portfolio_returns = np.array(portfolio_returns)
        
        # VaR = percentile of losses
        var_pct = np.percentile(portfolio_returns, (1 - self.confidence) * 100)
        var_usd = abs(var_pct) * portfolio_value
        
        return {
            'var_pct': var_pct,
            'var_usd': var_usd,
            'confidence': self.confidence,
            'horizon_days': 1
        }

Parametric (Variance-Covariance) VaR:

def parametric_var(positions, prices, cov_matrix, confidence=0.95, horizon=1):
    weights = np.array([positions[s] * prices[s] for s in positions.keys()])
    portfolio_value = weights.sum()
    weights_pct = weights / portfolio_value
    
    # Portfolio variance
    portfolio_variance = weights_pct @ cov_matrix @ weights_pct
    portfolio_std = np.sqrt(portfolio_variance * horizon)
    
    # Normal distribution: z-score for confidence level
    z_score = stats.norm.ppf(1 - confidence)
    var_pct = z_score * portfolio_std
    var_usd = abs(var_pct) * portfolio_value
    
    return var_usd

Monte Carlo VaR — most accurate for crypto portfolios (accounts for fat tails):

def monte_carlo_var(portfolio_value, returns_history, n_simulations=10000, 
                    confidence=0.95, horizon=1):
    mean = returns_history.mean()
    std = returns_history.std()
    
    # Simulate N scenarios
    simulated_returns = np.random.normal(mean, std, (n_simulations, horizon))
    simulated_pnl = portfolio_value * simulated_returns.sum(axis=1)
    
    var = np.percentile(simulated_pnl, (1 - confidence) * 100)
    return abs(var)

CVaR (Conditional Value at Risk / Expected Shortfall)

CVaR is average loss in worst (1 - confidence)% scenarios. Better than VaR for describing tail risk:

def calculate_cvar(returns, portfolio_value, confidence=0.95):
    var_threshold = np.percentile(returns, (1 - confidence) * 100)
    tail_returns = returns[returns <= var_threshold]
    cvar_pct = tail_returns.mean()
    return abs(cvar_pct) * portfolio_value

Fat Tails Problem in Crypto

Crypto market has significantly heavier "tails" of return distribution compared to normal distribution. Parametric VaR based on normal distribution significantly underestimates risk.

Solutions:

Student's t-distribution: better describes fat tails. Add degrees of freedom parameter:

from scipy.stats import t

def t_distribution_var(mean, std, df, confidence=0.95):
    t_score = t.ppf(1 - confidence, df)
    return abs(mean + std * t_score)

Historical distribution + EVT (Extreme Value Theory): for tails use generalized Pareto distribution.

GARCH-VaR: accounts for volatility clustering — high volatility periods follow high volatility.

Backtesting VaR (Kupiec Test)

Check: how often did actual losses exceed predicted VaR?

def kupiec_test(var_predictions, actual_returns, confidence=0.95):
    """
    If VaR 95% — violations should occur in 5% of cases
    """
    violations = actual_returns < -var_predictions
    n_violations = violations.sum()
    n_total = len(actual_returns)
    expected_violations = n_total * (1 - confidence)
    
    # Binomial test
    p_value = stats.binom_test(n_violations, n_total, 1 - confidence)
    
    return {
        'n_violations': n_violations,
        'expected_violations': expected_violations,
        'violation_rate': n_violations / n_total,
        'p_value': p_value,
        'model_valid': p_value > 0.05
    }

Multi-horizon VaR

VaR scales with horizon by square root of time (for normal distribution):

VaR(n days) = VaR(1 day) × √n

For crypto portfolio calculate VaR for several horizons:

Horizon Application
1 day Daily risk monitoring
7 days Weekly report
30 days Stress testing

Component VaR

Marginal VaR: contribution of each position to overall portfolio VaR. Identifies positions adding most risk.

def component_var(positions, cov_matrix, portfolio_var):
    """Contribution of each position to overall VaR"""
    weights = np.array(list(positions.values()))
    weights_pct = weights / weights.sum()
    
    # Marginal contribution
    marginal = cov_matrix @ weights_pct / portfolio_var
    component = weights_pct * marginal
    
    return dict(zip(positions.keys(), component))

Dashboard and Reporting

Realtime VaR monitor: recalculation on each position change or weekly with rolling covariance.

Daily VaR Report:

  • Current 1-day VaR (95% and 99%)
  • CVaR (Expected Shortfall)
  • VaR breakdown by assets
  • Backtesting: violations for last 30 days

Alerts: if current VaR exceeds limit (e.g., VaR 99% > 5% of capital) → Telegram alert.

We develop VaR system with historical, parametric and Monte Carlo methods, fat-tail correction, backtesting module (Kupiec test) and daily reporting.