{
  "openapi": "3.1.0",
  "info": {
    "title": "Replicurve",
    "version": "0.1.0"
  },
  "paths": {
    "/v1/health": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health",
        "operationId": "health_v1_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "tags": [
          "usage"
        ],
        "summary": "Read Usage",
        "description": "Return the authenticated key's monthly replication/offset call count.",
        "operationId": "read_usage_v1_usage_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/v1/replication": {
      "post": {
        "tags": [
          "replications"
        ],
        "summary": "Create Replication",
        "description": "Run a dynamic beta replication and return weights and metrics.",
        "operationId": "create_replication_v1_replication_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplicationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReplicationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/v1/offset": {
      "post": {
        "tags": [
          "replications"
        ],
        "summary": "Create Offset",
        "description": "Run a dynamic beta offset and return weights and metrics.",
        "operationId": "create_offset_v1_offset_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplicationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReplicationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/v1/validate": {
      "post": {
        "tags": [
          "replications"
        ],
        "summary": "Validate Replication",
        "description": "Check whether target/basket inputs are sufficient for the configured window.",
        "operationId": "validate_replication_v1_validate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplicationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "DateValue": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
          },
          "value": {
            "type": "number",
            "title": "Value"
          }
        },
        "type": "object",
        "required": [
          "date",
          "value"
        ],
        "title": "DateValue"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "HealthResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "default": "ok"
          },
          "version": {
            "type": "string",
            "title": "Version"
          }
        },
        "type": "object",
        "required": [
          "version"
        ],
        "title": "HealthResponse"
      },
      "RebalanceWeights": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
          },
          "weights": {
            "additionalProperties": {
              "type": "number"
            },
            "type": "object",
            "minProperties": 1,
            "title": "Weights"
          }
        },
        "type": "object",
        "required": [
          "date",
          "weights"
        ],
        "title": "RebalanceWeights"
      },
      "ReplicationConfig": {
        "properties": {
          "rebalance_freq": {
            "type": "string",
            "enum": [
              "daily",
              "weekly"
            ],
            "title": "Rebalance Freq",
            "default": "weekly"
          },
          "max_allocation": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Max Allocation",
            "default": 10
          },
          "direction": {
            "type": "string",
            "enum": [
              "long",
              "short",
              "long_short"
            ],
            "title": "Direction",
            "default": "long_short"
          },
          "weight_normalization": {
            "type": "string",
            "enum": [
              "none",
              "gross"
            ],
            "title": "Weight Normalization",
            "default": "none"
          }
        },
        "type": "object",
        "title": "ReplicationConfig",
        "description": "User-facing replication settings."
      },
      "ReplicationMetrics": {
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start"
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End"
          },
          "observations": {
            "type": "integer",
            "title": "Observations"
          },
          "period": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "title": "Period"
          },
          "correlation": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Correlation"
          },
          "r_squared": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "R Squared"
          },
          "beta": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Beta"
          },
          "alpha_annual": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Alpha Annual"
          },
          "tracking_error": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tracking Error"
          },
          "information_ratio": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Information Ratio"
          },
          "hit_rate": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hit Rate"
          },
          "mean_error": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mean Error"
          },
          "slippage": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slippage"
          },
          "target_total_return": {
            "type": "number",
            "title": "Target Total Return"
          },
          "target_cagr": {
            "type": "number",
            "title": "Target Cagr"
          },
          "target_volatility": {
            "type": "number",
            "title": "Target Volatility"
          },
          "target_sharpe": {
            "type": "number",
            "title": "Target Sharpe"
          },
          "target_max_drawdown": {
            "type": "number",
            "title": "Target Max Drawdown"
          },
          "portfolio_total_return": {
            "type": "number",
            "title": "Portfolio Total Return"
          },
          "portfolio_cagr": {
            "type": "number",
            "title": "Portfolio Cagr"
          },
          "portfolio_volatility": {
            "type": "number",
            "title": "Portfolio Volatility"
          },
          "portfolio_sharpe": {
            "type": "number",
            "title": "Portfolio Sharpe"
          },
          "portfolio_max_drawdown": {
            "type": "number",
            "title": "Portfolio Max Drawdown"
          },
          "avg_assets": {
            "type": "number",
            "title": "Avg Assets"
          },
          "turnover": {
            "type": "number",
            "title": "Turnover"
          },
          "gross_exposure": {
            "type": "number",
            "title": "Gross Exposure"
          }
        },
        "type": "object",
        "required": [
          "start",
          "end",
          "observations",
          "period",
          "correlation",
          "r_squared",
          "beta",
          "alpha_annual",
          "tracking_error",
          "information_ratio",
          "hit_rate",
          "mean_error",
          "slippage",
          "target_total_return",
          "target_cagr",
          "target_volatility",
          "target_sharpe",
          "target_max_drawdown",
          "portfolio_total_return",
          "portfolio_cagr",
          "portfolio_volatility",
          "portfolio_sharpe",
          "portfolio_max_drawdown",
          "avg_assets",
          "turnover",
          "gross_exposure"
        ],
        "title": "ReplicationMetrics"
      },
      "ReplicationRequest": {
        "properties": {
          "target": {
            "$ref": "#/components/schemas/SeriesPayload"
          },
          "basket": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "sp500",
                  "nasdaq100",
                  "ftse100",
                  "hk100",
                  "us_listed_etfs",
                  "ucits_etfs"
                ]
              },
              {
                "additionalProperties": {
                  "items": {
                    "$ref": "#/components/schemas/DateValue"
                  },
                  "type": "array"
                },
                "type": "object",
                "minProperties": 1
              }
            ],
            "title": "Basket"
          },
          "config": {
            "$ref": "#/components/schemas/ReplicationConfig"
          },
          "exclude_tickers": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Exclude Tickers"
          }
        },
        "type": "object",
        "required": [
          "target",
          "basket"
        ],
        "title": "ReplicationRequest"
      },
      "ReplicationResponse": {
        "properties": {
          "weights": {
            "items": {
              "$ref": "#/components/schemas/RebalanceWeights"
            },
            "type": "array",
            "title": "Weights"
          },
          "target": {
            "items": {
              "$ref": "#/components/schemas/DateValue"
            },
            "type": "array",
            "title": "Target"
          },
          "portfolio": {
            "items": {
              "$ref": "#/components/schemas/DateValue"
            },
            "type": "array",
            "title": "Portfolio"
          },
          "metrics": {
            "$ref": "#/components/schemas/ReplicationMetrics"
          }
        },
        "type": "object",
        "required": [
          "weights",
          "target",
          "portfolio",
          "metrics"
        ],
        "title": "ReplicationResponse"
      },
      "SeriesPayload": {
        "properties": {
          "returns": {
            "items": {
              "$ref": "#/components/schemas/DateValue"
            },
            "type": "array",
            "minItems": 2,
            "title": "Returns"
          }
        },
        "type": "object",
        "required": [
          "returns"
        ],
        "title": "SeriesPayload"
      },
      "UsageResponse": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period"
          },
          "plan": {
            "type": "string",
            "title": "Plan"
          },
          "calls_used": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Calls Used"
          },
          "calls_limit": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Calls Limit"
          },
          "calls_remaining": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Calls Remaining"
          },
          "allow_overage": {
            "type": "boolean",
            "title": "Allow Overage"
          }
        },
        "type": "object",
        "required": [
          "period",
          "plan",
          "calls_used",
          "calls_limit",
          "calls_remaining",
          "allow_overage"
        ],
        "title": "UsageResponse"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "ValidationResponse": {
        "properties": {
          "valid": {
            "type": "boolean",
            "title": "Valid"
          },
          "overlapping_days": {
            "type": "integer",
            "title": "Overlapping Days"
          },
          "basket_size": {
            "type": "integer",
            "title": "Basket Size"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message"
          }
        },
        "type": "object",
        "required": [
          "valid",
          "overlapping_days",
          "basket_size"
        ],
        "title": "ValidationResponse"
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}
