Advertisement
Guest User

Options trading with automated TA u/dj_options

a guest
Feb 15th, 2021
3,410
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.95 KB | None | 0 0
  1.     from util import util
  2.     import yfinance as yf
  3.     from finviz.screener import Screener
  4.     from dateutil.parser import *
  5.     from datetime import date
  6.     import pandas as pd
  7.     import pandas_ta as ta
  8.     from prettytable import PrettyTable
  9.      
  10.      
  11.     class OptionHolder:
  12.      
  13.         def __init__(self):
  14.             self.Ticker = ""
  15.             self.Strike = 0.0
  16.             self.Expiry = None
  17.             self.YahooString = ""
  18.             self.IsCall = False
  19.      
  20.             self.BidPrice = 0.0
  21.             self.AskPrice = 0.0
  22.             self.FilledPrice = 0.0
  23.             self.FilledAmount = 0.0
  24.             self.CurrentSpread = 0.0
  25.             self.Volume = 0
  26.             self.OpenInterest = 0
  27.             self.PercentChange = 0.0
  28.             self.IV = 0.0
  29.             self.VWAP = 0.0
  30.      
  31.             self.IdealBuy = 0.0
  32.             self.IdealSell = 0.0
  33.      
  34.             self.BBandHigh = 0.0
  35.             self.BBandLow = 0.0
  36.             self.RSI = 0.0
  37.             self.SMA = 0.0
  38.             self.BuyScore = 0
  39.      
  40.             self.HistoricData = None
  41.      
  42.      
  43.     def get_stock_list(amount_to_return=3):
  44.         filters = ['cap_small', 'geo_usa', 'sh_avgvol_o300', 'sh_opt_option',
  45.                    ]
  46.      
  47.         stock_list = Screener(filters=filters, table='Overview',
  48.                               order='-change')  # Get the performance table and sort it by price ascending
  49.      
  50.         stockList = []
  51.         for x in stock_list:
  52.             stockList.append(x['Ticker'])
  53.      
  54.         return stockList[:amount_to_return]
  55.      
  56.      
  57.     def get_eligible_option_data_for_stock(stock=""):
  58.         stockTicker = yf.Ticker(stock)
  59.      
  60.         optionHolderReturn = []
  61.      
  62.         for x in stockTicker.options:
  63.             expirationTime = parse(x)
  64.             if expirationTime.year > date.today().year:
  65.      
  66.                 for index, row in stockTicker.option_chain(x).calls.iterrows():
  67.      
  68.                     historicData = get_daily_data_for_option(row["contractSymbol"])
  69.                     if len(historicData) < 8:
  70.                         continue
  71.      
  72.                     newOptionHolder = OptionHolder()
  73.                     newOptionHolder.Ticker = stock
  74.                     newOptionHolder.IsCall = True
  75.                     newOptionHolder.Expiry = expirationTime
  76.                     newOptionHolder.FilledPrice = row["lastPrice"]
  77.                     newOptionHolder.BidPrice = row["bid"]
  78.                     newOptionHolder.AskPrice = row["ask"]
  79.                     newOptionHolder.Strike = row["strike"]
  80.                     newOptionHolder.CurrentSpread = newOptionHolder.AskPrice - newOptionHolder.BidPrice
  81.                     newOptionHolder.PercentChange = round(row["change"], 3)
  82.                     newOptionHolder.OpenInterest = row["openInterest"]
  83.                     newOptionHolder.IV = round(row["impliedVolatility"], 3)
  84.                     newOptionHolder.YahooString = row["contractSymbol"]
  85.                     newOptionHolder.HistoricData = historicData
  86.                     optionHolderReturn.append(newOptionHolder)
  87.      
  88.                 for index, row in stockTicker.option_chain(x).puts.iterrows():
  89.      
  90.                     historicData = get_daily_data_for_option(row["contractSymbol"])
  91.                     if len(historicData) < 8:
  92.                         continue
  93.      
  94.                     newOptionHolder = OptionHolder()
  95.                     newOptionHolder.Ticker = stock
  96.                     newOptionHolder.IsCall = False
  97.                     newOptionHolder.Expiry = expirationTime
  98.                     newOptionHolder.FilledPrice = row["lastPrice"]
  99.                     newOptionHolder.BidPrice = row["bid"]
  100.                     newOptionHolder.AskPrice = row["ask"]
  101.                     newOptionHolder.Strike = row["strike"]
  102.                     newOptionHolder.CurrentSpread = newOptionHolder.AskPrice - newOptionHolder.BidPrice
  103.                     newOptionHolder.PercentChange = round(row["change"], 3)
  104.                     newOptionHolder.OpenInterest = row["openInterest"]
  105.                     newOptionHolder.IV = round(row["impliedVolatility"], 3)
  106.                     newOptionHolder.YahooString = row["contractSymbol"]
  107.                     newOptionHolder.HistoricData = historicData
  108.                     optionHolderReturn.append(newOptionHolder)
  109.      
  110.         return optionHolderReturn
  111.      
  112.      
  113.     def get_daily_data_for_option(option=""):
  114.         stockTicker = yf.Ticker(option)
  115.      
  116.         return stockTicker.history(period="1mo", interval="1d", debug=False)
  117.      
  118.      
  119.     def get_ideal_buy_sell_magic(option):
  120.         option.IdealBuy = round(option.BidPrice + (option.CurrentSpread * .2), 3)
  121.         option.IdealSell = round(option.AskPrice - (option.CurrentSpread * .2), 3)
  122.      
  123.      
  124.     if __name__ == '__main__':
  125.         util.show_banner()
  126.      
  127.         pd.set_option('display.max_rows', 500)
  128.         pd.set_option('display.max_columns', 500)
  129.         pd.set_option('display.width', 1000)
  130.      
  131.         stockList = get_stock_list(5)
  132.      
  133.         eligibleOptions = []
  134.         for x in stockList:
  135.             print("Checking if stock is eligible: " + x)
  136.             eligibleOptions.extend(get_eligible_option_data_for_stock(x))
  137.      
  138.         if len(eligibleOptions) == 0:
  139.             print("No data to use")
  140.         else:
  141.      
  142.             for option in eligibleOptions:
  143.                 option.HistoricData["SMA"] = ta.sma(option.HistoricData["Close"], 5)
  144.                 option.HistoricData["RSI"] = ta.rsi(option.HistoricData["Close"], 5)
  145.                 option.HistoricData["VWAP"] = ta.vwap(low=option.HistoricData["Low"],
  146.                                                       high=option.HistoricData["High"],
  147.                                                       close=option.HistoricData["Close"],
  148.                                                       volume=option.HistoricData["Volume"])
  149.                 bbandData = ta.bbands(option.HistoricData["Close"], 5, 2)
  150.                 option.HistoricData["BBU"] = bbandData["BBU_5_2.0"]
  151.                 option.HistoricData["BBL"] = bbandData["BBL_5_2.0"]
  152.      
  153.                 option.BBandHigh = round(option.HistoricData["BBU"][-1], 3)
  154.                 option.BBandLow = round(option.HistoricData["BBL"][-1], 3)
  155.                 option.RSI = round(option.HistoricData["RSI"][-1], 3)
  156.                 option.SMA = round(option.HistoricData["SMA"][-1], 3)
  157.                 option.VWAP = round(option.HistoricData["VWAP"][-1], 3)
  158.                 option.Volume = round(option.HistoricData["Volume"].sum(), 3)
  159.                 option.CurrentSpread = round(
  160.                     max(option.HistoricData["Close"][-5:]) - min(option.HistoricData["Close"][-5:]), 3)
  161.                 get_ideal_buy_sell_magic(option)
  162.      
  163.             for option in eligibleOptions:
  164.                 if option.RSI <= 40:
  165.                     option.BuyScore = option.BuyScore + 1
  166.                 if option.Volume >= 100:
  167.                     option.BuyScore = option.BuyScore + 1
  168.                 if option.HistoricData["Close"][-1] <= option.BBandLow:
  169.                     option.BuyScore = option.BuyScore + 1
  170.                 if option.SMA <= option.VWAP:
  171.                     option.BuyScore = option.BuyScore + 1
  172.                 if option.CurrentSpread >= 0.05:
  173.                     option.BuyScore = option.BuyScore + 1
  174.                 if option.FilledPrice == option.BidPrice:
  175.                     option.BuyScore = option.BuyScore + 1
  176.                 if option.IV <= 40:
  177.                     option.BuyScore = option.BuyScore + 1
  178.                 if option.PercentChange <= 0:
  179.                     option.BuyScore = option.BuyScore + 1
  180.      
  181.             outputTable = PrettyTable()
  182.      
  183.             outputTable.field_names = ["Sr. no.", "Ticker", "Strike", "Expiry", "Bid", "Filled", "Ask", "Ideal (Buy/Sell)",
  184.                                        "Spread", "Vol / OI", "BB (S/R)", "RSI", "VWAP", "SMA(5)", "Today Gain", "IV",
  185.                                        "B-Score"]
  186.      
  187.             outputTable.align["Sr. no."] = "c"
  188.             outputTable.align["Ticker"] = "c"
  189.             outputTable.align["Strike"] = "c"
  190.             outputTable.align["Expiry"] = "c"
  191.             outputTable.align["Bid"] = "c"
  192.             outputTable.align["Filled"] = "c"
  193.             outputTable.align["Ask"] = "c"
  194.             outputTable.align["Ideal (Buy/Sell)"] = "c"
  195.             outputTable.align["Spread"] = "c"
  196.             outputTable.align["Vol / OI"] = "c"
  197.             outputTable.align["BB (S/R)"] = "c"
  198.             outputTable.align["RSI"] = "c"
  199.             outputTable.align["VWAP"] = "c"
  200.             outputTable.align["SMA(5)"] = "c"
  201.             outputTable.align["Today Gain"] = "c"
  202.             outputTable.align["IV"] = "c"
  203.             outputTable.align["B-Score"] = "c"
  204.      
  205.             # Sort this shit somehow
  206.             eligibleOptions.sort(key=lambda x: x.BuyScore, reverse=True)
  207.      
  208.             for index, option in enumerate(eligibleOptions):
  209.                 outputTable.add_row(
  210.                     [index,
  211.                      option.Ticker,
  212.                      option.Strike,
  213.                      option.Expiry,
  214.                      '{:.3f}'.format(option.BidPrice),
  215.                      '{:.3f}'.format(option.FilledPrice),
  216.                      '{:.3f}'.format(option.AskPrice),
  217.                      '{:.3f}'.format(option.IdealBuy) + " / " + '{:.3f}'.format(option.IdealSell),
  218.                      '{:.3f}'.format(round(option.CurrentSpread, 3)),
  219.                      str(option.Volume) + " / " + str(option.OpenInterest),
  220.                      '{:.3f}'.format(option.BBandLow) + " / " + '{:.3f}'.format(option.BBandHigh),
  221.                      '{:.3f}'.format(option.RSI),
  222.                      '{:.3f}'.format(option.VWAP),
  223.                      '{:.3f}'.format(option.SMA),
  224.                      '{:.3f}'.format(option.PercentChange),
  225.                      option.IV, str(option.BuyScore) + " / 8"])
  226.      
  227.             print(outputTable)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement