Skip to content

Get Performance History (WebSocket)

Retrieve comprehensive performance analytics including historical account value, PnL trends, and trading volume for a subaccount over a specified period through the WebSocket connection. Optimized for charting and performance analysis.

Endpoint

ws.send() wss://api.synthetix.io/v1/ws/trade

Request

Request Format

{
  "id": "performance-history-1",
  "method": "post",
  "params": {
    "action": "getPerformanceHistory",
    "subAccountId": "1867542890123456789",
    "period": "week",
    "expiresAfter": 1735689600,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Parameters

Request Parameters

ParameterTypeRequiredDescription
idstringYesClient-generated unique request identifier
methodstringYesMust be "post"
paramsobjectYesContains all parameters for the request

Params Object

ParameterTypeRequiredDescription
actionstringYesMust be "getPerformanceHistory"
subAccountIdstringYesSubaccount identifier
periodstringNoTime window: "day" (default), "week", "month", "threeMonth", "ytd", "allTime"
expiresAfterintegerNoOptional expiration timestamp in seconds
signatureobjectYesEIP-712 signature using SubAccountAction type
Important Notes:
  • This endpoint uses SubAccountAction EIP-712 type (no nonce required)
  • If period is omitted, the service returns day performance history by default

EIP-712 Signature

const domain = {
  name: "Synthetix",
  version: "1",
  chainId: 1,
  verifyingContract: "0x0000000000000000000000000000000000000000"
};
 
const types = {
  SubAccountAction: [
    { name: "subAccountId", type: "uint256" },
    { name: "action", type: "string" },
    { name: "expiresAfter", type: "uint256" }
  ]
};
 
const message = {
  subAccountId: "1867542890123456789",
  action: "getPerformanceHistory",
  expiresAfter: 0
};
 
const signature = await signer._signTypedData(domain, types, message);

Response Format

Success Response

{
  "id": "performance-history-1",
  "status": 200,
  "result": {
    "subAccountId": "1867542890123456789",
    "period": "week",
    "performanceHistory": {
      "history": [
        {
          "sampledAt": 1736947200000,
          "accountValue": "10000.50",
          "pnl": "12.34"
        },
        {
          "sampledAt": 1736950800000,
          "accountValue": "10020.10",
          "pnl": "15.67"
        },
        {
          "sampledAt": 1736954400000,
          "accountValue": "10150.25",
          "pnl": "145.92"
        }
      ],
      "volume": "250000.00"
    }
  }
}

Error Response

{
  "id": "performance-history-1",
  "status": 400,
  "result": null,
  "error": {
    "code": 400,
    "message": "Failed to retrieve performance history"
  }
}

Response Fields

Performance History Object

FieldTypeDescription
historyarrayOrdered list of performance points for the requested period
history[].sampledAtintegerUnix timestamp in milliseconds
history[].accountValuestringAccount value at the timestamp
history[].pnlstringPnL at the timestamp
volumestringTotal volume traded during the requested period

The response also echoes the subAccountId and the period that was requested.

Code Examples

Get Daily Performance

{
  "id": "daily-performance",
  "method": "post",
  "params": {
    "action": "getPerformanceHistory",
    "subAccountId": "1867542890123456789",
    "period": "day",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Get Weekly Performance

{
  "id": "weekly-performance",
  "method": "post",
  "params": {
    "action": "getPerformanceHistory",
    "subAccountId": "1867542890123456789",
    "period": "week",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Get Monthly Performance

{
  "id": "monthly-performance",
  "method": "post",
  "params": {
    "action": "getPerformanceHistory",
    "subAccountId": "1867542890123456789",
    "period": "month",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Get All-Time Performance

{
  "id": "alltime-performance",
  "method": "post",
  "params": {
    "action": "getPerformanceHistory",
    "subAccountId": "1867542890123456789",
    "period": "allTime",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Implementation Example

class PerformanceQuery {
  constructor(ws, signer) {
    this.ws = ws;
    this.signer = signer;
    this.pendingRequests = new Map();
  }
 
  async getPerformanceHistory(subAccountId, period = "day", expiresAfter = 0) {
    const signature = await this.signSubAccountAction(subAccountId, "getPerformanceHistory", expiresAfter);
 
    const request = {
      id: `performance-${Date.now()}`,
      method: "post",
      params: {
        action: "getPerformanceHistory",
        subAccountId,
        period,
        expiresAfter,
        signature
      }
    };
 
    return this.sendRequest(request);
  }
 
  async signSubAccountAction(subAccountId, action, expiresAfter = 0) {
    const domain = {
      name: "Synthetix",
      version: "1",
      chainId: 1,
      verifyingContract: "0x0000000000000000000000000000000000000000"
    };
 
    const types = {
      SubAccountAction: [
        { name: "subAccountId", type: "uint256" },
        { name: "action", type: "string" },
        { name: "expiresAfter", type: "uint256" }
      ]
    };
 
    const message = {
      subAccountId: BigInt(subAccountId),
      action,
      expiresAfter: BigInt(expiresAfter)
    };
 
    const sig = await this.signer.signTypedData(domain, types, message);
    const { v, r, s } = ethers.Signature.from(sig);
    return { v, r, s };
  }
 
  sendRequest(request) {
    return new Promise((resolve, reject) => {
      this.pendingRequests.set(request.id, { resolve, reject });
      this.ws.send(JSON.stringify(request));
 
      setTimeout(() => {
        if (this.pendingRequests.has(request.id)) {
          this.pendingRequests.delete(request.id);
          reject(new Error('Request timeout'));
        }
      }, 10000);
    });
  }
}
 
// Usage: Build performance dashboard
const query = new PerformanceQuery(ws, signer);
 
// Get weekly performance for charting
const weeklyData = await query.getPerformanceHistory("1867542890123456789", "week");
 
console.log(`Period: ${weeklyData.period}`);
console.log(`Volume: ${weeklyData.performanceHistory.volume}`);
console.log(`Data points: ${weeklyData.performanceHistory.history.length}`);
 
// Chart the data
weeklyData.performanceHistory.history.forEach(point => {
  console.log(`${new Date(point.sampledAt).toISOString()}: ${point.accountValue} (PnL: ${point.pnl})`);
});

Use Cases

  • Performance Dashboards: Build comprehensive performance tracking interfaces
  • PnL Analysis: Track profit and loss trends over different time periods
  • Trading Analytics: Analyze trading volume and activity patterns
  • Portfolio Reporting: Generate performance reports for users
  • Charting Applications: Power performance charts and visualizations
  • Trend Analysis: Identify performance patterns and trading behavior

Period Options

PeriodDescription
dayLast 24 hours (default)
weekLast 7 days
monthLast 30 days
threeMonthLast 90 days
ytdYear to date
allTimeAll available history

Data Format Notes

  • Timestamps: Unix timestamp in milliseconds
  • Time Series: Array ordered chronologically
  • Numeric Precision: All numeric values returned as strings to preserve precision
  • USDT Denomination: All monetary values are denominated in USDT

Common Errors

Error CodeMessageDescription
400Invalid request formatRequest payload could not be parsed
400Failed to retrieve performance dataInternal error retrieving data
404Subaccount not foundSpecified subaccount does not exist
401Insufficient permissionsAccount lacks access to this subaccount
ErrorDescription
Invalid signatureEIP-712 signature validation failed
Invalid market symbolMarket symbol not recognized
Nonce already usedNonce must be greater than previous value
Rate limit exceededToo many requests in time window
Request expiredexpiresAfter timestamp has passed

Next Steps