OptionTrading
Topic : Option trading Strategies , B&S , Implied Volatility &Stochastic & Local Volatility , Geometric Brownian Motion.
Install / Use
/learn @AdrienCss/OptionTradingREADME
Option trading and analysis
Designed for educational purposes. Here are some of the key topics:
- Data request : Recovery of Option & stock financial data via the yFinance API
- Option Trading Strategies: We'll explore various strategies for trading options, including both traditional and more exotics techniques.
- Black & Scholes Pricing Model: Implementation of the theoretical foundations of the Black & Scholes model:Observation of the parameters affecting the value of an option.
- Implied Volatility Surface / Local Volatility: Recovery and calculation of implied volatilities quoted on the market. Observing the long and short term skew/smile.Calculation of local volatility with the Dupire formula.
- Stochastic Volatility: We'll explore the concept of stochastic volatility with Heston Model
- Greeks: We'll cover the key "Greeks" (Delta, Gamma, Theta, Vega, Rho) and their profiles with different options strategies.
Data Retrieval
The initial step in this code utilizes the yahoofinance API to access financial quotes. This is achieved through the use of the internal modules y_finane_option_data and y_finane_stock_data, which are utilized to retrieve option and stock data for a specific ticker symbol.
During all the analysis of Read.me we will use as symbol TSLA
Here is the simplest code to retrieve data:
from DataRequest import y_finane_option_data , y_finane_stock_data
# Choose the instruments you want to recover
ticker = 'TSLA'
## Get Option & underlying stock price
option_df = y_finane_option_data.get_option_data(ticker)
stockPrices_ = y_finane_stock_data.get_stock_price(ticker)
Click here to access to dataFolder scprit Data Request folder
Example of output with TLSA:

