📃

Data Structure - Income Statement

I am more interested in the why of modeling financial data than the how. Inevitably, the question of how can be researched on the fly for any given situation, but getting to the source of how the analysis done is the wisdom we seek to apply generally to many situations.

Being said, to valuate something you need its data. So we’re going to build pandas data structures so we have data sets to learn from. This section may grow over time, honestly you can take this a million different directions.

💡
This is not investment advice, there is no implication of any guarantee. All investment is risky and you should take advice from actual advisors. EDUCATION ONLY.

Definition

Publicly traded information mandated by the SEC in the U.S. typically comes in three forms:

  • The Income Statement
  • The Balance Sheet
  • Statement of Cash Flows

This statement generally puts the focus on profits and loses. It focuses on expenses, revenue, and taxes over a period of time.

Revenue

Net sales, after refunds and returns.

Cost of Good Sold (COGS)

Expenses “Per Unit” of sales.

Gross Profit

Profit made per sale before expenses. (Rev - COGS).

Gross Margin Ratio

Income after COGS as a % (Gross Profit / Revenue).

Operating Expenses

Things not directly related to units sold such as marketing, rend, office supplies, insurance, people, etc.

Operating Income

Earnings before taxes & interest (Gross Profit - Total Operating Expenses).

Operating Margin

How it’s going after operating factors (Operating Income / Revenue)?

Other Income (or Expenses)

Other incomes.

Interest

Return on interest from investments.

Pre-Tax Income

(Operating Income + Other Income + Interest)

Income Taxes

Taxes (typically 24% * Pre-tax income)

Net Income

After everything, how much did the company generate? (Pre-Tax Income - Income Taxes)

Net Income Margin

(Net income / Revenue)

Python Code - Income Statement

Data Frame Shell

💡
Using Numpy and Pandas we’ll build a simple 1 row framework with some dummy data. I personally prefer a Pandas df over using an object-oriented class when operating on data, but there are advantages to each.
import numpy as np
import pandas as pd

