Full account report
Everything about one account in a single call — identity, curve, statement, indicators, every deal and the evaluation terms it is judged against.
Everything the platform knows about one trading account, in a single response: who it is, what it is worth, its month-by-month statement, its risk and streak indicators, its long/short split, its results per instrument and per weekday, every deal it has ever made, and the evaluation terms it is being judged against.
/v1/accounts/{account}/reportAvailablescope · accounts:readcurl "https://api.propexecutor.com/v1/accounts/10000042/report" \
-H "Authorization: Bearer $PFX_KEY"Which one should you call?
This endpoint and analytics answer the same question in two different shapes. Call report when you are rendering a whole account page and want one request with nothing to stitch together — it includes the deal list and the rule terms, which analytics leaves to separate calls.
Call analytics when you are driving charts and polling: it is the lighter of the two, it carries extra series (money and deal counts split into winners and losers) and it never reads the full ledger row by row. One thing to watch if you call both: its weekday chart is Sunday-first, while this endpoint’s profitDaily is Monday-first. Each matches the contract its own clients bind to.
This is the slow one
The report reads the account’s entire trade ledger, aggregates all of it, and fetches the equity curve — deliberately, because a partial report is not a report. A profit factor computed over one page of trades is not a profit factor.
So: call it on page load, not on a timer, and not on every price tick. There is no pagination anywhere in the response. What bounds it instead is tradeHistory.deals, which is capped at 5,000 entries — totalDeals is always the true count, so you can tell when you are seeing a truncated list, and every aggregate in the object is still computed over the whole ledger rather than the capped slice.
Range
fromtimestamptotimestampThe range affects balance.chart, growth.chart and the three longShort series only. Every total, indicator, table and deal covers the account’s whole life, so nothing on your statement changes because somebody looked at a different chart range.
Units, before anything else
The same measurement appears in two units in two places. This is the contract’s shape, not an accident, and it is the one thing worth reading before you bind a field to a label:
| Measurement | As a fraction | As a percentage | In currency |
|---|---|---|---|
| Growth on the starting balance | growth.growth, summary.gain, evaluation.metrics.profit_percent | — | balance.table.total |
| Drawdown from the all-time peak | growth.drawdown | summaryIndicators.drawdown | — |
| Share of closed trades that won | — | tradeHistory.summary.winRate | — |
| The rule limits | evaluation.rulesApplied.* | — | — |
summary.gain is a fraction, not money
summary.gain is growth on the starting balance as a fraction (-0.0546 means down 5.46%) — the same number as growth.growth and evaluation.metrics.profit_percent. The money form is balance.table.total, which equals tradeHistory.summary.totalProfit and profitTotal.profit + profitTotal.loss.
summary.activity is a fraction too: the share of the account’s life that has had trading on it, capped at 1. The deal count is tradeHistory.totalDeals.
Response
{
"account": 10000042,
"name": "$1K One Step",
"broker": "Northwind Funding",
"currency": "USD",
"balance": {
"balance": 945.19,
"equity": 945.19,
"period": 3600,
"chart": [
{ "x": 1771415040, "y": [1000, 1000] },
{ "x": 1788795349, "y": [945.19, 945.19] }
],
"table": {
"years": [{ "year": 2026, "months": { "1": 15.8, "2": -8.74 }, "yearly": 7.06 }],
"total": 7.06
}
},
"_id": "9f1c…",
"type": "demo",
"digits": 2,
"credentialKey": "1K_ONE_STEP",
"status": "ACTIVE",
"isBreached": false,
"breachReasons": [],
"statusChangedAt": null,
"updatedAt": "2026-09-29T08:41:02Z",
"__v": 1,
"summary": {
"gain": -0.054576,
"activity": 0.36,
"deposit": [1000, 1],
"withdrawal": [0, 0],
"dividend": 0, "correction": 0, "credit": 0
},
"summaryIndicators": {
"sharp_ratio": -0.8,
"profit_factor": 0.72,
"recovery_factor": -0.5,
"drawdown": 9.36,
"deposit_load": 0.0797,
"trades_per_week": 3.2,
"hold_time": 7047
},
"risksIndicators": {
"profit": [21.94, -12.36],
"max_consecutive_trades": [2, 16],
"max_consecutive_profit": [37.61, -74.44]
},
"growth": {
"growth": -0.054576,
"drawdown": 0.093599,
"period": 3600,
"chart": [
[{ "x": 1771415040, "y": [0.01] }],
[{ "x": 1771415040, "y": [0.002] }]
],
"table": { "years": [], "total": -0.054576 }
},
"drawdown": {
"drawdown": 0.093599, "deposit_load": 0.0797, "period": 3600,
"chart": [[…fraction], […currency], [0…], [0…]]
},
"dividend": { "dividend": 0, "correction": 0, "credit": 0, "period": 3600, "chart": [], "table": {} },
"profitMoney": { "period": 3600, "profit": [], "loss": [], "table": {} },
"profitDeals": { "period": 3600, "profit": [], "loss": [], "table": {} },
"profitType": {
"robot": { "x": 0, "y": [0, 0] },
"manual": { "x": 0, "y": [50, -104.56] },
"signals": { "x": 0, "y": [0, 0] }
},
"longShortDaily": { "chart": [{ "x": 0, "y": [13, 8] }] },
"risksMfeMaeMoney": { "max_avg_profit": 0, "max_avg_mfe": 0, "min_avg_loss": 0, "min_avg_mae": 0, "period": 3600, "chart": [[]] },
"risksMfeMaePercent": { "max_avg_profit_ratio": 0, "max_avg_mfe_ratio": 0, "min_avg_loss_ratio": 0, "min_avg_mae_ratio": 0, "period": 3600, "chart": [[]] },
"symbolIndicators": {
"profit_factor": [["US500", 1.51]], "netto_profit": [["US500", 10.16]], "fees": [["US500", 0]]
},
"symbolTypes": { "type": [["Index", 89], ["Currency", 4]] },
"symbolsTotal": { "total": [["US500", 10.16, 9]] },
"tradeTypeTotal": { "robots": 0, "manual": 93, "signals": 0 },
"longShort": {
"period": 3600,
"long": [{ "x": 1771113600, "y": [2] }],
"short": [{ "x": 1771113600, "y": [1] }],
"all": [{ "x": 1771113600, "y": [3] }]
},
"longShortTotal": { "long": 63, "short": 30 },
"longShortIndicators": {
"netto_pl": [-25.15, -29.41],
"average_pl": [-0.399206, -0.980333],
"average_pl_percent": [-0.000399, -0.00098],
"commissions": [0, 0],
"average_profit": [2.32127, 2.529333],
"average_profit_percent": [0.002321, 0.002529],
"trades": [63, 30],
"win_trades": [14, 12]
},
"profitDaily": {
"chart": [
{ "x": 0, "y": [38.06, -92.02] },
{ "x": 1, "y": [16.94, -61.25] },
{ "x": 2, "y": [61.21, -10.84] },
{ "x": 3, "y": [51.9, -49.63] },
{ "x": 4, "y": [54.01, -62.94] },
{ "x": 5, "y": [0, 0] },
{ "x": 6, "y": [0, 0] }
]
},
"symbolDeals": {
"period": 604800,
"chart": [
["US30", [{ "x": 1771113600, "y": [2] }, { "x": 1771718400, "y": [7] }]],
["US500", [{ "x": 1771113600, "y": [3] }, { "x": 1771718400, "y": [0] }]]
]
},
"symbolMoney": {
"period": 604800,
"chart": [
["US30", [{ "x": 1771113600, "y": [11.52] }, { "x": 1771718400, "y": [6.92] }]],
["US500", [{ "x": 1771113600, "y": [14.7] }, { "x": 1771718400, "y": [18.98] }]]
]
},
"tradeHistory": {
"fromDate": "2026-02-18T11:45:20Z",
"toDate": "2026-09-29T08:41:02Z",
"fetchedAt": "2026-09-29T08:41:02Z",
"dayOffsetHours": 0,
"totalDeals": 93,
"deals": [{
"ticket": 1000123, "order": 1000123, "position_id": 1000123,
"time": 1771113600, "time_msc": 1771113600000, "time_iso": "2026-02-15T00:00:00Z",
"type": 0, "type_name": "BUY",
"entry": 1, "entry_name": "OUT",
"magic": 0, "reason": 0,
"volume": 0.16, "price": 52049,
"commission": 0, "swap": 0, "fee": 0,
"profit": -10.5, "net_profit": -10.5,
"is_closing": true, "symbol": "US30",
"comment": "", "external_id": ""
}],
"trades": [{
"positionId": 1000123, "symbol": "US30", "side": "BUY", "volume": 0.16,
"openTime": 1771113600, "openTimeIso": "2026-02-15T00:00:00Z", "openPrice": 52049,
"closeTime": 1771117200, "closeTimeIso": "2026-02-15T01:00:00Z", "closePrice": 51983,
"durationSeconds": 3600,
"profit": -10.5, "commission": 0, "swap": 0, "fee": 0, "netProfit": -10.5,
"entries": [{
"time": 1771113600, "timeIso": "2026-02-15T00:00:00Z",
"type_name": "BUY", "entry": 0, "entry_name": "IN",
"price": 52049, "volume": 0.16, "cumulativeVolume": 0.16
}],
"entryCount": 1, "firstLegVolume": 0.16, "maxLegVolume": 0.16,
"volumeMultiple": 1, "isAveraging": false, "isMartingale": false
}],
"dailyNet": {
"2026-02-15": { "netProfit": -10.5, "grossProfit": -10.5, "closedDeals": 1 }
},
"summary": {
"totalProfit": -54.56,
"netProfit": -54.56,
"totalCommission": 0, "totalSwap": 0, "totalFee": 0,
"winningTrades": 26,
"losingTrades": 67,
"totalClosedTrades": 93,
"winRate": 27.96,
"symbolsTraded": ["US30", "US500"],
"tradingDays": 31,
"averagingPositions": 0, "martingalePositions": 0,
"averagingDetected": false, "martingaleDetected": false
}
},
"evaluation": {
"program": "1_STEP",
"evaluatedAt": "2026-09-29T08:41:02Z",
"credentialKey": "1K_ONE_STEP",
"rulesApplied": {
"profit_target": 0.1,
"max_loss_limit": 0.06,
"daily_loss_limit": 0.03,
"leverage": "1:50",
"min_trading_days": 3,
"min_profitable_days": null,
"max_inactivity_days": 14
},
"status": "ACTIVE",
"isBreached": false,
"breaches": [],
"breachReasons": [],
"metrics": {
"initial_balance": 1000,
"current_balance": 945.19,
"current_equity": 945.19,
"worst_balance_or_equity": 945.19,
"profit_percent": -0.0548,
"profit_target_hit": false,
"profitable_days": 11,
"consecutive_inactive_days": 4,
"daily_dd_total_days_checked": 31,
"daily_dd_peak_equity": 1000,
"daily_dd_threshold": 970,
"daily_dd_current_drawdown_pct": 0.05481,
"daily_dd_breached": true,
"daily_dd_breach_date": null,
"max_open_lots_limits": {},
"freedom_lot_peaks": {},
"freedom_lot_would_breach": []
}
},
"profitTotal": {
"profit": 50,
"profit_gross": 50,
"profit_dividend": 0,
"profit_swap": 0,
"loss": -104.56,
"loss_gross": -104.56,
"loss_commission": 0
}
}Identity
accountintegernamestringbrokerstringcurrencystring"USD". Every account on the platform is denominated in USD today.balance
balancenumberequitynumberchartpoint[]x a Unix second, y the pair [balance, equity] — balance first. Bucket width is chosen from the span you asked for. Empty when the equity curve is not available on your deployment; see equity curve.tableobject"1" … "12") and a month with no trading is absent rather than zero, so iterate the keys you get rather than 1–12. Computed from the ledger, never from the chart.summaryIndicators
sharp_rationumber0 when there is not enough history to measure a deviation — two days of trading has no meaningful one, and a number derived from it would be worse than none. (Spelled without the ‘e’ because the contract spells it that way.)profit_factornumber0 for an account with no losing trade — it has no ratio, and Infinity is not JSON a client can parse.recovery_factornumberdrawdownnumbertrades_per_weeknumberrisksIndicators
The streak view, read over closed deals in the order they settled. Every field is a two-element [best, worst] pair: index 0 describes winning, index 1 losing, and the losing figures are negative.
profit[number, number]max_consecutive_trades[integer, integer]max_consecutive_profit[number, number]profitDaily
Realized P&L by day of week: seven points, x = 0 for Monday through 6 for Sunday, y = [profit, loss] for that weekday across the whole ledger. Loss is negative, both are 0 for a day never traded, and every day is present so you can index the array directly. A deal counts on the day it settled, not the day it opened.
longShort
Three parallel series counting positions opened per bucket — the question a long/short chart answers is when exposure was taken on, not when it was closed. Every bucket in the range appears in all three series at the same x, so you can index them against each other without aligning timestamps, and all is always long + short for its bucket. longShortDaily is the same split by weekday, Monday first, as [long, short].
longShortTotal and longShortIndicators
The same split as scalars. longShortTotal is the deal count per direction — the totals of the series above, carried so you do not have to sum a chart to label a donut. longShortIndicators is how each direction performed, and every field in it is a two-element array indexed [long, short].
Counts include open positions, money does not: exposure was taken long the moment the position opened, but it has realized nothing until it closes. That is the same split tradeHistory.summary makes between totalDeals and totalClosedTrades.
netto_pl[number, number]average_pl[number, number]netto_pl over the direction’s total deal count, open positions included — not over its closed count. The contract’s own definition, and the reason it is not netto_pl / win_trades.average_pl_percent[number, number]commissions[number, number][0, 0] — no commission is modelled, for the same reason profitTotal’s gross and net pairs are equal. An explicit zero, not an omission.average_profit[number, number]average_profit_percent[number, number]trades[integer, integer]win_trades[integer, integer]trades counts open positions too, so it is not the denominator for a per-side win rate.symbolDeals and symbolMoney
One series per instrument over the same buckets as balance.chart. Both objects carry period (the bucket width in seconds) and chart, a list of positional [symbol, points] pairs — a two-element array, not an object — sorted alphabetically by instrument. Every symbol gets every bucket in the range, leading zeros included, so the series are index-aligned with each other and with longShort.
symbolDealsseriessymbolMoneyseriessummary.gain, and the last points of every symbol add up to it.tradeHistory
totalDealsintegerdealsdeal[]deals[].ticketintegerdeals[].timeintegerdeals[].type_namestring"BUY" or "SELL".deals[].volumenumberdeals[].pricenumberdeals[].profitnumber0 while the position is still open. An open position’s floating P&L is a price-dependent number that would make two calls a second apart disagree; totalClosedTrades tells you how many of the deals are settled.deals[].symbolstringsummary.winRatenumbersummary.netProfitnumbertotalProfit: the simulator charges no commission and no swap, so there is nothing to subtract. Both are reported so a client reading either gets a correct number.summary.symbolsTradedstring[]evaluation
The terms this account is judged against — read from the rule set version that was frozen onto it at creation, never from its rule set’s current version. Editing a rule set never changes the terms of accounts already running under it, and this object reflects that.
programstring"1_STEP". An account points at exactly one rule set version for its whole life — there is no phase 1 → phase 2 progression and no funded stage on this platform, so every account genuinely is a single step. Reported as a constant so you can switch on it.rulesApplied.profit_targetnumber | null0.1 = +10%). null when the rule set has no profit target, which means the account can never pass — not 0, which would say it already has.rulesApplied.max_loss_limitnumber | nullrulesApplied.daily_loss_limitnumber | nullrulesApplied.leveragestring"1:50". Leverage is set per asset class on this platform, and FX is reported as the single representative value an account-level field can carry. See rule sets for the per-class map.statusstringACTIVE, BREACHED, PASSED or CLOSED, uppercased.isBreachedbooleanbreachesobject[]{ rule, severity, observed, threshold, message }, plus peak_equity and breach_date on a drawdown breach. observed and threshold are null for a rule with no number to report. The rule that ended the account comes first; any other limit the account is also past follows it. Empty for a breach an administrator recorded by hand. See the note below.breachReasonsstring[]DAILY_DRAWDOWN, MAX_LOSS_LIMIT, INACTIVITY, or a typed rule's key uppercased (e.g. MAX_LOT_PER_ORDER). A breach an administrator recorded by hand carries its own text instead.metrics.profitable_daysintegermin_trading_days, which counts days traded at all.metrics.profit_percentnumberbreaches is not a history
The first entry is the rule that ended the account, recorded in the same transaction as the status change. Any further entries are other breach rules of the account's frozen rule set that its equity is also past right now. It is not a log you can page through, and a second breach cannot happen to an account that is already breached.
Rules that flag rather than breach are a different thing entirely: they accumulate, trading continues, and they are not in this array. They are reported separately — see rule sets.
profitTotal
Gross profit and gross loss over closed trades. loss and loss_gross are negative. The net and gross pairs are identical because no trading costs are modelled — adding commission or swap would change the simulator’s P&L and every drawdown that follows from it, so it is a product decision rather than a field we can fill in quietly.
Blocks that are structurally zero
The report serves the whole of its contract, including the parts a broker-backed account would fill and a simulator cannot. Those are explicit zeros and empty collections, never missing keys, so a client binding to them renders an empty panel instead of undefined:
dividend,summary.withdrawal,summary.dividend/correction/credit— a challenge account is funded once and never paid into or out of again.profitTotal.profit_swap,profitTotal.loss_commission,longShortIndicators.commissions,symbolIndicators.feesand the cost totals intradeHistory.summary— no commission or swap is modelled.profitType.robot/signalsandtradeTypeTotal— every fill comes through one order path, so everything is manual.risksMfeMaeMoneyandrisksMfeMaePercent— measuring how far a position ran in favour or against needs every tick it lived through recorded against it, and only the open and close prices are stored. Reporting anything else would be a guess dressed as a measurement.evaluation.metrics.freedom_lot_peaksandfreedom_lot_would_breach— peak concurrent lots per asset class needs an exposure history nothing records.max_open_lots_limitscarries at most the keyALL, because the lot ceiling here is account-wide rather than per class.tradeHistory.summary.averagingDetected/martingaleDetectedand their counts — a position cannot be added to on this platform, so there is no scaling-in pattern to find.
What this object does not carry
- A deposit history. A challenge account’s only deposit is the starting balance it was provisioned with, so
summary.depositis the contract’s[amount, count]pair with a count of1for the account’s whole life — the same number asmetrics.initial_balance. - Commission, swap, dividends and corrections. Not modelled — see
profitTotalabove. - An order source. There is no robot / signal / manual distinction; every fill comes through the same path.
- The trader’s identity. A report is about an account. The trader record holding it is on traders, and an API key never reaches a trader login.
One thing to know about history
The balance line in balance.chart is exact for the account’s whole life — it is reconstructed from the 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 two lines are equal and intraday dips from open losing positions are not visible.