PnL Analytics API

The Stratium PnL Analytics API computes FIFO-based realized and unrealized profit/loss for any Solana wallet tracked by the platform, with full audit trail showing which BUY lots were consumed by each SELL via the acquisitions_used field. Every calculation processes the complete trade history across 30+ DEX programs to produce deterministic, step-by-step PnL accounting.

Quick Start

# Full PnL summary for a wallet
curl "https://api.stratiumsol.com/v1/pnl/wallet/7xKXLkq...9bPq" \
  -H "X-API-Key: sk_live_your_key"

# Paginated FIFO steps
curl "https://api.stratiumsol.com/v1/pnl/wallet/7xKXLkq...9bPq/steps?limit=50" \
  -H "X-API-Key: sk_live_your_key"
# Full PnL summary for a wallet
curl "https://api.stratiumsol.com/v1/pnl/wallet/7xKXLkq...9bPq" \
  -H "X-API-Key: sk_live_your_key"

# Paginated FIFO steps
curl "https://api.stratiumsol.com/v1/pnl/wallet/7xKXLkq...9bPq/steps?limit=50" \
  -H "X-API-Key: sk_live_your_key"
const API_KEY = process.env.STRATIUM_API_KEY!;
const BASE = "https://api.stratiumsol.com/v1";

// Full PnL summary
const pnl = await fetch(`${BASE}/pnl/wallet/${walletAddress}`, {
  headers: { "X-API-Key": API_KEY },
}).then((r) => r.json());

console.log(pnl.data.cumulative_pnl); // 142.8 SOL

// Paginated FIFO steps with audit trail
const steps = await fetch(
  `${BASE}/pnl/wallet/${walletAddress}/steps?limit=50&action=SELL`,
  { headers: { "X-API-Key": API_KEY } }
).then((r) => r.json());

for (const step of steps.data) {
  console.log(`${step.action} ${step.token_mint}: ${step.realized_pnl} SOL`);
  console.log("  Lots consumed:", step.acquisitions_used);
}
import os
import requests

API_KEY = os.environ["STRATIUM_API_KEY"]
BASE = "https://api.stratiumsol.com/v1"
HEADERS = {"X-API-Key": API_KEY}

# Full PnL summary
pnl = requests.get(f"{BASE}/pnl/wallet/{wallet_address}", headers=HEADERS).json()
print(f"Cumulative PnL: {pnl['data']['cumulative_pnl']} SOL")

# Paginated FIFO steps
steps = requests.get(
    f"{BASE}/pnl/wallet/{wallet_address}/steps",
    params={"limit": 50, "action": "SELL"},
    headers=HEADERS,
).json()
for step in steps["data"]:
    print(f"{step['action']} {step['token_mint']}: {step['realized_pnl']} SOL")

Endpoints

GET
/api/v1/pnl/wallet/{address}

Full PnL summary including cumulative PnL, active positions, capital deployed, and calculation metadata.

GET
/api/v1/pnl/wallet/{address}/positions

Currently open token positions with cost basis, quantity held, and unrealized PnL per token.

GET
/api/v1/pnl/wallet/{address}/steps

Paginated FIFO calculation steps with full audit trail. Each SELL step includes acquisitions_used referencing consumed BUY lots.

GET
/api/v1/pnl/wallet/{address}/chart

Time-series PnL data optimized for chart rendering. Configurable period, interval, and currency.

GET
/api/v1/pnl/wallet/{address}/analytics

Derived risk and performance metrics: Sharpe ratio, max drawdown, profit factor, win rate, and consistency score.

Request Parameters

GET /api/v1/pnl/wallet/{address}

ParameterTypeRequiredDefaultDescription
addressstringRequiredSolana wallet address (base58, 32-44 characters)
forceRefreshbooleanOptionalfalseBypass cache and trigger fresh FIFO calculation
currencystringOptionalSOLPnL denomination: SOL or USD

GET /api/v1/pnl/wallet/{address}/steps

ParameterTypeRequiredDefaultDescription
actionstringOptionalFilter by trade action: BUY or SELL
token_mintstringOptionalFilter by specific token mint address
limitintegerOptional50Results per page (max 200)
offsetintegerOptional0Pagination offset
sortstringOptionalascSort order: asc (oldest first) or desc (newest first)

GET /api/v1/pnl/wallet/{address}/chart

ParameterTypeRequiredDefaultDescription
periodstringOptional90dTime range: 7d, 30d, 90d, all
intervalstringOptional1dData point interval: 1h, 1d, 1w
currencystringOptionalSOLPnL currency: SOL or USD

Response Schema