incomeStatement = pd.DataFrame(np.array([['JIM', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]),
                   columns=['Ticker', 'Revenue', 'COGS', 'GrossProfit', 'OperatingExpenses', 'OperatingIncome', 'OtherIncome', 'Interest', 'PreTaxIncome', 'IncomeTaxes', 'NetIncome', 'GrossMargin', 'OperatingMargin', 'NetIncomeMargin'])
print(incomeStatement)

Income Statement Using YFinance

💡
Building off the above, we want to then import data into our Data Frame using the YFinance package.
!pip install yfinance
import numpy as np
import pandas as pd
import yfinance as yf

counter = 0

def incomeYF(ticker):

  incomeStatement = pd.DataFrame(np.array([[ticker, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]),
                   columns=['Ticker', 'Revenue', 'COGS', 'GrossProfit', 'OperatingExpenses', 'OperatingIncome', 'OtherIncome', 'Interest', 'PreTaxIncome', 'IncomeTaxes', 'NetIncome', 'GrossMargin', 'OperatingMargin', 'NetIncomeMargin'])
  stocks = yf.Ticker(ticker)

  stock_df = pd.DataFrame(stocks.financials)
  incomeStatement.loc[counter][0] = ticker
  incomeStatement.loc[counter]['Revenue'] = stock_df.loc['Total Revenue'][0]
  incomeStatement.loc[counter]['COGS'] = stock_df.loc['Cost Of Revenue'][0]
  incomeStatement.loc[counter]['GrossProfit'] = stock_df.loc['Gross Profit'][0] 
  incomeStatement.loc[counter]['OperatingExpenses'] = stock_df.loc['Total Operating Expenses'][0]
  incomeStatement.loc[counter]['OperatingIncome'] = stock_df.loc['Operating Income'][0]
  incomeStatement.loc[counter]['OtherIncome'] = stock_df.loc['Total Other Income Expense Net'][0]
  incomeStatement.loc[counter]['Interest'] = stock_df.loc['Minority Interest'][0]
  incomeStatement.loc[counter]['PreTaxIncome'] = stock_df.loc['Income Before Tax'][0]
  incomeStatement.loc[counter]['IncomeTaxes'] = stock_df.loc['Income Tax Expense'][0]
  incomeStatement.loc[counter]['NetIncome'] = stock_df.loc['Net Income'][0]

  #Calculations - Gross Margin = Gross Profit / Revenue
  incomeStatement.loc[counter]['GrossMargin'] = incomeStatement.loc[counter]['GrossProfit'] / incomeStatement.loc[counter]['Revenue']
  incomeStatement.loc[counter]['OperatingMargin'] = incomeStatement.loc[counter]['OperatingIncome'] / incomeStatement.loc[counter]['Revenue']
  incomeStatement.loc[counter]['NetIncomeMargin'] = incomeStatement.loc[counter]['NetIncome'] / incomeStatement.loc[counter]['Revenue']
  return incomeStatement


with pd.option_context('display.max_rows', None, 'display.max_columns', None):
    print(incomeYF('AAPL'))

Visualization

💡
Now lets say we want to do a nice visual representation of the Income Statement as well.
!pip install yfinance
import numpy as np
import pandas as pd
import yfinance as yf
import plotly.express as px

counter = 0

def incomeYF(ticker):

  incomeStatement = pd.DataFrame(np.array([[ticker, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]),
                   columns=['Ticker', 'Revenue', 'COGS', 'GrossProfit', 'OperatingExpenses', 'OperatingIncome', 'OtherIncome', 'Interest', 'PreTaxIncome', 'IncomeTaxes', 'NetIncome', 'GrossMargin', 'OperatingMargin', 'NetIncomeMargin'])
  stocks = yf.Ticker(ticker)

  stock_df = pd.DataFrame(stocks.financials)
  incomeStatement.loc[counter][0] = ticker
  incomeStatement.loc[counter]['Revenue'] = stock_df.loc['Total Revenue'][0]
  incomeStatement.loc[counter]['COGS'] = stock_df.loc['Cost Of Revenue'][0]
  incomeStatement.loc[counter]['GrossProfit'] = stock_df.loc['Gross Profit'][0] 
  incomeStatement.loc[counter]['OperatingExpenses'] = stock_df.loc['Total Operating Expenses'][0]
  incomeStatement.loc[counter]['OperatingIncome'] = stock_df.loc['Operating Income'][0]
  incomeStatement.loc[counter]['OtherIncome'] = stock_df.loc['Total Other Income Expense Net'][0]
  incomeStatement.loc[counter]['Interest'] = stock_df.loc['Minority Interest'][0]
  incomeStatement.loc[counter]['PreTaxIncome'] = stock_df.loc['Income Before Tax'][0]
  incomeStatement.loc[counter]['IncomeTaxes'] = stock_df.loc['Income Tax Expense'][0]
  incomeStatement.loc[counter]['NetIncome'] = stock_df.loc['Net Income'][0]

  #Calculations - Gross Margin = Gross Profit / Revenue
  incomeStatement.loc[counter]['GrossMargin'] = incomeStatement.loc[counter]['GrossProfit'] / incomeStatement.loc[counter]['Revenue']
  incomeStatement.loc[counter]['OperatingMargin'] = incomeStatement.loc[counter]['OperatingIncome'] / incomeStatement.loc[counter]['Revenue']
  incomeStatement.loc[counter]['NetIncomeMargin'] = incomeStatement.loc[counter]['NetIncome'] / incomeStatement.loc[counter]['Revenue']

  stages = ["Revenue", "Gross Profit", "Operating Income", "Pre-Tax Income", "Net Income"]
  df_org = pd.DataFrame(dict(number=[incomeStatement.loc[counter]['Revenue'], incomeStatement.loc[counter]['GrossProfit'], incomeStatement.loc[counter]['OperatingIncome'], incomeStatement.loc[counter]['PreTaxIncome'], incomeStatement.loc[counter]['NetIncome']], stage=stages))


  fig = px.funnel(df_org, x='number', y='stage')
  fig.show()

  return incomeStatement


with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
    print(incomeYF('AAPL'))
image
Using a funnel model we can visualize revenue to net income step-by-step.
Using a funnel model we can visualize revenue to net income step-by-step.