{ "openapi": "3.0.0", "info": { "title": "Backtester Backend API", "version": "1.0.0", "description": "tastytrade options backtester" }, "servers": [ { "url": "https://backtester.vast.tastyworks.com", "description": "Backtester API" } ], "paths": { "/backtests": { "get": { "summary": "Get user's backtests", "description": "Get the IDs of all the current user's backtests", "operationId": "GetUsersBacktests", "responses": { "200": { "description": "Backtest list", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string" } } } } } } }, "post": { "summary": "Create backtest", "description": "Create new backtest", "operationId": "PostBacktests", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestPost" } } } }, "responses": { "200": { "description": "Backtest ready", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "201": { "description": "Backtest pending", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "400": { "$ref": "#/components/responses/400" }, "404": { "$ref": "#/components/responses/404" }, "500": { "$ref": "#/components/responses/500" } } } }, "/backtests/{id}": { "get": { "summary": "Get backtest", "description": "Get backtest by ID", "operationId": "GetBacktests", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Backtest details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "400": { "$ref": "#/components/responses/400" }, "404": { "$ref": "#/components/responses/404" }, "500": { "$ref": "#/components/responses/500" } } } }, "/backtests/{id}/logs": { "get": { "summary": "Get backtest Logs", "description": "Read logs of specified backtest", "operationId": "GetBacktestsLogs", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Backtest logs" }, "400": { "$ref": "#/components/responses/400" }, "404": { "$ref": "#/components/responses/404" } } } }, "/backtests/{id}/cancel": { "post": { "summary": "Cancel backtest", "description": "Cancel running backtest", "operationId": "CancelBacktests", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Backtest cancelled" }, "400": { "$ref": "#/components/responses/400" }, "404": { "$ref": "#/components/responses/404" } } } }, "/available-dates": { "get": { "summary": "Available historical date ranges", "description": "Available historical date ranges for every individual symbol", "operationId": "GetAvailableDates", "responses": { "200": { "description": "List of available symbols and dates", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AvailableSymbolDates" } } } } }, "400": { "$ref": "#/components/responses/400" }, "500": { "$ref": "#/components/responses/500" } } } }, "/simulate-trade": { "post": { "summary": "Simulate a trade", "description": "Returns historical prices for a trade", "operationId": "SimulateTrade", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "underlying": { "type": "string", "description": "Underlying symbol of the trade" }, "startTime": { "type": "string", "format": "date-time", "description": "Optionally, start time of the trade in ISO 8601 format." }, "endTime": { "type": "string", "format": "date-time", "description": "Optionally, end time of the trade in ISO 8601 format." }, "legs": { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string", "description": "The leg symbol uses the tastytrade / OCC symbology convention - https://developer.tastytrade.com/api-overview/#tastytrade-symbology" }, "direction": { "type": "string", "enum": [ "long", "short" ] }, "quantity": { "type": "integer" } } } } } }, "examples": { "coveredCall": { "summary": "Covered call", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227C00275000", "direction": "short", "quantity": 1 }, { "symbol": "SPY", "direction": "long", "quantity": 100 } ] } }, "putRatioSpread": { "summary": "Put ratio spread", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227P00265000", "direction": "long", "quantity": 3 }, { "symbol": "SPY 190227P00275000", "direction": "short", "quantity": 1 } ] } }, "longCallButterfly": { "summary": "Long call butterfly", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227C00270000", "direction": "long", "quantity": 2 }, { "symbol": "SPY 190227C00275000", "direction": "short", "quantity": 1 }, { "symbol": "SPY 190227C00265000", "direction": "short", "quantity": 1 } ] } } } } } }, "responses": { "200": { "description": "Trade simulation successful", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "dateTime": { "type": "string", "format": "date-time" }, "price": { "type": "string" }, "effect": { "type": "string", "enum": [ "debit", "credit" ] }, "underlyingPrice": { "type": "string" }, "delta": { "type": "string" } } } } } } } } } } }, "components": { "schemas": { "BacktestPost": { "type": "object", "properties": { "symbol": { "type": "string" }, "startDate": { "type": "string", "format": "date" }, "endDate": { "type": "string", "format": "date" }, "legs": { "type": "array", "items": { "type": "object", "allOf": [ { "$ref": "#/components/schemas/Leg" } ] } }, "entryConditions": { "allOf": [ { "$ref": "#/components/schemas/EntryConditions" } ] }, "exitConditions": { "allOf": [ { "$ref": "#/components/schemas/ExitConditions" } ] } } }, "BacktestGet": { "type": "object", "properties": { "id": { "type": "string" }, "symbol": { "type": "string" }, "startDate": { "type": "string", "format": "date" }, "endDate": { "type": "string", "format": "date" }, "legs": { "type": "array", "items": { "type": "object", "allOf": [ { "$ref": "#/components/schemas/Leg" } ] } }, "entryConditions": { "allOf": [ { "$ref": "#/components/schemas/EntryConditions" } ] }, "exitConditions": { "allOf": [ { "$ref": "#/components/schemas/ExitConditions" } ] }, "ETA": { "type": "number" }, "progress": { "type": "number" }, "status": { "type": "string", "enum": [ "pending", "running", "completed" ] }, "statistics": { "type": "array", "items": { "type": "object" } }, "trials": { "type": "array", "items": { "allOf": [ { "$ref": "#/components/schemas/Trial" } ] } }, "snapshots": { "type": "array", "items": { "allOf": [ { "$ref": "#/components/schemas/Snapshot" } ] } }, "notices": { "description": "Conditional annotations appearing if specific conditions are met (e.g. overlapping due to stock split)", "type": "array", "items": { "type": "string" } } } }, "Snapshot": { "type": "object", "properties": { "dateTime": { "type": "string" }, "profitLoss": { "type": "number" }, "underlyingPrice": { "type": "number" } } }, "Trial": { "type": "object", "properties": { "openDateTime": { "type": "string" }, "closeDateTime": { "type": "string" }, "profitLoss": { "type": "number" } } }, "Leg": { "type": "object", "required": [ "type", "direction", "quantity", "strikeSelection", "daysUntilExpiration" ], "properties": { "type": { "type": "string", "enum": [ "equity", "equity-option" ], "description": "The instrument type" }, "direction": { "type": "string", "enum": [ "long", "short" ], "description": "The position direction" }, "side": { "type": "string", "enum": [ "call", "put" ], "description": "The option side (only applicable for equity-option type)" }, "quantity": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Number of contracts or shares (1-10 for options, 1-100 for stocks)" }, "strikeSelection": { "type": "string", "enum": [ "delta", "percentageOTM", "percentageOTMRelative", "currentPriceOffset", "currentPriceOffsetRelative", "currentPriceExactOffsetRelative", "premium" ], "description": "How to select the strike for this leg" }, "strikeRelativeLeg": { "type": "integer", "description": "Index of the leg to use as reference when strike selection is relative to another leg" }, "delta": { "type": "number", "minimum": 1, "maximum": 100, "description": "Delta value when strikeSelection is \"delta\" (expressed as integer from 1 to 100)" }, "percentageOTM": { "type": "number", "description": "Percentage OTM when strikeSelection is \"percentageOTM\" or \"percentageOTMRelative\" (e.g. 0.1 for 10% OTM, -0.1 for 10% ITM)" }, "currentPriceOffset": { "type": "number", "maximum": 50000, "description": "Offset from current price when strikeSelection is currentPriceOffset related (max 50000)" }, "premium": { "type": "number", "maximum": 50000, "description": "Premium value when strikeSelection is \"premium\" (max 50000)" }, "daysUntilExpiration": { "type": "integer", "description": "Days until expiration for this leg" } } }, "EntryConditions": { "type": "object", "properties": { "frequency": { "type": "string", "nullable": true, "enum": [ "every day", "on specific days of the week", "on exact days to expiration match" ] }, "specificDays": { "type": "array", "nullable": true, "items": { "type": "integer" } }, "maximumActiveTrials": { "type": "integer", "nullable": true }, "maximumActiveTrialsBehavior": { "type": "string", "nullable": true, "enum": [ "don't enter", "close oldest" ] }, "minimumVIX": { "type": "integer", "nullable": true }, "maximumVIX": { "type": "integer", "nullable": true } } }, "ExitConditions": { "type": "object", "properties": { "takeProfitPercentage": { "type": "integer", "nullable": true }, "stopLossPercentage": { "type": "integer", "nullable": true }, "afterDaysInTrade": { "type": "integer", "nullable": true }, "atDaysToExpiration": { "type": "integer", "nullable": true }, "minimumVIX": { "type": "integer", "nullable": true } } }, "AvailableSymbolDates": { "type": "object", "properties": { "symbol": { "type": "string" }, "startDate": { "type": "string" }, "endDate": { "type": "string" } } } }, "responses": { "400": { "description": "Request included malformed input" }, "401": { "description": "Unauthorized" }, "404": { "description": "Backtest not found" }, "500": { "description": "Failed to process request" } } } }