> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doomberg.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Computed Analytics Skills

> Reference for correlation.matrix, factor.exposures, dcf.value, portfolio.optimize, montecarlo.simulate, scenario.project, risk.stress, tearsheet, walkforward.run, technical.indicators, seasonality.monthly, and seasonality.heatmap — the computed analytics skills exposed to AI agents.

Computed analytics skills run trusted numpy/pandas code over archive closes or agent-supplied inputs to produce derived metrics. They never execute agent-authored code. Every result includes the [provenance envelope](/skills/overview#the-provenance-envelope) with `source: "computed"` or `source: "archive-community"` when the skill reads closes.

<Callout type="info">
  Skills that read closes pull them from the archive by `symbol` — you don't pass a price series. Skills marked **agent-supplied** take inputs directly (e.g. cash flows for DCF).
</Callout>

## Skill summary

| Skill ID               | Tool name              | Source            | Runtime      | Description                                    |
| ---------------------- | ---------------------- | ----------------- | ------------ | ---------------------------------------------- |
| `correlation.matrix`   | `correlation_matrix`   | archive-community | scan         | Rolling correlation matrix for a ticker set    |
| `factor.exposures`     | `factor_exposures`     | archive-community | interactive  | Style factor loadings                          |
| `dcf.value`            | `dcf_value`            | computed          | interactive  | Discounted cash flow valuation                 |
| `portfolio.optimize`   | `portfolio_optimize`   | archive-community | optimization | Mean-variance / risk-parity optimization       |
| `montecarlo.simulate`  | `montecarlo_simulate`  | archive-community | optimization | Path simulation for a portfolio or strategy    |
| `scenario.project`     | `scenario_project`     | computed          | interactive  | Project returns under a named scenario         |
| `risk.stress`          | `risk_stress`          | archive-community | backtest     | Stress-test P\&L under historical shocks       |
| `tearsheet`            | `tearsheet`            | archive-community | backtest     | Full performance tearsheet                     |
| `walkforward.run`      | `walkforward_run`      | archive-community | backtest     | Walk-forward optimization over a strategy spec |
| `technical.indicators` | `technical_indicators` | archive-community | interactive  | RSI, MACD, ATR, Bollinger, etc.                |
| `seasonality.monthly`  | `seasonality_monthly`  | archive-community | interactive  | Average monthly returns over N years           |
| `seasonality.heatmap`  | `seasonality_heatmap`  | archive-community | backtest     | Day/month return heatmap                       |

***

## correlation.matrix

Rolling correlation matrix for a set of tickers, computed from archive closes.

**Arguments**

| Name      | Type      | Required | Default   | Description              |
| --------- | --------- | -------- | --------- | ------------------------ |
| `symbols` | string\[] | yes      | —         | Tickers (2–50)           |
| `window`  | int       | no       | `60`      | Lookback in trading days |
| `as_of`   | ISO date  | no       | latest    | End date                 |
| `method`  | string    | no       | `pearson` | `pearson` or `spearman`  |

**What it computes**: pairwise correlation of log returns over the trailing `window`.

**Example**

```json theme={null}
correlation_matrix({ "symbols": ["SPY","QQQ","IWM","TLT","GLD"], "window": 60 })
```

```json theme={null}
{
  "skill_id": "correlation.matrix",
  "data": {
    "as_of": "2025-06-27", "window": 60, "method": "pearson",
    "matrix": {
      "SPY": { "SPY": 1.00, "QQQ": 0.94, "IWM": 0.86, "TLT": -0.32, "GLD": 0.12 },
      "QQQ": { "SPY": 0.94, "QQQ": 1.00, "IWM": 0.78, "TLT": -0.28, "GLD": 0.10 }
    }
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 3, "tier": "basic" }, "warnings": [] }
}
```

***

## factor.exposures

Style factor loadings — momentum, value, quality, size, low-vol, growth — for a ticker or portfolio.

**Arguments**

| Name            | Type      | Required                  | Default  | Description                               |
| --------------- | --------- | ------------------------- | -------- | ----------------------------------------- |
| `symbol`        | string    | one of `symbol`/`weights` | —        | Single ticker                             |
| `weights`       | object    | one of `symbol`/`weights` | —        | Map of `{symbol: weight}` for a portfolio |
| `as_of`         | ISO date  | no                        | latest   | Snapshot date                             |
| `lookback_days` | int       | no                        | `252`    | Factor model window                       |
| `factors`       | string\[] | no                        | core set | Factor names                              |

**What it computes**: rolling regression of ticker returns against factor returns.

**Example**

```json theme={null}
factor_exposures({ "symbol": "NVDA", "factors": ["momentum","value","quality","growth","size","low_vol"] })
```

```json theme={null}
{
  "skill_id": "factor.exposures",
  "data": {
    "symbol": "NVDA", "as_of": "2025-06-27",
    "exposures": { "momentum": 1.42, "growth": 1.18, "quality": 0.62, "value": -0.81, "size": 0.74, "low_vol": -0.92 },
    "r_squared": 0.68
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 3, "tier": "basic" }, "warnings": [] }
}
```

***

## dcf.value

Discounted cash flow valuation. **Agent-supplied** cash flows.

**Arguments**

| Name                 | Type     | Required | Default | Description                    |
| -------------------- | -------- | -------- | ------- | ------------------------------ |
| `cash_flows`         | float\[] | yes      | —       | Projected annual cash flows    |
| `terminal_growth`    | float    | no       | `0.02`  | Perpetual growth rate          |
| `discount_rate`      | float    | no       | `0.10`  | WACC                           |
| `shares_outstanding` | float    | no       | —       | For per-share value            |
| `net_debt`           | float    | no       | `0`     | Subtract from enterprise value |

**What it computes**: NPV of cash flows + terminal value (Gordon growth), minus net debt, divided by shares.

**Example**

```json theme={null}
dcf_value({ "cash_flows": [5000,6000,7200,8500,10000], "terminal_growth": 0.02, "discount_rate": 0.09, "shares_outstanding": 25000, "net_debt": 8000 })
```

```json theme={null}
{
  "skill_id": "dcf.value",
  "data": {
    "enterprise_value": 142000, "equity_value": 134000,
    "per_share_value": 5.36, "terminal_value_pct": 0.62
  },
  "provenance": { "source": "computed", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 1, "tier": "free" }, "warnings": ["cash_flows agent-supplied; not validated against filings"] }
}
```

***

## portfolio.optimize

Mean-variance or risk-parity optimization for a set of tickers. Runs under the **optimization** profile (14,400 s).

**Arguments**

| Name             | Type      | Required | Default      | Description                                               |
| ---------------- | --------- | -------- | ------------ | --------------------------------------------------------- |
| `symbols`        | string\[] | yes      | —            | Tickers (2–30)                                            |
| `objective`      | string    | no       | `max_sharpe` | `max_sharpe`, `min_variance`, `risk_parity`, `max_return` |
| `risk_free_rate` | float     | no       | `0.045`      | For Sharpe                                                |
| `lookback_days`  | int       | no       | `252`        | Covariance window                                         |
| `constraints`    | object    | no       | —            | `{min_weight, max_weight, long_only, sector_caps}`        |
| `as_of`          | ISO date  | no       | latest       | Snapshot date                                             |

**What it computes**: solves the selected objective over the covariance matrix from archive closes.

**Example**

```json theme={null}
portfolio_optimize({ "symbols": ["SPY","QQQ","TLT","GLD","VNQ"], "objective": "max_sharpe", "lookback_days": 252 })
```

```json theme={null}
{
  "skill_id": "portfolio.optimize",
  "data": {
    "objective": "max_sharpe", "as_of": "2025-06-27",
    "weights": { "SPY": 0.32, "QQQ": 0.28, "TLT": 0.18, "GLD": 0.12, "VNQ": 0.10 },
    "expected_return": 0.112, "expected_vol": 0.121, "expected_sharpe": 0.55
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 8, "tier": "pro" }, "warnings": [] }
}
```

***

## montecarlo.simulate

Path simulation for a portfolio or strategy spec. Runs under the **optimization** profile.

**Arguments**

| Name           | Type      | Required | Default      | Description                  |
| -------------- | --------- | -------- | ------------ | ---------------------------- |
| `symbols`      | string\[] | yes      | —            | Tickers                      |
| `weights`      | float\[]  | yes      | —            | Portfolio weights            |
| `horizon_days` | int       | no       | `252`        | Simulation horizon           |
| `n_paths`      | int       | no       | `10000`      | Number of paths              |
| `method`       | string    | no       | `historical` | `historical` or `parametric` |
| `as_of`        | ISO date  | no       | latest       | Start date                   |

**What it computes**: bootstraps or parametrically simulates portfolio return paths; returns percentile bands and terminal distribution.

**Example**

```json theme={null}
montecarlo_simulate({ "symbols": ["SPY","TLT"], "weights": [0.6,0.4], "horizon_days": 252, "n_paths": 10000 })
```

```json theme={null}
{
  "skill_id": "montecarlo.simulate",
  "data": {
    "horizon_days": 252, "n_paths": 10000,
    "terminal_return": { "p5": -0.18, "p25": 0.02, "p50": 0.09, "p75": 0.17, "p95": 0.31 },
    "max_drawdown": { "p50": -0.08, "p95": -0.21 },
    "prob_loss": 0.22
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 10, "tier": "pro" }, "warnings": [] }
}
```

***

## scenario.project

Project returns under a named scenario (e.g. `rate_hike_2022`, `covid_crash_2020`). **Agent-supplied** shocks applied to a portfolio.

**Arguments**

| Name        | Type   | Required | Default | Description                         |
| ----------- | ------ | -------- | ------- | ----------------------------------- |
| `scenario`  | string | yes      | —       | Named scenario or `custom`          |
| `shocks`    | object | no       | —       | For `custom`: `{symbol: shock_pct}` |
| `portfolio` | object | yes      | —       | `{symbol: weight}`                  |

**What it computes**: applies scenario shocks to the portfolio and returns projected P\&L.

**Example**

```json theme={null}
scenario_project({ "scenario": "rate_hike_2022", "portfolio": { "SPY": 0.6, "TLT": 0.4 } })
```

```json theme={null}
{
  "skill_id": "scenario.project",
  "data": {
    "scenario": "rate_hike_2022",
    "portfolio_pnl_pct": -0.082,
    "by_symbol": { "SPY": -0.064, "TLT": -0.109 }
  },
  "provenance": { "source": "computed", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 2, "tier": "basic" }, "warnings": [] }
}
```

***

## risk.stress

Stress-test P\&L under historical shocks (2008 GFC, 2020 COVID, 2022 rate hike, etc.). Reads archive closes.

**Arguments**

| Name        | Type      | Required | Default | Description            |
| ----------- | --------- | -------- | ------- | ---------------------- |
| `portfolio` | object    | yes      | —       | `{symbol: weight}`     |
| `scenarios` | string\[] | no       | all     | Named stress scenarios |
| `as_of`     | ISO date  | no       | latest  | Snapshot date          |

**What it computes**: replays each historical shock window over the portfolio's current holdings.

**Example**

```json theme={null}
risk_stress({ "portfolio": { "SPY": 0.7, "QQQ": 0.3 }, "scenarios": ["gfc_2008","covid_2020"] })
```

```json theme={null}
{
  "skill_id": "risk.stress",
  "data": {
    "results": [
      { "scenario": "gfc_2008", "window": "2008-09-15 to 2009-03-09", "pnl_pct": -0.42, "max_drawdown": -0.48 },
      { "scenario": "covid_2020", "window": "2020-02-19 to 2020-03-23", "pnl_pct": -0.31, "max_drawdown": -0.34 }
    ]
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 5, "tier": "basic" }, "warnings": [] }
}
```

***

## tearsheet

Full performance tearsheet — returns, drawdowns, risk ratios — for a ticker or portfolio. Runs under the **backtest** profile.

**Arguments**

| Name             | Type     | Required                  | Default    | Description        |
| ---------------- | -------- | ------------------------- | ---------- | ------------------ |
| `symbol`         | string   | one of `symbol`/`weights` | —          | Single ticker      |
| `weights`        | object   | one of `symbol`/`weights` | —          | Portfolio weights  |
| `benchmark`      | string   | no                        | `SPY`      | Benchmark symbol   |
| `from`           | ISO date | no                        | `now - 5y` | Start date         |
| `to`             | ISO date | no                        | latest     | End date           |
| `risk_free_rate` | float    | no                        | `0.045`    | For Sharpe/Sortino |

**What it computes**: CAGR, vol, Sharpe, Sortino, max drawdown, Calmar, win rate, monthly returns table, drawdown series.

**Example**

```json theme={null}
tearsheet({ "symbol": "QQQ", "benchmark": "SPY", "from": "2020-01-01" })
```

```json theme={null}
{
  "skill_id": "tearsheet",
  "data": {
    "symbol": "QQQ", "benchmark": "SPY", "from": "2020-01-01", "to": "2025-06-27",
    "cagr": 0.182, "vol": 0.221, "sharpe": 0.62, "sortino": 0.85,
    "max_drawdown": -0.32, "calmar": 0.57, "win_rate": 0.55,
    "alpha_vs_benchmark": 0.041, "beta_vs_benchmark": 1.12
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 5, "tier": "basic" }, "warnings": [] }
}
```

***

## walkforward.run

Walk-forward optimization over a strategy spec. Runs under the **backtest** profile.

**Arguments**

| Name           | Type   | Required | Default | Description                                |
| -------------- | ------ | -------- | ------- | ------------------------------------------ |
| `strategy_id`  | string | yes      | —       | Strategy spec ID (from `propose_strategy`) |
| `train_window` | int    | no       | `252`   | Training window (days)                     |
| `test_window`  | int    | no       | `63`    | Out-of-sample test window                  |
| `step`         | int    | no       | `63`    | Rebalance step                             |
| `param_grid`   | object | no       | —       | Parameter grid to search                   |

**What it computes**: rolls train/test windows, optimizes on train, evaluates on test, aggregates OOS performance.

**Example**

```json theme={null}
walkforward_run({ "strategy_id": "strat_abc123", "train_window": 252, "test_window": 63 })
```

```json theme={null}
{
  "skill_id": "walkforward.run",
  "data": {
    "strategy_id": "strat_abc123",
    "n_folds": 12,
    "oos_cagr": 0.094, "oos_sharpe": 0.51, "oos_max_drawdown": -0.18,
    "is_oos_decay": 0.32
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 12, "tier": "pro" }, "warnings": [] }
}
```

***

## technical.indicators

Standard technical indicators from archive closes — RSI, MACD, ATR, Bollinger, SMA/EMA, ADX.

**Arguments**

| Name         | Type      | Required | Default    | Description                                            |
| ------------ | --------- | -------- | ---------- | ------------------------------------------------------ |
| `symbol`     | string    | yes      | —          | Ticker symbol                                          |
| `indicators` | string\[] | no       | core set   | `rsi`, `macd`, `atr`, `bollinger`, `sma`, `ema`, `adx` |
| `periods`    | object    | no       | defaults   | Map of indicator to period(s)                          |
| `from`       | ISO date  | no       | `now - 1y` | Start date                                             |
| `to`         | ISO date  | no       | latest     | End date                                               |

**What it computes**: each indicator over the archive close series.

**Example**

```json theme={null}
technical_indicators({ "symbol": "AAPL", "indicators": ["rsi","macd","bollinger"], "periods": { "rsi": 14 } })
```

```json theme={null}
{
  "skill_id": "technical.indicators",
  "data": {
    "symbol": "AAPL", "as_of": "2025-06-27",
    "indicators": {
      "rsi_14": 62.4,
      "macd": { "macd": 1.82, "signal": 1.41, "histogram": 0.41 },
      "bollinger": { "upper": 218.20, "middle": 212.55, "lower": 206.90, "width": 0.053 }
    }
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 2, "tier": "free" }, "warnings": [] }
}
```

***

## seasonality.monthly

Average monthly returns over N years — detects recurring seasonal patterns.

**Arguments**

| Name        | Type     | Required | Default | Description                 |
| ----------- | -------- | -------- | ------- | --------------------------- |
| `symbol`    | string   | yes      | —       | Ticker symbol               |
| `years`     | int      | no       | `10`    | Lookback years              |
| `as_of`     | ISO date | no       | latest  | End date                    |
| `statistic` | string   | no       | `mean`  | `mean`, `median`, or `both` |

**What it computes**: groups archive returns by month, averages per month over the lookback.

**Example**

```json theme={null}
seasonality_monthly({ "symbol": "SPY", "years": 20 })
```

```json theme={null}
{
  "skill_id": "seasonality.monthly",
  "data": {
    "symbol": "SPY", "years": 20,
    "monthly": {
      "Jan": 0.012, "Feb": 0.004, "Mar": 0.008, "Apr": 0.015, "May": 0.001,
      "Jun": -0.004, "Jul": 0.011, "Aug": -0.006, "Sep": -0.009,
      "Oct": 0.008, "Nov": 0.018, "Dec": 0.012
    },
    "best_month": "Nov", "worst_month": "Sep"
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 2, "tier": "free" }, "warnings": [] }
}
```

***

## seasonality.heatmap

Day-of-month × month return heatmap — finer-grained seasonality. Runs under the **backtest** profile.

**Arguments**

| Name         | Type     | Required | Default | Description         |
| ------------ | -------- | -------- | ------- | ------------------- |
| `symbol`     | string   | yes      | —       | Ticker symbol       |
| `years`      | int      | no       | `10`    | Lookback years      |
| `as_of`      | ISO date | no       | latest  | End date            |
| `resolution` | string   | no       | `daily` | `daily` or `weekly` |

**What it computes**: average return for each (month, day) bucket over the lookback.

**Example**

```json theme={null}
seasonality_heatmap({ "symbol": "SPY", "years": 10 })
```

```json theme={null}
{
  "skill_id": "seasonality.heatmap",
  "data": {
    "symbol": "SPY", "years": 10, "resolution": "daily",
    "buckets": [
      { "month": "Jan", "day": 2, "mean_return": 0.0042, "n_obs": 10, "hit_rate": 0.80 }
    ],
    "best_bucket": { "month": "Dec", "day": 31, "mean_return": 0.0061 },
    "worst_bucket": { "month": "Sep", "day": 15, "mean_return": -0.0048 }
  },
  "provenance": { "source": "archive-community", "freshness": { "as_of": "2025-06-27T20:00:00Z", "lag_seconds": 0 }, "cost": { "credits": 4, "tier": "basic" }, "warnings": [] }
}
```

## Next steps

<Card title="Financials & Earnings Skills" icon="file-invoice-dollar" href="/skills/financials">
  Income statements, balance sheets, cash flow, transcripts, earnings calendars, dividends, splits.
</Card>

<Card title="Strategy & Backtest" icon="flask" href="/strategy/spec">
  Turn your research into a declarative StrategySpec and run a deterministic backtest.
</Card>
