Strategy Payoff
Calculate the net expiration profit and loss (P&L) profile of a multi-leg option (and, optionally, stock) strategy across a range of stock prices.
A strategy is expressed as a list of “legs”. Each leg is a dictionary describing either an option position or a stock position:
- For an option leg: “instrument”: “option” (default), “strike_price” (float, required), “put_option” (bool, defaults to False), “position” (“long” or “short”, defaults to “long”), “premium” (float, defaults to 0).
- For a stock leg: “instrument”: “stock”, “position” (“long” or “short”, defaults to “long”), “premium” (float, the entry price, defaults to 0).
This single, generic building block can express many common strategies by combining legs, for example:
- Straddle: long call + long put, same strike.
- Strangle: long call + long put, different (OTM) strikes.
- Bull call spread: long call (lower strike) + short call (higher strike).
- Bear put spread: long put (higher strike) + short put (lower strike).
- Covered call: long stock + short call.
- Protective put: long stock + long put.
- Iron condor: short put + long put (lower strikes) + short call + long call (higher strikes).
The formula is as follows, for each stock price at expiration S(T) and one unit per leg:
\[\text{Call Leg Value} = \max(S(T) - K,\; 0)\] \[\text{Put Leg Value} = \max(K - S(T),\; 0)\] \[\text{Stock Leg Value} = S(T)\] \[\text{Leg}\; \text{P\&L} = \text{Leg Value} - \text{Premium for}\; a \;\text{long leg},\;\; \text{Premium - Leg Value for a short leg}\] \[\text{Strategy}\; \text{P\&L} = \operatorname{SUM}(\text{Leg}\; \text{P\&L}) \text{over all legs}\]Where K is the leg’s strike price and the premium is the price paid (long) or received (short) for the leg, or the entry price of a stock leg. The P&L is not discounted.
Also known as: option strategy payoff diagram, P&L profile.
Strategy Payoff in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_strategy_payoff as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["TSLA"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2025-01-01",
end_date="2025-12-31",
)
toolkit.options.get_strategy_payoff(stock_price_range=0.25, stock_price_step_size=5)
Or, after setting up the Finance Toolkit MCP, ask:
What is the profit or loss at expiry of an at-the-money straddle on Tesla, bought at the end of 2025 with 30 days to expiry, for share prices within 25% of that price in $5 steps?
Which returns:
| Stock Price | TSLA |
|---|---|
| 335 | 49.7821 |
| 340 | 44.7821 |
| 345 | 39.7821 |
| 350 | 34.7821 |
| 355 | 29.7821 |
| 360 | 24.7821 |
| 365 | 19.7821 |
| 370 | 14.7821 |
| 375 | 9.7821 |
| 380 | 4.7821 |
| 385 | -0.2179 |
| 390 | -5.2179 |
| 395 | -10.2179 |
| 400 | -15.2179 |
| 405 | -20.2179 |
| 410 | -25.2179 |
| 415 | -30.2179 |
| 420 | -35.2179 |
| 425 | -40.2179 |
| 430 | -45.2179 |
| 435 | -50.2179 |
| 440 | -55.2179 |
| 445 | -60.2179 |
| 450 | -64.6579 |
| 455 | -59.6579 |
| 460 | -54.6579 |
| 465 | -49.6579 |
| 470 | -44.6579 |
| 475 | -39.6579 |
| 480 | -34.6579 |
| 485 | -29.6579 |
| 490 | -24.6579 |
| 495 | -19.6579 |
| 500 | -14.6579 |
| 505 | -9.6579 |
| 510 | -4.6579 |
| 515 | 0.3421 |
| 520 | 5.3421 |
| 525 | 10.3421 |
| 530 | 15.3421 |
| 535 | 20.3421 |
| 540 | 25.3421 |
| 545 | 30.3421 |
| 550 | 35.3421 |
| 555 | 40.3421 |
Parameters
get_strategy_payoff accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
legs | list[dict] | None | A list of leg dictionaries as described above. Must contain at least one leg. The same legs are applied to every ticker, so strike prices should be chosen with the relevant tickers’ price levels in mind. Defaults to None, which buys an at-the-money straddle on each ticker: a call and a put with the stock price on the start date as strike and 30 days to expiration, priced with the Black Scholes model on the volatility, risk free rate and dividend yield of that date, as get_black_scholes_model does. | [{"strike_price": 250, "premium": 8}, {"strike_price": 250, "put_option": True, "premium": 6}] |
start_date | str | None | The date whose price, volatility and rates the values start from; a date without prices (a weekend or a holiday) uses the last trading day before it, and a ticker without a price on that day is left out with a warning. Defaults to None, which uses the last date of the historical data. | "2021-01-01" |
stock_price_range | float | The percentage range to use for the stock prices at expiration. Defaults to 0.5 which equals 50% and thus results in stock prices from 50 to 150 if the current stock price is 100. | 0.25 |
stock_price_step_size | int | The step size to use for the stock prices at expiration. Defaults to 1. | 5 |
rounding | int | None | The number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise). | 2 |