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.

ParameterTypeDescriptionExample
legslist[dict] | NoneA 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_datestr | NoneThe 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_rangefloatThe 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_sizeintThe step size to use for the stock prices at expiration. Defaults to 1.5
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise).2
Share