Case Studies

1. Speeding Up API with Thread Pools

Introduction:

  • Application Program Interface (API) Request information server a through calss and to receive valid response.

Challenge:

  • Retrieving Huge Amount of Data in Quick time is challenging using multiple API Request

Solution:

  • Use Thread Pools Library

Setup:

pip install yahoofinancials
pip install pandas

Model:

Note

Free Cash Flow (FCF)

\[FCF = Cash from Operations - Capital Expenditure\]

Normal API Request:

Alternative text
from yahoofinancials import YahooFinancials
import pandas as pd
#import concurrent.futures

print("Normal API Program Started .... Please wait for results ...")
import time
start_time = time.time()

def calculate_fcf(ticker):
    print("ticker: ", [ticker][0])

    # make yahoofinancials instance
    yahoo_financials = YahooFinancials(ticker)
    print("yahoofinancials instance got created")


    # get date for the last quarter reported
    last_quarter_reported = next(iter(yahoo_financials.get_financial_stmts('quarterly', 'cash')['cashflowStatementHistoryQuarterly'][ticker][0]))

    # get total cash from operating activities
    print("calculating total from operating activities...")
    tcfoa = yahoo_financials.get_financial_stmts('quarterly', 'cash')['cashflowStatementHistoryQuarterly'][ticker][0][last_quarter_reported]['totalCashFromOperatingActivities']

    # get capital expenditures
    print("calculating capital expenditures...")
    capex = yahoo_financials.get_financial_stmts('quarterly',  'cash')['cashflowStatementHistoryQuarterly'][ticker][0][last_quarter_reported]['capitalExpenditures']

    # get free cash flow
    fcf = tcfoa-abs(capex)

    # return date of last quarter reported and free cash flow
    return last_quarter_reported, fcf


tickers = ['NEM', 'FCX', 'BBL', 'GLNCY', 'VALE', 'RTNTF', 'SCCO', 'AU', 'NGLOY', 'HL']  # ticker list
quarter_dates = []  # list to store quarter dates
fcfs = []  # list to store free cash flows
for ticker in tickers:  # loop through tickers list
    calc_fcf = calculate_fcf(ticker) # use function for API request
    quarter_date = calc_fcf[0] # get date element from function
    fcf = calc_fcf[1]  # get fcf element from function
    # append results to lists
    quarter_dates.append(quarter_date)
    fcfs.append(fcf)

print("Free Cash Flow (FCF): ",fcfs)
print("Time Taken: --- %s seconds ---" % (time.time() - start_time))

Output:

 Normal API Program Started .... Please wait for results ...
 ticker:  NEM
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  FCX
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  BBL
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  GLNCY
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  VALE
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  RTNTF
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  SCCO
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  AU
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  NGLOY
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 ticker:  HL
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 Free Cash Flow (FCF):  [1288000000, 939000000, 2877500000, 406000000, 20925000000, 3375500000, 852100000, 245000000, -441500000, 28267000]
 Time Taken: --- 73.05337882041931 seconds ---

API Request Thread Pools:

Alternative text
from yahoofinancials import YahooFinancials
import pandas as pd
import concurrent.futures

print("Thread Pool API Program Started .... Please wait for results ...")
import time
start_time = time.time()

def calculate_fcf(ticker):
    print("ticker: ", [ticker][0])

    # make yahoofinancials instance
    yahoo_financials = YahooFinancials(ticker)
    print("yahoofinancials instance got created")


    # get date for the last quarter reported
    last_quarter_reported = next(iter(yahoo_financials.get_financial_stmts('quarterly', 'cash')['cashflowStatementHistoryQuarterly'][ticker][0]))

    # get total cash from operating activities
    print("calculating total from operating activities...")
    tcfoa = yahoo_financials.get_financial_stmts('quarterly', 'cash')['cashflowStatementHistoryQuarterly'][ticker][0][last_quarter_reported]['totalCashFromOperatingActivities']

    # get capital expenditures
    print("calculating capital expenditures...")
    capex = yahoo_financials.get_financial_stmts('quarterly',  'cash')['cashflowStatementHistoryQuarterly'][ticker][0][last_quarter_reported]['capitalExpenditures']

    # get free cash flow
    fcf = tcfoa-abs(capex)

    # return date of last quarter reported and free cash flow
    return last_quarter_reported, fcf

with concurrent.futures.ThreadPoolExecutor() as executor:
    tickers = ['NEM', 'FCX', 'BBL', 'GLNCY', 'VALE', 'RTNTF', 'SCCO', 'AU', 'NGLOY', 'HL']  # ticker list
    results = executor.map(calculate_fcf, tickers) # map takes the  function and iterables
    quarter_dates = [] # list to store quarter dates
    fcfs = [] # list to store free cash flows
    for result in results: # loop through results
        quarter_dates.append(result[0]) # append date element
        fcfs.append(result[1]) # append fcf element

print("Free Cash Flow (FCF): ",fcfs)
print("Time Taken with ThreadPool: --- %s seconds ---" % (time.time() - start_time))

Output:

 Thread Pool API Program Started .... Please wait for results ...
 ticker:  NEM
 yahoofinancials instance got created
 ticker:  FCX
 yahoofinancials instance got created
 ticker:  BBL
 yahoofinancials instance got created
 ticker:  GLNCY
 yahoofinancials instance got created
 ticker:  VALE
 yahoofinancials instance got created
 ticker:  RTNTF
 yahoofinancials instance got created
 ticker:  SCCO
 yahoofinancials instance got created
 ticker:  AU
 yahoofinancials instance got created
 ticker:  NGLOY
 yahoofinancials instance got created
 ticker:  HL
 yahoofinancials instance got created
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 calculating total from operating activities...
 calculating capital expenditures...
 Free Cash Flow (FCF):  [1288000000, 939000000, 2877500000, 406000000, 20925000000, 3375500000, 852100000, 245000000, -441500000, 28267000]
 Time Taken with ThreadPool: --- 10.280215740203857 seconds ---

Using Pandas:

df = pd.DataFrame({'Ticker': tickers,'Last quarter reported': quarter_dates, 'Free Cash Flow': fcfs})
df = df.sort_values(by=['Free Cash Flow'], ascending=False)
df['Free Cash Flow'] = df['Free Cash Flow'] / 1000000000
df = df.rename(columns={'Free Cash Flow': 'Free Cash Flow (billions $)'})

Results Table:

Alternative text