Skip to content

Pnl#

GET https://api.pro.anboto.xyz/api/v2/portfolio/pnl

Daily PnL from equity closes at 00:00 UTC, net of deposits and withdrawals: the same figures as the PnL page of the trading UI. total covers the whole selection; with groupBy, groups splits it per exchange or account (money values add up to the total, ratios do not). Every *_pct value is in percent. period_return_pct is a simple return, not time-weighted; equity_prev in each point gives the denominator for a time-weighted return. nav_usd and today_pnl come from live equity (as_of). Exchanges without daily PnL coverage are listed in uncovered_exchanges and never counted as zero. Scope spot or future is recomputed per day and limited to 366 days. ApiKeyAuth required.

Query params#

accounts string
Comma-separated accounts: binance = every account on Binance (main and subaccounts), binance: = the main account only, binance:Sub1 = that subaccount. Omit for every account of the team. At most 20 items. Unlike /api/v2/trading/*, a missing subaccount means all accounts. Sign the raw value, e.g. accounts=binance:,bybit:Sub1.
Example: binance:,bybit:Sub1
scope enum
Wallet scope: total (default), spot or future — total, spot, future
Default: total
groupBy enum
Split the result into groups: none (default), exchange or account — none, exchange, account
Default: none
period string
Window ending at endDate: <N>d (N from 1 to 3660), week, month, quarter or year. Default 30d. Ignored when startDate is given
Example: 90d
startDate date
First day, YYYY-MM-DD (UTC, inclusive)
endDate date
Last day, YYYY-MM-DD (UTC, inclusive). At most today. The series ends yesterday at the latest, the last closed day: the default, and the day an endDate of today is answered up to (to_date gives the applied end; today's PnL so far is today_pnl). The window spans at most 3660 days, or 366 days for scope spot or future

Headers#

Header
X-API-KEY string required
X-TIMESTAMP int64 ms required
X-SIGN string required
X-RECV-WINDOW int, default 5000

Responses#

200 The daily PnL
400 Invalid parameter,
401 Unauthorized: missing or unknown API key
429 Rate limit exceeded, retry later
503 The portfolio service is unavailable,

Response fields — PortfolioPnlResponse#

as_of date-time required
UTC time of the newest live equity snapshot used for today_pnl; null when none was available
nav_usd number required
Net asset value of the selection now: the sum of each account's newest live equity snapshot (at most 3 days old; for scope spot or future, that wallet's equity), in USD. Null when no snapshot was available
from_date date required
First day of the window (YYYY-MM-DD, UTC), as applied
to_date date required
Last day of the window (YYYY-MM-DD, UTC), as applied. Days are closed at 00:00 UTC, so this is at most yesterday
scope enum required
Wallet scope — total, spot, future
group_by enum required
Grouping of groups — none, exchange, account
currency string required
Currency of every money value
Example: USD
accounts array[PortfolioAccountRef] required
The resolved account selection; null when the request covered every account of the team
accounts[].exchange string required
Exchange code, e.g. binance
accounts[].subaccount string required
Subaccount name; "" is the main account and null means every account on the exchange
uncovered_exchanges array[string]
Requested or connected exchanges without daily PnL coverage. They are left out of every figure, never counted as zero
total PnlSummary required
PnL figures and daily series of a selection
total.today_pnl number required
PnL since 00:00 UTC from live equity; null when no live snapshot exists or a flow today could not be priced
total.cumulative_pnl number required
Sum of daily_pnl over the window
total.period_return_pct number required
Simple return over the window in percent: cumulative_pnl over the first flow-adjusted equity (not time-weighted)
total.since_inception_pnl number required
PnL since the selection's first closed day
total.since_inception_return_pct number required
Simple return since inception, in percent
total.since_inception_date date required
First closed day of the selection (YYYY-MM-DD)
total.sharpe number required
Sharpe ratio of the daily returns, annualised with √365; null with fewer than 2 points
total.max_drawdown_pct number required
Largest peak-to-trough drawdown in the window, in percent (≤ 0)
total.estimated boolean
True when at least one day in the window is estimated rather than closed from snapshots
total.reconstructed_range PnlDateRange required
First and last UTC day of a run of PnL points
total.point_count integer required
Number of points in series
total.series array[PnlPoint] required
One point per UTC day, oldest first. Days without comparable data are skipped
total.series[].date date required
UTC day (YYYY-MM-DD)
total.series[].daily_pnl number required
PnL of the day, net of deposits and withdrawals
total.series[].net_flows number required
Net external flows of the day: positive for deposits, negative for withdrawals
total.series[].equity_close number required
Equity at the day's close (00:00 UTC of the next day)
total.series[].equity_prev number
Equity at the previous close; the denominator of a time-weighted return
total.series[].daily_return_pct number required
daily_pnl over the flow-adjusted previous equity, in percent
total.series[].drawdown_pct number required
Drawdown from the running peak, in percent (≤ 0)
total.series[].daily_unrealized_pnl number required
Change of unrealised PnL over the day, where the exchange reports it
total.series[].unrealized_pnl_close number required
Unrealised PnL at the close, where the exchange reports it
total.series[].quality enum required
ok, or estimated when the close was not taken from a snapshot — ok, estimated
total.series[].reconstructed boolean required
True when the day's close or the previous close was rebuilt from the account's fills, income history and daily mark prices, for days before its first stored daily close. quality is estimated on those days
groups array[PnlGroup]
One entry per exchange or account; present only when group_by is not none. Money values add up to total; ratios (returns, sharpe, drawdown) do not
groups[].key PnlGroupKey required
Identity of a PnL group
groups[].as_of date-time required
UTC time of the newest live snapshot used for this group's today_pnl
groups[].today_pnl number required
Group PnL since 00:00 UTC; null when not available for this group
groups[].cumulative_pnl number required
Sum of the group's daily_pnl over the window
groups[].period_return_pct number required
Simple return of the group over the window, in percent
groups[].since_inception_pnl number required
groups[].since_inception_return_pct number required
groups[].since_inception_date date required
groups[].sharpe number required
groups[].max_drawdown_pct number required
In percent (≤ 0)
groups[].estimated boolean
True when at least one of the group's days is estimated
groups[].reconstructed_range PnlDateRange required
First and last UTC day of a run of PnL points
groups[].point_count integer required
Number of points in series
groups[].series array[PnlPoint] required
Only the days of total.series on which the group had data; a missing day contributed 0
groups[].series[].date date required
UTC day (YYYY-MM-DD)
groups[].series[].daily_pnl number required
PnL of the day, net of deposits and withdrawals
groups[].series[].net_flows number required
Net external flows of the day: positive for deposits, negative for withdrawals
groups[].series[].equity_close number required
Equity at the day's close (00:00 UTC of the next day)
groups[].series[].equity_prev number
Equity at the previous close; the denominator of a time-weighted return
groups[].series[].daily_return_pct number required
daily_pnl over the flow-adjusted previous equity, in percent
groups[].series[].drawdown_pct number required
Drawdown from the running peak, in percent (≤ 0)
groups[].series[].daily_unrealized_pnl number required
Change of unrealised PnL over the day, where the exchange reports it
groups[].series[].unrealized_pnl_close number required
Unrealised PnL at the close, where the exchange reports it
groups[].series[].quality enum required
ok, or estimated when the close was not taken from a snapshot — ok, estimated
groups[].series[].reconstructed boolean required
True when the day's close or the previous close was rebuilt from the account's fills, income history and daily mark prices, for days before its first stored daily close. quality is estimated on those days
curl -X GET "$BASE/api/v2/portfolio/pnl?accounts=string" \
  -H "X-API-KEY: $API_KEY" -H "X-TIMESTAMP: $ts" \
  -H "X-SIGN: $sign"
params = {"accounts": ..., "scope": ..., "groupBy": ..., "period": ..., "startDate": ..., "endDate": ...}
r = requests.get(f"{BASE}/api/v2/portfolio/pnl",
    params=params
    headers=signed_headers_query(params))
print(r.json())
let resp = client
    .get(format!("{BASE}/api/v2/portfolio/pnl?accounts=string"))
    .headers(signed_headers_query(&params))
    .send()?;
println!("{}", resp.text()?);
req, _ := http.NewRequest("GET", BASE+"/api/v2/portfolio/pnl?accounts=string", nil)
for k, v := range signedHeadersQuery(req.URL.Query()) {
    req.Header.Set(k, v)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
HttpResponse<String> resp = client.send(
    signedGet("/api/v2/portfolio/pnl?accounts=string"),
    HttpResponse.BodyHandlers.ofString());
const res = await fetch(`${BASE}/api/v2/portfolio/pnl?accounts=string`, {
  method: "GET",
  headers: signedHeadersQuery(params),
});
const data: PortfolioPnlResponse = await res.json();
val request = signedGet("/api/v2/portfolio/pnl?accounts=string")
val response = client.send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
cpr::Response r = cpr::Get(
    cpr::Url{BASE + "/api/v2/portfolio/pnl?accounts=string"},
    signedHeadersQuery(params));
std::cout << r.text << std::endl;
const res = await fetch(`${BASE}/api/v2/portfolio/pnl?accounts=string`, {
  method: "GET",
  headers: signedHeadersQuery(params),
});
console.log(await res.json());

Response 200

{
  "as_of": "string",
  "nav_usd": 0.0,
  "from_date": "string",
  "to_date": "string",
  "scope": "total",
  "group_by": "none",
  "currency": "USD",
  "accounts": [
    {
      "exchange": "string",
      "subaccount": "string"
    }
  ],
  "uncovered_exchanges": [
    "string"
  ],
  "total": {
    "today_pnl": 0.0,
    "cumulative_pnl": 0.0,
    "period_return_pct": 0.0,
    "since_inception_pnl": 0.0,
    "since_inception_return_pct": 0.0,
    "since_inception_date": "string",
    "sharpe": 0.0,
    "max_drawdown_pct": 0.0,
    "estimated": true,
    "reconstructed_range": {
      "first_date": "string",
      "last_date": "string"
    },
    "point_count": 0,
    "series": [
      {
        "date": "string",
        "daily_pnl": 0.0,
        "net_flows": 0.0,
        "equity_close": 0.0,
        "equity_prev": 0.0,
        "daily_return_pct": 0.0,
        "drawdown_pct": 0.0,
        "daily_unrealized_pnl": 0.0,
        "unrealized_pnl_close": 0.0,
        "quality": "ok",
        "reconstructed": true
      }
    ]
  },
  "groups": [
    {
      "key": {
        "exchange": "string",
        "subaccount": "string",
        "market": "string"
      },
      "as_of": "string",
      "today_pnl": 0.0,
      "cumulative_pnl": 0.0,
      "period_return_pct": 0.0,
      "since_inception_pnl": 0.0,
      "since_inception_return_pct": 0.0,
      "since_inception_date": "string",
      "sharpe": 0.0,
      "max_drawdown_pct": 0.0,
      "estimated": true,
      "reconstructed_range": {
        "first_date": "string",
        "last_date": "string"
      },
      "point_count": 0,
      "series": [
        {}
      ]
    }
  ]
}