PnL Summary

TypeScript Interface
interface PnLSummary {
  wallet_address: string;
  total_trades: number;            // Total BUY + SELL count
  total_buys: number;
  total_sells: number;
  cumulative_pnl: number;          // Final running PnL (SOL)
  active_positions_count: number;  // Tokens still held
  capital_in_positions: number;    // SOL locked in open positions
  earliest_trade: string;          // ISO 8601
  latest_trade: string;            // ISO 8601
  calculation_version: number;
  was_truncated: boolean;          // true if > 500,000 trades
  calculated_at: string;           // ISO 8601
}
interface PnLSummary {
  wallet_address: string;
  total_trades: number;            // Total BUY + SELL count
  total_buys: number;
  total_sells: number;
  cumulative_pnl: number;          // Final running PnL (SOL)
  active_positions_count: number;  // Tokens still held
  capital_in_positions: number;    // SOL locked in open positions
  earliest_trade: string;          // ISO 8601
  latest_trade: string;            // ISO 8601
  calculation_version: number;
  was_truncated: boolean;          // true if > 500,000 trades
  calculated_at: string;           // ISO 8601
}

FIFO Calculation Step

TypeScript Interface
interface PnLStep {
  step_sequence: number;           // 0-based within calculation
  transaction_signature: string;   // Solana transaction signature
  timestamp: number;               // Unix milliseconds
  token_mint: string;              // Token mint address
  action: "BUY" | "SELL";         // Trade direction
  amount: number;                  // Token amount
  price_per_token: number;         // Execution price (SOL)
  total_value: number;             // amount * price_per_token
  cost_basis: number | null;       // SELL only: FIFO cost basis
  realized_pnl: number | null;    // SELL only: proceeds - cost_basis
  cumulative_pnl: number;          // Running PnL total
  remaining_position: number;      // Tokens still held after step
  capital_in_positions: number;    // Total SOL locked in open positions
  holding_time_seconds: number | null; // SELL only: time held
  token_roi_sol: number | null;    // SELL only: return on investment
  acquisitions_used: Array<{       // SELL only: BUY lots consumed
    signature: string;             //   Original BUY transaction
    amount: number;                //   Quantity from this lot
    price: number;                 //   Original purchase price
    timestamp: number;             //   When the BUY occurred
  }> | null;
}
Example Response
{
  "success": true,
  "data": [
    {
      "step_sequence": 42,
      "transaction_signature": "3xKp9V...mN7q",
      "timestamp": 1712841600000,
      "token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "action": "SELL",
      "amount": 1500.0,
      "price_per_token": 0.00245,
      "total_value": 3.675,
      "cost_basis": 2.85,
      "realized_pnl": 0.825,
      "cumulative_pnl": 14.32,
      "remaining_position": 0,
      "capital_in_positions": 8.42,
      "holding_time_seconds": 7200,
      "token_roi_sol": 28.95,
      "acquisitions_used": [
        {
          "signature": "5yRm2Q...kL4p",
          "amount": 1000.0,
          "price": 0.0019,
          "timestamp": 1712834400000
        },
        {
          "signature": "8wTn5K...jP2r",
          "amount": 500.0,
          "price": 0.0019,
          "timestamp": 1712836200000
        }
      ]
    }
  ],
  "meta": {
    "total": 156,
    "offset": 0,
    "limit": 50
  },
  "timestamp": "2026-04-14T12:00:00Z"
}
interface PnLStep {
  step_sequence: number;           // 0-based within calculation
  transaction_signature: string;   // Solana transaction signature
  timestamp: number;               // Unix milliseconds
  token_mint: string;              // Token mint address
  action: "BUY" | "SELL";         // Trade direction
  amount: number;                  // Token amount
  price_per_token: number;         // Execution price (SOL)
  total_value: number;             // amount * price_per_token
  cost_basis: number | null;       // SELL only: FIFO cost basis
  realized_pnl: number | null;    // SELL only: proceeds - cost_basis
  cumulative_pnl: number;          // Running PnL total
  remaining_position: number;      // Tokens still held after step
  capital_in_positions: number;    // Total SOL locked in open positions
  holding_time_seconds: number | null; // SELL only: time held
  token_roi_sol: number | null;    // SELL only: return on investment
  acquisitions_used: Array<{       // SELL only: BUY lots consumed
    signature: string;             //   Original BUY transaction
    amount: number;                //   Quantity from this lot
    price: number;                 //   Original purchase price
    timestamp: number;             //   When the BUY occurred
  }> | null;
}
{
  "success": true,
  "data": [
    {
      "step_sequence": 42,
      "transaction_signature": "3xKp9V...mN7q",
      "timestamp": 1712841600000,
      "token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "action": "SELL",
      "amount": 1500.0,
      "price_per_token": 0.00245,
      "total_value": 3.675,
      "cost_basis": 2.85,
      "realized_pnl": 0.825,
      "cumulative_pnl": 14.32,
      "remaining_position": 0,
      "capital_in_positions": 8.42,
      "holding_time_seconds": 7200,
      "token_roi_sol": 28.95,
      "acquisitions_used": [
        {
          "signature": "5yRm2Q...kL4p",
          "amount": 1000.0,
          "price": 0.0019,
          "timestamp": 1712834400000
        },
        {
          "signature": "8wTn5K...jP2r",
          "amount": 500.0,
          "price": 0.0019,
          "timestamp": 1712836200000
        }
      ]
    }
  ],
  "meta": {
    "total": 156,
    "offset": 0,
    "limit": 50
  },
  "timestamp": "2026-04-14T12:00:00Z"
}

