{
  "serviceId": "backtest-reconcile-v1",
  "displayName": "Backtest Reconcile",
  "description": "Do the claimed backtest numbers follow from the trades? Send a TradingView \"List of trades\" CSV or a JSON trade list with the claimed metrics; get net profit, win rate, profit factor, drawdown and per-trade P&L recomputed, each claim marked MATCH or MISMATCH, and findings such as cost-free backtests. Deterministic, no market data. POST /v1/reconcile.",
  "category": "finance",
  "resourceUrl": "https://test.agent.pocket.network/v1/backtest-reconcile-v1",
  "priceUsd": "0.005000",
  "priceVersion": 1,
  "rails": [
    {
      "id": "base",
      "network": "eip155:84532",
      "chainId": 84532,
      "tokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "tokenDecimals": 6,
      "payToAddress": "0xF732ea490c5766071785a2310523f7fA2CEbB829"
    }
  ],
  "paymentNetworks": [
    "eip155:84532"
  ],
  "paymentProtocols": [
    "x402"
  ],
  "protocols": [
    "rest"
  ],
  "inputSchema": {
    "type": "object",
    "description": "The body of POST /v1/reconcile, up to 2 MiB. Send trades_csv or trades.",
    "properties": {
      "trades_csv": {
        "type": "string",
        "description": "A TradingView Strategy Tester \"List of trades\" CSV export."
      },
      "trades": {
        "type": "array",
        "description": "The trades as a JSON list, in place of trades_csv.",
        "items": {
          "type": "object",
          "properties": {
            "n": {
              "description": "Trade number."
            },
            "side": {
              "type": "string",
              "enum": [
                "long",
                "short"
              ]
            },
            "entry_time": {
              "type": "string"
            },
            "exit_time": {
              "type": "string"
            },
            "entry_price": {
              "type": "number"
            },
            "exit_price": {
              "type": "number"
            },
            "qty": {
              "type": "number"
            },
            "commission": {
              "type": "number"
            },
            "reported_pnl": {
              "type": "number"
            }
          }
        }
      },
      "initial_capital": {
        "type": "number",
        "description": "Starting capital for the percentage figures."
      },
      "commission": {
        "type": "object",
        "description": "Commission applied to every trade.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "percent",
              "per_contract",
              "cash_per_order"
            ]
          },
          "value": {
            "type": "number"
          }
        }
      },
      "claimed": {
        "type": "object",
        "description": "The claimed metrics to check, any of net_profit, net_profit_pct, gross_profit, gross_loss, total_trades, win_rate, profit_factor, max_drawdown, max_drawdown_pct, avg_trade, largest_win, largest_loss."
      },
      "tolerance_pct": {
        "type": "number",
        "default": 0.5,
        "description": "How far a claim may differ, in percent, and still MATCH."
      },
      "single_position": {
        "type": "boolean",
        "default": true,
        "description": "Flag overlapping trades."
      }
    }
  },
  "outputSchema": {
    "type": "object",
    "description": "POST /v1/reconcile answers a backtest-reconcile/v1 object: verdict, the recomputed metrics, each claim with claimed, recomputed, diff and status, findings with code and severity, counts, and the assumptions used. Properties are pinned from live paid responses; nothing is required, because every route's 2xx response is validated against this one schema.",
    "properties": {
      "schema": {
        "type": "string"
      },
      "service": {
        "type": "string"
      },
      "version": {
        "type": "string"
      },
      "verdict": {
        "type": "string"
      },
      "recomputed": {
        "type": "object",
        "properties": {
          "net_profit": {
            "type": "number"
          },
          "net_profit_pct": {
            "type": "number"
          },
          "gross_profit": {
            "type": "number"
          },
          "gross_loss": {
            "type": "number"
          },
          "total_trades": {
            "type": "number"
          },
          "win_rate": {
            "type": "number"
          },
          "profit_factor": {
            "type": "null"
          },
          "max_drawdown": {
            "type": "number"
          },
          "max_drawdown_pct": {
            "type": "number"
          },
          "avg_trade": {
            "type": "number"
          },
          "largest_win": {
            "type": "number"
          },
          "largest_loss": {
            "type": "number"
          },
          "total_commission": {
            "type": "number"
          }
        }
      },
      "claims": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "metric": {
              "type": "string"
            },
            "claimed": {
              "type": "number"
            },
            "recomputed": {
              "type": "number"
            },
            "diff": {
              "type": "number"
            },
            "status": {
              "type": "string"
            }
          }
        }
      },
      "findings": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string"
            },
            "severity": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "trade": {
              "type": "number"
            },
            "reported": {
              "type": "number"
            },
            "recomputed": {
              "type": "number"
            },
            "metric": {
              "type": "string"
            }
          }
        }
      },
      "counts": {
        "type": "object",
        "properties": {
          "error": {
            "type": "number"
          },
          "warning": {
            "type": "number"
          },
          "info": {
            "type": "number"
          }
        }
      },
      "assumptions": {
        "type": "object",
        "properties": {
          "commission": {
            "type": "null"
          },
          "initial_capital": {
            "type": "number"
          },
          "tolerance_pct": {
            "type": "number"
          },
          "equity": {
            "type": "string"
          }
        }
      },
      "notes": {
        "type": "array",
        "items": {}
      },
      "scope": {
        "type": "string"
      }
    }
  },
  "methods": {
    "GET /v1/health": "read",
    "GET /v1/rules": "read",
    "GET /v1/version": "read",
    "POST /v1/reconcile": "read"
  },
  "example": {
    "method": "POST",
    "path": "/v1/reconcile",
    "request": {
      "trades": [
        {
          "n": 1,
          "side": "long",
          "entry_time": "2024-01-15 10:00",
          "exit_time": "2024-01-15 14:00",
          "entry_price": 100,
          "exit_price": 105,
          "qty": 10,
          "commission": 2,
          "reported_pnl": 50
        },
        {
          "n": 2,
          "side": "short",
          "entry_time": "2024-01-16 09:30",
          "exit_time": "2024-01-16 11:30",
          "entry_price": 200,
          "exit_price": 195,
          "qty": 5,
          "commission": 3,
          "reported_pnl": 25
        }
      ],
      "initial_capital": 10000,
      "claimed": {
        "net_profit": 80,
        "win_rate": 100,
        "total_trades": 2
      }
    },
    "response": {
      "portal": {
        "provenance": "third-party-supplier",
        "serviceId": "backtest-reconcile-v1",
        "schemaCheck": "unchecked"
      },
      "data": {
        "schema": "backtest-reconcile/v1",
        "service": "backtest-reconcile-v1",
        "version": "0.1.0",
        "verdict": "MISMATCH",
        "recomputed": {
          "net_profit": 70,
          "net_profit_pct": 0.7,
          "gross_profit": 70,
          "gross_loss": 0,
          "total_trades": 2,
          "win_rate": 100,
          "profit_factor": null,
          "max_drawdown": 0,
          "max_drawdown_pct": 0,
          "avg_trade": 35,
          "largest_win": 48,
          "largest_loss": 0,
          "total_commission": 5
        },
        "claims": [
          {
            "metric": "net_profit",
            "claimed": 80,
            "recomputed": 70,
            "diff": 10,
            "status": "MISMATCH"
          },
          {
            "metric": "win_rate",
            "claimed": 100,
            "recomputed": 100,
            "diff": 0,
            "status": "MATCH"
          },
          {
            "metric": "total_trades",
            "claimed": 2,
            "recomputed": 2,
            "diff": 0,
            "status": "MATCH"
          }
        ],
        "findings": [
          {
            "code": "B102",
            "severity": "warning",
            "message": "trade 1: reported 50.0000 vs recomputed 48.0000 (gross 50.0000 - fee 2.0000)",
            "trade": 1,
            "reported": 50,
            "recomputed": 48
          },
          {
            "code": "B102",
            "severity": "warning",
            "message": "trade 2: reported 25.0000 vs recomputed 22.0000 (gross 25.0000 - fee 3.0000)",
            "trade": 2,
            "reported": 25,
            "recomputed": 22
          },
          {
            "code": "B105",
            "severity": "info",
            "message": "2 closed trades; small samples make win rate and profit factor unstable"
          }
        ],
        "counts": {
          "error": 1,
          "warning": 2,
          "info": 1
        },
        "assumptions": {
          "commission": null,
          "initial_capital": 10000,
          "tolerance_pct": 0.5,
          "equity": "closed-trade"
        },
        "notes": [],
        "scope": "arithmetic consistency of the given trades only; says nothing about whether the strategy works live"
      }
    },
    "capturedAt": "2026-10-14T09:12:05Z"
  },
  "firstParty": true,
  "networks": [
    "eip155:84532"
  ],
  "serving": true,
  "page": "https://test.agent.pocket.network/services/backtest-reconcile-v1",
  "descriptor": "https://test.agent.pocket.network/services/backtest-reconcile-v1/descriptor.json"
}