This is my 1st Python program I've actually written and I have little to no background in the language. I just figured I could learn and do something that interested me at the same time.
I'm not a book learner. I can't just sit down and read a bunch of technical documents and stuff like that so I'm sure a lot of this code is unconventional at best and just plain bad at worst. I learn best by doing, so now that I got this program to work I want to learn how to make it better.
The goal of the program is to load the Yahoo finance options page for each ticker in a file that I created. Then pull all of the call options data for each expiration date and load all of that data into a SQL database (to be queried later).
I added the multi-processing to try and make it faster, but it seems to have just slowed it down. I gotta figure that part out.
import logging
import pyodbc
import config
import yahoo_fin as yfin
import asyncio
import multiprocessing
import time
from yahoo_fin import options
from datetime import datetime, date
from selenium import webdriver
def main():
read_ticker_file()
def init_selenium():
driver = webdriver.Chrome(config.CHROME_DRIVER)
return driver
def yfin_options(symbol):
logging.basicConfig(filename='yfin.log', level=logging.INFO)
logging.basicConfig(filename='no_options.log', level=logging.ERROR)
try:
# get all options dates (in epoch) from dropdown on yahoo finance options page
dates = get_exp_dates(symbol)
# iterate each date to get all calls and insert into sql db
for date in dates:
arr = yfin.options.get_calls(symbol, date)
arr_length = len(arr.values)
i = 0
for x in range(0, arr_length):
strike: str = str(arr.values[i][2])
volume = str(arr.values[i][8])
open_interest = str(arr.values[i][9])
convert_epoch = datetime.fromtimestamp(int(date))
try:
sql_insert(symbol, strike, volume, open_interest, convert_epoch)
i += 1
except Exception as insert_fail:
print("I failed at sqlinsert {0}".format(insert_fail))
file_name_dir = "C:\\temp\\rh\\options{0}{1}.xlsx".format(symbol, date)
logging.info(arr.to_excel(file_name_dir))
except Exception as e:
bad_tickers_file_dir = config.BAD_TICKERS
f = open(bad_tickers_file_dir, "a")
f.write(symbol)
f.write('\n')
def sql_insert(symbol, strike, volume, open_interest, exp_date):
conn_string = ('Driver={SQL Server};'
'Server=DESKTOP-7ONNV8L;'
'Database=optionsdb;'
'Trusted_Connection=yes;')
conn = pyodbc.connect(conn_string)
cursor = conn.cursor()
insert_string = """INSERT INTO dbo.options (Ticker, Strike, Volume, OpenInterest, expDate)
VALUES
(?, ?, ?, ?, ?)"""
cursor.execute(insert_string, symbol, strike, volume, open_interest, str(exp_date))
conn.commit()
def get_exp_dates(symbol):
url = "https://finance.yahoo.com/quote/" + symbol + "/options?p=" + symbol
chromedriver = init_selenium()
chromedriver.get(url)
# Yahoo Finance options dropdown class name (find better way to do this)
select_dropdown = chromedriver.find_element_by_css_selector("div[class='Fl(start) Pend(18px)'] > select")
options_list = [x for x in select_dropdown.find_elements_by_tag_name("option")]
dates = []
for element in options_list:
dates.append(element.get_attribute("value"))
return dates
def read_ticker_file():
file1 = open(config.TICKER_FILE, 'r')
lines = file1.readlines()
count = 0
ticker_arr = []
# loop to read each ticker in file
for line in lines:
count += 1
line = line.strip('\n')
line = line.strip()
ticker_arr.append(line)
return ticker_arr
if __name__ == "__main__":
pool = multiprocessing.Pool()
# input list
inputs = read_ticker_file()
# pool object with number of element
pool = multiprocessing.Pool(processes=4)
pool.map(yfin_options, inputs)
pool.close()
pool.join()
.options
property which shows the expiration dates. From that, you can then iterate through the dates and load the chain for each date. \$\endgroup\$