Creating Option trading stategies
In this script, we will construct a variety of strategies using real optional data. We will establish "Option"& "Stocks" data type and devise distinct strategies from it. Additionally, we will plot the corresponding Payoff profiles for these strategies. We will have the capability to display the Greek profiles of these strategies, projected over a range of underlying prices. This will allow us to analyze and evaluate the potential outcomes and risks associated with each strategies.
In the case of the following strategies we have taken real options that quote the market on the underlying TSLA.
Click here to see the code of the strategy Engine => OptionStrategies.py<=
# We take the 5th closest maturity
maturity =option_df['T_days'].unique()[5]
options_df = option_df[option_df['T_days'] ==maturity]
call_df = options_df[options_df['Type'] =='CALL']
put_df = options_df[options_df['Type'] =='PUT']
#Getting real Quotes options
call_90_df = call_df.iloc[(call_df['strike']-(currentprice * 0.90)).abs().argsort()[:1]]
call_80_df = call_df.iloc[(call_df['strike']-(currentprice * 0.80)).abs().argsort()[:1]]
put_90_df = put_df.iloc[(put_df['strike']-(currentprice * 0.90)).abs().argsort()[:1]]
put_80_df = put_df.iloc[(put_df['strike']-(currentprice * 0.80)).abs().argsort()[:1]]
# Creating Call spread 80 / 90
call90 = Option(price=call_90_df['lastPrice'].values[0], K=call_90_df['strike'].values[0] , type= OpionType.CALL)
call80 = Option(price=call_80_df['lastPrice'].values[0], K=call_80_df['strike'].values[0] , type= OpionType.CALL)
strategy = OptionStrategies(name = "Call spread 90/80" ,St = currentprice)
strategy.add_Option(option= call90 ,buySell= BuySellSide.SELL , option_number=1 )
strategy.add_Option(option= call80 ,buySell= BuySellSide.BUY , option_number=1 )
strategy.plot()
# Creating put spread 80 / 90
put90 = Option(price=put_90_df['lastPrice'].values[0], K=put_90_df['strike'].values[0] , type= OpionType.PUT)
put80 = Option(price=put_80_df['lastPrice'].values[0], K=put_80_df['strike'].values[0] , type= OpionType.PUT)
strategy = OptionStrategies(name = "PUT Spread 90/ 80" ,St = currentprice)
strategy.add_Option(option= put90 ,buySell= BuySellSide.BUY , option_number=1 )
strategy.add_Option(option= put80,buySell= BuySellSide.SELL , option_number=1 )
strategy.plot()
Put Spread Payoff 80%/90% | Call Spread Payoff 80%/90% :-------------------------:|:-------------------------: <img src="Images/putSpread8090.png" width="400"> | <img src="Images/callSpread.png" width="400">
-Butterflies , Straddle , Strangle
Straddle Payoff | Strangle Payoff :-------------------------:|:-------------------------: <img src="Images/straddle.png" width="400"> | <img src="Images/strangle.png" width="400">
Long Butterfly spread | Short Butterfly spread :-------------------------:|:-------------------------: <img src="Images/LongButterfly.png" width="400"> | <img src="Images/ShortButterFly.png" width="400">
A synthetic call is a combination of a stock and a cash position, such as a long stock position and a short put option position, that simulates the payoff of a long call option. A synthetic put is a combination of a stock and a cash position, such as a short stock position and a long call option position, that simulates the payoff of a long put option. These options strategies can be used to replicate the payout of a call or put option, while potentially reducing the cost or risk associated with buying or selling the actual option.
#synthetic call
put_df1 = put_df.iloc[(put_df['strike']-(currentprice - 15)).abs().argsort()[:1]]
put = Option(price=put_df1['lastPrice'].values[0], K=put_df1['strike'].values[0] , type= OpionType.PUT)
stock = Stock(price = last_price)
strategy = OptionStrategies(name = "Synthetic call" ,St = currentprice)
strategy.add_Option(option= put ,buySell= BuySellSide.BUY, option_number=1 )
strategy.add_deltaOne(stock=stock,buySell= BuySellSide.BUY )
strategy.plot()
#synthetic PUT
call_df1 = call_df.iloc[(call_df['strike']-(currentprice - 15)).abs().argsort()[:1]]
call = Option(price=call_df1['lastPrice'].values[0], K=call_df1['strike'].values[0] , type= OpionType.CALL)
stock = Stock(price = currentprice)
strategy = OptionStrategies(name = "Synthetic PUT", St = currentprice)
strategy.add_Option(option= call ,buySell= BuySellSide.BUY, option_number=1 )
strategy.add_deltaOne(stock=stock,buySell= BuySellSide.SELL )
strategy.plot()
Synthetic call | Synthetic Put :-------------------------:|:-------------------------: <img src="Images/SyntheticCall.png" width="400"> | <img src="Images/SyntheticPUT.png" width="400">
-Covered call/ Put
Call Spread Greeks Profile The engine also allows you to profile greek strategies. Here are the results obtained for a call spread
T = maturity /252
r = 0.015
vol = np.average(call_90_df['impliedVolatility'].values[0] + call_80_df['impliedVolatility'].values[0])
strategy.compute_greek_profile(T ,r , vol)
strategy.plotGreek(greekStr='gamma')
strategy.plotGreek(greekStr='theta')
strategy.plotGreek(greekStr='delta')
strategy.plotGreek(greekStr='vega')
Delta profile | Gamma Profile :-------------------------:|:-------------------------: <img src="Images/Delta.png" width="400"> | <img src="Images/Gamma.png" width="400"> Vega profile | Theta Profile <img src="Images/Vega.png" width="400"> | <img src="Images/Theta.png" width="400">
Call/ Put Parity
Call-Put Parity is a concept that refers to the relationship between call options and put options on the same underlying asset. The relationship is given by the following formula:
$$ C +K*\exp(-rT) = S_0 + P $$
Through this simple relationship we will see if there are arbitrage opportunities in the market. First, let's observe for a chosen maturity the call and put prices on the market for a strike range
<img src="Images/MktPriceCP.png" width="400"> As we can see, the market prices seem to resemble classic option prices, without any particular problem.Now let's calculate the corresponding prices of calls and puts to see if arbitrage opportunities can exist..
Call | Put :-------------------------:|:-------------------------: <img src="Images/calls_CP.png" width="400"> | <img src="Images/Put_CP.png" width="400">
In both cases the two curves are not distinctly observable! This proves that the market is totally efficient and that arbitrage opportunities do not exist on these options
Option Princing : Binomial & B&S
The B&S model is based on the following assumptions:
- The underlying asset price follows a geometric Brownian motion with constant drift and volatility.
- There are no transaction costs or taxes.
- Trading can be done continuously.
- The risk-free interest rate is constant.
- The option can only be exercised at expiration.
Under these assumptions, the Black-Scholes model provides a closed-form solution for the price of a European call or put option.
The binomial model provides a multi-period view of the underlying asset price as well as the price of the option. In contrast to the Black-Scholes model, which provides a numerical result based on inputs, the binomial model allows for the calculation of the asset and the option for multiple periods along with the range of possible results for each period .
#Binomial Method
def combos(n, i):
return math.factorial(n) / (math.factorial(n - i) * math.factorial(i))
def binom_EU1(S0, K, T, r, sigma, N, type_='call'):
dt = T / N
u = np.exp(sigma * np.sqrt(dt))
d = np.exp(-sigma * np.sq
