tastytradeDeveloper Docs
Legacy ↗

API Reference / Backtesting

Create A Backtest

postBacktests
post/backtests

Base URL: https://backtester.vast.tastyworks.com (Backtester API)

Submits a backtest definition (underlying `symbol`, a `startDate`/`endDate` window, and one or more `legs`) and starts the run. A `201` means the backtest is pending and still running; a `200` means it is already completed. Either way the body includes an `id` to poll with `GET /backtests/{id}`.

Code samples

curl -X POST 'https://backtester.vast.tastyworks.com/backtests' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'User-Agent: tastytrade-docs-example/1.0' \
  -H 'Content-Type: application/json' \
  -d '{
  "symbol": "SPY",
  "startDate": "2022-01-01",
  "endDate": "2022-12-31",
  "legs": [
    {
      "type": "equity-option",
      "direction": "short",
      "side": "put",
      "quantity": 1,
      "strikeSelection": "delta",
      "strikeRelativeLeg": 0,
      "delta": 16,
      "percentageOTM": 0.1,
      "currentPriceOffset": 5,
      "premium": 2.5,
      "daysUntilExpiration": 45
    }
  ],
  "entryConditions": {
    "frequency": "every day",
    "specificDays": [
      0
    ],
    "maximumActiveTrials": 5,
    "maximumActiveTrialsBehavior": "don'\''t enter",
    "minimumVIX": 15,
    "maximumVIX": 30
  },
  "exitConditions": {
    "takeProfitPercentage": 50,
    "stopLossPercentage": 100,
    "afterDaysInTrade": 21,
    "atDaysToExpiration": 7,
    "minimumVIX": 12
  }
}'

Parameters

No parameters.

Request bodyapplication/json

Example

{
  "symbol": "SPY",
  "startDate": "2022-01-01",
  "endDate": "2022-12-31",
  "legs": [
    {
      "type": "equity-option",
      "direction": "short",
      "side": "put",
      "quantity": 1,
      "strikeSelection": "delta",
      "strikeRelativeLeg": 0,
      "delta": 16,
      "percentageOTM": 0.1,
      "currentPriceOffset": 5,
      "premium": 2.5,
      "daysUntilExpiration": 45
    }
  ],
  "entryConditions": {
    "frequency": "every day",
    "specificDays": [
      0
    ],
    "maximumActiveTrials": 5,
    "maximumActiveTrialsBehavior": "don't enter",
    "minimumVIX": 15,
    "maximumVIX": 30
  },
  "exitConditions": {
    "takeProfitPercentage": 50,
    "stopLossPercentage": 100,
    "afterDaysInTrade": 21,
    "atDaysToExpiration": 7,
    "minimumVIX": 12
  }
}

