{
  "openapi": "3.1.1",
  "info": {
    "title": "CurveRisk.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://curverisk.austonfeng.com/"
    }
  ],
  "paths": {
    "/api/v1/market-snapshots": {
      "post": {
        "tags": [
          "Market snapshots"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMarketSnapshotRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketSnapshotResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Market snapshots"
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageResponseOfMarketSnapshotResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/market-snapshots/{id}": {
      "get": {
        "tags": [
          "Market snapshots"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketSnapshotResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/market-snapshots/{id}/curve": {
      "get": {
        "tags": [
          "Market snapshots"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurveResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trades": {
      "post": {
        "tags": [
          "Trades"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTradeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Trades"
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageResponseOfTradeResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trades/{tradeId}": {
      "get": {
        "tags": [
          "Trades"
        ],
        "parameters": [
          {
            "name": "tradeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Trades"
        ],
        "parameters": [
          {
            "name": "tradeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTradeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "412": {
            "description": "Precondition Failed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "428": {
            "description": "Precondition Required",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Trades"
        ],
        "parameters": [
          {
            "name": "tradeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "412": {
            "description": "Precondition Failed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "428": {
            "description": "Precondition Required",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/valuations": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValuationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValuationResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scenario-runs": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScenarioRunRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioRunResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/risk-runs": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRiskRunRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskRunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/copilot/answers": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopilotQuestionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopilotAnswerResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/risk-runs/{id}": {
      "get": {
        "tags": [
          "Calculations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskRunResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "BucketDeltaDto": {
        "required": [
          "tenorYears",
          "delta"
        ],
        "type": "object",
        "properties": {
          "tenorYears": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "delta": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "PV change for a +1bp bump of that pillar's zero rate.",
            "format": "double"
          }
        }
      },
      "CopilotAnswerResponse": {
        "required": [
          "status",
          "answer",
          "toolCalls",
          "ungroundedFigures",
          "modelCalls",
          "inputTokens",
          "outputTokens",
          "costUsd"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Answered, UngroundedWithheld, Refused, Truncated, CallLimitReached, BudgetExhausted or ModelUnavailable.\r\nOnly Answered carries the model's own text; every other status carries a fixed explanation."
          },
          "answer": {
            "type": "string"
          },
          "toolCalls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CopilotToolCallDto"
            }
          },
          "ungroundedFigures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Figures the model stated that no engine result supports. Empty when Answered."
          },
          "modelCalls": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "inputTokens": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "outputTokens": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "costUsd": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "CopilotQuestionRequest": {
        "required": [
          "snapshotId",
          "question"
        ],
        "type": "object",
        "properties": {
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "question": {
            "type": "string"
          }
        },
        "description": "A question for the Risk Copilot about the trades booked, priced on the given snapshot."
      },
      "CopilotToolCallDto": {
        "required": [
          "name",
          "outcome"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "outcome": {
            "type": "string",
            "description": "Succeeded, Failed, Denied or UnknownTool."
          }
        }
      },
      "CreateMarketSnapshotRequest": {
        "required": [
          "curveId",
          "asOf",
          "interpolation",
          "quotes"
        ],
        "type": "object",
        "properties": {
          "curveId": {
            "type": "string"
          },
          "asOf": {
            "type": "string",
            "description": "yyyy-MM-dd."
          },
          "interpolation": {
            "type": "string",
            "description": "LogLinearDiscount, LinearZero or MonotoneCubicLogDiscount."
          },
          "quotes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuoteDto"
            }
          }
        },
        "description": "The quotes a curve is built from on one date."
      },
      "CreateRiskRunRequest": {
        "required": [
          "snapshotId",
          "tradeIds"
        ],
        "type": "object",
        "properties": {
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "tradeIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CreateTradeRequest": {
        "required": [
          "tradeId",
          "notionalAmount",
          "fixedRatePercent",
          "direction",
          "tenor",
          "description"
        ],
        "type": "object",
        "properties": {
          "tradeId": {
            "type": "string"
          },
          "notionalAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "fixedRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "direction": {
            "type": "string",
            "description": "PayFixed or ReceiveFixed."
          },
          "tenor": {
            "type": "string",
            "description": "Such as \"5Y\"."
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CurvePillarDto": {
        "required": [
          "tenorYears",
          "zeroRatePercent",
          "discountFactor"
        ],
        "type": "object",
        "properties": {
          "tenorYears": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "zeroRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Continuously compounded.",
            "format": "double"
          },
          "discountFactor": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "CurveResponse": {
        "required": [
          "snapshotId",
          "curveId",
          "asOf",
          "interpolation",
          "pillars"
        ],
        "type": "object",
        "properties": {
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "curveId": {
            "type": "string"
          },
          "asOf": {
            "type": "string"
          },
          "interpolation": {
            "type": "string"
          },
          "pillars": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CurvePillarDto"
            }
          }
        }
      },
      "HttpValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "MarketSnapshotResponse": {
        "required": [
          "id",
          "curveId",
          "asOf",
          "interpolation",
          "quotes",
          "createdUtc"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "curveId": {
            "type": "string"
          },
          "asOf": {
            "type": "string"
          },
          "interpolation": {
            "type": "string"
          },
          "quotes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuoteDto"
            }
          },
          "createdUtc": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PageResponseOfMarketSnapshotResponse": {
        "required": [
          "items",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketSnapshotResponse"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One page of a collection. Pass string? PageResponse&lt;T&gt;.NextCursor as `cursor` to get the next; null means the end."
      },
      "PageResponseOfTradeResponse": {
        "required": [
          "items",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TradeResponse"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One page of a collection. Pass string? PageResponse&lt;T&gt;.NextCursor as `cursor` to get the next; null means the end."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "QuoteDto": {
        "required": [
          "tenor",
          "ratePercent"
        ],
        "type": "object",
        "properties": {
          "tenor": {
            "type": "string"
          },
          "ratePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        },
        "description": "One par quote: a tenor such as \"5Y\" and its rate in percent (3.78 for 3.78%)."
      },
      "RiskRunResponse": {
        "required": [
          "id",
          "status",
          "snapshotId",
          "tradeIds",
          "results",
          "error",
          "createdUtc",
          "completedUtc"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "Pending, Completed or Failed."
          },
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "tradeIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "results": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/TradeRiskDto"
            },
            "description": "Present once Completed."
          },
          "error": {
            "type": [
              "null",
              "string"
            ],
            "description": "Present once Failed."
          },
          "createdUtc": {
            "type": "string",
            "format": "date-time"
          },
          "completedUtc": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        },
        "description": "A risk calculation that runs in the background. Poll until the status is Completed or Failed."
      },
      "ScenarioRunRequest": {
        "required": [
          "snapshotId",
          "tradeId",
          "parallelBp",
          "steepenerBp"
        ],
        "type": "object",
        "properties": {
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "tradeId": {
            "type": "string"
          },
          "parallelBp": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Added to every zero rate. Positive means rates up.",
            "format": "double"
          },
          "steepenerBp": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Change in the 2s10s zero spread. Positive steepens.",
            "format": "double"
          }
        }
      },
      "ScenarioRunResponse": {
        "required": [
          "tradeId",
          "currency",
          "parallelBp",
          "steepenerBp",
          "basePresentValue",
          "shockedPresentValue",
          "profitAndLoss"
        ],
        "type": "object",
        "properties": {
          "tradeId": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "parallelBp": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "steepenerBp": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "basePresentValue": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "shockedPresentValue": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "profitAndLoss": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "TradeResponse": {
        "required": [
          "tradeId",
          "notionalAmount",
          "fixedRatePercent",
          "direction",
          "tenor",
          "description",
          "createdUtc"
        ],
        "type": "object",
        "properties": {
          "tradeId": {
            "type": "string"
          },
          "notionalAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "fixedRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "direction": {
            "type": "string"
          },
          "tenor": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "createdUtc": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TradeRiskDto": {
        "required": [
          "tradeId",
          "currency",
          "parallelDv01",
          "buckets"
        ],
        "type": "object",
        "properties": {
          "tradeId": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "parallelDv01": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "PV change for a +1bp parallel shift of zero rates (zero-rate risk, not par-quote risk).",
            "format": "double"
          },
          "buckets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BucketDeltaDto"
            }
          }
        }
      },
      "UpdateTradeRequest": {
        "required": [
          "notionalAmount",
          "fixedRatePercent",
          "tenor",
          "description"
        ],
        "type": "object",
        "properties": {
          "notionalAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "fixedRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "tenor": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "The editable part of a trade. The id and economic direction are fixed once booked."
      },
      "ValuationRequest": {
        "required": [
          "snapshotId",
          "tradeId"
        ],
        "type": "object",
        "properties": {
          "snapshotId": {
            "type": "string",
            "format": "uuid"
          },
          "tradeId": {
            "type": "string"
          }
        }
      },
      "ValuationResponse": {
        "required": [
          "tradeId",
          "currency",
          "presentValue",
          "parRatePercent",
          "fixedRatePercent"
        ],
        "type": "object",
        "properties": {
          "tradeId": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "presentValue": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "From our side, in the trade currency.",
            "format": "double"
          },
          "parRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "fixedRatePercent": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Market snapshots"
    },
    {
      "name": "Trades"
    },
    {
      "name": "Calculations"
    }
  ]
}