{
  "openapi": "3.0.1",
  "info": {
    "title": "Stratium Data API",
    "version": "1.0.0-beta",
    "description": "Solana wallet scoring, on-chain FIFO PnL computation, and portfolio backtesting API. Stratium analyzes trades across 30+ DEX programs (Jupiter, Raydium, Orca, Pump.fun, Meteora, and others) to produce enriched wallet quality scores, full profit/loss audit trails, and configurable historical simulations.\n\nAll data is derived from on-chain Solana transactions. Wallet scores use 21 metrics computed from FIFO P&L analysis. PnL steps include the `acquisitions_used` field showing exactly which BUY lots were consumed by each SELL.\n\nPrivate beta — request access at https://www.stratiumsol.com/developers/console",
    "contact": {
      "name": "Stratium",
      "url": "https://www.stratiumsol.com"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.stratiumsol.com/v1",
      "description": "Production (private beta)"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Wallet Scores",
      "description": "Enriched wallet quality metrics and composite scores for Solana wallets discovered by the Alpha Forge pipeline."
    },
    {
      "name": "PnL Analytics",
      "description": "FIFO-based profit/loss computation with full audit trail for tracked Solana wallets."
    },
    {
      "name": "Portfolio Backtest",
      "description": "Historical portfolio simulation with configurable capital, sizing, and multi-wallet strategy comparison."
    }
  ],
  "paths": {
    "/wallets/scored": {
      "get": {
        "tags": ["Wallet Scores"],
        "summary": "List scored wallets",
        "description": "Returns a paginated list of scored Solana wallets with 21 enriched quality metrics. Results are cached and include a composite `enriched_score` (0-1) combining win rate, profit factor, consistency, drawdown, and other indicators. Use this to discover high-performing wallets for copy-trading strategy research.",
        "operationId": "getScoredWallets",
        "parameters": [
          {
            "name": "min_score",
            "in": "query",
            "required": false,
            "description": "Minimum enriched_score threshold (0-1). Only wallets with a composite score at or above this value are returned.",
            "schema": {
              "type": "number",
              "format": "float",
              "minimum": 0,
              "maximum": 1,
              "default": 0
            }
          },
          {
            "name": "min_sell_count",
            "in": "query",
            "required": false,
            "description": "Minimum number of SELL trades the wallet must have executed. Higher values filter out low-activity wallets.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 10
            }
          },
          {
            "name": "min_pnl_sol",
            "in": "query",
            "required": false,
            "description": "Minimum total realized PnL in SOL. Use to filter for wallets with positive track records.",
            "schema": {
              "type": "number",
              "format": "float",
              "default": 0
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Field to sort results by.",
            "schema": {
              "type": "string",
              "enum": ["enriched_score", "win_rate", "total_pnl_sol", "sell_count"],
              "default": "enriched_score"
            }
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "description": "Sort direction.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of results per page. Maximum 100.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Pagination offset. Use with limit for paging through results.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of scored wallets.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/WalletScore" }
                    },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
                      "enriched_score": 0.742,
                      "win_rate": 67.3,
                      "total_pnl_sol": 47.832,
                      "sell_count": 89,
                      "win_count": 60,
                      "avg_pnl_percent": 12.45,
                      "avg_holding_time_sec": 3842,
                      "best_trade_pnl_sol": 8.291,
                      "profit_factor": 2.14,
                      "max_drawdown_pct": 18.4,
                      "consistency_score": 0.68,
                      "sharpe_per_trade": 0.312,
                      "concentration_top_token_pct": 22.1,
                      "concentration_top_token": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                      "median_hold_time_sec": 2940,
                      "sizing_cv": 0.45,
                      "noise_flags": [],
                      "discovery_source": "program_observer",
                      "review_status": "scored",
                      "updated_at": "2026-04-14T08:23:41Z"
                    }
                  ],
                  "meta": {
                    "total": 142,
                    "limit": 20,
                    "offset": 0,
                    "has_more": true,
                    "cached": true,
                    "cache_age_seconds": 45
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/wallets/{address}/score": {
      "get": {
        "tags": ["Wallet Scores"],
        "summary": "Get wallet score",
        "description": "Returns the full score and all 21 enriched quality metrics for a specific Solana wallet address. The response includes the composite enriched_score plus individual indicators like profit_factor, max_drawdown_pct, consistency_score, and noise_flags.",
        "operationId": "getWalletScore",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Full wallet score with all 21 metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/WalletScore" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
                    "enriched_score": 0.742,
                    "win_rate": 67.3,
                    "total_pnl_sol": 47.832,
                    "sell_count": 89,
                    "win_count": 60,
                    "avg_pnl_percent": 12.45,
                    "avg_holding_time_sec": 3842,
                    "best_trade_pnl_sol": 8.291,
                    "profit_factor": 2.14,
                    "max_drawdown_pct": 18.4,
                    "consistency_score": 0.68,
                    "sharpe_per_trade": 0.312,
                    "concentration_top_token_pct": 22.1,
                    "concentration_top_token": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                    "median_hold_time_sec": 2940,
                    "sizing_cv": 0.45,
                    "noise_flags": [],
                    "discovery_source": "program_observer",
                    "review_status": "scored",
                    "updated_at": "2026-04-14T08:23:41Z"
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Wallet not found or not yet scored.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" },
                "example": {
                  "success": false,
                  "error": { "code": "NOT_FOUND", "message": "Wallet not found or not yet scored by Alpha Forge pipeline." },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/wallets/stream": {
      "get": {
        "tags": ["Wallet Scores"],
        "summary": "Stream wallet score events",
        "description": "Server-Sent Events (SSE) stream of real-time wallet scoring and discovery pipeline events. The connection stays open and pushes events as wallets are detected, scored, promoted, or rejected by the Alpha Forge pipeline.\n\nEvent types:\n- `score_updated` — a wallet's score was recalculated\n- `wallet_scored` — a new wallet completed scoring\n- `wallet_rejected` — a wallet was auto-rejected by quality filters\n\nEach event is a JSON object with `type`, `wallet_address`, and event-specific fields. The server sends a `heartbeat` event every 25 seconds to keep the connection alive.",
        "operationId": "streamWalletScores",
        "responses": {
          "200": {
            "description": "SSE stream of wallet scoring events.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-Sent Events stream. Each event has `event:` (type) and `data:` (JSON) fields.\n\nExample SSE message:\n```\nevent: wallet_scored\ndata: {\"type\":\"wallet_scored\",\"wallet_address\":\"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU\",\"enriched_score\":0.742,\"win_rate\":67.3,\"total_pnl_sol\":47.832}\n\n```"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pnl/wallet/{address}": {
      "get": {
        "tags": ["PnL Analytics"],
        "summary": "Get PnL summary",
        "description": "Returns a full FIFO-based PnL summary for a tracked Solana wallet, including cumulative realized PnL, active position count, capital deployed, and calculation metadata. The FIFO engine processes every BUY and SELL chronologically to compute accurate cost basis and realized gains.",
        "operationId": "getWalletPnl",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Bypass the 10-minute cache and trigger a fresh FIFO calculation from trade #1. Use sparingly — fresh calculations are compute-intensive.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "PnL denomination currency.",
            "schema": {
              "type": "string",
              "enum": ["SOL", "USD"],
              "default": "SOL"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PnL summary for the wallet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/PnLSummary" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "wallet_address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
                    "total_trades": 312,
                    "total_buys": 178,
                    "total_sells": 134,
                    "cumulative_pnl": 47.832,
                    "active_positions_count": 12,
                    "capital_in_positions": 8.45,
                    "earliest_trade": "2025-11-02T14:22:18Z",
                    "latest_trade": "2026-04-14T07:58:31Z",
                    "calculation_version": 1,
                    "was_truncated": false,
                    "calculated_at": "2026-04-14T08:00:12Z"
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Wallet not found or has no tracked trades.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pnl/wallet/{address}/positions": {
      "get": {
        "tags": ["PnL Analytics"],
        "summary": "Get open positions",
        "description": "Returns currently open token positions for a tracked wallet. Each position includes the token mint, quantity held, FIFO cost basis, and current unrealized PnL. Positions are tokens that have been bought but not fully sold.",
        "operationId": "getWalletPositions",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of open token positions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Position" }
                    },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "token_mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                      "token_symbol": "BONK",
                      "remaining_amount": 15000000.0,
                      "cost_basis_sol": 0.832,
                      "current_value_sol": 1.104,
                      "unrealized_pnl_sol": 0.272,
                      "acquisitions": [
                        {
                          "signature": "4Nf8cEj3kPTcRhxVd8ZgvCkLHWMfMrAQBnxJPqwGvLs8AzPVPUiprXs9TNqEYLfKvtYbKV4oqrRFNYEJcHKvJ1U",
                          "amount": 15000000.0,
                          "price": 0.0000000555,
                          "timestamp": "2026-04-10T14:22:18Z"
                        }
                      ]
                    }
                  ],
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Wallet not found.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pnl/wallet/{address}/steps": {
      "get": {
        "tags": ["PnL Analytics"],
        "summary": "Get FIFO calculation steps",
        "description": "Returns paginated FIFO calculation steps with a full audit trail. Each step represents one trade event (BUY or SELL). For SELL steps, the `acquisitions_used` field shows exactly which prior BUY lots were consumed and at what price, enabling independent P&L verification.",
        "operationId": "getWalletPnlSteps",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "description": "Filter steps by trade direction. Omit to return both BUY and SELL steps.",
            "schema": {
              "type": "string",
              "enum": ["BUY", "SELL"]
            }
          },
          {
            "name": "token_mint",
            "in": "query",
            "required": false,
            "description": "Filter steps by a specific token mint address (base58, 32-44 characters).",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of steps per page. Maximum 200.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Pagination offset.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort order by timestamp. `asc` returns oldest first (chronological FIFO order), `desc` returns newest first.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "asc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated FIFO calculation steps.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/PnLStep" }
                    },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "step_sequence": 0,
                      "transaction_signature": "4Nf8cEj3kPTcRhxVd8ZgvCkLHWMfMrAQBnxJPqwGvLs8AzPVPUiprXs9TNqEYLfKvtYbKV4oqrRFNYEJcHKvJ1U",
                      "timestamp": 1712834538000,
                      "token_mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                      "action": "BUY",
                      "amount": 15000000.0,
                      "price_per_token": 0.0000000555,
                      "total_value": 0.832,
                      "cost_basis": null,
                      "realized_pnl": null,
                      "cumulative_pnl": 0.0,
                      "remaining_position": 15000000.0,
                      "capital_in_positions": 0.832,
                      "holding_time_seconds": null,
                      "token_roi_sol": null,
                      "acquisitions_used": null
                    },
                    {
                      "step_sequence": 1,
                      "transaction_signature": "3YpR7mJxL2QvKfHnW9dkTmS5rNqF8xBcVeGkJ4nMhwL6PqWuRs2JkXgTvN8yAcZ5mDeFbKqHjLwR9sU7tYpV4xK",
                      "timestamp": 1712838142000,
                      "token_mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                      "action": "SELL",
                      "amount": 15000000.0,
                      "price_per_token": 0.0000000738,
                      "total_value": 1.107,
                      "cost_basis": 0.832,
                      "realized_pnl": 0.275,
                      "cumulative_pnl": 0.275,
                      "remaining_position": 0.0,
                      "capital_in_positions": 0.0,
                      "holding_time_seconds": 3604,
                      "token_roi_sol": 0.3305,
                      "acquisitions_used": [
                        {
                          "signature": "4Nf8cEj3kPTcRhxVd8ZgvCkLHWMfMrAQBnxJPqwGvLs8AzPVPUiprXs9TNqEYLfKvtYbKV4oqrRFNYEJcHKvJ1U",
                          "amount": 15000000.0,
                          "price": 0.0000000555,
                          "timestamp": 1712834538000
                        }
                      ]
                    }
                  ],
                  "meta": {
                    "total": 312,
                    "limit": 50,
                    "offset": 0,
                    "has_more": true,
                    "cached": true,
                    "cache_age_seconds": 120
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pnl/wallet/{address}/chart": {
      "get": {
        "tags": ["PnL Analytics"],
        "summary": "Get PnL chart data",
        "description": "Returns time-series PnL data optimized for chart rendering. Each data point includes a timestamp and the cumulative PnL value at that point. Configurable period, interval, and currency denomination.",
        "operationId": "getWalletPnlChart",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Time range for the chart data.",
            "schema": {
              "type": "string",
              "enum": ["7d", "30d", "90d", "all"],
              "default": "90d"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "required": false,
            "description": "Data point interval.",
            "schema": {
              "type": "string",
              "enum": ["1h", "1d", "1w"],
              "default": "1d"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "PnL denomination currency.",
            "schema": {
              "type": "string",
              "enum": ["SOL", "USD"],
              "default": "SOL"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Time-series PnL chart data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "object",
                      "properties": {
                        "points": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/ChartPoint" }
                        },
                        "period": { "type": "string" },
                        "interval": { "type": "string" },
                        "currency": { "type": "string" }
                      }
                    },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "points": [
                      { "timestamp": "2026-01-15T00:00:00Z", "cumulative_pnl": 0.0 },
                      { "timestamp": "2026-01-16T00:00:00Z", "cumulative_pnl": 1.23 },
                      { "timestamp": "2026-01-17T00:00:00Z", "cumulative_pnl": 3.89 },
                      { "timestamp": "2026-01-18T00:00:00Z", "cumulative_pnl": 2.45 },
                      { "timestamp": "2026-01-19T00:00:00Z", "cumulative_pnl": 5.67 }
                    ],
                    "period": "90d",
                    "interval": "1d",
                    "currency": "SOL"
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pnl/wallet/{address}/analytics": {
      "get": {
        "tags": ["PnL Analytics"],
        "summary": "Get risk and performance analytics",
        "description": "Returns derived risk and performance metrics for a tracked wallet: Sharpe ratio, maximum drawdown, profit factor, win rate, consistency score, and concentration analysis. These are computed from the FIFO P&L steps.",
        "operationId": "getWalletAnalytics",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58-encoded Solana wallet address (32-44 characters). Example: DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Risk and performance analytics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/WalletAnalytics" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "wallet_address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
                    "sharpe_ratio": 1.42,
                    "max_drawdown_pct": 18.4,
                    "profit_factor": 2.14,
                    "win_rate": 67.3,
                    "consistency_score": 0.68,
                    "concentration_top_token_pct": 22.1,
                    "concentration_top_token": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                    "avg_holding_time_sec": 3842,
                    "median_hold_time_sec": 2940,
                    "total_trades_analyzed": 312,
                    "analysis_period_start": "2025-11-02T14:22:18Z",
                    "analysis_period_end": "2026-04-14T07:58:31Z"
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Wallet not found.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/run": {
      "post": {
        "tags": ["Portfolio Backtest"],
        "summary": "Run a backtest",
        "description": "Submit a new portfolio backtest simulation. The engine replays historical trades from the specified wallets, simulating copy-trading with configurable capital allocation, trade sizing, and slippage. Returns a backtest_id for polling progress and retrieving results.\n\nBacktests are asynchronous — poll `/backtest/{id}/progress` until status is `completed`, then fetch results from `/backtest/{id}`.",
        "operationId": "runBacktest",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/BacktestRequest" },
              "example": {
                "wallets": [
                  {
                    "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
                    "allocation": 0.6,
                    "slippageBps": 50
                  },
                  {
                    "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
                    "allocation": 0.4,
                    "slippageBps": 50
                  }
                ],
                "capital": {
                  "solAmount": 10.0
                },
                "period": {
                  "start": "2026-01-01",
                  "end": "2026-04-01"
                },
                "sizing": {
                  "mode": "PERCENTAGE",
                  "positionCapPercent": 5.0
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Backtest submitted. Use the returned backtest_id to poll for progress.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "object",
                      "properties": {
                        "backtest_id": {
                          "type": "string",
                          "description": "Unique backtest identifier. Format: bt_*",
                          "example": "bt_a1b2c3d4e5f6"
                        }
                      },
                      "required": ["backtest_id"]
                    },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": { "backtest_id": "bt_a1b2c3d4e5f6" },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/{id}/progress": {
      "get": {
        "tags": ["Portfolio Backtest"],
        "summary": "Get backtest progress",
        "description": "Poll the execution progress of a running backtest. Returns the current status and a progress percentage (0-100). Poll this endpoint until `status` is `completed` or `failed`, then fetch full results from `/backtest/{id}`.",
        "operationId": "getBacktestProgress",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Backtest ID returned by POST /backtest/run. Format: bt_*",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current backtest progress.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/BacktestProgress" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "backtest_id": "bt_a1b2c3d4e5f6",
                    "status": "running",
                    "progress_percent": 64
                  },
                  "timestamp": "2026-04-14T12:00:15Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Backtest ID not found.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/{id}": {
      "get": {
        "tags": ["Portfolio Backtest"],
        "summary": "Get backtest results",
        "description": "Retrieve completed backtest results with full performance metrics including PnL, ROI, drawdown, Sharpe ratio, win rate, and profit factor. Returns an error if the backtest is still running — poll `/backtest/{id}/progress` first.",
        "operationId": "getBacktestResult",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Backtest ID returned by POST /backtest/run. Format: bt_*",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Completed backtest results.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/BacktestResult" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "backtest_id": "bt_a1b2c3d4e5f6",
                    "status": "completed",
                    "progress_percent": 100,
                    "wallets": ["7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK"],
                    "capital_sol": 10.0,
                    "period_start": "2026-01-01T00:00:00Z",
                    "period_end": "2026-04-01T00:00:00Z",
                    "sizing_mode": "PERCENTAGE",
                    "total_trades": 247,
                    "successful_trades": 238,
                    "failed_trades": 9,
                    "final_pnl_sol": 14.832,
                    "roi_percent": 148.32,
                    "roi_annualized_percent": 593.28,
                    "max_capital_deployed_sol": 8.74,
                    "max_drawdown_percent": 12.7,
                    "win_rate_percent": 64.2,
                    "profit_factor": 1.89,
                    "sharpe_ratio": 1.34,
                    "best_trade_pnl_sol": 3.21,
                    "worst_trade_pnl_sol": -0.94,
                    "median_trade_pnl_sol": 0.042,
                    "created_at": "2026-04-14T12:00:00Z",
                    "completed_at": "2026-04-14T12:00:32Z"
                  },
                  "timestamp": "2026-04-14T12:00:35Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Backtest ID not found.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/{id}/steps": {
      "get": {
        "tags": ["Portfolio Backtest"],
        "summary": "Get backtest FIFO steps",
        "description": "Returns paginated FIFO calculation steps for the simulated portfolio. Same schema as PnL Analytics steps — each step is a BUY or SELL event with cost basis, realized PnL, and acquisitions_used audit trail.",
        "operationId": "getBacktestSteps",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Backtest ID returned by POST /backtest/run. Format: bt_*",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of steps per page. Maximum 200.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Pagination offset.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "description": "Filter steps by trade direction.",
            "schema": {
              "type": "string",
              "enum": ["BUY", "SELL"]
            }
          },
          {
            "name": "token_mint",
            "in": "query",
            "required": false,
            "description": "Filter steps by a specific token mint address (base58, 32-44 characters).",
            "schema": {
              "type": "string",
              "minLength": 32,
              "maxLength": 44
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated backtest FIFO steps.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/PnLStep" }
                    },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Backtest ID not found.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/compare": {
      "post": {
        "tags": ["Portfolio Backtest"],
        "summary": "Compare backtest strategies",
        "description": "Compare up to 10 strategy configurations side by side. Each strategy is a full backtest configuration (wallets, capital, period, sizing). Returns normalized performance metrics for fair comparison across different capital amounts.",
        "operationId": "compareBacktests",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["strategies"],
                "properties": {
                  "strategies": {
                    "type": "array",
                    "description": "Array of up to 10 backtest configurations to compare.",
                    "minItems": 2,
                    "maxItems": 10,
                    "items": { "$ref": "#/components/schemas/BacktestRequest" }
                  },
                  "normalize": {
                    "type": "boolean",
                    "description": "Normalize all strategies to the same starting capital for fair comparison.",
                    "default": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Comparison results for all submitted strategies.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/BacktestResult" }
                    },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/backtest/available-wallets": {
      "get": {
        "tags": ["Portfolio Backtest"],
        "summary": "List available wallets for backtesting",
        "description": "Returns wallets that have sufficient historical trade data for backtesting within a given time period. Use this to discover which wallets can be included in a backtest before submitting a run.",
        "operationId": "getAvailableWallets",
        "parameters": [
          {
            "name": "period_start",
            "in": "query",
            "required": false,
            "description": "Filter wallets with trade data starting from this date. ISO 8601 or YYYY-MM-DD format.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "period_end",
            "in": "query",
            "required": false,
            "description": "Filter wallets with trade data up to this date. ISO 8601 or YYYY-MM-DD format.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "min_trades",
            "in": "query",
            "required": false,
            "description": "Minimum number of trades the wallet must have in the period.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 10
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of results per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Pagination offset.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of wallets with sufficient historical data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/AvailableWallet" }
                    },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
                      "trade_count": 312,
                      "period_start": "2025-08-14T00:00:00Z",
                      "period_end": "2026-04-14T07:58:31Z"
                    },
                    {
                      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
                      "trade_count": 189,
                      "period_start": "2025-10-01T00:00:00Z",
                      "period_end": "2026-04-13T22:14:07Z"
                    }
                  ],
                  "meta": {
                    "total": 31,
                    "limit": 50,
                    "offset": 0,
                    "has_more": false,
                    "cached": false,
                    "cache_age_seconds": 0
                  },
                  "timestamp": "2026-04-14T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key issued after access request approval. Format: sk_live_*"
      }
    },
    "schemas": {
      "WalletScore": {
        "type": "object",
        "description": "Enriched wallet quality metrics computed from on-chain FIFO P&L analysis.",
        "required": ["wallet_address", "enriched_score", "win_rate", "total_pnl_sol", "sell_count"],
        "properties": {
          "wallet_address": { "type": "string", "description": "Base58-encoded Solana wallet address.", "example": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" },
          "enriched_score": { "type": "number", "format": "float", "description": "Composite quality score (0-1) combining win rate, profit factor, consistency, drawdown, and other indicators.", "minimum": 0, "maximum": 1, "example": 0.742 },
          "win_rate": { "type": "number", "format": "float", "description": "Percentage of SELL trades that were profitable.", "example": 67.3 },
          "total_pnl_sol": { "type": "number", "format": "float", "description": "Total realized PnL in SOL across all closed trades.", "example": 47.832 },
          "sell_count": { "type": "integer", "description": "Total number of SELL trades analyzed.", "example": 89 },
          "win_count": { "type": "integer", "description": "Number of profitable SELL trades.", "example": 60 },
          "avg_pnl_percent": { "type": "number", "format": "float", "description": "Average PnL percentage per trade.", "example": 12.45 },
          "avg_holding_time_sec": { "type": "number", "format": "float", "description": "Average holding time in seconds between BUY and SELL.", "example": 3842 },
          "best_trade_pnl_sol": { "type": "number", "format": "float", "description": "Largest single-trade realized PnL in SOL.", "example": 8.291 },
          "profit_factor": { "type": "number", "format": "float", "description": "Ratio of gross profit to gross loss. Values above 1.0 indicate overall profitability.", "example": 2.14 },
          "max_drawdown_pct": { "type": "number", "format": "float", "description": "Worst peak-to-trough portfolio decline as a percentage.", "example": 18.4 },
          "consistency_score": { "type": "number", "format": "float", "description": "Performance consistency score (0-1). Higher values indicate more stable returns across time periods.", "minimum": 0, "maximum": 1, "example": 0.68 },
          "sharpe_per_trade": { "type": "number", "format": "float", "description": "Risk-adjusted return per trade.", "example": 0.312 },
          "concentration_top_token_pct": { "type": "number", "format": "float", "description": "Percentage of total PnL attributable to the single most profitable token.", "example": 22.1 },
          "concentration_top_token": { "type": "string", "description": "Mint address of the token contributing the most to total PnL.", "example": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" },
          "median_hold_time_sec": { "type": "number", "format": "float", "description": "Median holding time in seconds (more robust than average against outliers).", "example": 2940 },
          "sizing_cv": { "type": "number", "format": "float", "description": "Coefficient of variation of trade sizes. Lower values indicate more consistent position sizing.", "example": 0.45 },
          "noise_flags": { "type": "array", "items": { "type": "string", "enum": ["high_frequency", "single_token", "small_trades", "round_trip", "young_wallet"] }, "description": "Quality flags indicating potential noise patterns in the wallet's trading behavior. Empty array for clean wallets.", "example": [] },
          "discovery_source": { "type": "string", "description": "How the wallet was discovered by the Alpha Forge pipeline.", "enum": ["pnl_scan", "program_observer", "co_occurrence"], "example": "program_observer" },
          "review_status": { "type": "string", "description": "Current pipeline status.", "enum": ["scored", "promoted"], "example": "scored" },
          "updated_at": { "type": "string", "format": "date-time", "description": "When the wallet score was last updated.", "example": "2026-04-14T08:23:41Z" }
        }
      },
      "PnLSummary": {
        "type": "object",
        "description": "FIFO-based PnL summary for a tracked Solana wallet.",
        "required": ["wallet_address", "total_trades", "cumulative_pnl", "calculated_at"],
        "properties": {
          "wallet_address": { "type": "string", "example": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK" },
          "total_trades": { "type": "integer", "description": "Total BUY + SELL trade count.", "example": 312 },
          "total_buys": { "type": "integer", "example": 178 },
          "total_sells": { "type": "integer", "example": 134 },
          "cumulative_pnl": { "type": "number", "format": "float", "description": "Final running PnL in the requested currency.", "example": 47.832 },
          "active_positions_count": { "type": "integer", "description": "Number of tokens still held (bought but not fully sold).", "example": 12 },
          "capital_in_positions": { "type": "number", "format": "float", "description": "Total SOL cost basis locked in open positions.", "example": 8.45 },
          "earliest_trade": { "type": "string", "format": "date-time", "description": "Timestamp of the first trade.", "example": "2025-11-02T14:22:18Z" },
          "latest_trade": { "type": "string", "format": "date-time", "description": "Timestamp of the most recent trade.", "example": "2026-04-14T07:58:31Z" },
          "calculation_version": { "type": "integer", "description": "FIFO engine version used for this calculation.", "example": 1 },
          "was_truncated": { "type": "boolean", "description": "True if the wallet has more than 500,000 trades and the calculation was capped.", "example": false },
          "calculated_at": { "type": "string", "format": "date-time", "description": "When this calculation was performed.", "example": "2026-04-14T08:00:12Z" }
        }
      },
      "PnLStep": {
        "type": "object",
        "description": "A single FIFO calculation step representing one trade event (BUY or SELL).",
        "required": ["step_sequence", "transaction_signature", "timestamp", "token_mint", "action", "amount", "price_per_token", "total_value", "cumulative_pnl"],
        "properties": {
          "step_sequence": { "type": "integer", "description": "0-based index within the calculation. Steps are ordered chronologically.", "example": 1 },
          "transaction_signature": { "type": "string", "description": "Solana transaction signature (base58, 88 characters). Verifiable on Solscan.", "example": "3YpR7mJxL2QvKfHnW9dkTmS5rNqF8xBcVeGkJ4nMhwL6PqWuRs2JkXgTvN8yAcZ5mDeFbKqHjLwR9sU7tYpV4xK" },
          "timestamp": { "type": "integer", "format": "int64", "description": "Unix timestamp in milliseconds when the trade occurred.", "example": 1712838142000 },
          "token_mint": { "type": "string", "description": "Solana token mint address (base58, 32-44 characters).", "example": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" },
          "action": { "type": "string", "enum": ["BUY", "SELL"], "description": "Trade direction. Token-to-token swaps produce two steps: SELL(input) + BUY(output).", "example": "SELL" },
          "amount": { "type": "number", "format": "double", "description": "Token amount traded.", "example": 15000000.0 },
          "price_per_token": { "type": "number", "format": "double", "description": "Execution price per token in the requested currency.", "example": 0.0000000738 },
          "total_value": { "type": "number", "format": "double", "description": "Total trade value (amount * price_per_token).", "example": 1.107 },
          "cost_basis": { "type": "number", "format": "double", "nullable": true, "description": "FIFO cost basis for SELL steps. Null for BUY steps.", "example": 0.832 },
          "realized_pnl": { "type": "number", "format": "double", "nullable": true, "description": "Realized profit or loss for this SELL step (proceeds - cost_basis). Null for BUY steps.", "example": 0.275 },
          "cumulative_pnl": { "type": "number", "format": "double", "description": "Running total of realized PnL after this step.", "example": 0.275 },
          "remaining_position": { "type": "number", "format": "double", "nullable": true, "description": "Token quantity still held after this step.", "example": 0.0 },
          "capital_in_positions": { "type": "number", "format": "double", "nullable": true, "description": "Total SOL cost basis in all open positions after this step.", "example": 0.0 },
          "holding_time_seconds": { "type": "integer", "nullable": true, "description": "Seconds between the BUY and this SELL. Null for BUY steps.", "example": 3604 },
          "token_roi_sol": { "type": "number", "format": "double", "nullable": true, "description": "Return on investment for this SELL in SOL terms. Null for BUY steps.", "example": 0.3305 },
          "acquisitions_used": {
            "nullable": true,
            "description": "For SELL steps: array of BUY lots consumed by this SELL (FIFO audit trail). Null for BUY steps. Each entry references the original BUY transaction, quantity consumed, and purchase price.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "signature": { "type": "string", "description": "Transaction signature of the original BUY." },
                "amount": { "type": "number", "description": "Quantity consumed from this BUY lot." },
                "price": { "type": "number", "description": "Original purchase price per token." },
                "timestamp": { "type": "integer", "format": "int64", "description": "Unix timestamp (ms) of the original BUY." }
              }
            },
            "example": [
              {
                "signature": "4Nf8cEj3kPTcRhxVd8ZgvCkLHWMfMrAQBnxJPqwGvLs8AzPVPUiprXs9TNqEYLfKvtYbKV4oqrRFNYEJcHKvJ1U",
                "amount": 15000000.0,
                "price": 0.0000000555,
                "timestamp": 1712834538000
              }
            ]
          }
        }
      },
      "Position": {
        "type": "object",
        "description": "An open token position with cost basis and unrealized PnL.",
        "properties": {
          "token_mint": { "type": "string", "description": "Solana token mint address.", "example": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" },
          "token_symbol": { "type": "string", "description": "Token ticker symbol.", "example": "BONK" },
          "remaining_amount": { "type": "number", "format": "double", "description": "Token quantity still held.", "example": 15000000.0 },
          "cost_basis_sol": { "type": "number", "format": "double", "description": "FIFO cost basis in SOL.", "example": 0.832 },
          "current_value_sol": { "type": "number", "format": "double", "description": "Current market value in SOL.", "example": 1.104 },
          "unrealized_pnl_sol": { "type": "number", "format": "double", "description": "Unrealized profit/loss (current_value - cost_basis).", "example": 0.272 },
          "acquisitions": {
            "type": "array",
            "description": "BUY lots that make up this position.",
            "items": {
              "type": "object",
              "properties": {
                "signature": { "type": "string" },
                "amount": { "type": "number" },
                "price": { "type": "number" },
                "timestamp": { "type": "string", "format": "date-time" }
              }
            }
          }
        }
      },
      "ChartPoint": {
        "type": "object",
        "description": "A single data point in a PnL time series.",
        "properties": {
          "timestamp": { "type": "string", "format": "date-time", "description": "Data point timestamp.", "example": "2026-01-15T00:00:00Z" },
          "cumulative_pnl": { "type": "number", "format": "double", "description": "Cumulative PnL at this point in time.", "example": 3.89 }
        }
      },
      "WalletAnalytics": {
        "type": "object",
        "description": "Derived risk and performance metrics for a wallet.",
        "properties": {
          "wallet_address": { "type": "string", "example": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK" },
          "sharpe_ratio": { "type": "number", "format": "float", "description": "Risk-adjusted return metric.", "example": 1.42 },
          "max_drawdown_pct": { "type": "number", "format": "float", "description": "Worst peak-to-trough decline percentage.", "example": 18.4 },
          "profit_factor": { "type": "number", "format": "float", "description": "Gross profit divided by gross loss.", "example": 2.14 },
          "win_rate": { "type": "number", "format": "float", "description": "Percentage of profitable SELL trades.", "example": 67.3 },
          "consistency_score": { "type": "number", "format": "float", "description": "Performance consistency (0-1).", "example": 0.68 },
          "concentration_top_token_pct": { "type": "number", "format": "float", "example": 22.1 },
          "concentration_top_token": { "type": "string", "example": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" },
          "avg_holding_time_sec": { "type": "number", "format": "float", "example": 3842 },
          "median_hold_time_sec": { "type": "number", "format": "float", "example": 2940 },
          "total_trades_analyzed": { "type": "integer", "example": 312 },
          "analysis_period_start": { "type": "string", "format": "date-time", "example": "2025-11-02T14:22:18Z" },
          "analysis_period_end": { "type": "string", "format": "date-time", "example": "2026-04-14T07:58:31Z" }
        }
      },
      "BacktestRequest": {
        "type": "object",
        "description": "Configuration for a portfolio backtest simulation.",
        "required": ["wallets", "capital", "period", "sizing"],
        "properties": {
          "wallets": {
            "type": "array",
            "description": "Wallets to include in the backtest with allocation weights.",
            "minItems": 1,
            "maxItems": 10,
            "items": {
              "type": "object",
              "required": ["address", "allocation"],
              "properties": {
                "address": { "type": "string", "description": "Base58-encoded Solana wallet address.", "example": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" },
                "allocation": { "type": "number", "format": "float", "description": "Capital allocation weight (0-1). All allocations should sum to 1.0.", "minimum": 0, "maximum": 1, "example": 0.6 },
                "slippageBps": { "type": "integer", "description": "Simulated slippage in basis points (0-1000). 100 bps = 1%.", "minimum": 0, "maximum": 1000, "default": 0, "example": 50 }
              }
            }
          },
          "capital": {
            "type": "object",
            "required": ["solAmount"],
            "properties": {
              "solAmount": { "type": "number", "format": "float", "description": "Starting capital in SOL.", "minimum": 0.01, "example": 10.0 }
            }
          },
          "period": {
            "type": "object",
            "required": ["start", "end"],
            "properties": {
              "start": { "type": "string", "format": "date", "description": "Backtest start date (ISO 8601 or YYYY-MM-DD).", "example": "2026-01-01" },
              "end": { "type": "string", "format": "date", "description": "Backtest end date (ISO 8601 or YYYY-MM-DD).", "example": "2026-04-01" }
            }
          },
          "sizing": {
            "type": "object",
            "required": ["mode"],
            "properties": {
              "mode": { "type": "string", "enum": ["FIXED_SIZE", "PERCENTAGE"], "description": "Trade sizing mode. FIXED_SIZE uses a fixed SOL amount per trade. PERCENTAGE uses a percentage of portfolio value.", "example": "PERCENTAGE" },
              "fixedAmountSol": { "type": "number", "format": "float", "description": "SOL amount per trade when mode is FIXED_SIZE.", "example": 0.1 },
              "positionCapPercent": { "type": "number", "format": "float", "description": "Maximum percentage of capital per position when mode is PERCENTAGE.", "default": 5.0, "example": 5.0 }
            }
          }
        }
      },
      "BacktestProgress": {
        "type": "object",
        "description": "Current execution progress of a backtest.",
        "required": ["backtest_id", "status", "progress_percent"],
        "properties": {
          "backtest_id": { "type": "string", "example": "bt_a1b2c3d4e5f6" },
          "status": { "type": "string", "enum": ["pending", "running", "completed", "failed"], "example": "running" },
          "progress_percent": { "type": "number", "minimum": 0, "maximum": 100, "description": "Execution progress (0-100).", "example": 64 }
        }
      },
      "BacktestResult": {
        "type": "object",
        "description": "Completed backtest results with full performance metrics.",
        "required": ["backtest_id", "status"],
        "properties": {
          "backtest_id": { "type": "string", "example": "bt_a1b2c3d4e5f6" },
          "status": { "type": "string", "enum": ["pending", "running", "completed", "failed"], "example": "completed" },
          "progress_percent": { "type": "number", "example": 100 },
          "wallets": { "type": "array", "items": { "type": "string" }, "description": "Input wallet addresses.", "example": ["7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK"] },
          "capital_sol": { "type": "number", "format": "float", "description": "Starting capital in SOL.", "example": 10.0 },
          "period_start": { "type": "string", "format": "date-time", "example": "2026-01-01T00:00:00Z" },
          "period_end": { "type": "string", "format": "date-time", "example": "2026-04-01T00:00:00Z" },
          "sizing_mode": { "type": "string", "enum": ["FIXED_SIZE", "PERCENTAGE"], "example": "PERCENTAGE" },
          "total_trades": { "type": "integer", "description": "Total trades simulated.", "example": 247 },
          "successful_trades": { "type": "integer", "example": 238 },
          "failed_trades": { "type": "integer", "example": 9 },
          "final_pnl_sol": { "type": "number", "format": "float", "description": "Cumulative realized PnL in SOL.", "example": 14.832 },
          "roi_percent": { "type": "number", "format": "float", "description": "Return on investment as a percentage.", "example": 148.32 },
          "roi_annualized_percent": { "type": "number", "format": "float", "description": "Annualized ROI percentage.", "example": 593.28 },
          "max_capital_deployed_sol": { "type": "number", "format": "float", "description": "Peak capital deployed in positions.", "example": 8.74 },
          "max_drawdown_percent": { "type": "number", "format": "float", "description": "Worst peak-to-trough decline percentage.", "example": 12.7 },
          "win_rate_percent": { "type": "number", "format": "float", "description": "Percentage of profitable SELL trades.", "example": 64.2 },
          "profit_factor": { "type": "number", "format": "float", "description": "Gross profit / gross loss.", "example": 1.89 },
          "sharpe_ratio": { "type": "number", "format": "float", "description": "Risk-adjusted return.", "example": 1.34 },
          "best_trade_pnl_sol": { "type": "number", "format": "float", "example": 3.21 },
          "worst_trade_pnl_sol": { "type": "number", "format": "float", "example": -0.94 },
          "median_trade_pnl_sol": { "type": "number", "format": "float", "example": 0.042 },
          "created_at": { "type": "string", "format": "date-time", "example": "2026-04-14T12:00:00Z" },
          "completed_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Null while backtest is still running.", "example": "2026-04-14T12:00:32Z" }
        }
      },
      "AvailableWallet": {
        "type": "object",
        "description": "A wallet with sufficient historical data for backtesting.",
        "properties": {
          "address": { "type": "string", "description": "Solana wallet address.", "example": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" },
          "trade_count": { "type": "integer", "description": "Number of trades in the period.", "example": 312 },
          "period_start": { "type": "string", "format": "date-time", "description": "Earliest trade date.", "example": "2025-08-14T00:00:00Z" },
          "period_end": { "type": "string", "format": "date-time", "description": "Latest trade date.", "example": "2026-04-14T07:58:31Z" }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "description": "Pagination and caching metadata included in list responses.",
        "properties": {
          "total": { "type": "integer", "description": "Total number of matching records.", "example": 142 },
          "limit": { "type": "integer", "description": "Page size used for this request.", "example": 20 },
          "offset": { "type": "integer", "description": "Offset used for this request.", "example": 0 },
          "has_more": { "type": "boolean", "description": "True if more results exist beyond this page.", "example": true },
          "cached": { "type": "boolean", "description": "Whether this response was served from cache.", "example": true },
          "cache_age_seconds": { "type": "number", "description": "Seconds since the cached data was computed. 0 if not cached.", "example": 45 }
        }
      },
      "ApiError": {
        "type": "object",
        "description": "Error response envelope.",
        "required": ["success", "error", "timestamp"],
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "description": "Machine-readable error code.", "example": "INVALID_PARAMETER" },
              "message": { "type": "string", "description": "Human-readable error description.", "example": "Parameter 'min_score' must be between 0 and 1." }
            }
          },
          "timestamp": { "type": "string", "format": "date-time", "example": "2026-04-14T12:00:00Z" }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameters or malformed request body.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" },
            "example": {
              "success": false,
              "error": { "code": "INVALID_PARAMETER", "message": "Parameter 'min_score' must be between 0 and 1." },
              "timestamp": "2026-04-14T12:00:00Z"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" },
            "example": {
              "success": false,
              "error": { "code": "UNAUTHORIZED", "message": "Missing or invalid X-API-Key header." },
              "timestamp": "2026-04-14T12:00:00Z"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded. Check Retry-After header.",
        "headers": {
          "Retry-After": {
            "description": "Seconds until the next request is allowed.",
            "schema": { "type": "integer", "example": 12 }
          }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" },
            "example": {
              "success": false,
              "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded. Retry after 12 seconds." },
              "timestamp": "2026-04-14T12:00:00Z"
            }
          }
        }
      }
    }
  }
}
