diff --git a/README.md b/README.md index 18bc923..a3506f2 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ [![PyPI](https://img.shields.io/pypi/v/opstrat)](https://pypi.org/project/opstrat/) [![PyPI - License](https://img.shields.io/pypi/l/opstrat)](https://pypi.org/project/opstrat/) -[![GitHub top language](https://img.shields.io/github/languages/top/abhijith-git/opstrat)](https://github.com/abhijith-git/opstrat) -[![GitHub Repo stars](https://img.shields.io/github/stars/abhijith-git/opstrat?style=social)](https://github.com/hashabcd/opstrat) -[![Twitter Follow](https://img.shields.io/twitter/follow/hashabcd?style=social)](https://twitter.com/hashabcd) +[![GitHub top language](https://img.shields.io/github/languages/top/hashabcd/opstrat)](https://github.com/abhijith-git/opstrat) +[![GitHub Repo stars](https://img.shields.io/github/stars/abhijith-git/opstrat?style=social)](https://github.com/abhijith-git/opstrat) +[![Twitter Follow](https://img.shields.io/twitter/follow/hashabcd?style=social)](https://twitter.com/intent/user?screen_name=hashabcd) [![Youtube](https://img.shields.io/youtube/views/EU3L4ziz3nk?style=social)](https://www.youtube.com/watch?v=EU3L4ziz3nk) Python library for visualizing options. @@ -221,4 +221,4 @@ Please make sure to update tests as appropriate. ### Tutorial in Video Format -[![Watch the video](https://img.youtube.com/vi/EU3L4ziz3nk/maxresdefault.jpg)](https://youtu.be/EU3L4ziz3nk) +[![Watch the video](https://img.youtube.com/vi/EU3L4ziz3nk/maxresdefault.jpg)](https://youtu.be/EU3L4ziz3nk) \ No newline at end of file diff --git a/opstrat/__init__.py b/opstrat/__init__.py index 4e1e81a..6d76292 100644 --- a/opstrat/__init__.py +++ b/opstrat/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.3" +__version__ = "0.1.4" __author__ = "Abhijith Chandradas" from .basic_multi import * diff --git a/opstrat/basic_multi.py b/opstrat/basic_multi.py index 2e89eb7..2e6ac36 100644 --- a/opstrat/basic_multi.py +++ b/opstrat/basic_multi.py @@ -1,17 +1,19 @@ -#basic_multi +#multiplotter import numpy as np import matplotlib.pyplot as plt import seaborn as sns +from helpers import payoff_calculator, check_optype, check_trtype + abb={'c': 'Call', 'p': 'Put', 'b': 'Long', 's': 'Short'} def multi_plotter(spot_range=20, spot=100, - op_list=[{'op_type':'c','strike':110,'tr_type':'s','op_pr':2}, - {'op_type':'p','strike':95,'tr_type':'s','op_pr':6}], - save=False, file='fig.png'): + op_list=[{'op_type':'c','strike':110,'tr_type':'s','op_pr':2,'contract':1}, + {'op_type':'p','strike':95,'tr_type':'s','op_pr':6,'contract':1}], + save=False, file='fig.png'): """ Plots a basic option payoff diagram for a multiple options and resultant payoff diagram @@ -33,7 +35,9 @@ def multi_plotter(spot_range=20, spot=100, 'op_pr': int, float, default: 10 Option Price 'op_type': kind {'c','p'}, default:'c' - Opion type>> 'c': call option, 'p':put option + Opion type>> 'c': call option, 'p':put option + 'contracts': int default:1, optional + Number of contracts save: Boolean, default False Save figure @@ -43,8 +47,8 @@ def multi_plotter(spot_range=20, spot=100, Example ------- - op1={'op_type':'c','strike':110,'tr_type':'s','op_pr':2} - op2={'op_type':'p','strike':95,'tr_type':'s','op_pr':6} + op1={'op_type':'c','strike':110,'tr_type':'s','op_pr':2,'contract':1} + op2={'op_type':'p','strike':95,'tr_type':'s','op_pr':6,'contract':1} import opstrat as op op.multi_plotter(spot_range=20, spot=100, op_list=[op1,op2]) @@ -53,27 +57,7 @@ def multi_plotter(spot_range=20, spot=100, """ x=spot*np.arange(100-spot_range,101+spot_range,0.01)/100 - y0=np.zeros_like(x) - - def check_optype(op_type): - if (op_type not in ['p','c']): - raise ValueError("Input 'p' for put and 'c' for call!") - def check_trtype(tr_type): - if (tr_type not in ['b','s']): - raise ValueError("Input 'b' for Buy and 's' for Sell!") - - def payoff_calculator(op_type, strike, op_pr, tr_type): - y=[] - if op_type=='c': - for i in range(len(x)): - y.append(max((x[i]-strike-op_pr),-op_pr)) - else: - for i in range(len(x)): - y.append(max(strike-x[i]-op_pr,-op_pr)) - - if tr_type=='s': - y=-np.array(y) - return y + y0=np.zeros_like(x) y_list=[] for op in op_list: @@ -84,14 +68,24 @@ def payoff_calculator(op_type, strike, op_pr, tr_type): strike=op['strike'] op_pr=op['op_pr'] - y_list.append(payoff_calculator(op_type, strike, op_pr, tr_type)) + try: + contract=op['contract'] + except: + contract=1 + y_list.append(payoff_calculator(x, op_type, strike, op_pr, tr_type, contract)) def plotter(): y=0 plt.figure(figsize=(10,6)) for i in range (len(op_list)): - label=str(abb[op_list[i]['tr_type']])+' '+str(abb[op_list[i]['op_type']])+' ST: '+str(op_list[i]['strike']) + try: + contract=str(op_list[i]['contract']) + except: + contract='1' + + label=contract+' '+str(abb[op_list[i]['tr_type']])+' '+str(abb[op_list[i]['op_type']])+' ST: '+str(op_list[i]['strike']) + print(len(x),len(y_list[i])) sns.lineplot(x=x, y=y_list[i], label=label, alpha=0.5) y+=np.array(y_list[i]) diff --git a/opstrat/basic_single.py b/opstrat/basic_single.py index e7a6e04..6cb92f3 100644 --- a/opstrat/basic_single.py +++ b/opstrat/basic_single.py @@ -2,6 +2,7 @@ import matplotlib.pyplot as plt import seaborn as sns import warnings +from helpers import check_optype, check_trtype warnings.filterwarnings('ignore') @@ -50,18 +51,8 @@ def single_plotter(op_type='c',spot=100, spot_range=10,strike=102,tr_type='b',op op_type=str.lower(op_type) tr_type=str.lower(tr_type) - - - def check_inputs(): - """ - Check inputs are proper - """ - if op_type not in ['p','c']: - raise ValueError("Input 'p' for put and 'c' for call!") - if tr_type not in ['b','s']: - raise ValueError("Input 'b' for Buy and 's' for Sell!") - - check_inputs() + check_optype(op_type) + check_trtype(tr_type) def payoff_calculator(): x=spot*np.arange(100-spot_range,101+spot_range,0.01)/100 diff --git a/opstrat/helpers.py b/opstrat/helpers.py new file mode 100644 index 0000000..0fac3bc --- /dev/null +++ b/opstrat/helpers.py @@ -0,0 +1,33 @@ +import yfinance as yf +import numpy as np + +def check_optype(op_type): + if (op_type not in ['p','c']): + raise ValueError("Input 'p' for put and 'c' for call!") + +def check_trtype(tr_type): + if (tr_type not in ['b','s']): + raise ValueError("Input 'b' for Buy and 's' for Sell!") + +def payoff_calculator(x, op_type, strike, op_pr, tr_type, n): + y=[] + if op_type=='c': + for i in range(len(x)): + y.append(max((x[i]-strike-op_pr),-op_pr)) + else: + for i in range(len(x)): + y.append(max(strike-x[i]-op_pr,-op_pr)) + y=np.array(y) + + if tr_type=='s': + y=-y + return y*n + +def check_ticker(ticker): + """ + Check ticker + """ + try: + return yf.Ticker('msft').info['currentPrice'] + except KeyError: + raise ValueError('Ticker not recognized') \ No newline at end of file diff --git a/opstrat/yf.py b/opstrat/yf.py index 901bd9d..7edf91c 100644 --- a/opstrat/yf.py +++ b/opstrat/yf.py @@ -3,14 +3,20 @@ import seaborn as sns import yfinance as yf +from helpers import check_ticker, check_optype, check_trtype, payoff_calculator + +import warnings +warnings.filterwarnings('ignore') + + abb={'c': 'Call', 'p': 'Put', 'b': 'Long', 's': 'Short'} def yf_plotter(ticker='msft',exp='default',spot_range=10, - op_list=[{'op_type':'c','strike':250,'tr_type':'b'}, - {'op_type':'p','strike':225,'tr_type':'b'}], + op_list=[{'op_type':'c','strike':250,'tr_type':'b', 'contract':1}, + {'op_type':'p','strike':225,'tr_type':'b', 'contract':1}], save=False, file='fig.png'): """ Plots a basic option payoff diagram for a multiple options and resultant payoff diagram @@ -34,6 +40,8 @@ def yf_plotter(ticker='msft',exp='default',spot_range=10, Transaction Type>> 'b': long, 's': short 'op_type': kind {'c','p'}, default:'c' Opion type>> 'c': call option, 'p':put option + 'contracts': int default:1, optional + Number of contracts save: Boolean, default False Save figure @@ -43,8 +51,8 @@ def yf_plotter(ticker='msft',exp='default',spot_range=10, Example ------- - op1={'op_type':'c','strike':250,'tr_type':'b'} - op2={'op_type':'p','strike':225,'tr_type':'b'} + op1={'op_type':'c','strike':250,'tr_type':'b', 'contract':1} + op2={'op_type':'p','strike':225,'tr_type':'b','contract':3} import opstrat as op op.yf_plotter(ticker='msft',exp='2021-03-26',spot_range=10, op_list=[op1,op2]) @@ -52,21 +60,11 @@ def yf_plotter(ticker='msft',exp='default',spot_range=10, #Plots option payoff diagrams for each op1 and op2 and combined payoff """ - - - def check_ticker(ticker): - """ - Check ticker - """ - try: - spot=yf.Ticker(ticker).info['bid'] - except KeyError: - raise ValueError('Ticker not recognized') - - check_ticker(ticker) - - spot=yf.Ticker(ticker).info['bid'] + #Check input and assigns spot price + spot=check_ticker(ticker) + #Expiry dates exp_list=yf.Ticker(ticker).options + x=spot*np.arange(100-spot_range,101+spot_range,0.01)/100 y0=np.zeros_like(x) @@ -82,29 +80,11 @@ def check_exp(exp): exp=yf.Ticker('msft').options[0] else: check_exp(exp) - - def check_optype(op_type): - if (op_type not in ['p','c']): - raise ValueError("Input 'p' for put and 'c' for call!") - def check_trtype(tr_type): - if (tr_type not in ['b','s']): - raise ValueError("Input 'b' for Buy and 's' for Sell!") + def check_strike(df, strike): if strike not in df.strike.unique(): raise ValueError('Option for the given Strike Price not available!') - def payoff_calculator(op_type, strike, op_pr, tr_type): - y=[] - if op_type=='c': - for i in range(len(x)): - y.append(max((x[i]-strike-op_pr),-op_pr)) - else: - for i in range(len(x)): - y.append(max(strike-x[i]-op_pr,-op_pr)) - - if tr_type=='s': - y=-np.array(y) - return y y_list=[] for op in op_list: @@ -118,21 +98,33 @@ def payoff_calculator(op_type, strike, op_pr, tr_type): df=yf.Ticker(ticker).option_chain(exp).puts else: df=yf.Ticker(ticker).option_chain(exp).calls - strike=op['strike'] check_strike(df, strike) - op_pr=df[df.strike==strike].lastPrice.sum() + try: + contract=op['contract'] + print('Setting contract =', contract) + except: + contract=1 + print('default') - y_list.append(payoff_calculator(op_type, strike, op_pr, tr_type)) + y_list.append(payoff_calculator(x, op_type, strike, op_pr, tr_type, contract)) def plotter(): y=0 plt.figure(figsize=(10,6)) for i in range (len(op_list)): - label=str(abb[op_list[i]['tr_type']])+' '+str(abb[op_list[i]['op_type']])+' ST: '+str(op_list[i]['strike']) + try: + contract=str(op_list[i]['contract']) + except: + contract='1' + + label=contract+' '+str(abb[op_list[i]['tr_type']])+' '+str(abb[op_list[i]['op_type']])+' ST: '+str(op_list[i]['strike']) + print(label) + print(len(x)) + print(len(y_list[i])) sns.lineplot(x=x, y=y_list[i], label=label, alpha=0.5) y+=np.array(y_list[i]) diff --git a/setup.py b/setup.py index 391293f..2bb6c45 100644 --- a/setup.py +++ b/setup.py @@ -7,10 +7,10 @@ README = readme_file.read() -VERSION = '0.1.3' +VERSION = '0.1.4' DESCRIPTION = 'Option stategy visualizer' #LONG_DESCRIPTION = DESCRIPTION -URL = 'https://github.com/abhijith-git/opstrat' +URL = 'https://github.com/hashabcd/opstrat' # Setting up setup(