Financial Analysis with Python: A Beginner Program

Article Readability Stats: 1,564 words; Flesch-Kincaid Grade Level = 9.2

I’ve always liked finance and trading, and have been short of good methods to use to quickly and effectively research companies and make decisions. Since the summer I have been beginning to learn Python, and the code in this article is a program I wrote—following a few examples online (1, 2, 3, 4)—to help with both my job and hobby-trading (just a small amount I invested about 6 years ago in college). I couldn’t find any websites that did what I wanted them to, such as downloading historical prices; complex plotting; company information; ratios; and more; so, I decided to build my own program to do those. Since I’ve been trying to learn Python it seemed like good practice as well.

I wrote most of this code in Spyder on Anaconda so that I can catch any bugs/problems live, but I prefer running my finished programs on Jupyter Notebook, also through Anaconda. I recommend downloading Anaconda for free if you want to play around with this code—you’ll need to install Spyder to use that, or just open up Jupyter Notebook.

First, here are the packages used in the program. You’ll have to install any you haven’t already.

import yfinance as yf
from yahoofinancials import YahooFinancials
from datetime import date
from plotly.offline import plot
import plotly.graph_objs as go

The Main program has 7 different programs you can choose from to gather and visualize data. First, there’s a program to plot, on a basic plot, one or many tickers’ historical prices. You are able to set the tickers (upper- or lowercase, separated by just a space), start date, and end date (formatted yyyy-mm-dd, and input “na” for today’s date). This program I’ve titled “plots”. What this is doing is taking in your ticker and date inputs to then plot them on a regular price graph. You have the option to view a candlestick plot (boxplots of open/close/high/low prices), but this only works with a single ticker. Below is the code:

# graphing stock(s) from start to end date and giving basic info
def plots():
    stocks = input("What stocks would you like to plot? \n>: ")
    startDate = input("What is the start date? ")
    endDate = input("What is the end date? na for today, format yyyy-mm-dd \n>: ")
    if endDate == "na":
        endDate =
    portfolio =,
                             start = startDate,
                             end = endDate,
                             auto_adjust = True)
    plotInput = input("What type of plot would you like? \n1: Price \n2: Candlestick (note: only works with one ticker) \n>: ")
    if plotInput == "1":
        portfolio['Close'].plot(title="Portfolio Close Price")
    if plotInput == "2":
        fig = go.Figure(data=[go.Candlestick(x=portfolio.index,
        fig.update_layout(yaxis_title='Price', xaxis_title='Date', hovermode='x')
        plot(fig, auto_open=True)

Here’s a sample output with multiple tickers:

And here’s a screenshot of the interactive Plotly output for the Candlestick graph. Running the plots() program will automatically open the Plotly graph in your default web browser.

The next program is probably my favorite program—definitely the most fun to look at (in my opinion), and has a lot going on. Bollinger plots are candlestick plots which incorporate two “Bollinger bands”: (20-day moving average + 2σ) and (20-day moving average – 2σ). 20 days is the most-used period, but you could use a different number of days. Most models use 20 days and 2σ.

Bollinger bands are used widely by traders (and auto-trading machines!) to better inform buying/selling decisions. I’ll describe here in short what they do. Typically, when a day’s candlestick “breaks” the upper band (the 20-day moving average plus 2 standard deviations), the price will decrease over a period of time, correcting itself. Conversely, when a day’s candlestick “breaks” the lower band, the price will increase to correct itself. There’s more going on, and a fun observation is an “M” shape when breaking the upper band (increase to break, small decrease, increase again, then a larger decrease) and a “W” shape when breaking the lower band (decrease, increase, decrease, large increase).

Of course, you cannot rely on these plots to trade, but they’re cool to look at historically, and I’ll use them only to see if I should hold off a few days before making a trade or not. For this program, you’ll be prompted to input one ticker and the start date. Below you can see Apple’s Bollinger plot since 2020-01-01. Even in the Pandemic times, Bollinger bands typically hold true. You can see that many times the bands are broken the price corrects itself. A cool theory of Bollinger bands is also shown in May thru July—when the candlesticks don’t break the bands by much, but instead seem to “ride” them, the price tends to continue moving in that direction. In this instance, that’s a price increase over a long stretch of time. Before breaking the upper band in September, lower band in October, and then upper and lower in quick succession before November. Very cool stuff.

Bollinger Plot for Apple, YTD 2020

The next program allows you to quickly download a company’s financial statements, either Annual or Quarterly. You can view Income, Balance, and Cash Flow statements as well as Earnings, which is only the firm’s revenue. The program also asks if you want to download these in CSV form—you’ll have to change the file pathname in the code so that it prints where you’d like it to. I have a print() output reminding me where it saved to, so you can change that to (or get rid of that line if you want).

# Pull a few statements and publish to a csv file
def stmts():
    stockInput = input("What stock would you like to see statements for? \n>: ")
    stock = yf.Ticker(stockInput)
    stmtInput = input("What statement would you like? \n1: Income \n2: Balance \n3: Cash Flow \n4: Earnings? \n>: ")
    stmtPeriod = input("And what period would you like? \n1: Annual \n2: Quarterly? \n>: ")
    if stmtInput == "1":
        if stmtPeriod == "1":
            sheets = stock.financials
        elif stmtPeriod == "2":
            sheets = stock.quarterly_financials
    if stmtInput == "2":
        if stmtPeriod == "1":
            sheets = stock.balance_sheet
        elif stmtPeriod == "2":
            sheets = stock.quarterly_balance_sheet
    if stmtInput == "3":
        if stmtPeriod == "1":
            sheets = stock.cashflow
        elif stmtPeriod == "2":
            sheets = stock.quarterly_cashflow
    if stmtInput == "4":
        if stmtPeriod == "1":
            sheets = stock.earnings
        elif stmtPeriod == "4":
            sheets = stock.quarterly_earnings
    printInput = input("Want to print this to a csv file? y/n >: ")
    if printInput == "y":
        sheets.to_csv('/Users/bengriffis/Desktop/Python/Python Output/financial sheet output.csv',index=True)
        print("Your info was printed to 'financial sheet output' in the Python Output folder")

The below table a sample printout of Nike’s Annual Income statement. The program will output the last 4 years or quarters; my screenshot only shows 2.

Nike’s previous 2 year’s income statements output

The next program you can run will download, in CSV format, historical prices of the ticker(s) you input. The output will have each day’s Open, Close, High, and Low prices as well as trading volume. This program was initially the first program I coded for the Financial Analysis main program, as I hadn’t found any site that lets me quickly and easily download historical prices for one ticker, let alone multiple.

This yfinanceMetrics() program will prompt you for the same information as the basic/candlestick plotting program: tickers (upper- or lowercase, separated by a space), start date, end date (yyyy-mm-dd). Just like the previous program, change the file pathname in the code to where you want the CSV to save to on your computer. Feel free to delete the print() line telling you where it printed; I sometimes forget exactly where the folder is! Below is a sample printout for 2 stocks.

Apple and Nike’s historical prices for YTD 2020

Next, there’s a program for seeing a lot of important information on a specific company. The way I was able to create a nice printout means that you sadly can’t download this as a CSV—but I think it works alright in your browser or however you’re running python. This program only prompts you for a ticker, and then spits out information like the company’s website, industry and sector, a summary of the company and its operations, and some various metrics, among others (I find all this information good to look at, at least. look at the full yfinance “.info” printout for possible other information you can add).

If you don’t need all of the information from the yfinanceMetrics() program, you can use the more succinct metrics() program, shown below. This program returns just some basic, but important, statistics: Beta, P/E Ratio, Earnings Per Share, and Gross Profit in millions.

# print a couple basic statistics
def metrics():
    tickerInput = input("What stock do you want to see the Beta, PE ratio, and Profit (in millions) for? \n>: ")
    ticker = YahooFinancials(tickerInput)
    beta = ticker.get_beta()
    per = ticker.get_pe_ratio()
    print("P/E Ratio:",per)
    eps = ticker.get_earnings_per_share()
    print ("EPS:",eps)
    profit = ticker.get_gross_profit()
    print("Profit (millions):",profit/1000000)

Finally, the last program allows you to pull a number of different pieces of information you may want to look at when researching a company. Recommendations shows you past Analyst Recommendations on the stock and any possible changes in the recommendations. You see dates these recommendations were made to inform your decision. You can also see the dates and amounts of past Dividends and see the upcoming Earnings Call dates.

Last, you can pull the company’s Sustainability report from the yfinance package, which will give you a decent overview of how well the company is doing from a triple-bottom-line perspective among other metrics such as if they deal in alcohol, fur/leather, gambling, etc. Note that not every company has a full report, and I tend to use this more for the “esgPerformance” score, which is the Environmental, Social, and Governance performance of the firm. This can clue you into whether a certain company may be neglecting their sustainable responsibilities. For example, Nike, which is notorious for their practices in developing countries, scores as “underperforming”. Not a surprise given their track record on the Social side of sustainability. You can see the numbers that help make up the esgPerformance in the printout as well, socialScore, governanceScore, and environmentScore.

# Print a few bits of information
def info():
    stockInput = input("What stocks would you like to see? \n>: ")
    stock = yf.Ticker(stockInput)
    infoInput = input("What information do you want? \n1: Recommendations \n2: Dividends \n3: Upcoming Earnings Call Dates \n4: Sustainability? \n>: ")
    if infoInput == "1":
        sheets = stock.recommendations
    if infoInput == "2":
        sheets = stock.dividends
    if infoInput == "3":
        sheets = stock.calendar
    if infoInput == "4":
        sheets = stock.sustainability
    printInput = input("Want to print this to a csv file? y/n >: ")
    if printInput == "y":
        sheets.to_csv('/Users/bengriffis/Desktop/Python/Python Output/info output.csv',index=True)
        print("Your info was printed to 'info output' in the Python Output folder")

You are able to print any of these outputs to a CSV file, just make sure to change the file pathname in the code like the other programs.

In order to use this program in full and be prompted which program you want to use, insert this code at the bottom of your file. This way, you run the main() program and are able to choose what plot/report you want to see, as opposed to having to run an individual program.

# Run the main program
def main():
    queryInput = input("What report do you want to run? \n1: Price Plotting, \n2: Bollinger Bands, \n3: Financial Statements, \n4: Download Prices, \n5: Many Metrics/Info, \n6: Basic Comparison Metrics, \n7: Various Other Information \n>: ")
    if queryInput =="1":
    if queryInput =="2":
    if queryInput =="3":
    if queryInput =="4":
    if queryInput =="5":
    if queryInput =="6":
    if queryInput =="7":
Main() program’s prompt to pick which specific program you want to run

Overall, this program has helped me further my knowledge of Python while being an easy to use tool for researching companies. And what’s even better is that some of these programs make my job much faster—instead of having to go to company sites, I can just run a program and put in their ticker!

Since I’m still a beginner with Python some of this code may be sloppy. Please shoot me a comment if you know how I can improve it! Hope you enjoy this, and feel free to use this code. I have all of the code shared here in a single Jupyter Notebook and just pull it up to run it whenever I need it. I love how easy it is to get the code up and running. Last, to the left is a screenshot of the prompt you see when running the main() program. Simply type the corresponding number of the program you want to use, and you’ll be on your way!

1 Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s