# How the Unified Risk Engine Computes VaR and CVaR in CloddsBot

> Learn how CloddsBot's unified risk engine computes VaR and CVaR with rolling windows, historical percentiles, and Gaussian models for real-time risk metrics.

- Repository: [AL/CloddsBot](https://github.com/alsk1992/CloddsBot)
- Tags: deep-dive
- Published: 2026-09-14

---

**CloddsBot's unified risk engine calculates Value-at-Risk (VaR) and Conditional VaR (CVaR) using a rolling window of profit-and-loss data, applying both historical percentile methods and parametric Gaussian models to deliver real-time portfolio risk metrics.**

The `alsk1992/CloddsBot` repository implements a sophisticated risk management system that monitors trading exposure through dedicated statistical modules. This engine processes profit-and-loss histories to compute risk metrics that drive automated circuit-breaker decisions, preventing trades that would exceed configured risk thresholds.

## Architecture of the Unified Risk Engine

### The VaR Calculator Module

The core calculations reside in [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts), which exports the **`createVaRCalculator`** factory function. This module maintains a rolling window of P&L records and exposes the **`calculateAt`** method for retrieving risk metrics at specified confidence levels.

In [`src/risk/engine.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/engine.ts), the risk engine instantiates the calculator during initialization with a configurable window size (defaulting to 100 observations). Line 158 creates the calculator instance, while line 290 invokes the calculation logic to enforce VaR limits against user-defined thresholds during trade evaluation.

### P&L Data Management

The calculator stores the last `windowSize` P&L values in memory, updating the rolling window whenever new trades are recorded. This data structure enables rapid recalculation of risk metrics without reprocessing entire historical datasets, ensuring low-latency risk checks during active trading sessions.

## VaR and CVaR Calculation Methods

### Historical VaR (Percentile-Based)

The engine computes **historical VaR** by sorting the P&L array in ascending order at line 165 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts). It then extracts the loss at the target percentile—for 95% confidence, this represents the 5th percentile worst loss observed in the window. The sign is flipped to return a positive dollar amount, ensuring VaR represents potential portfolio loss rather than negative return values.

### Parametric VaR (Gaussian Approach)

For **parametric VaR**, the calculator assumes normally distributed returns. It computes the mean and standard deviation of the P&L series, then applies the formula `-(mean - z × σ)` where `z` represents the z-score for the confidence level (e.g., 1.645 for 95%). This implementation appears at line 171 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts), providing a model-based alternative to the empirical historical method.

### CVaR (Expected Shortfall)

**Conditional VaR** measures tail risk by averaging all losses that exceed the VaR threshold. Lines 175-179 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts) isolate the "tail" events beyond the calculated VaR percentile and compute their mean. This **Expected Shortfall** metric indicates the average loss severity should the portfolio breach the VaR level, offering deeper insight into extreme downside scenarios.

## Practical Implementation

### Portfolio-Level Risk Queries

The engine exposes consolidated risk metrics through the `calculateAt` method. The following example demonstrates retrieving VaR and CVaR at the 95% confidence level:

```typescript
import { RiskEngine } from '@/risk/engine';

const engine = new RiskEngine(/* config */);
const { historicalVaR, parametricVaR, cvar } = engine.getVaRCalculator().calculateAt(0.95);

console.log(`Historical VaR (95%): $${historicalVaR.toFixed(2)}`);
console.log(`Parametric VaR (95%): $${parametricVaR.toFixed(2)}`);
console.log(`CVaR/Expected Shortfall: $${cvar.toFixed(2)}`);

```

### Per-Position Risk Analysis

The calculator provides position-level granularity through the **`positionVaR`** method. Lines 212-220 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts) apply historical VaR logic to individual position P&L slices and calculate contribution ratios to total portfolio risk:

```typescript
const positionVaRs = engine.getVaRCalculator().positionVaR();

positionVaRs.forEach(position => {
  console.log(
    `${position.id}: VaR $${position.var.toFixed(2)} ` +
    `(contribution: ${(position.contribution * 100).toFixed(1)}%)`
  );
});

```

### Result Packaging

The calculator returns a **`VaRResult`** object containing historical VaR, parametric VaR, and CVaR values. Any negative values are clamped to zero (lines 179-180 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts)), ensuring risk metrics represent actual potential loss exposures rather than statistical artifacts or data errors.

## Summary

- The unified risk engine in `alsk1992/CloddsBot` computes **Value-at-Risk** using both historical percentile and parametric Gaussian methods via [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts).
- **Conditional VaR** (Expected Shortfall) is calculated as the average of tail losses exceeding the VaR threshold, implemented at lines 175-179.
- The `createVaRCalculator` function maintains a rolling window of P&L data (default 100 records) integrated through [`src/risk/engine.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/engine.ts).
- Risk metrics drive circuit-breaker logic by comparing calculated VaR against configurable limits at lines 158 and 290 of the engine implementation.
- Per-position VaR analysis enables granular risk attribution and contribution analysis for portfolio diversification insights.

## Frequently Asked Questions

### What is the default window size for P&L history in CloddsBot?

The default **window size** is 100 records, configurable through the `varWindowSize` parameter in the risk engine configuration. This rolling window determines how many historical profit-and-loss observations factor into VaR calculations, with older observations discarded as new trades arrive.

### How does CloddsBot handle negative VaR values?

The calculator clamps negative values to zero when packaging results into the `VaRResult` object at lines 179-180 of [`src/risk/var.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/var.ts). This ensures that risk metrics represent actual potential loss exposures rather than statistical artifacts or profitable tail scenarios.

### What confidence levels does the parametric VaR method support?

The parametric method supports any confidence level mapped to standard normal distribution z-scores, with 95% (z ≈ 1.645) being the system default. The implementation at line 171 dynamically calculates the appropriate z-score for the requested confidence level passed to the `calculateAt` method.

### Can the risk engine reject trades based on VaR limits?

Yes. In [`src/risk/engine.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/risk/engine.ts) at line 290, the engine queries `currentVaR.historicalVaR` and compares it against user-defined VaR limits. If the calculated risk exceeds the threshold, the circuit-breaker logic rejects the trade to prevent excessive portfolio exposure, utilizing the unified risk engine's real-time computation capabilities.