How FIFO Calculation Works

  1. 1. Trade ingestion — All on-chain swap transactions for the wallet are fetched and decoded across 30+ DEX programs (Jupiter, Raydium, Orca, Pump.fun, Meteora, and others).
  2. 2. Chronological ordering — Trades are sorted by block time. Token-to-token swaps are decomposed into SELL (input token) + BUY (output token) step pairs.
  3. 3. FIFO queue per token — Each BUY creates an acquisition lot appended to a per-token FIFO queue. Each SELL consumes lots from the front of the queue until the sold quantity is fulfilled.
  4. 4. PnL computation — For each consumed lot: realized_pnl = (sell_price - buy_price) * quantity. The acquisitions_used array records every lot consumed with its original signature, price, and quantity.
  5. 5. Running totals — cumulative_pnl, remaining_position, and capital_in_positions are updated at every step, providing a complete state snapshot at each point in the wallet's trading history.

Rate Limits

Pricing Tiers

ParameterTypeRequiredDefaultDescription
Analytics tier$249/moOptional120 req/minFull access to PnL Analytics + Wallet Scores
Backtest tier$499/moOptional120 req/minAll endpoints

PnL Analytics requires the Analytics tier or above. Starting from. Pricing details finalized at launch.

Use Cases

Tax reporting

Use the FIFO step trail with acquisitions_used to generate tax-compliant cost basis reports. Each SELL maps directly to specific BUY lots with timestamps and prices.

Portfolio monitoring

Track cumulative_pnl and capital_in_positions in real time. Build dashboards showing per-token exposure, unrealized gains, and historical performance curves.

Risk analysis

Compute drawdown from the cumulative_pnl time series. Analyze capital_in_positions peaks to understand maximum exposure. Use holding_time_seconds to profile trading behavior.

Strategy validation

Compare PnL curves across multiple wallets to validate copy-trading strategies. Filter steps by token_mint to analyze per-token performance attribution.

Start Building with PnL Analytics

The API is in private beta. Request access to integrate FIFO P&L computation into your application.

Request API Access

Frequently Asked Questions

What is FIFO PnL and why does Stratium use it?

FIFO (First In, First Out) matches each SELL against the oldest outstanding BUY lots for that token. This produces a deterministic, auditable PnL trail where every SELL step references the exact BUY transactions it consumed via the acquisitions_used field. FIFO is the standard accounting method for crypto and avoids the ambiguity of average-cost or LIFO approaches.

What does the acquisitions_used field contain?

Each SELL step includes an acquisitions_used array listing the prior BUY lots that were consumed to fulfill the sale. Each entry contains the original BUY transaction signature, the quantity drawn from that lot, the original purchase price, and the timestamp. This provides a complete audit trail from sale back to purchase.

How is capital_in_positions calculated?

capital_in_positions represents the total SOL cost basis locked in all currently open positions at the time of each step. It increases on BUY (cost basis added) and decreases on SELL (consumed lot cost basis removed). This metric is essential for computing capital efficiency and maximum drawdown.

What happens with token-to-token swaps?

Token-to-token swaps (e.g., USDC to BONK) are decomposed into two PnL steps: a SELL of the input token and a BUY of the output token. The SELL step closes the input position and records realized PnL; the BUY step opens a new position in the output token. Both steps share the same transaction_signature.

Are PnL calculations real-time?

PnL is recomputed on demand when requested with forceRefresh and cached for 10 minutes. Each recalculation processes the full trade history from the first trade using the FIFO algorithm. For wallets with more than 500,000 trades, the calculation is truncated and the was_truncated flag is set to true.