beginner – Python yahoo finance option chain scraper

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.

So, 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 and then pull all of the call options data for each expiration date and then 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 so 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()