API reference

Account analytics

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

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}/analyticsAvailablescope · accounts:read
curl
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

fromtimestamp
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.
totimestamp
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)
{
  "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 */ ] }
}
iduuid
Internal identifier.
accountinteger
The 8-digit account number.
namestring
The account type's name — the challenge the account is running.
currencystring
Always "USD". Every account on the platform is denominated in USD today.
typestring
Always "demo". Fills are simulated against live prices and never routed to a venue.
brokerstring
Your firm's name.
digitsinteger
Decimal places for money. Always 2.
statusstring
active · breached · passed · archived.

summary

gainnumber
Fraction up or down on the starting balance — 0.023 is +2.3%. Measured on equity, so an open position counts.
activitynumber
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 · creditnumber
Always 0. A simulated account has no corporate actions.

summary_indicators

sharpe_rationumber
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_factornumber
Gross profit over gross loss. 0 when there are no losses — there is no ratio, and infinity is not valid JSON.
recovery_factornumber
Net profit over the worst drawdown in currency.
drawdownnumber
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_loadnumber
Margin in use over balance — how hard the account is leaning on its capital right now.
trades_per_weeknumber
Average over the account's whole life, not a recent rate.
hold_timenumber
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.

SeriesBucketsWhat y holds
balance.chartBy time[balance, equity] — two lines in one tuple.
growth.chartBy timeGrowth as a fraction of the starting balance.
growth.drawdown_chartBy timeTrailing drawdown as a fraction of the all-time peak.
profit_moneyBy close timeRealized P&L, winners in profit, losers in loss.
profit_dealsBy close timeTrade counts, split the same way.
long_shortBy open timePositions opened — longs in profit, shorts in loss.
profit_daily.chartBy weekdayx 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
{
  "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 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 for the detail.