# Account analytics

> One account's whole performance picture — gain, drawdown, profit factor, the balance/equity curve and the monthly tables.

Source: https://www.propexecutor.com/docs/analytics
Whole reference in one file: https://www.propexecutor.com/doc.md

One request returns everything a performance dashboard draws for a single account: the headline numbers, the risk indicators, the balance and equity curve, the profit and loss series, and the monthly and yearly tables.

`GET /v1/accounts/{account}/analytics` · **Available** · scope `accounts:read`

<!-- curl -->
```bash
curl "https://api.propexecutor.com/v1/accounts/10000042/analytics?from=2026-09-01T00:00:00Z&to=2026-09-27T00:00:00Z" \
  -H "Authorization: Bearer $PFX_KEY"
```

## Range

| Field | Type | Description |
| --- | --- | --- |
| `from` | timestamp | Start of the window, RFC 3339. Defaults to 24 hours ago. Clamped forward to the account’s creation — nothing existed before that, so a wider request would only pad the series with invented flat buckets. |
| `to` | timestamp | End of the window. Defaults to now, and is clamped to now. |

The range affects the **time series** only. The totals, indicators and tables are computed over the account’s whole life, so the number on your statement never changes because somebody looked at a different chart range.

## Response

<!-- 200 OK (abridged) -->
```json
{
  "id": "6ab66c2b-a334-ee36-8da4-5f2700000001",
  "account": 10000042,
  "name": "$10K Standard",
  "currency": "USD",
  "type": "demo",
  "broker": "Apex Prop",
  "digits": 2,
  "status": "active",

  "summary": {
    "gain": 0.022972,
    "activity": 0.148,
    "deposit": [10000, 1],
    "withdrawal": [0, 0],
    "dividend": 0, "correction": 0, "credit": 0
  },
  "summary_indicators": {
    "sharpe_ratio": 1.84,
    "profit_factor": 46.944,
    "recovery_factor": 45.944,
    "drawdown": 0.0121,
    "deposit_load": 0.0306,
    "trades_per_week": 4.2,
    "hold_time": 242
  },
  "balance": {
    "balance": 10229.72,
    "equity": 10187.4,
    "period": 300,
    "chart": [
      { "x": 1790348400, "y": [10000, 10000] },
      { "x": 1790348700, "y": [10229.72, 10241.05] }
    ],
    "table": {
      "years": [{ "year": 2026, "months": { "9": 229.72 }, "yearly": 229.72 }],
      "total": 229.72
    }
  },
  "growth": {
    "growth": 0.022972,
    "drawdown": 0.0121,
    "period": 300,
    "chart": [{ "x": 1790348400, "y": 0 }],
    "drawdown_chart": [{ "x": 1790348400, "y": 0.0005 }],
    "table": { "years": [ /* … */ ], "total": 0.022972 }
  },
  "profit_total": {
    "profit": 234.72, "profit_gross": 234.72,
    "profit_dividend": 0, "profit_swap": 0,
    "loss": -5, "loss_gross": -5, "loss_commission": 0
  },
  "profit_money": { "period": 300, "profit": [ /* … */ ], "loss": [ /* … */ ], "table": { /* … */ } },
  "profit_deals": { "period": 300, "profit": [ /* … */ ], "loss": [ /* … */ ], "table": { /* … */ } },
  "profit_daily": { "chart": [{ "x": 0, "y": [0, 0] }, { "x": 4, "y": [234.72, -5] }] },
  "profit_type": {
    "robot":   { "x": 0, "y": [0, 0] },
    "manual":  { "x": 0, "y": [234.72, -5] },
    "signals": { "x": 0, "y": [0, 0] }
  },
  "long_short_total": { "long": 0, "short": 1 },
  "long_short": { "period": 300, "profit": [ /* longs */ ], "loss": [ /* shorts */ ] }
}
```

## Header fields

| Field | Type | Description |
| --- | --- | --- |
| `id` | uuid | Internal identifier. |
| `account` | integer | The 8-digit account number. |
| `name` | string | The account type's name — the challenge the account is running. |
| `currency` | string | Always `"USD"`. Every account on the platform is denominated in USD today. |
| `type` | string | Always `"demo"`. Fills are simulated against live prices and never routed to a venue. |
| `broker` | string | Your firm's name. |
| `digits` | integer | Decimal places for money. Always 2. |
| `status` | string | `active` · `breached` · `passed` · `archived`. |

