πŸ”™

NOPAT, Invested Capital, & ROIC

πŸ’‘
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

Return on Invested Capital (ROIC)

Return on Invested Capital is a measure of company efficiency. A given company is investing capital into itself to produce goods, those goods are then sold to generate profit. In general, ROIC is the amount of money a company makes that is above the cost of debt and equity. If ROIC is greater than WACC, it is efficient.

In general the game seems to be to think of a company as an investment machine. It generates profit and that profit should beat what the company could get investing its money elsewhere.

Formula

OR

  • NOPAT stands for β€œNet Operating Profit After Tax” or net income - dividends
  • Invested Capital is debt + equity.

Takeaway

The inspiration for this comes from reading β€œValuation.” ROIC seems like a fundamental formula, and it actually resonates a lot with my work in marketing as well. I was surprised when looking online how wildly different sources differ in terms of output.

I ended up going with mostly the Yahoo definition, to keep consistent with the data set I’m using. ROIC is a measure of efficiency, which is great. You can build an efficient machine, but it also needs to scale well (growth), which will likely be a new area of focus soon.

Python Code

NOPAT

!pip install yfinance
import numpy as np
import pandas as pd
import yfinance as yf

counter = 0

def NOPAT(ticker, taxRate):

  incomeStatement = pd.DataFrame(np.array([[ticker, 0, 0]]),
                   columns=['Ticker', 'OperatingIncome', 'NOPAT'])
  stocks = yf.Ticker(ticker)

  stock_df = pd.DataFrame(stocks.financials)
  incomeStatement.loc[counter]['OperatingIncome'] = stock_df.loc['Operating Income'][0]
  incomeStatement.loc[counter]['NOPAT'] = stock_df.loc['Operating Income'][0] * (1-taxRate)

  return incomeStatement


with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
    print(NOPAT('AAPL', .133))
πŸ’‘
Ticker OperatingIncome NOPAT AAPL 1.08949e+11 9.44588e+10

Invested Capital

#Invested Capital (IC) = Short-term debt + Long-term debt + Shareholder equity - Goodwill.
!pip install yfinance
import numpy as np
import pandas as pd
import yfinance as yf

counter = 0

def Capital(ticker, goodWill):

  cap = pd.DataFrame(np.array([[ticker, 0, 0, 0, 0, 0, 0]]),
                   columns=['Ticker', 'STDebt', 'LTDebt', 'shareholderEquity', 'CashEq', 'Goodwill', 'Capital'])
  stocks = yf.Ticker(ticker)

  stock_df = pd.DataFrame(stocks.financials)
  stock_balance = pd.DataFrame(stocks.balance_sheet)
  cap.loc[counter]['STDebt'] = stock_balance.loc['Short Long Term Debt'][0]
  cap.loc[counter]['LTDebt'] = stock_balance.loc['Long Term Debt'][0]
  cap.loc[counter]['shareholderEquity'] = stock_balance.loc['Total Stockholder Equity'][0]
  cap.loc[counter]['CashEq'] = stock_balance.loc['Cash'][0]
  cap.loc[counter]['GoodWill'] = goodWill
  cap.loc[counter]['Capital'] = cap.loc[counter]['STDebt'] + cap.loc[counter]['LTDebt'] + cap.loc[counter]['shareholderEquity']
  
  return cap


with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
    print(Capital('AAPL',0))
πŸ’‘
Ticker STDebt LTDebt shareholderEquity CashEq Goodwill AAPL 9.613e+09 1.09106e+11 6.309e+10 3.494e+10 0 Capital 1.46869e+11

ROIC

!pip install yfinance
import numpy as np
import pandas as pd
import yfinance as yf

counter = 0

def ROIC(ticker, taxRate, goodWill):

  roic = pd.DataFrame(np.array([[ticker, 0, 0, 0, 0, 0, 0, 0, 0]]),
                   columns=['Ticker', 'STDebt', 'LTDebt', 'shareholderEquity', 'CashEq', 'Goodwill', 'investedCapital', 'NOPAT', 'ROIC'])
  stocks = yf.Ticker(ticker)

  stock_df = pd.DataFrame(stocks.financials)
  stock_balance = pd.DataFrame(stocks.balance_sheet)
  roic.loc[counter]['STDebt'] = stock_balance.loc['Short Long Term Debt'][0]
  roic.loc[counter]['LTDebt'] = stock_balance.loc['Long Term Debt'][0]
  roic.loc[counter]['shareholderEquity'] = stock_balance.loc['Total Stockholder Equity'][0]
  roic.loc[counter]['CashEq'] = stock_balance.loc['Cash'][0]
  roic.loc[counter]['GoodWill'] = goodWill
  roic.loc[counter]['investedCapital'] = roic.loc[counter]['STDebt'] + roic.loc[counter]['LTDebt'] + roic.loc[counter]['shareholderEquity']
  roic.loc[counter]['NOPAT'] = stock_df.loc['Operating Income'][0] * (1-taxRate)
  roic.loc[counter]['ROIC'] = float(roic.loc[counter]['NOPAT']) / float(roic.loc[counter]['investedCapital'])
  return roic


with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
    print(ROIC('AAPL', .133, 0))
πŸ’‘
Ticker STDebt LTDebt shareholderEquity CashEq Goodwill AAPL 9.613e+09 1.09106e+11 6.309e+10 3.494e+10 0 investedCapital NOPAT ROIC 1.81809e+11 9.44588e+10 0.51955