Schema

  • symbolstring

    Underlying symbol the strategy trades. Confirm history exists for your date range via `GET /available-dates`.

    example: "SPY"

  • startDatestring <date>

    First date of the historical window to backtest, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-01-01"

  • endDatestring <date>

    Last date of the historical window to backtest, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-12-31"

  • legsarray<object>
    • typerequiredstring

      The instrument type for this leg: `equity` for shares or `equity-option` for an option contract.

      enum: equity, equity-option

      example: "equity-option"

    • directionrequiredstring

      The position direction: `long` to buy, `short` to sell.

      enum: long, short

      example: "short"

    • sidestring

      The option side, `call` or `put`. Only applicable when `type` is `equity-option`.

      enum: call, put

      example: "put"

    • quantityrequiredinteger

      Number of contracts or shares (1-10 for options, 1-100 for stocks).

      example: 1

    • strikeSelectionrequiredstring

      How the strike is chosen for this leg. The accompanying value field depends on this: for example `delta` reads `delta`, `premium` reads `premium`.

      enum: delta, percentageOTM, percentageOTMRelative, currentPriceOffset, currentPriceOffsetRelative, currentPriceExactOffsetRelative, premium

      example: "delta"

    • strikeRelativeLeginteger

      Index of the leg to use as reference when strike selection is relative to another leg.

      example: 0

    • deltanumber

      Delta value used when `strikeSelection` is `delta`, expressed as an integer from 1 to 100.

      example: 16

    • percentageOTMnumber

      Percentage out-of-the-money when `strikeSelection` is `percentageOTM` or `percentageOTMRelative` (for example 0.1 for 10% OTM, -0.1 for 10% ITM).

      example: 0.1

    • currentPriceOffsetnumber

      Offset from current price when `strikeSelection` is a currentPriceOffset variant (max 50000).

      example: 5

    • premiumnumber

      Target premium when `strikeSelection` is `premium` (max 50000).

      example: 2.5

    • daysUntilExpirationrequiredinteger

      Number of days until expiration to target for this leg.

      example: 45

  • entryConditionsobject (EntryConditions)

    Optional rules controlling when new trials are opened during the backtest, such as entry frequency, concurrency limits, and VIX bounds.

    • frequencystring | null

      How often to open new trials: `every day`, `on specific days of the week`, or `on exact days to expiration match`.

      enum: every day, on specific days of the week, on exact days to expiration match

      example: "every day"

    • specificDaysarray<integer>

      Days of the week on which to enter, used when `frequency` is `on specific days of the week`.

    • maximumActiveTrialsinteger | null

      Maximum number of trials allowed open simultaneously.

      example: 5

    • maximumActiveTrialsBehaviorstring | null

      What to do when the active-trial limit is reached: `don't enter` to skip the entry, or `close oldest` to free a slot.

      enum: don't enter, close oldest

      example: "don't enter"

    • minimumVIXinteger | null

      Only open trials when the VIX is at or above this value.

      example: 15

    • maximumVIXinteger | null

      Only open trials when the VIX is at or below this value.

      example: 30

  • exitConditionsobject (ExitConditions)

    Optional rules controlling when trials are closed during the backtest, such as profit/loss targets, time in trade, and days to expiration.

    • takeProfitPercentageinteger | null

      Profit threshold for closing a trial, expressed as a percentage.

      example: 50

    • stopLossPercentageinteger | null

      Loss threshold for closing a trial, expressed as a percentage.

      example: 100

    • afterDaysInTradeinteger | null

      Close a trial after it has been open this many days.

      example: 21

    • atDaysToExpirationinteger | null

      Close a trial when this many days to expiration remain.

      example: 7

    • minimumVIXinteger | null

      VIX threshold used as an exit condition for closing trials.

      example: 12

Responses

200Backtest completed and ready to read. The body is a fully populated backtest object.application/json

Example response

{
  "id": "b1f8c2a4-9e7d-4a31-8c6f-2d5e1a0b3c7e",
  "symbol": "SPY",
  "startDate": "2022-01-01",
  "endDate": "2022-12-31",
  "legs": [
    {
      "type": "equity-option",
      "direction": "short",
      "side": "put",
      "quantity": 1,
      "strikeSelection": "delta",
      "strikeRelativeLeg": 0,
      "delta": 16,
      "percentageOTM": 0.1,
      "currentPriceOffset": 5,
      "premium": 2.5,
      "daysUntilExpiration": 45
    }
  ],
  "entryConditions": {
    "frequency": "every day",
    "specificDays": [
      0
    ],
    "maximumActiveTrials": 5,
    "maximumActiveTrialsBehavior": "don't enter",
    "minimumVIX": 15,
    "maximumVIX": 30
  },
  "exitConditions": {
    "takeProfitPercentage": 50,
    "stopLossPercentage": 100,
    "afterDaysInTrade": 21,
    "atDaysToExpiration": 7,
    "minimumVIX": 12
  },
  "ETA": 0,
  "progress": 0,
  "status": "completed",
  "statistics": [
    {}
  ],
  "trials": [
    {
      "openDateTime": "2022-01-03T14:30:00Z",
      "closeDateTime": "2022-01-20T20:00:00Z",
      "profitLoss": 128.5
    }
  ],
  "snapshots": [
    {
      "dateTime": "2022-01-03T14:30:00Z",
      "profitLoss": 128.5,
      "underlyingPrice": 477.71
    }
  ],
  "notices": []
}