## summary

| Field | Type | Description |
| --- | --- | --- |
| `gain` | number | Fraction up or down on the starting balance — `0.023` is +2.3%. Measured on **equity**, so an open position counts. |
| `activity` | number | Share of the account's life it has traded on: distinct trading days over days since provisioning, 0–1. |
| `deposit` | [amount, count] | Always exactly one deposit — the starting balance the account was provisioned with. |
| `withdrawal` | [amount, count] | Always `[0, 0]`. A challenge account is never withdrawn from. |
| `dividend · correction · credit` | number | Always 0. A simulated account has no corporate actions. |

## summary_indicators

| Field | Type | Description |
| --- | --- | --- |
| `sharpe_ratio` | number | Annualized on 252 trading days, over daily realized returns. `0` when there is not enough to measure — fewer than two trading days, or no variance at all. |
| `profit_factor` | number | Gross profit over gross loss. `0` when there are no losses — there is no ratio, and infinity is not valid JSON. |
| `recovery_factor` | number | Net profit over the worst drawdown in currency. |
| `drawdown` | number | How far below its all-time equity high the account is **now**, as a fraction. The same number your `max_drawdown_pct` rule is measured against. |
| `deposit_load` | number | Margin in use over balance — how hard the account is leaning on its capital right now. |
| `trades_per_week` | number | Average over the account's whole life, not a recent rate. |
| `hold_time` | number | Mean position lifetime in seconds, over closed trades. |

## Time series

Every series is bucketed at the same width, reported as `period` in **seconds**, and every `x` is a Unix **second** timestamp — multiply by 1000 for JavaScript `Date`.

The width is chosen from the range so the point count stays roughly constant: ask for four hours and you get 5-minute buckets, ask for three years and you get weekly ones. Read it off `period` rather than assuming — that is what it is there for.

| Series | Buckets | What y holds |
| --- | --- | --- |
| `balance.chart` | By time | `[balance, equity]` — two lines in one tuple. |
| `growth.chart` | By time | Growth as a fraction of the starting balance. |
| `growth.drawdown_chart` | By time | Trailing drawdown as a fraction of the all-time peak. |
| `profit_money` | By close time | Realized P&L, winners in `profit`, losers in `loss`. |
| `profit_deals` | By close time | Trade counts, split the same way. |
| `long_short` | By open time | Positions opened — longs in `profit`, shorts in `loss`. |
| `profit_daily.chart` | By weekday | `x` is 0 (Sunday) to 6; `y` is `[profit, loss]`. |

> **Losses keep their sign**
> Every `loss` figure is negative, and `profit_total.loss` is too. Do not negate them again when you stack a chart.

## table

Realized profit and loss grouped by calendar month and year, keyed on the **close** date — that is when a trade books. Months are keyed as strings, `"1"` to `"12"`, and a month with no trading is **absent rather than zero**, so iterate the keys you get rather than assuming twelve.

<!-- table -->
```json
{
  "years": [
    { "year": 2026, "months": { "8": 229.72, "9": -14.5 }, "yearly": 215.22 }
  ],
  "total": 215.22
}
```

## Fields that are always zero

These are present so a dashboard expecting them renders a real zero rather than breaking on a missing key. They are not placeholders that will fill in later without us saying so.

- `profit_swap` and `loss_commission` — the simulator charges neither swap nor commission. If you model trading costs in your challenge pricing, they are not reflected here.
- `profit_type.robot` and `profit_type.signals` — there is no order-source concept, so every trade counts as `manual`.
- `dividend`, `correction`, `credit` and `withdrawal` — see [summary](#summary) above.

## One thing to know about history

> **Equity history starts when the curve did**
> The **balance** line is exact for the account’s whole life — it is reconstructed from the trade ledger. The **equity** line needs the floating value of open positions at each moment, which is only recorded from the day the equity curve shipped on your deployment.
> 
> For any earlier period the equity line equals the balance line, and intraday dips from open losing positions are not visible. See [equity curve](https://www.propexecutor.com/docs/equity-curve) for the detail.
