{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://polytraders.dev/schemas/PortfolioConfig.json",
  "title": "PortfolioConfig",
  "description": "Portfolio is the unit of account. Strategies, positions, signals and risk all hang off a Portfolio.",
  "type": "object",
  "required": [
    "portfolio_id",
    "label",
    "balance_pusd",
    "guardrails",
    "bound_strategies"
  ],
  "properties": {
    "portfolio_id":    { "$ref": "_common.json#/$defs/PortfolioId" },
    "label":           { "type": "string", "minLength": 1, "maxLength": 80 },
    "balance_pusd":    { "$ref": "_common.json#/$defs/Decimal" },
    "guardrails": {
      "type": "object",
      "required": [
        "max_concurrent_positions",
        "daily_loss_limit_pusd",
        "max_drawdown_pct",
        "cluster_exposure_caps"
      ],
      "properties": {
        "max_concurrent_positions": { "type": "integer", "minimum": 1, "maximum": 500 },
        "daily_loss_limit_pusd":    { "$ref": "_common.json#/$defs/Decimal" },
        "max_drawdown_pct":         { "type": "number", "minimum": 0, "maximum": 100 },
        "cluster_exposure_caps": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["cluster_id", "cap_pct_of_balance"],
            "properties": {
              "cluster_id":          { "$ref": "_common.json#/$defs/ClusterId" },
              "cap_pct_of_balance":  { "type": "number", "minimum": 0, "maximum": 100 }
            },
            "additionalProperties": false
          }
        }
      },
      "additionalProperties": false
    },
    "bound_strategies": {
      "type": "array",
      "items": { "$ref": "_common.json#/$defs/StrategyId" }
    }
  },
  "additionalProperties": false
}