Schema

  • idstring

    Unique identifier for this backtest. Use it with `GET /backtests/{id}` to poll status and read results.

    example: "b1f8c2a4-9e7d-4a31-8c6f-2d5e1a0b3c7e"

  • symbolstring

    Underlying symbol the strategy trades.

    example: "SPY"

  • startDatestring <date>

    First date of the backtested historical window, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-01-01"

  • endDatestring <date>

    Last date of the backtested historical window, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-12-31"

  • legsarray<object>
    • typerequiredstring

      The instrument type for this leg: `equity` for shares or `equity-option` for an option contract.

      enum: equity, equity-option

      example: "equity-option"

    • directionrequiredstring

      The position direction: `long` to buy, `short` to sell.

      enum: long, short

      example: "short"

    • sidestring

      The option side, `call` or `put`. Only applicable when `type` is `equity-option`.

      enum: call, put

      example: "put"

    • quantityrequiredinteger

      Number of contracts or shares (1-10 for options, 1-100 for stocks).

      example: 1

    • strikeSelectionrequiredstring

      How the strike is chosen for this leg. The accompanying value field depends on this: for example `delta` reads `delta`, `premium` reads `premium`.

      enum: delta, percentageOTM, percentageOTMRelative, currentPriceOffset, currentPriceOffsetRelative, currentPriceExactOffsetRelative, premium

      example: "delta"

    • strikeRelativeLeginteger

      Index of the leg to use as reference when strike selection is relative to another leg.

      example: 0

    • deltanumber

      Delta value used when `strikeSelection` is `delta`, expressed as an integer from 1 to 100.

      example: 16

    • percentageOTMnumber

      Percentage out-of-the-money when `strikeSelection` is `percentageOTM` or `percentageOTMRelative` (for example 0.1 for 10% OTM, -0.1 for 10% ITM).

      example: 0.1

    • currentPriceOffsetnumber

      Offset from current price when `strikeSelection` is a currentPriceOffset variant (max 50000).

      example: 5

    • premiumnumber

      Target premium when `strikeSelection` is `premium` (max 50000).

      example: 2.5

    • daysUntilExpirationrequiredinteger

      Number of days until expiration to target for this leg.

      example: 45

  • entryConditionsobject (EntryConditions)

    Optional rules controlling when new trials are opened during the backtest, such as entry frequency, concurrency limits, and VIX bounds.

    • frequencystring | null

      How often to open new trials: `every day`, `on specific days of the week`, or `on exact days to expiration match`.

      enum: every day, on specific days of the week, on exact days to expiration match

      example: "every day"

    • specificDaysarray<integer>

      Days of the week on which to enter, used when `frequency` is `on specific days of the week`.

    • maximumActiveTrialsinteger | null

      Maximum number of trials allowed open simultaneously.

      example: 5

    • maximumActiveTrialsBehaviorstring | null

      What to do when the active-trial limit is reached: `don't enter` to skip the entry, or `close oldest` to free a slot.

      enum: don't enter, close oldest

      example: "don't enter"

    • minimumVIXinteger | null

      Only open trials when the VIX is at or above this value.

      example: 15

    • maximumVIXinteger | null

      Only open trials when the VIX is at or below this value.

      example: 30

  • exitConditionsobject (ExitConditions)

    Optional rules controlling when trials are closed during the backtest, such as profit/loss targets, time in trade, and days to expiration.

    • takeProfitPercentageinteger | null

      Profit threshold for closing a trial, expressed as a percentage.

      example: 50

    • stopLossPercentageinteger | null

      Loss threshold for closing a trial, expressed as a percentage.

      example: 100

    • afterDaysInTradeinteger | null

      Close a trial after it has been open this many days.

      example: 21

    • atDaysToExpirationinteger | null

      Close a trial when this many days to expiration remain.

      example: 7

    • minimumVIXinteger | null

      VIX threshold used as an exit condition for closing trials.

      example: 12

  • ETAnumber

    Estimated time remaining until the run completes. Use it to space out polls while the backtest is still running.

  • progressnumber

    Completion progress of the run.

  • statusstring

    Current run state. Moves through `pending`, `running`, and `completed`; read results once it is `completed`.

    enum: pending, running, completed

    example: "completed"

  • statisticsarray<object>

    Aggregate performance metrics for the run, populated once the backtest completes.

  • trialsarray<object>
    • openDateTimestring

      Timestamp the trial opened, in ISO 8601 format.

      example: "2022-01-03T14:30:00Z"

    • closeDateTimestring

      Timestamp the trial closed, in ISO 8601 format.

      example: "2022-01-20T20:00:00Z"

    • profitLossnumber

      Realized profit or loss for this trial.

      example: 128.5

  • snapshotsarray<object>
    • dateTimestring

      Timestamp of this snapshot in ISO 8601 format.

      example: "2022-01-03T14:30:00Z"

    • profitLossnumber

      Cumulative strategy profit or loss at this point in the run.

      example: 128.5

    • underlyingPricenumber

      Price of the underlying symbol at this point in the run.

      example: 477.71

  • noticesarray<string>

    Conditional annotations appearing if specific conditions are met (for example overlapping ranges due to a stock split).

    example: []

201Backtest accepted and still running. Poll `GET /backtests/{id}` and watch `status` until it reaches `completed`.application/json

Example response

{
  "id": "b1f8c2a4-9e7d-4a31-8c6f-2d5e1a0b3c7e",
  "symbol": "SPY",
  "startDate": "2022-01-01",
  "endDate": "2022-12-31",
  "legs": [
    {
      "type": "equity-option",
      "direction": "short",
      "side": "put",
      "quantity": 1,
      "strikeSelection": "delta",
      "strikeRelativeLeg": 0,
      "delta": 16,
      "percentageOTM": 0.1,
      "currentPriceOffset": 5,
      "premium": 2.5,
      "daysUntilExpiration": 45
    }
  ],
  "entryConditions": {
    "frequency": "every day",
    "specificDays": [
      0
    ],
    "maximumActiveTrials": 5,
    "maximumActiveTrialsBehavior": "don't enter",
    "minimumVIX": 15,
    "maximumVIX": 30
  },
  "exitConditions": {
    "takeProfitPercentage": 50,
    "stopLossPercentage": 100,
    "afterDaysInTrade": 21,
    "atDaysToExpiration": 7,
    "minimumVIX": 12
  },
  "ETA": 0,
  "progress": 0,
  "status": "completed",
  "statistics": [
    {}
  ],
  "trials": [
    {
      "openDateTime": "2022-01-03T14:30:00Z",
      "closeDateTime": "2022-01-20T20:00:00Z",
      "profitLoss": 128.5
    }
  ],
  "snapshots": [
    {
      "dateTime": "2022-01-03T14:30:00Z",
      "profitLoss": 128.5,
      "underlyingPrice": 477.71
    }
  ],
  "notices": []
}

Schema

  • idstring

    Unique identifier for this backtest. Use it with `GET /backtests/{id}` to poll status and read results.

    example: "b1f8c2a4-9e7d-4a31-8c6f-2d5e1a0b3c7e"

  • symbolstring

    Underlying symbol the strategy trades.

    example: "SPY"

  • startDatestring <date>

    First date of the backtested historical window, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-01-01"

  • endDatestring <date>

    Last date of the backtested historical window, in ISO 8601 `YYYY-MM-DD` format.

    example: "2022-12-31"

  • legsarray<object>
    • typerequiredstring

      The instrument type for this leg: `equity` for shares or `equity-option` for an option contract.

      enum: equity, equity-option

      example: "equity-option"

    • directionrequiredstring

      The position direction: `long` to buy, `short` to sell.

      enum: long, short

      example: "short"

    • sidestring

      The option side, `call` or `put`. Only applicable when `type` is `equity-option`.

      enum: call, put

      example: "put"

    • quantityrequiredinteger

      Number of contracts or shares (1-10 for options, 1-100 for stocks).

      example: 1

    • strikeSelectionrequiredstring

      How the strike is chosen for this leg. The accompanying value field depends on this: for example `delta` reads `delta`, `premium` reads `premium`.

      enum: delta, percentageOTM, percentageOTMRelative, currentPriceOffset, currentPriceOffsetRelative, currentPriceExactOffsetRelative, premium

      example: "delta"

    • strikeRelativeLeginteger

      Index of the leg to use as reference when strike selection is relative to another leg.

      example: 0

    • deltanumber

      Delta value used when `strikeSelection` is `delta`, expressed as an integer from 1 to 100.

      example: 16

    • percentageOTMnumber

      Percentage out-of-the-money when `strikeSelection` is `percentageOTM` or `percentageOTMRelative` (for example 0.1 for 10% OTM, -0.1 for 10% ITM).

      example: 0.1

    • currentPriceOffsetnumber

      Offset from current price when `strikeSelection` is a currentPriceOffset variant (max 50000).

      example: 5

    • premiumnumber

      Target premium when `strikeSelection` is `premium` (max 50000).

      example: 2.5

    • daysUntilExpirationrequiredinteger

      Number of days until expiration to target for this leg.

      example: 45

  • entryConditionsobject (EntryConditions)

    Optional rules controlling when new trials are opened during the backtest, such as entry frequency, concurrency limits, and VIX bounds.

    • frequencystring | null

      How often to open new trials: `every day`, `on specific days of the week`, or `on exact days to expiration match`.

      enum: every day, on specific days of the week, on exact days to expiration match

      example: "every day"

    • specificDaysarray<integer>

      Days of the week on which to enter, used when `frequency` is `on specific days of the week`.

    • maximumActiveTrialsinteger | null

      Maximum number of trials allowed open simultaneously.

      example: 5

    • maximumActiveTrialsBehaviorstring | null

      What to do when the active-trial limit is reached: `don't enter` to skip the entry, or `close oldest` to free a slot.

      enum: don't enter, close oldest

      example: "don't enter"

    • minimumVIXinteger | null

      Only open trials when the VIX is at or above this value.

      example: 15

    • maximumVIXinteger | null

      Only open trials when the VIX is at or below this value.

      example: 30

  • exitConditionsobject (ExitConditions)

    Optional rules controlling when trials are closed during the backtest, such as profit/loss targets, time in trade, and days to expiration.

    • takeProfitPercentageinteger | null

      Profit threshold for closing a trial, expressed as a percentage.

      example: 50

    • stopLossPercentageinteger | null

      Loss threshold for closing a trial, expressed as a percentage.

      example: 100

    • afterDaysInTradeinteger | null

      Close a trial after it has been open this many days.

      example: 21

    • atDaysToExpirationinteger | null

      Close a trial when this many days to expiration remain.

      example: 7

    • minimumVIXinteger | null

      VIX threshold used as an exit condition for closing trials.

      example: 12

  • ETAnumber

    Estimated time remaining until the run completes. Use it to space out polls while the backtest is still running.

  • progressnumber

    Completion progress of the run.

  • statusstring

    Current run state. Moves through `pending`, `running`, and `completed`; read results once it is `completed`.

    enum: pending, running, completed

    example: "completed"

  • statisticsarray<object>

    Aggregate performance metrics for the run, populated once the backtest completes.

  • trialsarray<object>
    • openDateTimestring

      Timestamp the trial opened, in ISO 8601 format.

      example: "2022-01-03T14:30:00Z"

    • closeDateTimestring

      Timestamp the trial closed, in ISO 8601 format.

      example: "2022-01-20T20:00:00Z"

    • profitLossnumber

      Realized profit or loss for this trial.

      example: 128.5

  • snapshotsarray<object>
    • dateTimestring

      Timestamp of this snapshot in ISO 8601 format.

      example: "2022-01-03T14:30:00Z"

    • profitLossnumber

      Cumulative strategy profit or loss at this point in the run.

      example: 128.5

    • underlyingPricenumber

      Price of the underlying symbol at this point in the run.

      example: 477.71

  • noticesarray<string>

    Conditional annotations appearing if specific conditions are met (for example overlapping ranges due to a stock split).

    example: []

400Request included malformed input
401Unauthorized.
404Backtest not found
429Request rate exceeded reasonable thresholds. Back off exponentially before retrying.
500Failed to process request

Related

Agents: this page is also Markdown (with the embedded OpenAPI definition) — append .md or send Accept: text/markdown. Index at /llms.txt.