Hanesbrands Inc. (HBI)

Last update: 12 April 2023
annual report: 2021
share price data from: 4/20/2022

Note

Last update: 28 Nov 2023
This page is a test post. The Jupyter notebook is a rough draft. So far I like how Quarto renders JupyterLab notebooks to HTML. This post is for testing only.

\(\Large {\color {red} {\text {update dates and stock history before publishing}}}\)

Use this file. Some edits were made in the HPL folder.

Write this up as a case study.

In Feb 2023 HBI anounced end of dividends and stock fell from \$8.78 to \$6.20, now trades at \$4.91.

https://www.fool.com/investing/2023/02/03/hanesbrands-drops-its-dividend-as-times-get-tough/

https://www.yahoo.com/now/hanesbrands-plunges-gloomy-outlook-dividend-152149039.html

https://www.dividendpower.org/2023/03/10/hanesbrands-hbi-dividend-cut-to-zero/

Is this now a value stock?

451 shares

Date Quantity Price
09/01/2022 116 8.595
06/16/2022 110 9.71
05/02/2022 153 13.1199
04/20/2022 72 14.6763

weighted average cost
\((116*8.595+110*9.71+153*13.1199+72*14.6763)/(116+110+153+72) = 11.372856541019958\)

Total cost basis
\((116*8.595+110*9.71+153*13.1199+72*14.6763) = 5129.158300000001\)

number of shares
\((116+110+153+72) = 451\)

current value 2,214

Hold stock for now since intrinic value is above current price.

Data from May 3, 2023
\(\Large {\color {red} {\text {Note}}}\)
exporting to MD for offline editing, files to bring for ASUS
- MD file - HTML and convert to pdf - annual report - compustat report

Hanesbrands Inc. (HBI)

$ 5.16

Previous Close  4.91
Open    5.10
Bid 4.96 x 3200
Ask 4.97 x 27000
Day's Range 4.97 - 5.29
52 Week Range   4.73 - 14.19
Volume  948,323
Avg. Volume 11,934,518

Market Cap  1.803B
Beta (5Y Monthly)   1.58
PE Ratio (TTM)  N/A
EPS (TTM)   -0.38
Earnings Date   May 03, 2023
Forward Dividend & Yield    N/A (N/A)
Ex-Dividend Date    Nov 21, 2022
1y Target Est   5.21

Stock price from 4/20/2022
14.66

Symbol: HBI
Security Description: Hanesbrands Inc
Action: BOUGHT
Security No./CUSIP: 410345-10-2
Type: Cash
Trade Date: 04/20/22
Settle Date: 04/22/22
Quantity        Price       Principal       Charges and/or Interest     Total Amount
72      $14.6763        $1,056.69       
N/A
$1,056.69

Abstract

This notebook presents analysis and commentary for HanesBrands (NYSE: HBI). The analysis presented is based on examination of the business fundamentals. A discount cash flow analysis is used to estimate the intrinsic value of the company. A second evaluation method based on earnings history and historical price to earnings ratio is calculated. Using some judgment calls, as explained in the analysis, an intrinsic stock value is calculated. Some shares of HBI were purchased based on dividend yield and the intrinsic stock value. As described in the analysis, HBI suspended the dividend in order to direct funds to pay down the debt. Since the company is not paying a dividend, does it make sense to hold the company as a value stock? The analysis concludes that there is some merit to think the company might be a value stock, but as a non-dividend paying stock, having HBI does not fit my investment goals of holding quality dividend paying stocks.

At the time of writing this report, some stock analysis were suggesting that HBI might be a value play, that is, buying this stock on the cheap and holding until the price recovers or the dividend is re-instated. See the articles here and here. My analysis shown below indicates that the even if NOP can be increased over time by 10%, the ratio of NOP to total liabilities remains above 7. (need to recalculate projected total liabilities and clean up the analysis). Historically the ratio was near 5 when HBI initiated their dividend.

Introduction

Shares of HBI were purchased based on dividend yield and intrinsic value of the company. The dividend yield at the time of purchase was running about 4%. I currently hold 451 shares and my purchase history is:

Date Quantity Price
04/20/2022 72 \$14.67
05/02/2022 153 \$13.11
06/16/2022 110 \$9.71
09/01/2022 116 \$8.595

My weighted average cost is \$11.372 per share and my cost basis is \$5,129.16. The current value of my shares are \$2,214, a loss of about 57%. If I hold the shares until September of 2023, all the shares will be long term capital losses.

Since HBI has canceled the dividend payments, should this stock be retained for its value or for possible restoration of dividends? The most recent financial results for the quarter ending are shown in the current news section below.

Company description

Hanesbrands Inc. is an American multinational clothing company based in Winston-Salem, North Carolina. It employs 65,300 people internationally. On September 6, 2006, the company and several brands were spun off by the Sara Lee Corporation. Hanesbrands owns several clothing brands, including Hanes, Champion, Playtex, Bali, L’eggs, Just My Size, Barely There, Wonderbra, Maidenform, Berlei, and Bonds.

Hanesbrands Inc., a Maryland corporation, is a consumer goods company with a portfolio of leading apparel brands, including Hanes, Champion, Bonds, Maidenform, Bali, Playtex, Bras N Things, JMS/Just My Size, Gear for Sports, Wonderbra, Berlei, Comfortwash, and Alternative. The Company designs, manufactures, sources and sells a broad range of basic apparel such as T-shirts, bras, panties, shapewear, underwear, socks and activewear. The Company’s fiscal year ends on the Saturday closest to December 31. All references to “2022”, “2021” and “2020” relate to the 52-week fiscal year ended on December 31, 2022 and January 1, 2022, and the 53-week fiscal year ended on January 2, 2021, respectively. Two subsidiaries of the Company close one day after the Company’s consolidated year end. The difference in reporting of financial information for these subsidiaries did not have a material impact on the Company’s financial condition, results of operations or cash flows.

In late 2020, the Company undertook a comprehensive global business review focused on building consumer-centric growth. The review resulted in the Company’s Full Potential plan, which is its multi-year growth strategy that focuses on four pillars to drive growth and enhance long-term profitability and identifies the initiatives to unlock growth. The Company’s four pillars of growth are to grow the Champion brand globally, drive growth in Innerwear with brands and products that appeal to younger consumers, drive consumer-centricity by delivering innovative products and improving awareness through investments in brand marketing and digital capabilities, and streamline its global portfolio.

In the fourth quarter of 2020, the Company began the implementation of its Full Potential plan and as part of its strategy to streamline its portfolio, the Company determined that its personal protective equipment (“PPE”) business was no longer a growth opportunity and recorded a charge of \$362,913 to write down its entire PPE inventory balance to its estimated net realizable value and a charge of \$26,400 to accrue for vendor commitments for PPE materials that were paid in 2021. Additionally, the Company commenced an initiative to reduce 20% of its SKUs in inventory in order to streamline product offerings while also implementing a formal lifecycle management process. As a result, the Company recorded a charge of \$192,704 to write down inventory to its estimated net realizable value taking into account these initiatives. These initiatives will position the Company for long-term growth by driving higher margin sales, lowering costs and improving service to customers.

In the first quarter of 2021, the Company announced that it reached the decision to exit its European Innerwear business as part of its strategy to streamline its portfolio under its Full Potential plan and determined that this business met held-for-sale and discontinued operations accounting criteria. Accordingly, the Company began to separately report the results of its European Innerwear business as discontinued operations in its Consolidated Statements of Income, and to present the related assets and liabilities as held for sale in the Consolidated Balance Sheets. On November 4, 2021, the Company announced that it reached an agreement to sell its European Innerwear business to an affiliate of Regent, L.P. and completed the sale on March 5, 2022. Unless otherwise noted, discussion within these notes to the consolidated financial statements relates to continuing operations. See Note “Assets and Liabilities Held for Sale” for additional information.

In addition, in the fourth quarter of 2021, the Company reached the decision to divest its U.S. Sheer Hosiery business, including the L’eggs brand, as part of its strategy to streamline its portfolio under its Full Potential plan and determined that this business met held-for-sale accounting criteria, The related assets and liabilities are presented as held for sale in the Consolidated Balance Sheets at December 31, 2022 and January 1, 2022. The operations of the U.S. Sheer Hosiery business are reported in “Other” for all periods presented in Note “Business Segment Information”. The Company is currently exploring potential purchasers for this business and expects to complete the sale within the next 12 months. See Note “Assets and Liabilities Held for Sale” for additional information.

HBI operations are managed and reported in three operating segments, each of which is a reportable segment for financial reporting purposes: Innerwear, Activewear and International. These segments are organized principally by product category and geographic location. Each segment has its own management team that is responsible for the operations of the segment’s businesses, but the segments share a common supply chain and media and marketing platforms.

The following table summarizes HBI operating segments by product category:

Segment Primary Products Primary Brands
Innerwear Basics, including men’s underwear, women’s panties, children’s underwear and socks and intimate apparel, such as bras and shapewear Hanes, Maidenform, Bali, Champion, Playtex, JMS/Just My Size, Bras N Things, Polo Ralph Lauren
Activewear T-shirts, fleece, sport shirts, performance T-shirts and shorts, sports bras, thermals and teamwear Champion, Hanes, Gear for Sports, Comfortwash, Alternative, JMS/Just My Size, Hanes Beefy-T
International Activewear, men’s underwear, women’s panties, children’s underwear, intimate apparel, socks and home goods Champion, Bonds, Sheridan, Bras N Things, Hanes, Wonderbra, Berlei, Playtex, Zorba, Sol y Oro, Rinbros, Polo Ralph Lauren

Innerwear net sales decreased 11% compared to prior year primarily due to softer point-of-sale trends, impacts to replenishment orders from retailers’ decisions to reduce broader inventory positions, business disruption as a result of the ransomware attack in the second quarter of 2022 and the overlap of last year’s sales benefits from retailer restocking and government-stimulus spending partially offset by pricing actions taken and retail space gains in the first quarter of 2022.

Activewear net sales decreased 7% compared to prior year primarily due to softer point-of-sale trends primarily related to the Champion brand, retailer inventory levels and business disruption as a result of the ransomware attack in the second quarter of 2022. The net sales decrease was partially offset by growth in the collegiate and printwear channels and pricing actions primarily taken in the third quarter of 2022.

Net sales in the International segment decreased 7% compared to prior year due to unfavorable foreign currency exchange rates. The unfavorable impact of foreign currency exchange rates decreased net sales approximately \$182 million in 2022. International net sales on a constant currency basis, defined as net sales excluding the impact of foreign currency, increased 1%. The impact of foreign currency exchange rates is calculated by applying prior period exchange rates to the current year financial results.

Other net sales decreased primarily as a result of lower sales at our retail outlets during 2022 compared to prior year partially offset by increased sales from our supply chain to the European Innerwear business. HBI has continued certain sales from our supply chain to this business on a transitional basis after the sale in the first quarter of 2022. These sales and the related profit are included in Other in all periods presented and have not been eliminated as intercompany transactions in consolidation for the period when this business was owned by us.

HBI’s multi-year growth strategy (“Full Potential plan”) focuses on four pillars to drive growth and enhance long-term profitability and identifies the initiatives to unlock growth. HBI four pillars of growth are to grow the Champion brand globally, drive growth in Innerwear with brands and products that appeal to younger consumers, build e-commerce excellence across channels and streamline our global portfolio. In order to deliver this growth and create a more efficient and productive business model, HBI has launched a multi-year cost savings program intended to self-fund the investments necessary to achieve the Full Potential plan’s objectives. We remain confident that our strong brand portfolio, world-class supply chain and diverse category and geographic footprint will help us unlock our full potential, deliver long-term growth and create stockholder value.

Included in restructuring and other action-related charges within operating profit in 2022 and 2021 were \$60 million and\$132 million, respectively, of charges related to the implementation of our Full Potential plan. Full Potential plan charges in 2022 included charges related to supply chain segmentation of \$18 million to position our manufacturing network to align with revenue growth opportunities of our Full Potential plan demand trends, \$10 million related to corporate headcount reductions and a non-cash gain of\$4 million to adjust the valuation allowance related to the U.S. Sheer Hosiery business resulting from a decrease in carrying value due to changes in working capital. Full Potential plan charges in 2021 included a charge of \$16 million for an action to resize our U.S. corporate office workforce through a voluntary retirement program and impairment charges of \$7 million related to the full impairment of an indefinite-lived trademark related to a specific brand within the European Innerwear business that was excluded from the disposal group as it was not marketed for sale.

The Board of Directors has recently eliminated its prior dividend policy pursuant to which HBI has historically paid a cash dividend on our common stock on a quarterly basis in order to direct free cash flow toward reducing our debt. The declaration and payment of any dividend in the future will be subject to the approval of the Board of Directors and our dividend may thereafter be discontinued or reduced at any time. The Board of Directors regularly evaluates our capital allocation strategy and dividend policy, and any future determination to continue to pay dividends, and the amount of such dividends, will be at the discretion of the Board of Directors. The ability to pay cash dividends is also limited by restrictions or limitations on our ability to obtain sufficient funds through dividends from subsidiaries, as well as by contractual restrictions, including the requirements of the agreements governing our indebtedness. There can be no assurance that HBI will declare cash dividends in the future in any particular amounts, or at all.

OLD }——————- HanesBrands (NYSE: HBI) makes everyday apparel that is known and loved by consumers around the world for comfort, quality and value. Among the company’s iconic brands are Hanes, the leading basic apparel brand in the United States; Champion, an innovator at the intersection of lifestyle and athletic apparel; and Bonds, which is setting new standards for design and sustainability.

HBI employs 51,000 associates in 32 countries and has built a strong reputation for workplace quality and ethical business practices. In May 2021, HBI launched its Full Potential plan – the company’s roadmap to drive improved revenue and profits during the next three years and beyond.

Unlike most apparel companies, more than 70% of the apparel we sell is manufactured in our own facilities or those of dedicated contractors. Owning the majority of our supply chain not only impacts cost, scale and flexibility, but also the ability to adhere to best-in-class workplace and sustainability practices.

In 2021, HBI was one of two apparel manufacturers named one of the World’s Most Ethical Companies by Ethisphere and garnered a spot on Barron’s 100 Most Sustainable Companies for the third consecutive year. This follows the December 2020 announcement that HBI earned “A List” recognition for leadership in corporate sustainability in the CDP 2020 Climate Change Report.

We are committed to making the world a more comfortable, livable and inclusive place. We have established new, wide-ranging 2030 global sustainability goals and launched a new sustainability website, www.HBISustains.com, designed to increase our transparency on key metrics. We approach sustainability from a broad, holistic perspective and focus our efforts in areas addressed by the United Nations’ Sustainable Development Goals under three pillars: People, Planet and Product.

https://ir.hanesbrands.com/

https://finance.yahoo.com/quote/HBI

Previous Close  4.8800
Open    4.8000
Bid 4.4200 x 2900
Ask 4.4000 x 29200
Day's Range 4.3200 - 4.8500
52 Week Range   4.3200 - 13.2800
Volume  15,869,504
Avg. Volume 12,093,670
Market Cap  1.533B
Beta (5Y Monthly)   N/A
PE Ratio (TTM)  N/A
EPS (TTM)   -0.3500
Earnings Date   May 03, 2023
Forward Dividend & Yield    N/A (N/A)
Ex-Dividend Date    Nov 21, 2022
1y Target Est   4.64

Sector(s): Consumer Cyclical
Industry: Apparel Manufacturing
Full Time Employees: 50,000

Hanesbrands Inc., a consumer goods company, designs, manufactures, sources, and sells a range of basic apparel for men, women, and children. The company operates through three segments: Innerwear, Activewear, and International.

www.hanes.com/corporate

Bottom line up front

HBI fails some of the decision model checks. Revisit to see if buy or sell in June. Follow the link to the Conclusion.

Revision history

  • 1/10/2022: Copied from VZ notebook and reorganized
  • Feb 2022: updated quick look, reorganized flow of calculations, corrected usage of financial rates, organized end sections
  • 23 Mar 2022: Cleaning up financial data spreadsheet. Removed NAIC tab. Removed duplicate reveneu data.
  • 27 Mar 2022: MFG template copied from BMY
  • 27 Jun 2023:
    1. Updates to narrative
    2. updated Market Cap and total value of common equity plot to look at last full year and current price history
    3. removed dividend payout analysis
    4. In the Financial ratios section, added return on capital to plot
    5. In the NAIC section, added profit margin to plot
    6. Added new section called Earnings yield
    7. Removed Percent earned on equity since it was another way of saying RoE
    8. Avg closing price calculated

Analysis

The following sections of this notebook contain the financial analysis for the company.

Contents

  1. Stock screener results
  2. Load financial spreadsheet
  3. Discounted cash flow analysis, baseline
  4. DCF Scenarios
  5. NACI stock selection guide analysis
  6. Future stock price
  7. Dividend payout
  8. Management performance
  9. Decision model
  10. Conclusion
  11. Notes
  12. References

Todo:

  • update notebook with new organization
  • load other sheets to test with different data
  • add red flag ratios
  • add section to calculate future stock price, use number in IRR
  • update spreadsheet with 2021 data
  • fix Weighted After-Tax Yield in the print out of the DFC inputs
  • FIX nopm and nopm_avg usage
  • clean up commented code
  • check one dollar premise
  • fix outline levels
  • fix outline order
  • research preferred stock
  • check inputs to financial worksheets
  • check and fix links to yahoo finance
  • verify shares outstanding
  • check neg retained earnings
  • add fix it marks
  • remove raw cells
  • review Current news
  • review most recent quarterly results
  • read annual report
  • write analysis and commentary
  • write conclusions
  • spell check
  • remove NAIC sheet and move data to mextrics sheet
  • save as MFG template before final cleanup and upload to github
  • upload updated files to github
  • write blog report and post
  • review blog report to make more interesting
  • why should I care about this company
  • why the key features are important, what are key features
  • add some “because of this…that” flow between and linking the key features

example note

\(\Large {\color {red} {\text {Note}}}\)

from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from dateutil.parser import parse
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
import os
from pandas.plotting import register_matplotlib_converters
import np_financial
register_matplotlib_converters()

1) Stock screener results

This company was selected from the Fidelity stock screener results. The search results are based on Dividend yield (high and very high, 2.83% and higher), Volume 90 average (high and very high. 535k and higher) and Revenue Growth 5 years (0 or higher).

Current news
A review of receint SEC filings and financial news sites yahoo and google showed the following:

On May 24, 2022, the Company identified that it had become subject to a ransomware attack and activated its incident response and business continuity plans designed to contain the incident. As part of the Company’s forensic investigation and assessment of the impact, the Company determined that certain of its information technology systems were affected by the ransomware attack.

Upon discovering the incident, the Company took a series of measures to further safeguard the integrity of its information technology systems, including working with cybersecurity experts to contain the incident and implementing business continuity plans to restore and support continued operations. These measures also included resecuring data, remediation of the malware across infected machines, rebuilding critical systems, global password reset and enhanced security monitoring. The Company notified appropriate law enforcement authorities as well as certain data protection regulators, and in addition to the Company’s public announcements of the incident, the Company provided breach notifications and regulatory filings as required by applicable law starting in August 2022. At this time, the Company believes the incident has been contained, the Company has restored its critical information technology systems, and manufacturing, retail and other internal operations continue. There is no ongoing operational impact on the Company’s ability to provide its products and services. The Company maintains insurance, including coverage for cyber-attacks, subject to certain deductibles and policy limitations, in an amount that the Company believes appropriate.

The Company is named in two pending lawsuits in connection with its previously disclosed ransomware incident. On October 7, 2022, a putative class action was filed against “Hanes Brands Inc.” alleging, among other things, negligence, negligence per se, breach of implied contract, unjust enrichment, breach of implied covenant of good faith and fair dealing, unfair business practices under the California Business and Professions Code, and violations of the California Confidentiality of Medical Information Act in connection with the ransomware incident. The litigation is entitled, Roman v. Hanes Brands Inc., and is pending in the United States District Court for the Central District of California. Plaintiff Roman also subsequently filed a second putative class action with regard to the ransomware incident in the United States District Court for the Middle District of North Carolina on January 16, 2023, entitled Roman v. Hanesbrands Inc., which was voluntarily dismissed without prejudice on January 20, 2023. On October 13, 2022, another putative class action was filed against HanesBrands Inc. alleging, among other things, negligence, negligence per se, breach of implied contract, invasion of privacy, and unjust enrichment in connection with the ransomware incident. The litigation is entitled, Toussaint v. HanesBrands Inc. and is pending in the United States District Court for the Middle District of North Carolina. The pending lawsuits seek, among other things, monetary and injunctive relief. The Company is vigorously defending these matters and believes the cases are without merit. The Company does not expect any of these claims, individually or in the aggregate, to have a material adverse effect on its consolidated financial position or results of operations. However, at this early stage in the proceedings, the Company is not able to determine the probability of the outcome of these matters or a range of reasonably expected losses, if any. The Company maintains insurance, including coverage for cyber-attacks, subject to certain deductibles and policy limitations, in an amount that the Company believes appropriate.

During the year ended December 31, 2022, the Company incurred costs of \$15,427, net of expected insurance recoveries, related to the ransomware attack. The costs for the year ended December 31, 2022 included \$14,168 related primarily to supply chain disruptions, which are reflected in the “Cost of sales” line of the Consolidated Statements of Income and \$1,259, net of expected insurance recoveries, related primarily to legal, information technology and consulting fees, which are reflected in the “Selling, general and administrative expenses” line of the Consolidated Statements of Income. The Company continues to assess the security event and cannot determine, at this time, the full extent of the impact from such event on its business, results of operations or financial condition or whether such impact will ultimately have a material adverse effect.

Review quarterly results
Since this analysis mainly looks at the annual reports, a review of the quarterly reports and the most recent 12 months is needed to see if the recent quarterly trends match the yearly trends. - yahoo finance - The Compustat Company Research from Fidelity - SEC filings from Hanesbrands Inc. Investor Relations

Condensed Consolidated Statements of Income 04/01/23 04/02/22
Net sales \$1,389,410 \$1,576,156
Cost of sales \$939,717 \$991,978
Gross profit \$449,693 \$584,178
Selling, general and administrative expenses \$392,374 \$413,666
Operating profit \$57,319 \$170,512
Other expenses \$14,771 \$987
Interest expense, net \$58,452 \$31,963
Income (loss) from continuing operations before income tax expense -\$15,904 \$137,562
Income tax expense \$18,500 \$23,385
Income (loss) from continuing operations -\$34,404 \$114,177
(amounts in thousands)

As is shown in the table above, HBI’s sales are down and they experienced a loss from continuing operations. Since I’m going to wait until later in the year to sell my shares, I can evaluate the second and third quarter results before making a final decision.

Average daily volume
Average daily volume: 5,510,768

Dividend yield
Forward dividend yield: 5.16% - no longer valid

\(\Large {\color {red} {\text {add review of compustat report}}}\)

Compustat Company Research Hanesbrands Inc NYSE: HBI Mar. 14, 2023

2) Load financial spreadsheet

Data from consolidated financial statements and annual reports was collected and entered into a spreadsheet. All numerical data is converted from thousands or millions of dollars to dollars. The stock share price history was obtained from yahoo and is included as a tab in the spreadsheet. Other tabs in the spreadsheet are various worksheets.

\(\Large {\color {red} {\text {need to organize folders on drive}}}\)

/home/jeff32/HPL_legacy_files/HPL_legacy_files/Documents/Dividend Investing/DCF data/HBI_Financials.xlsx

/home/jeff32/Documents/Dividend Investing/DCF data/HBI_Financials.xlsx

ticker = 'HBI' # company ticker symbol
#os.chdir('/home/jim/Documents/Dividend Investing/DCF data/')
os.chdir('/home/jeff32/Documents/Dividend Investing/DCF data/')

file_name = ticker+'_Financials.xlsx'
df_dcf_sheet = pd.read_excel(file_name,sheet_name='DCF data')
#df_NAIC_financials = pd.read_excel(file_name,sheet_name='NAIC data')
df_metrics_sheet = pd.read_excel(file_name,sheet_name='metrics')
df_price_history = pd.read_excel(file_name,sheet_name='Historical Prices')

# change the working director back to the Jupyter folder
#os.chdir('/home/jim/Documents/JupyterLab/Discount Cash Flow Analysis/')
os.chdir('/home/jeff32/Documents/JupyterLab/Discount Cash Flow Analysis/')
# convert dates from string to datetime format in stock price history
price_date_list = []
for i in range(len(df_price_history)):
    price_date_list.append(datetime.strptime(str(df_price_history['Date'][i]), '%Y-%m-%d'))

df_price_history.insert(0, 'datetime', price_date_list)  # insert a new column with datetime data
df_price_history.sort_values(by=['datetime'], inplace=True) # sort data frame by datetime

df_price_history.set_index('datetime',inplace=True)

#df_price_history.head()

2.1) Format data frame

Generate a new data frame that holds the financial data needed for the DCF model. Data from financial statements is copied into a spreadsheet which contains the data used in the analysis. The data in the DCF_data tab is in a consistent format for ease of use by this notebook. Standard names are used for the rows and columns.

#column names: fiscal years 
fy_data = df_dcf_sheet.columns[1:].values.astype('datetime64[Y]')-1970
#line 0: Total revenue  
revenue_data = df_dcf_sheet.iloc[0].to_numpy()[1:].astype('float')
#line 1: Cost of goods sold
Cost_of_goods_sold_data = df_dcf_sheet.iloc[1].to_numpy()[1:].astype('float')
#line 2: General and administrative
General_and_administrative_data = df_dcf_sheet.iloc[2].to_numpy()[1:].astype('float')
#line 3: Research and development
Research_and_development_data = df_dcf_sheet.iloc[3].to_numpy()[1:].astype('float')
#line 4: Depreciation and amortization
Depreciation_and_amortization_data = df_dcf_sheet.iloc[4].to_numpy()[1:].astype('float')
#line 5: Investment
Investment_data = df_dcf_sheet.iloc[5].to_numpy()[1:].astype('float')
# line 6: Income before income taxes
Income_before_income_taxes_data = df_dcf_sheet.iloc[6].to_numpy()[1:].astype('float')
# line 7: Income tax
Income_tax_data = df_dcf_sheet.iloc[7].to_numpy()[1:].astype('float')
# line 8: Accounts receivable
Accounts_receivable_data = df_dcf_sheet.iloc[8].to_numpy()[1:].astype('float')
# line 9: Inventories
Inventories_data = df_dcf_sheet.iloc[9].to_numpy()[1:].astype('float')
# line 10: Accounts payable
Accounts_payable_data = df_dcf_sheet.iloc[10].to_numpy()[1:].astype('float')
# line 11: Current assets
Current_assets_data = df_dcf_sheet.iloc[11].to_numpy()[1:].astype('float')
# line 12: Current liabilities
Current_liabilities_data = df_dcf_sheet.iloc[12].to_numpy()[1:].astype('float')
# line 13: Long term debt
Long_term_debt_data = df_dcf_sheet.iloc[13].to_numpy()[1:].astype('float')
# line 14: Shares outstanding
Shares_outstanding_data = df_dcf_sheet.iloc[14].to_numpy()[1:].astype('float')
# make a new data frame to store selected financial data
df_dcf_data = pd.DataFrame(data={
    'FY':fy_data[::-1],
    'revenue':revenue_data[::-1],
    'cost_of_goods_sold':Cost_of_goods_sold_data[::-1],
    'general_and_administrative':General_and_administrative_data[::-1],
    'research_and_development':Research_and_development_data[::-1],
    'depreciation':Depreciation_and_amortization_data[::-1],
    'investment':Investment_data[::-1],
    'income_before_income_taxes':Income_before_income_taxes_data[::-1],
    'income_tax':Income_tax_data[::-1],
    'accounts_receivable':Accounts_receivable_data[::-1],
    'inventories':Inventories_data[::-1],
    'accounts_payable':Accounts_payable_data[::-1], 
    'current_assets':Current_assets_data[::-1],
    'current_liabilities':Current_liabilities_data[::-1],
    'long_term_debt':Long_term_debt_data[::-1],
    'shares_outstanding':Shares_outstanding_data[::-1]
    })

#df_dcf_data

3) Discounted cash flow analysis, baseline

Discounted cash flow (DCF) is a valuation method used to estimate the value of an investment based on its expected future cash flows. DCF analysis attempts to figure out the value of an investment today, based on projections of how much money it will generate in the future. In finance, discounted cash flow (DCF) analysis is a method of valuing a security, project, company, or asset using the concepts of the time value of money. The DCF method used in this notebook follows [1].

The value of any financial investment equals the present value of the expected future cash flows, discounted for risk and timing of these cash flows. The DCF method to value stocks is a four step process.
1. Develop a set of future free cash flows for the corporation based on revenue growth, net operating profit margin, income tax rate and fix and working capital requirements. 2. Estimate the discount rate for the cash flows based on expected timing and risk. 3. Discount the cash flows and total them to calculate the value for the corporation as a whole. 4. Subtract the debt, preferred stock value and other claims and divide by the number of shares outstanding to get the intrinsic value.

Sections - Revenue growth rate
- Net operating profit margin
- Tax rate
- Depreciation Rate
- Investment Rate
- Working Capital Rate
- Current Assets
- Current Liabilities
- Value of Debt Outstanding
- Current stock price
- Shares outstanding
- 10 year treasury bond yield
- Bond yield spread to treasury
- Preferred stock yield
- Equity risk premium
- Company specific beta
- DCF model inputs
- Future cash flows

Future forecast based on historical data

The DCF model uses historical financial data to estimate future cash flows. However, future changes are largely unpredictable, so we assume that the past record can be used as a rough guide to the future. The more questionable this assumption is, the less valuable is the analysis. So the DCF model is more useful when applied to stable well established companies, since companies with stable earnings are easier to forecast.

Revenue growth rate

The revenue growth rate (also sometimes called net sales) of the corporation plus any other revenues associated with the main operations of the business. It does not include dividends, interest income or non-operating income. Historic revenue data is obtained from consolidated income statements. The year over year change in revenue is calculated and converted to a percent, then an average revenue growth rate is calculated.

Adjustments for Hanesbrands Inc.
No adjustments for this company.

# calculate the percent change in revenue
pcr = np.zeros(len(df_dcf_data['revenue'].to_numpy())) # percent change in revenue
for i in range(len(df_dcf_data['revenue'].to_numpy()[0:-1])):
    pcr[i+1] = ((df_dcf_data['revenue'].to_numpy()[i+1] - df_dcf_data['revenue'].to_numpy()[i])/
                df_dcf_data['revenue'].to_numpy()[i+1])*100

width = 100

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('Revenue, $B')

# plot revenue as single bar
plt.bar(df_dcf_data['FY'],df_dcf_data['revenue']/1e9, width,color='k')

ax1.tick_params(axis='y')
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:green'

ax2.plot(df_dcf_data['FY'],pcr,'+-g')
    
ax2.set_ylabel('% Change in revenue',color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim((-10,15))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Revenue')
plt.show()

Observation:
Net sales decreased 8% during 2022 primarily due to the following: - Softer point-of-sale trends and higher retailer inventory levels as a result of the macroeconomic pressures; - The impact of the ransomware attack to the business; - Global supply chain disruptions resulting in product delays; - Ongoing COVID-related pressures on consumer traffic in certain markets in Asia; and - The unfavorable impact from foreign currency exchange rates in our International business of approximately \$182 million. - Partially offset by: Pricing actions taken throughout 2022.

Net Sales for the year ending 12/31/2022
Innerwear \$2,429,966
Activewear \$1,555,062
International \$1,914,268
Other \$334,354
Total \$6,233,650
(amounts in thousands)

HBI products are primarily distributed through HBI wholesale customers’ stores and websites, as well as through our own stores and websites. In 2022, approximately 69% of HBI total net sales were in the United States and approximately 31% were outside the United States. HBI largest customer is Walmart Inc. (“Walmart”), accounting for 16% of total net sales in 2022.

Sales to mass merchants in the United States accounted for approximately 19% of HBI total net sales in 2022 and included all of our product categories under our Hanes, Playtex, Maidenform and JMS/Just My Size brands, as well as licensed logo apparel. Mass merchants feature high-volume, low-cost sales of basic apparel items along with a diverse variety of consumer goods products, such as grocery and drug products and other hard lines. HBI largest mass merchant customer is Walmart.

A significant percentage of HBI total revenues (approximately 31% in 2022) is derived from markets outside the United States. HBI sells a majority of products in transactions denominated in U.S. dollars; however, HBI purchases many of their raw materials, pay a portion of wages and make other payments to participants in the supply chain in foreign currencies. As a result, when the U.S. dollar weakens against any of these currencies, HBI cost of sales could increase substantially.

Outside the United States, HBI may pay for materials or finished products in U.S. dollars, and in some cases a strengthening of the U.S. dollar could effectively increase HBI costs where they use foreign currency to purchase the U.S. dollars they need to make such payments.

Outlook for 2023 HBI 2023 guidance as follows: - Net sales of approximately \$6.05 billion to \$6.20 billion, net of approximately \$42 million of unfavorable foreign exchange impact;
- Operating profit of approximately \$446 million to \$496 million, net of approximately \$6 million of unfavorable foreign exchange impact;
- Restructuring and other action-related charges totaling \$60 million including Full Potential plan-related charges of approximately \$54 million included in operating profit and refinancing charges of \$6 million included in other expenses;
- Interest expense and other expenses of approximately \$306 million combined;
- Tax expense from continuing operations of approximately \$90 million to \$100 million;
- Diluted earnings per share from continuing operations of approximately \$0.14 to \$0.25;
- Cash flow from operating activities of approximately \$500 million; and
- Capital investments of approximately \$150 million, including capital expenditures of \$70 million within investing cash flow activities and cloud computing assets of \$80 million within operating cash flow activities.

Third-party brick-and-mortar wholesale revenue is primarily generated by sales of the Company’s products to retailers to support their brick-and-mortar operations. Also included within third-party brick-and-mortar wholesale revenue is royalty revenue from licensing agreements. The Company earns royalties through license agreements with manufacturers of other consumer products that incorporate certain of the Company’s brands. The Company accrues revenue earned under these contracts based upon reported sales from the licensees. Additionally, third-party brick-and-mortar wholesale revenue for the year ended January 2, 2021 includes \$518,309 of revenue from contracts with governments generated from the sale of both cloth face coverings and gowns for use to help mitigate the spread of the virus during the COVID-19 pandemic.

rgr_avg = pcr[-5:].mean()/100 # last five years
print('average revenue growth rate: {:.2f}%'.format(rgr_avg*100))
average revenue growth rate: -0.88%

Net operating profit margin

Net Operating Profit should reflect the future revenue generating ability and expense requirements of the operating business that comprise the ongoing operations of the company.

\(\text{NOPM} = \frac{\text{Revenue} - \text{Expenses}}{\text{Revenue}}\)

\(\text{Expenses} = \text{Cost of Goods Sold (CGS)} + \text{General and Administrative (G\&A)} + \text{Research and Development (R\&D)}\)

General and Administrative (G&A) is also called Sales, General and Administrative (SG&A)

Adjustments for Hanesbrands Inc.
No adjustments for this company.

# NOP = (Revenue - Expenses)
nop = (df_dcf_data['revenue'].to_numpy() - \
    (df_dcf_data['cost_of_goods_sold'].to_numpy() + \
    df_dcf_data['general_and_administrative'].to_numpy() + \
    df_dcf_data['research_and_development'].to_numpy()) )

# net operating profit margin as percent of revenue
nopm = nop/df_dcf_data['revenue'].to_numpy()

# plot as four grouped bar chart with labels on right and working capital rate on left
# calculate position of bars
x1_bar_position = []
x2_bar_position = []
x3_bar_position = []
x4_bar_position = []
for i in df_dcf_data['FY']:
    x1_bar_position.append(i-relativedelta(months=3))
    x2_bar_position.append(i-relativedelta(months=1))
    x3_bar_position.append(i+relativedelta(months=1))
    x4_bar_position.append(i+relativedelta(months=3))
    
width = 40  # the width of the bars
    
# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('Net operating profit, \\$B')

ax1.bar(x1_bar_position,df_dcf_data['cost_of_goods_sold'].to_numpy()/1e9, width,label='CGS')
ax1.bar(x2_bar_position,df_dcf_data['general_and_administrative'].to_numpy()/1e9, width,label='G&A')
ax1.bar(x3_bar_position,df_dcf_data['research_and_development'].to_numpy()/1e9, width,label='R&D')
ax1.bar(x4_bar_position,nop/1e9, width,label='NOP')

ax1.tick_params(axis='y')
#ax1.set_ylim((0,4))
ax1.legend()
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:cyan'

ax2.plot(df_dcf_data['FY'],nopm*100,'+-c')
    
ax2.set_ylabel('% NOPM',color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim((0,40))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Net Operating Profit')
plt.show()

Observation
The COVID-19 pandemic has impacted HBI business operations and financial results for 2020, as described in more detail under “Consolidated Results of Operations - Year Ended January 2, 2021 (“2020”) Compared with Year Ended December 28, 2019 (“2019”)” below, due to decreased customer traffic and temporary retail store closures worldwide. While most of our retail stores were temporarily closed for varying periods of time throughout 2020, most reopened by the end of the second quarter but have experienced, and are expected to continue to experience, reductions in customer traffic, and as a result, net sales. Sales of PPE, used to help mitigate the spread of the COVID-19 virus, partially offset the negative impact of the decline in net sales and earnings due to the COVID-19 pandemic on our financial results. Our e-commerce sites have remained open in all regions and online sales have grown as consumer spending continued to shift towards online shopping experiences due to the changing retail landscape as a result of the COVID-19 pandemic.

During the second quarter of 2020, HBI recorded \$11 million of bad debt charges for customer bankruptcies and \$20 million of charges to reserve for increased excess and obsolete inventory related primarily to canceled orders of seasonal inventory. Also during the second quarter of 2020, BHI completed a quantitative impairment analysis for certain indefinite-lived intangible assets as a result of the significant impact of the COVID-19 pandemic on their performance. Based on this analysis, HBI recorded impairment charges of \$20 million on certain indefinite-lived trademarks and other intangible assets within the European Innerwear business. In the third quarter of 2020, HBI recorded \$49 million of supply chain re-start up charges primarily related to incremental costs incurred, such as freight and sourcing premiums, to expedite product to meet customer demand following the extended shut-down of parts of our manufacturing network as a result of the COVID-19 pandemic. Additionally, in the fourth quarter of 2020, HBI recorded a \$25 million charge for the impairment of goodwill related to the U.S. Hosiery reporting unit primarily as a result of the significant impact that the COVID-19 pandemic has had on this business.

Operating profit as a percentage of net sales was 8.3% in 2022, representing a decrease from 11.7% in the prior year. Operating margin decreased as a result of lower sales volume, input cost inflation, impact from the ransomware attack, costs associated with our manufacturing time-out inventory reduction actions, deleverage from a higher proportion of transportation and distribution costs, unfavorable impact from foreign currency exchange rates and increased Full Potential plan-related investments in brand marketing and technology partially offset by pricing actions and cost reduction actions. Included in operating profit in 2022 and 2021 were charges of \$60 million and \$132 million, respectively, related to the implementation of the Full Potential plan.

Operating Activities Our overall liquidity has historically been driven by our cash flow provided by operating activities, which is dependent on net income and changes in our working capital. As compared to the prior year, higher net cash used by operating activities was due to changes in working capital primarily accounts payable, accruals, inventory due to inflationary increases, softer point-of-sale trends and supply chain disruptions, and increased capital investments in our cloud computing assets partially offset by improvement in accounts receivable and lower pension plan contributions in 2022. Net cash from operating activities includes a \$40 million contribution to our U.S. pension plan made in the first quarter of 2021.

  • Advertising represents one of several brand building methods used by the Company. Advertising costs, which include the development and production of advertising materials and the communication of these materials through various forms of media, are expensed in the period the advertising first takes place. The Company recognized advertising expense in the “Selling, general and administrative expenses” line in the Consolidated Statements of Income of \$208,881, \$208,998 and \$113,586 in 2022, 2021 and 2020, respectively.
  • Revenue received for shipping and handling costs is included in net sales and was \$13,578, \$19,461 and \$18,943 in 2022, 2021 and 2020, respectively. Shipping costs, which comprise payments to third-party shippers, and handling costs, which consist of warehousing costs in the Company’s various distribution facilities, were \$415,989, \$447,131 and \$389,252 in 2022, 2021 and 2020, respectively. The Company recognizes shipping, handling and distribution costs in the “Selling, general and administrative expenses” line in the Consolidated Statements of Income.
  • Research and development costs are expensed as incurred and are included in the “Selling, general and administrative expenses” line in the Consolidated Statements of Income. Research and development includes expenditures for new product, technological improvements for existing products and process innovation, which primarily consist of salaries, consulting and supplies attributable to time spent on research and development activities. Additional costs include depreciation and maintenance for research and development equipment and facilities. Research and development expense was \$38,911, \$39,320 and \$37,367 in 2022, 2021 and 2020, respectively.
#Average net operating profit margin
nopm_avg = nopm[-5:].mean()
print('average net operating profit margin: {:.2f}%'.format(nopm_avg*100))
average net operating profit margin: 9.13%

Tax rate

Tax payments are taken from the consolidated income statement, provision for income taxes. The effect of taxes on profits is accounted for.

\(\text{Tax rate} = \frac{\text{Income taxes}}{\text{Income before income taxes}}\)

Adjustments for Hanesbrands Inc.
No adjustments for this company.

# plot as Grouped bar chart with labels on right and tax rate on left
# calculate position of bars
x1_bar_position = []
x2_bar_position = []
for i in df_dcf_data['FY']:
    x1_bar_position.append(i-relativedelta(months=1))
    x2_bar_position.append(i+relativedelta(months=1))

# calculate tax rate
tax_rate = df_dcf_data['income_tax']/df_dcf_data['income_before_income_taxes']

width = 50  # the width of the bars

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('dollars, \\$M')

rects1 = ax1.bar(x1_bar_position,df_dcf_data['income_before_income_taxes']/1e6, width,
    label='Income before income taxes')
rects2 = ax1.bar(x2_bar_position,df_dcf_data['income_tax']/1e6, width,
    label='Income taxes')

ax1.tick_params(axis='y')
#ax1.set_ylim((-2e3,2e3))
ax1.legend()
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:green'

ax2.plot(df_dcf_data['FY'],tax_rate * 100,'+-g')
    
ax2.set_ylabel('% Tax rate',color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim((0,100))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Tax Rate')
plt.show()

Observation:
HBI has a complex multinational tax structure with multiple types of intercompany transactions, and allocation of profits and losses among HBI and subsidiaries through intercompany transfer pricing agreements is subject to review by the Internal Revenue Service and other tax authorities.

The company’s tax payments and tax rate from 2016 to 2022 departed from the historically contestant average of about 12% as shown in the plot above. The 10K’s for the years 2017, 2020 and 2022 describe the changes to the tax law which caused the changes in these years. Additionally, the company has deferred taxes, tax credits and unrecognized tax benefits which complicate the analysis of the tax burden. The average tax rate calculated over the last five years is 47%, which as shown below results in a base line ISV of \$7. Adjusting the average tax rate to 20% would change the baseline ISV to \$10, which shows that the tax rate has a significant effect on the value of the company.

Taxes for 2017

  • The 2017 enacted Tax Act significantly revised U.S. corporate income tax law by, among other things, reducing the corporate income tax rate to 21%, imposing a new minimum tax on global intangible low-taxed income (“GILTI”) and implementing a modified territorial tax system that includes a one-time transition tax on deemed repatriated earnings of foreign subsidiaries. Some of the tax provisions that become effective in the fiscal year 2018 are expected to increase HBI’s effective tax rates, such as the GILTI tax. Due to the complexities involved in accounting for the enactment of the Tax Act, SEC Staff Accounting Bulletin 118 (“SAB 118”) allows companies to record provisional estimates of the impacts of the Tax Act during a measurement period which is similar to the measurement period of up to one year from the enactment which is similar to the measurement period used when accounting for business combinations. The Company will continue to assess the impact of the recently enacted tax law on its consolidated financial statements.
  • Income tax expense for 2017 includes a one-time provisional charge related to U.S. tax reform of \$457 million, primarily for the transition tax on deemed repatriated earnings of foreign subsidiaries and revaluation of our deferred tax assets and liabilities, to the lower corporate income tax rate of 21%.
  • Income Tax Expense – income tax expense for 2017 includes a provisional charge related to the Tax Act of \$435 million, which includes a \$360 million transition tax charge on deemed repatriated earnings of foreign subsidiaries, a charge of \$72 million for the revaluation of our deferred tax assets and liabilities to the lower corporate income tax rate of 21% and a \$3 million charge related to the deductibility of employee compensation. In addition, HBI incurred incremental tax costs of approximately \$22 million for other impacts of tax reform and other actions taken in 2017. HBI’s effective income tax rate was 6.0% and 9.5% in 2016 and 2015, respectively. The lower effective income tax rate was primarily attributable to a lower proportion of earnings attributed to domestic subsidiaries, which are taxed at rates higher than foreign subsidiaries. Income tax expense also benefited from the adoption of accounting rules related to accounting for stock compensation, which required excess tax benefits and deficiencies to be recognized in income as they occur.

Taxes for 2020 (See 10K-2020 pdf pages 103 to 107)

  • The Company generated income (loss) before income tax expense of \$(183,122), \$679,727, and \$643,581 for the years 2020, 2019, and 2018, respectively.
  • In 2020, the Company continued to analyze the impacts of the Tax Act and recently issued regulations that have been published to help taxpayers interpret and apply the legislation. As a result of its analysis, Management changed its estimate of the tax liability due in connection with the one-time mandatory transition tax and recognized a \$38,315 income tax benefit in the current period.

Taxes for 2022

  • As of December 31, 2022, the valuation allowance for deferred tax assets was \$626,540, made up of \$306,743 for foreign loss carry forwards, \$21,232 for other foreign deferred tax assets, \$63,619 for federal and state operating loss carry forwards, and \$234,946 for other federal and state deferred tax assets. The net change in the total valuation allowance for 2022 was \$320,319, which relates to an increase of \$24,172 for foreign loss carry forwards, an increase of \$9,166 for other foreign deferred tax assets, an increase of \$52,035 for federal and state operating loss carryforwards and an increase of \$234,946 for other federal and state deferred tax assets.
  • During 2022, the Company recorded \$696,028 of additional foreign net operating losses due to tax-deductible impairments in Switzerland and Luxembourg. These losses are subject to recapture in Switzerland and Luxembourg such that they will be taxable in a future year, therefore deferred tax liabilities were recorded. The Company believes it is reasonably possible that the deferred tax liability in Switzerland will reverse within the next twelve months due to expected actions by the Company in 2023.

Income Tax Expense – The effective income tax rate was 137.2% and 10.3% for 2022 and 2021, respectively. The higher effective tax rate for 2022 was primarily due to non-cash discrete tax charges of \$423 million for valuation allowances established against U.S. deferred tax assets and tax impairments in Switzerland which generated deferred tax liabilities during 2022.

Current and deferred tax provisions (benefits) were:

Year ended December 31, 2022 Current Deferred Total
Domestic \$15,188 \$201,112 \$216,300
Foreign \$83,607 \$95,558 \$179,165
State -\$2,712 \$91,154 \$88,442
Total \$96,083 \$387,824 \$483,907
(amounts in thousands)

Deferred tax assets relate to temporary differences (differences between the assets and liabilities in the consolidated financial statements and the assets and liabilities in the calculation of taxable income) including net operating losses.

HBI continues to use a portfolio approach to release the income tax effects in accumulated other comprehensive loss related to pension and post retirement benefits. Under this approach, the income tax effects are released from accumulated other comprehensive loss based on the pre-tax adjustments to pension liabilities or assets recognized within other comprehensive income. Any tax effects remaining in accumulated other comprehensive loss are released only when the entire portfolio of the pension and post retirement benefits is liquidated, sold or extinguished.

In December 31, 2022, the Company had domestic tax credit carry forwards totaling \$10,859, which expire beginning after 2022.

In 2022, 2021, and 2020, the Company recognized reductions of unrecognized tax benefits for tax positions of prior years of \$311, \$12,599, and \$18,385, respectively. In 2022, 2021, and 2020, income tax benefits recognized in connection with the expiration of statutes of limitations were \$7,191, \$147, and \$16,655, respectively. The Company believes it is reasonably possible that the amount of unrecognized tax benefits may decrease by \$3,267 within the next 12 months due to expirations in statutes of limitations. (See pdf page 100 for table)

At December 31, 2022, the balance of the Company’s unrecognized tax benefits, which would, if recognized, affect the Company’s annual effective tax rate was \$28,444. The Company’s policy is to recognize interest and/or penalties related to income tax matters in income tax expense. The Company recognized \$81, \\(933 and \\\)(5,206) in 2022, 2021 and 2020, respectively, for interest and penalties classified as income tax expense (benefit) in the Consolidated Statements of Income. At December 31, 2022 and January 1, 2022, the Company had a total of \$6,303 and \$5,865, respectively, of interest and penalties accrued related to unrecognized tax benefits.

# Average tax rate
tax_rate_avg = tax_rate[-5:].mean()
print('average tax rate: {:.2f}%'.format(tax_rate_avg*100))
average tax rate: 46.81%

Depreciation Rate

The depreciation rate is used to project the future net investment cash flows. The effect is to reduce the amount of FCFF. Depreciation amounts are from the Consolidated Statement of Cash Flows, Depreciation and Amortization.

\(\text{Depreciation Rate}=\frac{\text{Depreciation and Amortization}}{\text{Revenues}}\)

Depreciation is the write off or expensing of a percentage of the historical cost of an asset over the asset’s useful life. Property, plant and equipment (PP&E) are long term or non current assets owned or controlled by the company and used to manufacture and or sell the company’s products. The balance sheet typically shows all categories of PP&E grouped together, net of accumulated depreciation. Depreciation represents wear and tear on an asset or the fact that an asset gets used up over time. Companies record depreciation expense in the income statement every year for all depreciable assets in service or used by the company during the year. The difference between GAAP and Tax Accounting methods is handled through deferred taxes.

Amortization is the write off or expensing of the cost of a financial instrument or an intangible asset over the shorter of its useful life or legal life. Amortization is similar to depreciation and reflects the declining useful life and value of the intangible asset over time. Companies in research and development intensive fields typically have many patents. Such industries include high technology, pharmaceuticals and chemicals.

# depreciation rate
depreciation_rate = df_dcf_data['depreciation'] / df_dcf_data['revenue'].to_numpy()

# plot depreciation on left and rate on right
# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('dollars, $B')

ax1.bar(df_dcf_data['FY'],df_dcf_data['depreciation']/1e9, width=100,color='k')

ax1.tick_params(axis='y')
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:Blue'

ax2.plot(df_dcf_data['FY'],depreciation_rate*100,'+-')
    
ax2.set_ylabel('% Depreciation rate',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((0,30))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Depreciation')
plt.show()

Observation:
Average depreciation rate as as percentage of revenue over the last 5 years is 1.84%. The depreciation and amortization expense for 2022 is comprised of the following:

Depreciation and amortization expense: 12/31/22
Innerwear \$26,518
Activewear \$22,420
International \$19,670
Other \$3,341
Corporate \$32,538
Total depreciation and amortization expense \$106,267
(amounts in thousands)

Property is stated at historical cost and depreciation expense is computed using the straight-line method over the estimated useful lives of the assets. Machinery and equipment is depreciated over periods ranging from one to 15 years and buildings and building improvements over periods of up to 40 years. A change in the depreciable life is treated as a change in accounting estimate and the accelerated depreciation is accounted for in the period of change and future periods. Additions and improvements that substantially extend the useful life of a particular asset and interest costs incurred during the construction period of major properties are capitalized. Repairs and maintenance costs are expensed as incurred. Upon sale or disposition of an asset, the cost and related accumulated depreciation are removed from the accounts.

# average depreciation rate
depreciation_rate_avg = depreciation_rate[-5:].mean()
print('average depreciation rate: {:.2f}%'.format(depreciation_rate_avg*100))
average depreciation rate: 1.84%

Investment Rate

Taken from Consolidated Statement of Cash Flows, Cash used for investing activities. Net investment in the dollar amount needed to support the growth of the firm. Included investments in properties, plant equipment in excess of the depreciation expenses associated with past investments. Net investment decreases the amount of money available to the stockholders. Investment in property, plant and equipment is necessary to both maintain service and sales and also to grow revenues and profits. Investment amounts should include capital expenditures and research and development.

\(Ir=\frac {\text {Capital Expenditures}}{\text{Revenues}}\)

For this company, the yearly investment amounts are taken from the Consolidated Statements of Cash Flows, Net Cash Used in Investing Activities.

Adjustments for Hanesbrands Inc.
No adjustments for this comapany.

# investment rate
investment_rate = df_dcf_data['investment'] / df_dcf_data['revenue'].to_numpy()

# plot investment on left and rate on right
# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('dollars, \\$B')

ax1.bar(df_dcf_data['FY'],df_dcf_data['investment']/1e9, width=100,color='k')

ax1.tick_params(axis='y')
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:Blue'

ax2.plot(df_dcf_data['FY'],investment_rate*100,'+-')
    
ax2.set_ylabel('% New Investment Rate',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-10,40))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('New Investment')
plt.show()

Observation:
Average investment rate as as percentage of revenue over the last 5 years is 2.52%.

The investing activities shown in the 2022 K-10 are shown in the table below:

Investing activities 12/31/22
Capital expenditures -\$112,122
Purchase of trademarks -\$103,000
Proceeds from sales of assets \$157
Other -\$1,463
Net cash from investing activities -\$216,428
(amounts in thousands)

The following investments for the years 2013, 2016 and 2018 are described below.

  • In October 2013, HBI expanded their portfolio of brands through the acquisition of Maidenform, a global intimate apparel company. Maidenform is a leading seller of bras, shapewear and panties under brands such as Maidenform , Flexees, Lilyette, Self Expressions and Sweet Nothings , as well as Donna Karan and DKNY intimate apparel under license. The acquisition was an all cash transaction valued at approximately \$581 million.
  • HBI acquired Champion Europe on June 30, 2016. The acquisition, combined with Champion brand rights previously owned, unites the Champion brand globally and gives HBI a powerful platform for growth on every continent.
  • HBI acquired Hanes Australasia on July 14, 2016.
  • On July 14, 2016, the Company acquired 100% of the outstanding shares of Pacific Brands Limited (“Hanes Australasia”) for a total purchase price of AUD \$1,049,360 (US \$800,871).
  • On February 12, 2018, HBI acquired 100% of the outstanding equity of BNT Holdco Pty Limited (“Bras N Things”) for a total purchase price of AUD \$498,236 (US \$391,572). The purchase price was subsequently revised to AUD \$495,224 (US \$389,205) due to a final working capital adjustment.
  • In June of 2022, HBI purchased the Champion trademark for footwear in the United States, Puerto Rico and Canada from Keds, LLC (“KEDS”) for \$103 million.
# average investment rate
investment_rate_avg = investment_rate[-5:].mean()
print('average investment rate: {:.2f}%'.format(investment_rate_avg*100))
average investment rate: 2.52%

Working Capital Rate

Working capital is needed to support the corporate sales effort of any company. Often a company’s incremental change in net working capital either positive or negative is approximately proportional to its change in revenue.

\(\text{Working capital} = \text{Accounts Receivable} + \text{Inventories} - \text{Accounts Payable}\)

Working capital is a company’s net investment in its accounts receivable and its inventories (cash outflows), minus its accounts payable (a cash inflow). Working capital and taxes are cash outflows from the corporation that are not available to pay debts and stockholders.

Adjustments for Hanesbrands Inc.
No adjustments for this company.

# plot as four grouped bar chart with labels on right and working capital rate on left
# calculate position of bars
x1_bar_position = []
x2_bar_position = []
x3_bar_position = []
x4_bar_position = []
for i in df_dcf_data['FY']:
    x1_bar_position.append(i-relativedelta(months=3))
    x2_bar_position.append(i-relativedelta(months=1))
    x3_bar_position.append(i+relativedelta(months=1))
    x4_bar_position.append(i+relativedelta(months=3))

# calculate working capital rate
working_capital = (df_dcf_data['accounts_receivable'] + df_dcf_data['inventories']) - \
    df_dcf_data['accounts_payable']
working_capital_rate = working_capital / df_dcf_data['revenue']

width = 40  # the width of the bars

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('dollars, \\$B')

rects1 = ax1.bar(x1_bar_position,df_dcf_data['accounts_receivable']/1e9, width,\
    label='Accounts Receivable')
rects2 = ax1.bar(x2_bar_position,df_dcf_data['inventories']/1e9, width, label='Inventory')

rects2 = ax1.bar(x3_bar_position,df_dcf_data['accounts_payable']/1e9, width, label='Accounts Payable')
rects2 = ax1.bar(x4_bar_position,working_capital/1e9, width, label='Working Capital')

ax1.tick_params(axis='y')
#ax1.set_ylim((-50,200))
ax1.legend()
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:Blue'

ax2.plot(df_dcf_data['FY'],working_capital_rate * 100,'+-')
    
ax2.set_ylabel('% Working Capital Rate',color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim((0,50))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Working Capital')
plt.show()

Observation:
Average working capital rate as as percentage of revenue over the last 5 years is 24%.

Customers increasingly require some of products on an exclusive basis, which could cause an increase in the number of stock keeping units, or “SKUs,” that must carried and, consequently, increase inventory levels and working capital requirements

HBI’s overall liquidity has historically been driven by cash flow provided by operating activities, which is dependent on net income and changes in working capital. As compared to the prior year, higher net cash used by operating activities was due to changes in working capital primarily accounts payable, accruals, inventory due to inflationary increases, softer point-of-sale trends and supply chain disruptions, and increased capital investments in cloud computing assets partially offset by improvement in accounts receivable and lower pension plan contributions in 2022.

Accounts receivable consist primarily of amounts due from customers. HBI carries accounts receivable at their net realizable value. In determining the appropriate allowance for doubtful accounts, HBI evaluates receivables on a collection (pool) basis which are aggregated based on similar risk characteristics and consider a combination of factors, such as historical losses, the aging of trade receivables, industry trends, and our customers’ financial strength, credit standing and payment and default history. Changes in the characteristics of accounts receivables and the aforementioned factors, among others, are reviewed quarterly and may lead to adjustments in allowance for doubtful accounts. The calculation of the required allowance involves judgment by our management as to the impact of these and other factors on the ultimate realization of trade receivables. Charges to the allowance for doubtful accounts are reflected in the “Selling, general and administrative expenses” line and charges to the allowance for customer chargebacks and other customer deductions are primarily reflected as a reduction in the “Net sales” line in Consolidated Statements of Income.

Accounts receivable are stated at their net realizable value. The allowance for doubtful accounts reflects the Company’s best estimate of probable losses inherent in the accounts receivable portfolio. Trade receivables are evaluated on a collection (pool) basis and aggregated on the basis of similar risk characteristics which are determined on the basis of historical losses, the aging of trade receivables, industry trends, and its customers’ financial strength, credit standing and payment and default history.

The Company has entered into agreements to sell selected trade accounts receivable to financial institutions based on programs offered by certain of the Company’s largest customers as well as programs sponsored by the Company. As a result of the strong credit worthiness of these customers, the discount taken on most of these programs is less than the marginal borrowing rate on the Company’s variable rate credit facilities. In all agreements, after the sale, the Company does not retain any beneficial interests in the receivables. The applicable financial institution services and collects the accounts receivable directly from the customer for programs offered by the Company’s customers. For programs sponsored by the Company, the Company maintains continued involvement as the servicer to collect the accounts receivable from the customer and remit payment to the financial institution. Net proceeds of these accounts receivable sale programs are recognized in the Consolidated Statements of Cash Flows as part of operating cash flows. The Company recognized total funding fees of \$8,823, \$3,312 and \$4,932 in 2022, 2021 and 2020, respectively, for sales of accounts receivable to financial institutions in the “Other expenses” line in the Consolidated Statements of Income.

See ARS Facility on pdf page 91

HBI carries inventory on the balance sheet at the estimated lower of cost or market. Cost is determined by the first-in, first-out, or “FIFO,” method for our inventories. HBI carries obsolete, damaged and excess inventory at the net realizable value, which they determine by assessing historical recovery rates, current market conditions and our future marketing and sales plans.

Inventories are stated at the estimated lower of cost or net realizable value. Cost is determined by the first-in, first-out, or “FIFO”, method for inventories. Obsolete, damaged, and excess inventory is carried at the net realizable value, which is determined by assessing historical recovery rates, current market conditions and future marketing and sales plans. Rebates, discounts and other cash consideration received from a vendor related to inventory purchases are reflected as reductions in the cost of the related inventory item and are therefore reflected in cost of sales when the related inventory item is sold.

Inventories 12/31/22
Raw materials \$69,279
Work in process \$107,904
Finished goods \$1,802,489
Total \$1,979,672
(amounts in thousands)
# average working capital rate
working_capital_rate_avg = working_capital_rate[-5:].mean()
print('average working capital rate: {:.2f}%'.format(working_capital_rate_avg*100))
average working capital rate: 24.19%

Current assets

Total Current Assets from the most recent balance sheet statement of the company. Current assets include inventory, cash and accounts receivables.

Adjustments for Hanesbrands Inc.
None for this company.

# plot Short Term Assets
width = 100  # the width of the bars

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

plt.bar(df_dcf_data['FY'],df_dcf_data['current_assets']/1e9, width)

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Current assets')
plt.ylabel('dollars, \\$B')

plt.grid()
plt.show()

Observation:
The current assets for HBI are \$3.13B. Current assets are used to calculate the total corporate value.

sta = df_dcf_data['current_assets'].iloc[-1]
print('Current assets: ${:.2f}B'.format(sta/1e9))
Current assets: $3.13B

Current liabilities

Total Current Liabilities from the most recent balance sheet consolidated statement.

Adjustments for Hanesbrands Inc.
None for this company.

# plot Short Term Liabilities

width = 100  # the width of the bars

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

plt.bar(df_dcf_data['FY'],df_dcf_data['current_liabilities']/1e9, width)

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Current liabilities')
plt.ylabel('dollars, \\$B')

plt.grid()
plt.show()

print('Average of current liabilities: ${:.2f}B'.format(df_dcf_data['current_liabilities'].mean()/1e9))
Average of current liabilities: $1.54B

Observation:
The current liabilities for HBI are \$1.79B. Current liabilities are used to calculate the total value of common equity.

stl = df_dcf_data['current_liabilities'].iloc[-1]
print('Current liabilities: ${:.2f}B'.format(stl/1e9))
Current liabilities: $1.79B

Value of Debt Outstanding

Amount of debt outstanding from the most recent balance sheet of the company.

Adjustments for Hanesbrands Inc.
None for this company.

# calculate the percent change in debt, pcd
pcd = np.zeros(len(df_dcf_data['long_term_debt'].to_numpy())) # percent change in debt
for i in range(len(df_dcf_data['long_term_debt'].to_numpy()[0:-1])):
    pcd[i+1] = ((df_dcf_data['long_term_debt'].to_numpy()[i+1] - df_dcf_data['long_term_debt'].to_numpy()[i])/
                df_dcf_data['long_term_debt'].to_numpy()[i+1])*100

width = 100

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('Dollars, $B')

# plot revenue as single bar
plt.bar(df_dcf_data['FY'],df_dcf_data['long_term_debt']/1e9, width,color='k')

ax1.tick_params(axis='y')
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:green'

ax2.plot(df_dcf_data['FY'],pcd,'+-g')
    
ax2.set_ylabel('% Change in debt',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-40,100))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('debt')
plt.show()

dgr_avg = pcd[1:].mean()/100
print('average debt growth rate: {:.2f}%'.format(dgr_avg*100))
average debt growth rate: 3.04%

Observation:
The total long term debt and other for HBI is \$3.61B. Currently the Debt to NOP ratio is 7. HBI Directors eliminated the quarterly cash dividend as they recently shifted their capital allocation strategy to pay down debt to bring leverage back to a range that is no greater than two to three times on a net debt-to-adjusted EBITDA basis. Future principal payments for all of the facilities described above are as follows: \$247,000 due in 2023, \$1,485,275 due in 2024, \$62,500 due in 2025, and \$2,077,500 due in 2026.

A summary of the Company’s debt is presented below:

Senior Secured Credit Facility Interest Rate Principal Amount Maturity Date
Revolving Loan Facility 5.83% \$352,500 11/01/26
Term Loan A 5.92% \$975,000 11/01/26
4.875% Senior Notes 4.88% \$900,000 05/01/26
4.625% Senior Notes 4.63% \$900,000 05/01/24
3.5% Senior Notes 3.50% \$535,275 06/01/24
Accounts Receivable Securitization Facility 5.09% \$209,500 06/01/23
as of December 31, 2022 (amounts in thousands)

Total cash paid for interest related to debt in 2022, 2021 and 2020 was \$150,452, \$161,202 and \$157,094, respectively.

During 2022, 2021 and 2020, the Company paid \$3,159, \$8,346 and \$15,010, respectively, in capitalized debt issuance costs related to the Company’s financing arrangements within continuing operations. Debt issuance costs are amortized to interest expense over the respective lives of the debt instruments, which range from one to 10 years. As of December 31, 2022, the net carrying value of unamortized debt issuance costs for the revolving loan facilities, which is included in “Other noncurrent assets” in the Consolidated Balance Sheets, was \$6,831 and the net carrying value of unamortized debt issuance costs for the remainder of the Company’s debt, which is included in “Long-term debt” in the Consolidated Balance Sheets was \$13,198. The Company’s debt issuance cost amortization in continuing operations was \$7,300, \$12,305 and \$11,349 in 2022, 2021 and 2020, respectively.

vod = df_dcf_data['long_term_debt'].iloc[-1]
print('Total long term debt and other: ${:.2f}B'.format(vod/1e9))
Total long term debt and other: $3.61B

Current stock price

Most recent stock price for the company. The current stock price is used to calculate the market value of the firm. Use the market value when looking at market capitalization for common stock.

csp = 4.4 # current stock price
print('current stock price: ${:,.2f}'.format(csp))
current stock price: $4.40

The current stock price: \$4.40. The 52 week range is \$3.85 to \$12.13.

Shares outstanding

The number of shares outstanding is used to calculate the intrinsic stock value.

so = df_dcf_data['shares_outstanding'].iloc[-1] # shares outstanding
print('shares outstanding, basic: {:,.0f}'.format(so))
shares outstanding, basic: 349,361,517
# calculate the percent change in shares outstanding, pcso
pcso = np.zeros(len(df_dcf_data['shares_outstanding'].to_numpy())) # percent change in debt
for i in range(len(df_dcf_data['shares_outstanding'].to_numpy()[0:-1])):
    pcso[i+1] = ((df_dcf_data['shares_outstanding'].to_numpy()[i+1] - df_dcf_data['shares_outstanding'].to_numpy()[i])/
                df_dcf_data['shares_outstanding'].to_numpy()[i+1])*100

width = 100

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('shares outstanding, M')

# plot revenue as single bar
plt.bar(df_dcf_data['FY'],df_dcf_data['shares_outstanding']/1e6, width,color='k')

ax1.tick_params(axis='y')
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:green'

ax2.plot(df_dcf_data['FY'],pcso,'+-g')
    
ax2.set_ylabel('% Change in shares outstanding',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-5,25))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Shares outstanding')
plt.show()

print('average shares outstanding growth rate: {:.2f}%'.format(pcso[1:].mean()))
average shares outstanding growth rate: -0.83%

Observation:
Under the February 6, 2020 share repurchase program, the Company entered into transactions to repurchase 14,464 shares at a weighted average repurchase price of \$13.83 per share for the year ended January 2, 2021. These shares were repurchased at a total cost of \$200,269. The Company did not purchase any shares of the Company’s common stock under the February 6, 2020 share repurchase program during 2021.

Under the new program, the Company entered into transactions to repurchase 1,577 shares at a weighted average repurchase price of \$15.84 per share for the year ended December 31, 2022. The shares were repurchased at a total cost of \$25,018 including broker’s commissions of \$31. The Company did not repurchase any shares under the previous share repurchase program during 2022 through the expiration of the program on February 2, 2022. At December 31, 2022, the remaining repurchase authorization under the current share repurchase program totaled \$575,013.

Dilution

Dilution occurs when a company issues new shares that result in a decrease in existing stockholders’ ownership percentage of that company. Stock dilution can also occur when holders of stock options, such as company employees, or holders of other optionable securities exercise their options. When the number of shares outstanding increases, each existing stockholder owns a smaller, or diluted, percentage of the company, making each share less valuable.

Investigate why there is a historic growth trend in number of shares outstanding. Search annual report for dilutive actions:

  • share sales
  • convertable debt
  • employee options

Search results:
The Company established the Omnibus Incentive Plan to award stock options, stock appreciation rights, restricted stock, restricted stock units, deferred stock units, performance shares and cash to its employees, non-employee directors and employees of its subsidiaries to promote the interests of the Company, incent performance and retain employees. In April 2020, the stockholders of the Company approved the Hanesbrands Inc. 2020 Omnibus Incentive Plan (the “2020 Omnibus Plan”). The Company satisfies the requirement for common shares for share-based payments to employees pursuant to the 2020 Omnibus Plan by issuing newly authorized shares. The 2020 Omnibus Plan authorized a total of 11,000 shares of common stock of the Company for awards granted under the 2020 Omnibus Plan, plus the number of shares of common stock of the Company available for grant under the predecessor HanesbrandsInc. Omnibus Incentive Plan (the “Prior Plan”) that had not yet been made subject to awards under the Prior Plan as of the effective date of the 2020 Omnibus Plan. The 2020 Omnibus Plan authorized 74,220 shares for awards of stock options and restricted stock units, of which 14,033 shares were available for future grants as of December 31, 2022.

In addition, during 2020, the Company granted stock awards to two newly hired executive officers outside of the 2020 Omnibus Plan in reliance on the employment inducement exemption under the New York Stock Exchange’s Listed Company Manual Rule 303A.08.

There were no stock option exercises during 2022 or 2021. The total intrinsic value of options that were exercised during 2020 was \$3,299.

The total fair value of shares vested during 2022, 2021 and 2020 was \$13,199, \$25,201 and \$15,325, respectively.

At December 31, 2022, there was \$23,329 of total unrecognized compensation cost related to non-vested stock-based compensation arrangements, of which \$16,349, \$6,097, and \$883 is expected to be recognized in continuing operations in 2023, 2024, and 2025, respectively.

Certain of the international plans, specifically those acquired in connection with the purchase of Champion Europe, are in substance nonretirement postemployment benefit plans, which are future liabilities funded through future operational results of the Company. However, for purposes of consolidation, the Company is including these plans within the defined benefit reporting. At December 31, 2022 and January 1, 2022, the total amounts accrued for these plans were \$871 and \$1,171, respectively and the total expense was \$9, \$8 and \$16 for 2022, 2021 and 2020, respectively.

The potential dilution seems to be 85,224 shares (11,000 + 74,220) authorized under the Omnibus Incentive Plan. This represents 0.024% of the shares outstanding. At \$5 per share, this has a value of \$4.26M.

10 year treasury bond yield

The 10 year treasury yield is used as a measure of the risk free rate.
Yield: 3.45%

iShares 7-10 Year Treasury Bond ETF (IEF)
Average Yield to Maturity: 3.5%

tby = (3.45+3.5)/2/100  # 10 year treasury bond yield, average of data from sources listed above
print('10 year treasury bond yield: {:,.2f}%'.format(tby*100))
10 year treasury bond yield: 3.48%

Bond yield spread to treasury

The spread to treasury implies that all corporate debt will have a higher yield than yields associated with comparable maturity US Treasury Bonds. The best way to determine default risk is to see how a particular company’s debt is trading in the market and compare it on a spread basis with comparable maturity yields.

Look at the following or use a default rating systems that are published by the three major rating agencies, Standards and Poors Corp, Moody’s Investor Services and Fitch & Company.

PIMCO Active Bond Exchange-Traded Fund (BOND)
Yield: 3.44%

iShares 5-10 Year Investment Grade Corporate Bond ETF (IGIB)
Average Yield to Maturity: 5.15%

iShares 10+ Year Investment Grade Corporate Bond ETF (IGLB)
Average Yield to Maturity: 5.35%

Web resources: - http://www.standardpoor.com/
- http://bond.yahoo.com/rates.html
- http://www.moodys.com/cust/default.asp
- http://www.fitchibca.com/corporate/index.cfm

bystt = ((3.44+5.15+5.35)/3-tby)/100           # bond yield spread (average) to treasury spread
print('Bond yield spread to treasury: {:,.2f}%'.format(bystt*100))
Bond yield spread to treasury: 4.61%

Preferred stock yield

Amount of preferred stock outstanding from the most recent balance sheet of the company.

Adjustments for Hanesbrands Inc.
Preferred stock (50,000,000 authorized shares; \$.01 par value) Issued and outstanding — None

psy = 0/100  # preferred stock yield
print('preferred stock yield: {:,.2f}%'.format(psy*100))

vps = 0 # value of preferred stock
print('value of preferred stock: {:,.2f}'.format(vps))
preferred stock yield: 0.00%
value of preferred stock: 0.00

Equity risk premium

The expected excess return a hypothetical average investor would require of a diversified portfolio of stock (assumed beta = 1.0) over the yield on the 10-year Treasury Bond. The equity risk premium has been going down over the years.
- 1926 to 1990: 5.5%
- 1962 to 1990: 3.25%
- 1981 to 1990: 0.19%

In times of sustained economic growth the risk premium demanded by investors generally declines.

I’m going to use 3% as the equity risk premium.

eq_rp = 3.0/100             # equity risk premium
print('Equity risk premium: {:,.2f}%'.format(eq_rp*100))
Equity risk premium: 3.00%

Company specific beta

The Beta used is Beta of Equity. Beta is the monthly price change of a particular company relative to the monthly price change of the S&P 500. The time period for Beta is 5 years when available. This value can be obtained at yahoo finance.

A measure of risk of an individual stock. It measures volatility of return - a higher beta means a higher risk. A financial model that uses Beta as its sole measure of risk (signal factor model) is called a Capital Asset Pricing Model (CAPM).

beta = 1.59 # company specific beta
print('Company specific beta: {:,.2f}'.format(beta))
Company specific beta: 1.59

DCF model inputs

Below are the DCF model inputs. These values were calculated above.

# various rates
rgr = rgr_avg              # revenue growth rate
print('revenue growth rate: {:,.2f}%'.format(rgr*100))
nopm = nopm_avg             # net operating profit margin
print('net operating profit margin: {:,.2f}%'.format(nopm*100))
tr = tax_rate_avg               # tax rate
print('tax rate: {:,.2f}%'.format(tr*100))
dr = depreciation_rate_avg              # depreciation rate (% of revenue)
print('depreciation rate: {:,.2f}%'.format(dr*100))
ir = investment_rate_avg              # investment rate (% of revenue)
print('investment rate: {:,.2f}%'.format(ir*100))
wcr = working_capital_rate_avg            # working capital rate (% of revenue)
print('working capital rate: {:,.2f}%'.format(wcr*100))
revenue growth rate: -0.88%
net operating profit margin: 9.13%
tax rate: 46.81%
depreciation rate: 1.84%
investment rate: 2.52%
working capital rate: 24.19%

Excess return period
The excess return period is based on a judgment call. The authors of [1] use the 1-5-7-10 rule. They group companies into one of four general categories and excess return periods. They use a 10 year excess return period to calculate what they would consider the maximum value. They use a more conservative 1 year, 5 year or 7 year return period to calculate a more reasonable or minimum value.

  • 1 year: Boring companies that operate in a highly competitive, low margin industry in which they have nothing particular going for them.
  • 5 year: Decent companies that have a recognizable name and decent reputation and perhaps a regulatory benefit (utility company), but can’t control pricing or growth.
  • 7 year: Good companies with good brand names, large companies of scale, good marketing channels and consumer identification (e.g. McDonald’s)
  • 10 year: Great companies with great growth potential, tremendous marketing power, band names and in-place benefits (e.g. Intel, Microsoft, Coca Cola, Disney)

The excess return period used for the base case is ten years, which should lead to a higher calculated intrinsic value.

# General Inputs
fy_start = df_dcf_data['FY'].iloc[-1].year # fiscal year to start excess return period
erp = 10 # excess return period, years
rev_start = df_dcf_data['revenue'].to_numpy()[-1] # starting revenues for excess return period
print('starting year: {:.0f}'.format(fy_start))
print('excess return period: {:.0f} years'.format(erp))
print('starting revenues: ${:,.2f}B'.format(rev_start/1e9))
print('shares outstanding: {:,.0f}'.format(so))
starting year: 2022
excess return period: 10 years
starting revenues: $6.23B
shares outstanding: 349,361,517
ps_mv = vps               # preferred stock, market value 
print('preferred stock, market value : ${:,.2f}B'.format(ps_mv/1e9))
cs_mv = csp*so            # common stock, market value 
print('common stock, market value: ${:,.2f}B'.format(cs_mv/1e9))
preferred stock, market value : $0.00B
common stock, market value: $1.54B

Long Term Debt, Market Value, ltd_mv
Use the book value for long term debt. Various online resources can be used to research this item. These include, Bondsonline and Bloomberg. The book value of debt and preferred stock is an accounting measure that relates to how much money was raised by the company when each security was issued. The market value of debt and the preferred and common stock is the price that specific obligations would trade at in today’s market.

Long term debt for firms can take one of two forms. It can be a long-term loan from a bank or other financial institution or it can be a long-term bond issued to financial markets, in which case the creditors are the investors in the bond. Firms often have long term obligations that are not captured in the long term debt item. These include obligations to lessors on assets that firms have leased, to employees in the form of pension fund and health care benefits yet to be paid, and to the government in the form of taxes deferred. In the last two decades, accountants have increasingly moved towards quantifying these liabilities and showing them as long term liabilities.

ltd_mv = vod              # market value of long term debt
tmv = ltd_mv+ps_mv+cs_mv  # total market value 
print('total market value: ${:,.2f}B'.format(tmv/1e9))
total market value: $5.15B

Cost of Common Equity, cce
The expected excess return a hypothetical average investor would require of a diversified portfolio of stock (assumed beta = 1.0) over the yield on the 10-year Treasury Bond. The annual rate of return that an investor expects to earn when investing in shares of a company is known as the cost of common equity. It includes dividends and increases in the market value.

cce = tby+beta*eq_rp      # cost of common equity or the expected return for the stock
print('cost of common equity: {:,.2f}%'.format(cce*100))
cost of common equity: 8.24%

Long Term Debt, Average Yield, ltd_ay
The total cost of long term debt.

ltd_ay = tby+bystt        # long term debt average yield
print('long term debt average yield: {:,.2f}%'.format(ltd_ay*100))
long term debt average yield: 8.09%

Long Term Debt, After Tax Yield, ltd_aty
The tax benefits of long term debt. Interest payments are tax deductible for the company.

ltd_aty = ltd_ay*(1-tr)   # long term debt after tax yield
print('long term debt after tax yield: {:,.2f}%'.format(ltd_aty*100))

ltd_pc = vod/tmv          # weight for long term debt 
ltd_ate = ltd_aty*ltd_pc  # after tax effect of long term debt 
ps_ay = psy               # preferred stock, average yield 
ps_aty = ps_ay            # preferred stock, average yield 
print('preferred stock, average yield: {:,.2f}%'.format(ps_aty*100))

ps_pc = ps_mv/tmv         # preferred stock, % capital 
ps_ate = ps_aty*ps_pc     # preferred stock, after tax effect 
cs_ay = cce               # common stock, average yield 
cs_aty = cce              # common stock, after tax yield 
print('common stock, after tax yield: {:,.2f}%'.format(cs_aty*100))

cs_pc = cs_mv/tmv         # common stock, % capital 
cs_ate = cs_aty*cs_pc     # common stock, after tax effect 
print('common stock, after tax effet: {:,.2f}%'.format(cs_ate*100))

tate = ltd_ate+ps_ate+cs_ate # total after tax effect 
print('total after tax effect: {:,.2f}%'.format(tate*100))
tpc = ltd_pc+ps_pc+cs_pc     # total % Capital
print('total % Capital: {:,.2f}%'.format(tpc*100))
long term debt after tax yield: 4.30%
preferred stock, average yield: 0.00%
common stock, after tax yield: 8.24%
common stock, after tax effet: 2.46%
total after tax effect: 5.48%
total % Capital: 100.00%

Weighted average cost of capital
A company’s weighted average cost of capital (WACC) is the weighted average of the company’s current cost of debt and equity calculated by using current debt, preferred stock and common stock market values. The WACC of the company, calculated after tax, is the discount rate used in the DCF valuation procedures. The WACC, which is the cost of the different components of financing used by the firm, weighted by their market value proportions. These include debt, preferred stock, and common stock.

WACC: Weighted Average Cost of Capital, the rate used to discount cash flows, based on the following three factors. 1. Base rate of return. 2. Expected return based on debt and preferred stock. 3. Expected return on common stock and Beta.

All adjusted for the tax advantage of interest payments and the percentage of debt, preferred stock and common stock.

wacc = tate
print('weighted average cost of capital: {:.1f}%'.format(wacc*100))
weighted average cost of capital: 5.5%

Future cash flows

The future cash flows to the firm are projected based on revenue growth. The cash flows are then discounted using the WACC and the ISV is calculated.

# make a list of the fiscal years in excess return period 
fy = np.zeros(erp+1)
fy[0] = fy_start
for i in range(1,erp+1): 
    fy[i]=fy_start+i

rev = np.zeros(len(fy))
ciwc = np.zeros(len(fy))
rev[0] = rev_start  #*rgr+rev_start   # find the future revenue using constant revenue growth rate 

for i in range(1,len(fy)): 
    rev[i] = rev[i-1]*rgr+rev[i-1]  # find the future revenue 
    ciwc[i] = (rev[i]-rev[i-1])*wcr  # find the change in working capital 

net_op = np.zeros(len(fy)) # net operating profit
adj_taxes = np.zeros(len(fy))
nopat = np.zeros(len(fy))
invest = np.zeros(len(fy))
depre = np.zeros(len(fy))
net_invest = np.zeros(len(fy))
fcff = np.zeros(len(fy))
disc_fact = np.zeros(len(fy))
disc_fcff = np.zeros(len(fy))                

# calculate values in table 
for i in range(1,len(fy)):
    net_op[i] = rev[i]*nopm # net operating profit margin
    adj_taxes[i] = net_op[i]*tr # net operating profit adjusted for taxes
    nopat[i] = net_op[i]-adj_taxes[i] # after tax net operating profit
    invest[i] = rev[i]*ir # future investments
    depre[i] = rev[i]*dr # future depreciations
    net_invest[i] = invest[i]-depre[i] # net investments
    fcff[i] = nopat[i]-net_invest[i]-ciwc[i] # free cash flow to the firm
    disc_fact[i] = 1/((1+wacc)**i) # discount factor
    disc_fcff[i] = disc_fact[i]*fcff[i] # discounted free cash flow to the firm
    
dcrv = nopat[-1]/wacc*disc_fact[-1] # discounted corporate residual value
derp_fcff = disc_fcff.sum() # discounted excess return period FCFF

tcv = derp_fcff+dcrv+sta # total corporate value
tvce = tcv-vod-vps-stl # total value of common equity
isv = tvce/so # intrinsic stock value

# print cash flows in a table
print('{:4s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}'.format('Year','Rev','NOP','AdjTaxes',
    'NOPAT','Invest.','Deprec.','dInvest.','dWC','FCFF','DF','DF*FCFF'))
for i in range(len(fy)):
    print('{:4.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.4f}{:10,.0f}'.format(fy[i],
        rev[i]/1e6,net_op[i]/1e6,adj_taxes[i]/1e6,nopat[i]/1e6,invest[i]/1e6,depre[i]/1e6,(invest[i]-depre[i])/1e6,ciwc[i]/1e6,
        fcff[i]/1e6,disc_fact[i],disc_fcff[i]/1e6))
Year       Rev       NOP  AdjTaxes     NOPAT   Invest.   Deprec.  dInvest.       dWC      FCFF        DF   DF*FCFF
2022     6,234         0         0         0         0         0         0         0         0    0.0000         0
2023     6,179       564       264       300       156       114        42       -13       271    0.9481       257
2024     6,124       559       262       297       154       113        42       -13       269    0.8988       242
2025     6,070       554       259       295       153       112        41       -13       267    0.8521       227
2026     6,017       549       257       292       151       111        41       -13       264    0.8079       213
2027     5,964       544       255       290       150       110        41       -13       262    0.7659       201
2028     5,911       540       253       287       149       109        40       -13       260    0.7261       188
2029     5,859       535       250       284       147       108        40       -13       257    0.6884       177
2030     5,808       530       248       282       146       107        39       -12       255    0.6526       166
2031     5,756       525       246       280       145       106        39       -12       253    0.6187       156
2032     5,706       521       244       277       144       105        39       -12       251    0.5866       147
# Intrinsic Value
print('discounted excess return period FCFF: ${:,.2f}B'.format(derp_fcff/1e9))
print('discounted corporate residual value: ${:,.2f}B'.format(dcrv/1e9))
print('total corporate value: ${:,.2f}B'.format(tcv/1e9))
print('total value of common equity: ${:,.2f}B'.format(tvce/1e9))
tvce_baseline = tvce # save value as baseline case
isv_baseline = isv # save the isv for the baseline case
print('intrinsic stock value, baseline case: ${:,.2f}'.format(isv_baseline))
print('current stock price: ${:,.2f}'.format(csp))
discounted excess return period FCFF: $1.98B
discounted corporate residual value: $2.97B
total corporate value: $8.07B
total value of common equity: $2.67B
intrinsic stock value, baseline case: $7.64
current stock price: $4.40

Observation:
The base line DCF analysis produces an intrinsic stock value of \$7.64. An intrinsic value greater than the current price indicates that the stock is a potential value stock. Some adjustments will be made in the scenario 1 case.

List of all inputs to the DCF model

The following print statements format the inputs to the model similar to how they are presented on the Valuepro page.

print('{:>35s} {:<10.0f} {:>35s} {:,.3f}'.format('Excess return period, years:',erp,'Depreciation rate, %:',dr*100))
print('{:>35s} {:<10,.2f} {:>35s} {:,.3f}'.format('Starting revenues, $B:',
    rev_start/1e9,'Investment rate, %:',ir*100))
print('{:>35s} {:<10,.3f} {:>35s} {:,.3f}'.format('Revenue growth rate, %:',
    rgr*100,'Working capital rate, %:',wcr*100))
print('{:>35s} {:<10,.3f} {:>35s} {:,.3f}'.format('Net operating profit margin, %:',
    nopm*100,'Current assets, $B:',sta/1e9))
print('{:>35s} {:<10,.3f} {:>35s} {:.3f}'.format('Tax rate, %:',
    tr*100,'Current liabilities, $B:',stl/1e9))
print('{:>35s} {:<10,.2f} {:>35s} {:,.2f}'.format('Current stock price, $:',
    csp,'Equity risk premium, %:',eq_rp*100))
print('{:>35s} {:<10,.0f} {:>35s} {:,.2f}'.format('Shares outstanding, basic, M:',
    so/1e6,'Company specific beta:',beta))
print('{:>35s} {:<10,.2f} {:>35s} {:.3f}'.format('10 year treasury bond yield, %:',
    tby*100,'Total long term debt and other, $B:',vod/1e9))
print('{:>35s} {:<10,.2f} {:>35s} {:,.3f}'.format('Bond yield spread to treasury, %:',
    bystt*100,'Value of preferred stock, $B:',vps/1e9))
print('{:>35s} {:<10,.2f}'.format('Preferred stock yield, %:',psy*100))
       Excess return period, years: 10                       Depreciation rate, %: 1.838
             Starting revenues, $B: 6.23                       Investment rate, %: 2.517
            Revenue growth rate, %: -0.881                Working capital rate, %: 24.192
    Net operating profit margin, %: 9.128                      Current assets, $B: 3.132
                       Tax rate, %: 46.805                Current liabilities, $B: 1.791
            Current stock price, $: 4.40                   Equity risk premium, %: 3.00
      Shares outstanding, basic, M: 349                     Company specific beta: 1.59
    10 year treasury bond yield, %: 3.48       Total long term debt and other, $B: 3.612
  Bond yield spread to treasury, %: 4.61             Value of preferred stock, $B: 0.000
          Preferred stock yield, %: 0.00      
# weighted average cost of capital inputs
print('Weighted Average Cost of Capital')
print('Cost of common equity')
print('{:s}'.format('-'*37))
print('{:>32s} {:,.2f}'.format('10 year treasury bond yield, %:',tby*100))
print('{:>32s} {:,.2f}'.format('Company specific beta:',beta))
print('{:>32s} {:,.2f}'.format('Equity risk premium, %:',eq_rp*100))
print('{:s}'.format('-'*37))
print('{:>32s} {:,.2f}'.format('Cost of common equity, %:',cce*100))
print()

print('Market Capitalization and After-Tax Weighted Average Cost of Capital')
print()
print('{:s}{:^10s}{:^10s}{:^10s}{:^15s}{:^15s}'.format(' '*20,'Current','After-Tax','Market','%','Weighted After-'))
print('{:s}{:^10s}{:^10s}{:^10s}{:^15s}{:^15s}'.format(' '*20,'Yield','Yield','Value','Capitalization','Tax Yield'))

print('{:s}'.format('-'*80))
print('{:<15s}{:>12.2f}{:>10.2f}{:>10,.0f}{:>12.2f}{:>15.2f}'.format('Long term debt',
    ltd_ay*100,(tby+eq_rp)*(1-tr)*100,vod/1e9,ltd_pc*100,ltd_ate*100))
print('{:<15s}{:>12.2f}{:>10.2f}{:>10,.0f}{:>12.2f}{:>15.2f}'.format('Preferred stock',
     psy*100,ps_ate*100,vps/1e9,ps_pc*100,ps_ate*100))
print('{:<15s}{:>12.2f}{:>10.2f}{:>10,.0f}{:>12.2f}{:>15.2f}'.format('Common stock',
     cs_ay*100,cs_aty*100,cs_mv/1e9,cs_pc*100,cs_aty*100))
print('{:s}'.format('-'*80))
print('{:<37s}{:>10,.0f}{:>12.2f}{:>15.2f}'.format('',tmv/1e9,tpc*100,wacc*100))
Weighted Average Cost of Capital
Cost of common equity
-------------------------------------
 10 year treasury bond yield, %: 3.48
          Company specific beta: 1.59
         Equity risk premium, %: 3.00
-------------------------------------
       Cost of common equity, %: 8.24

Market Capitalization and After-Tax Weighted Average Cost of Capital

                     Current  After-Tax   Market         %       Weighted After-
                      Yield     Yield     Value   Capitalization    Tax Yield   
--------------------------------------------------------------------------------
Long term debt         8.09      3.44         4       70.15           3.02
Preferred stock        0.00      0.00         0        0.00           0.00
Common stock           8.24      8.24         2       29.85           8.24
--------------------------------------------------------------------------------
                                              5      100.00           5.48

4) DCF Scenarios

The following adjustments were made to various model parameters.

  • excess return period was adjusted to a more conservative 5 years
  • revenue growth rate was adjusted to 0% (base case = -0.881 %)
  • net operating profit margin was adjusted to 9% (base case = 9.128%)
  • tax rate was adjusted to 30% (base case = 46.805%)
  • depreciation rate was adjusted to 2% (base case = 1.838%)
  • investment rate was adjust to 2% (base case = 2.517%)
  • working capital rate was set to an even 24% (base case = 24.192%)
  • weighted average cost of capital was adjusted up by 2% to reflect higher interest rates and provide a margin of safety (base case = 5.59%)
print('adjusted DCF input values and rates')
erp = 5
print('excess return period: {:,.0f} years'.format(erp))
rgr = 0/100
print('revenue growth rate: {:,.1f}%'.format(rgr*100))
nopm = isv_s1_nopm = 9/100  # save nopm rate for NAIC preferred method
print('net operating profit margin: {:.2f}%'.format(nopm*100))
tr = isv_s1_tr = 30/100  # save tax rate for NAIC preferred method
print('tax rate: {:.2f}%'.format(tr*100))
dr = 2/100
print('depreciation rate: {:,.2f}%'.format(dr*100))
ir = 2/100              # investment rate (% of revenue)
print('investment rate: {:,.2f}%'.format(ir*100))
wcr = 24/100
print('working capital rate: {:,.1f}%'.format(wcr*100))
wacc = (wacc+0.02) # weighted average cost of capital, increased by 2%
print('weighted average cost of capital: {:.1f}%'.format(wacc*100))
adjusted DCF input values and rates
excess return period: 5 years
revenue growth rate: 0.0%
net operating profit margin: 9.00%
tax rate: 30.00%
depreciation rate: 2.00%
investment rate: 2.00%
working capital rate: 24.0%
weighted average cost of capital: 7.5%
# make a list of the fiscal years in excess return period 
fy = np.zeros(erp+1)
fy[0] = fy_start
for i in range(1,erp+1): 
    fy[i]=fy_start+i

rev = np.zeros(len(fy))
ciwc = np.zeros(len(fy))
rev[0] = rev_start  #*rgr+rev_start   # find the future revenue using constant revenue growth rate 

for i in range(1,len(fy)): 
    rev[i] = rev[i-1]*rgr+rev[i-1]  # find the future revenue 
    ciwc[i] = (rev[i]-rev[i-1])*wcr  # find the change in working capital 

net_op = np.zeros(len(fy))
adj_taxes = np.zeros(len(fy))
nopat = np.zeros(len(fy))
invest = np.zeros(len(fy))
depre = np.zeros(len(fy))
net_invest = np.zeros(len(fy))
fcff = np.zeros(len(fy))
disc_fact = np.zeros(len(fy))
disc_fcff = np.zeros(len(fy))                

# calculate values in table 
for i in range(1,len(fy)): 
    net_op[i] = rev[i]*nopm # net operating profit
    adj_taxes[i] = net_op[i]*tr # net operating profit adjusted for taxes
    nopat[i] = net_op[i]-adj_taxes[i] # after tax net operating profit
    invest[i] = rev[i]*ir # future investments
    depre[i] = rev[i]*dr # future depreciations
    net_invest[i] = invest[i]-depre[i] # net investments
    fcff[i] = nopat[i]-net_invest[i]-ciwc[i] # free cash flow to the firm
    disc_fact[i] = 1/((1+wacc)**i) # discount factor
    disc_fcff[i] = disc_fact[i]*fcff[i] # discounted free cash flow to the firm
    
dcrv = nopat[-1]/wacc*disc_fact[-1] # discounted corporate residual value
derp_fcff = disc_fcff.sum() # discounted excess return period FCFF

tcv = derp_fcff+dcrv+sta # total corporate value
tvce = tcv-vod-vps-stl # total value of common equity
isv = tvce/so # intrinsic stock value

# print cash flows in a table
print('{:4s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}'.format(
    'Year','Rev','NOP','AdjTaxes',
    'NOPAT','Invest.','Deprec.','dInvest.','dWC','FCFF','DF','DF*FCFF'))
for i in range(len(fy)):
    print('{:4.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.0f}{:10,.4f}{:10,.0f}'.
        format(fy[i],rev[i]/1e6,net_op[i]/1e6,adj_taxes[i]/1e6,nopat[i]/1e6,invest[i]/1e6,depre[i]/1e6,
        (invest[i]-depre[i])/1e6,ciwc[i]/1e6,fcff[i]/1e6,disc_fact[i],disc_fcff[i]/1e6))
Year       Rev       NOP  AdjTaxes     NOPAT   Invest.   Deprec.  dInvest.       dWC      FCFF        DF   DF*FCFF
2022     6,234         0         0         0         0         0         0         0         0    0.0000         0
2023     6,234       561       168       393       125       125         0         0       393    0.9304       365
2024     6,234       561       168       393       125       125         0         0       393    0.8657       340
2025     6,234       561       168       393       125       125         0         0       393    0.8054       316
2026     6,234       561       168       393       125       125         0         0       393    0.7494       294
2027     6,234       561       168       393       125       125         0         0       393    0.6972       274
# Intrinsic Value
print('discounted excess return period FCFF: ${:,.2f}B'.format(derp_fcff/1e9))
print('discounted corporate residual value: ${:,.2f}B'.format(dcrv/1e9))
print('total corporate value: ${:,.2f}B'.format(tcv/1e9))
print('total value of common equity: ${:,.2f}B'.format(tvce/1e9))
tvce_S1 = tvce # save value as scenario 1
isv_S1 = isv # save the isv for scenario 1 case
print('intrinsic stock value, scenario 1 case: ${:,.2f}'.format(isv_S1))
print('current stock price: ${:,.2f}'.format(csp))
discounted excess return period FCFF: $1.59B
discounted corporate residual value: $3.66B
total corporate value: $8.38B
total value of common equity: $2.98B
intrinsic stock value, scenario 1 case: $8.53
current stock price: $4.40

The DCF model calculates with adjustments an intrinsic stock value of \$5.36, which is greater than the current stock price.

5) NACI stock selection guide analysis

This analysis follows the NAIC stock selection guide (SSG) [2]. The SSG relates revenue growth, EPS and share price history and makes a prediction about the future share price.

The National Association of Investors Clubs (NAIC) is a nonprofit organization dedicated to educating individual investors and investment clubs to become successful lifelong investors. NAIC’s Stock Selection Guide (SSG) is used in the following cells to analyze the company’s growth and whether the stock is selling at a reasonable price.

The SSG was originally developed in the 1950s as a paper worksheet by the not-for-profit National Association of Investors Corporation (NAIC). The SSG aims to aid individual investors in the fundamental analysis and selection of common stocks by reviewing components of a company’s growth, quality, and value.

Load data from metrics sheet

# column names: fiscal years 
fy_data = df_metrics_sheet.columns[1:].values.astype('datetime64[Y]')-1970
# line 0: Net income
net_income_data = df_metrics_sheet.iloc[0].to_numpy()[1:].astype('float')
# line 1: Shareholder equity
shareholder_equity_data =  df_metrics_sheet.iloc[1].to_numpy()[1:].astype('float')
# line 2: Total liabilities
total_liabilities_data = df_metrics_sheet.iloc[2].to_numpy()[1:].astype('float')
# line 3: Free cash flow, Net cash provided by operating activities 
free_cash_flow_data =  df_metrics_sheet.iloc[3].to_numpy()[1:].astype('float')
# line 4: Dividends
dividends_data =  df_metrics_sheet.iloc[4].to_numpy()[1:].astype('float')
# line 5: Total assets
total_assets_data = df_metrics_sheet.iloc[5].to_numpy()[1:].astype('float')
# line 6: Earnings per share
eps_data = df_metrics_sheet.iloc[6].to_numpy()[1:].astype('float')
# line 7: Dividends per share  
dps_data = df_metrics_sheet.iloc[7].to_numpy()[1:].astype('float')
# line 8: Total tangible assets
total_tangible_assets_data = df_metrics_sheet.iloc[8].to_numpy()[1:].astype('float')
# line 9: Liabilities w/o deposits
liabilities_wo_deposits_data = df_metrics_sheet.iloc[9].to_numpy()[1:].astype('float')
# line 10: Provision for credit losses
provision_for_credit_losses_data = df_metrics_sheet.iloc[10].to_numpy()[1:].astype('float')
# line 11: Short-term borrowings
short_term_borrowings_data = df_metrics_sheet.iloc[11].to_numpy()[1:].astype('float')
# line 12: Preferred stock
preferred_stock_data = df_metrics_sheet.iloc[12].to_numpy()[1:].astype('float')
# line 13: Net cash used in investing activities 
net_cash_used_in_investing_activities_data = df_metrics_sheet.iloc[13].to_numpy()[1:].astype('float')
# make a new data frame to store data from metrics sheet
df_metrics_data = pd.DataFrame(data={
    'FY':fy_data[::-1],
    'net_income':net_income_data[::-1],
    'shareholder_equity':shareholder_equity_data[::-1],
    'total_liabilities':total_liabilities_data[::-1],
    'free_cash_flow':free_cash_flow_data[::-1],
    'dividends':dividends_data[::-1],
    'total_assets':total_assets_data[::-1],
    'eps':eps_data[::-1],    
    'dps':dps_data[::-1],
    'total_tangible_assets':total_tangible_assets_data[::-1],
    'liabilities_wo_deposits':liabilities_wo_deposits_data[::-1],    
    'provision_for_credit_losses':provision_for_credit_losses_data[::-1],
    'short_term_borrowings':short_term_borrowings_data[::-1], 
    'preferred_stock':preferred_stock_data[::-1],
    'net_cash_used_in_investing_activities':net_cash_used_in_investing_activities_data[::-1]
    })

#df_metrics_data

check for matching years in both data frames

if all(df_dcf_data['FY'] == df_metrics_data['FY']) != True:
    print('error, years in data frame don\'t match')
    stop # this is not python code, so jupyterlab will throw an error
else:
    print('OK, years in data frame match')
OK, years in data frame match

NAIC section 1: Visual analysis

High and low price history for each year
From the daily price history obtained from yahoo finance, the high and low closing price for each is obtained and the data saved to the financial data frame as new columns.

\(\Large {\color {red} {\text {Avg closing price calculated, add to template}}}\)

#column names: fiscal years 
years_list = df_metrics_sheet.columns[1:].values.astype('str')[::-1]

# convert years to datetime format
year_ended_list = []
for i in years_list:
    year_ended_list.append(datetime.strptime(i, '%Y'))

# make empty lists to store open, close, average close, high and low price data for each fiscal year
fy_open = []
fy_close = []
fy_avg_close = []
fy_high = []
fy_low = []

for i in year_ended_list:
    start = i
    end = i + relativedelta(years=1)
    p1 = df_price_history.truncate(before=start, after=end)
    if len(p1) == 0:
        fy_open.append(np.nan)
        fy_close.append(np.nan)
        fy_avg_close.append(np.nan)
        fy_high.append(np.nan)
        fy_low.append(np.nan)
    else:
        fy_open.append(p1['Open'].iloc[0])
        fy_close.append(p1['Close'].iloc[-1])
        fy_avg_close.append(p1['Close'].mean()) # could also use median
        fy_high.append(p1['Close'].max())
        fy_low.append(p1['Close'].min())

# convert from list to numpy array
fy_open = np.asarray(fy_open)
fy_close = np.asarray(fy_close)
fy_avg_close = np.asarray(fy_avg_close)
fy_high = np.asarray(fy_high)
fy_low = np.asarray(fy_low)
fy_close
array([ 6.35    ,  5.465   ,  8.955   , 17.567499, 27.905001, 29.43    ,
       21.57    , 20.91    , 12.53    , 14.85    , 14.58    , 16.719999,
        6.36    ])
fy_avg_close
array([ 6.53318452,  6.7058631 ,  7.49818   , 13.47691467, 22.92302585,
       30.99999004, 26.50714288, 22.03254979, 18.60091629, 16.0516666 ,
       13.12505929, 18.31206347, 11.18338648])

Plotting the data
The annual sales, EPS and the high and low share price is plotted on a semilog plot. A consistent percentage change in the data will plot on the semi-log chart as a straight line.

The stock price is plotted separately from the sales and earnings for clarity.

fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(5.5, 3.5),layout=“constrained”)

ax1 = plt.subplot(212) ax1.margins(0.05) # Default margin is 0.05, value 0 means fit ax1.plot(t1, f(t1))

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

# figsize() function to adjust the size
plt.subplots(1,2,figsize=(15, 5)) # }--- put fix here

# using subplot function and creating
# plot one
plt.subplot(1, 2, 1)  # reseach this }------ generates warnings
width = 3  # the width of the bars
#plt.bar(year_ended_list,fy_high-fy_low, width,bottom=fy_low,label='price')
j = 0
for i in year_ended_list:
    color = 'green'
    if fy_open[j] > fy_close[j]: color= 'red'
    # high/low lines
    plt.plot([i,i],[fy_low[j],fy_high[j]],color=color, linewidth=width)
    # open marker
    plt.plot([i,i-relativedelta(months=1)], [fy_open[j],fy_open[j]], color=color, linewidth=width)
    # close marker
    plt.plot([i,i+relativedelta(months=1)], [fy_close[j],fy_close[j]], color=color, linewidth=width)
    j += 1

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

#plt.ylim((20,80))
plt.title('Yearly stock high and low price range')
plt.ylabel('stock price, $')
#plt.legend()
plt.grid()

# using subplot function and creating plot two
plt.subplot(1, 2, 2)

plt.plot(df_metrics_data['FY'],df_dcf_data['revenue']/1e9,'+-',label='revenue, $B')
plt.plot(df_metrics_data['FY'],df_metrics_data['eps'],'+-',label='EPS, $')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

#plt.yscale('log')
#plt.yticks([0.1,1,10,100,1000,10000],['0.1','1','10','100','1000','10000'])
#plt.ylim((0.1,1000))
plt.title('Revenue and EPS')
plt.ylabel('Revenue and EPS')
plt.legend()

plt.grid()

# space between the plots
#plt.tight_layout(4) this line generates a warning
'''
/tmp/ipykernel_2327/525771534.py:10: MatplotlibDeprecationWarning: Auto-removal of overlapping axes is deprecated since 3.6 and will be removed two minor releases later; explicitly call ax.remove() as needed.
  plt.subplot(1, 2, 1)

/tmp/ipykernel_2327/3890704171.py:10: MatplotlibDeprecationWarning: Auto-removal of overlapping axes is deprecated since 3.6 and will be removed two minor releases later; explicitly call ax.remove() as needed.
  plt.subplot(1, 2, 1)

'''

# show plot
plt.show()

Observation:
The share price dramatically fell when the dividend was discontinued and has continued to decline as the EPS has fallen. The 52 week range is between \$3.85 and \$11.91. The pandemic and the current recession have impacted the business. It is interesting to note that the share price has trended down since 2015, while the revenue was increasing over the period from 2013 to 2019. In 2016 HBI took on additional debt to fund acquisitions.

\(\Large {\color {red} {\text {fix warning about axes}}}\)

NAIC section 3, Price earnings history

Section 3 of the SSG is the Price-Earnings history. The following table is built from the high and low prices each year and the earnings per share. The high and low Price/Earnings ratios are calculated for each year and are listed in the columns labeled h-per and l-per.

print('{:4s}{:>10s}{:>10s}{:>10s}{:>10s}{:>10s}'.format('year','high','low','eps',
    'h-per','l-per'))
for i in range(len(year_ended_list)):
    print('{:s}{:10,.2f}{:10,.2f}{:10,.2f}{:10,.2f}{:10,.2f}'.format(year_ended_list[i].strftime("%Y"),
        fy_high[i], fy_low[i],df_metrics_data['eps'][i],
        fy_high[i]/df_metrics_data['eps'][i],
        fy_low[i]/df_metrics_data['eps'][i]))
year      high       low       eps     h-per     l-per
2010      7.70      5.42      0.55     14.07      9.89
2011      8.31      5.46      0.68     12.18      8.00
2012      9.12      5.55      0.42     21.86     13.29
2013     17.74      8.90      0.83     21.44     10.75
2014     28.93     16.04      1.00     28.79     15.96
2015     34.58     26.54      1.07     32.32     24.80
2016     31.18     21.53      1.41     22.11     15.27
2017     25.67     18.98      0.17    151.00    111.65
2018     23.24     11.62      1.48     15.70      7.85
2019     19.14     12.52      1.65     11.60      7.59
2020     17.62      7.17     -0.21    -83.90    -34.14
2021     22.37     14.40      0.22    101.68     65.45
2022     17.36      5.84     -0.36    -48.22    -16.22

Average high and P/E for select years
The average price to earning ratio based on high and low stock prices is calculated.

#Average high P/E for years 
pe_avg_high = (fy_high/df_metrics_data['eps']).mean()
print('average high P/E {:.2f}'.format(pe_avg_high))
#Average low P/E for years 
pe_avg_low = (fy_low/df_metrics_data['eps']).mean()
print('average low P/E {:.2f}'.format(pe_avg_low))
average high P/E 23.12
average low P/E 18.47

Estimate future EPS

A least squares fit is used to get the slope of the EPS data points.

y = df_metrics_data['eps']
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
print('EPS slope: {:.2f}'.format(m))
print('EPS intercept: {:.2f}'.format(c))
lstsq_fit = m*x + c  # data points for each year
EPS slope: -0.04
EPS intercept: 0.94
# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('EPS')

ax1.plot(df_metrics_data['FY'],df_metrics_data['eps'], 'o',label='EPS')
ax1.plot(df_metrics_data['FY'],lstsq_fit, '-',label='least squares fit')

ax1.tick_params(axis='y')
#ax1.set_ylim((0,4))
ax1.legend()
plt.grid()

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('EPS and least squares fit')
plt.show()

Using the equation for the best fit line, find the y value for the eps point at five years in the future.

# estimated eps in 5 years
eps_5yr_est = m*(x[-1]+5) + c
print('estimated eps in 5 years: {:.1f}'.format(eps_5yr_est))
estimated eps in 5 years: 0.2

Using the high and low price to earning ratio from above and the projected eps, calculate the range of stock price in five years.

naic_price_eps_low = eps_5yr_est*pe_avg_low
naic_price_eps_high = eps_5yr_est*pe_avg_high
print('estimated price range in 5 years: ${:.2f} to ${:.2f}'.format(naic_price_eps_low,naic_price_eps_high))
estimated price range in 5 years: $4.01 to $5.02

This is the estimated price range of the stock based on projected EPS and is a guide for what the stock price might be if conditions remain the same. Since the slope of the EPS history is negative, the projected stock price is negative.

NAIC section 3: 5 year estimated EPS, preferred method

See page 87 and figure 10-1, Need the following data:
- estimate sales in 5 years based on sales growth
- NOPM
- Tax rate
- shares outstanding

Net Operating Profit should reflect the future revenue generating ability and expense requirements of the operating business that comprise the ongoing operations of the company.

\(\text{NOPM} = \frac{\text{Revenue} - \text{Expenses}}{\text{Revenue}}\)

Tax payments are taken from the consolidated income statement, provision for income taxes. The effect of taxes on profits is accounted for.

\(\text{Tax rate} = \frac{\text{Income taxes}}{\text{Income before income taxes}}\)

To get future EPS

\(\text{future EPS} = \frac {\text{future revenue} \times \text{NOPM} \times \text{(1-tax rate)}}{\text{number of shares}}\)

Revenue and least square fit

y = df_dcf_data['revenue']/1e6
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
print('revenue slope: {:.2f}'.format(m))
print('revenue intercept: {:.2f}'.format(c))
lstsq_fit = m*x + c  # data points for each year
revenue slope: 228.20
revenue intercept: 4411.07
# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('dollars, $M')

ax1.plot(df_metrics_data['FY'],df_dcf_data['revenue']/1e6, 'o',label='revenue')
ax1.plot(df_metrics_data['FY'],lstsq_fit, '-',label='least squares fit')

ax1.tick_params(axis='y')
#ax1.set_ylim((0,4))
ax1.legend()
plt.grid()

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Revenue and least squares fit')
plt.show()

Using the equation for the best fit line, find the y value for the EPS point at five years in the future.

# estimated revenue in 5 years
rev_5yr_est = m*(x[-1]+5) + c
print('estimated rev in 5 years: ${:,.1f}M'.format(rev_5yr_est))
estimated rev in 5 years: $8,290.5M

need to include estimate of number of shares outstanding in 5 years

print('starting revenues: ${:,.2f}'.format(rev_start/1e9))
starting revenues: $6.23

Using the adjusted NOPM and tax rate from scenario 1.
adjusted DCF input values and rates

pm_nopm = isv_s1_nopm # use nopm from scenario 1
pm_tax_rate = isv_s1_tr # use tr from scenario 1

pm_eps_5yr_est = rev_5yr_est*pm_nopm*(1-pm_tax_rate)*1e6/df_dcf_data['shares_outstanding'].iloc[-1] 
#pm_eps_5yr_est = rev_5yr_est*nopm_avg*1e6/df_dcf_data['shares_outstanding'].iloc[-1] 
print('using preferred method: estimated eps in 5 years: ${:.2f}'.format(pm_eps_5yr_est))
using preferred method: estimated eps in 5 years: $1.50

Using the high and low price to earning ratio from above and the projected EPS, calculate the range of stock price in five years.

naic_price_pm_low = pm_eps_5yr_est*pe_avg_low
naic_price_pm_high = pm_eps_5yr_est*pe_avg_high
print('estimated price range in 5 years from preferred method: {:.2f} to {:.2f}'.format(
    naic_price_pm_low,naic_price_pm_high))
estimated price range in 5 years from preferred method: 27.62 to 34.57

Observation: Based on revenue growth, the projected stock price is a bit higher than the current price. However, based on price history, the stock is not expected to appreciate.

6) Future stock price

The projected future stock price is estimated from the results shown in this notebook based on DCF intrinsic stock value, the NAIC method or a combination of both. The DCF method does not consider market sentiment or popularity of the stock, whereas the NAIC method looks at the PE and EPS to develop the historical consensus that the market has put on the price of the stock. Both the NAIC and the DCF valuation should be considered. The DCF valuation is of the current ISV which is used as an indication of the future value, since it is assumed that the market price will converge eventually to the intrinsic value.

The estimated future stock price considers the following:
- base case ISV
- Senario ISV
- NAIC EPS growth
- NAIC preferred method

Using 5 year NAIC as a conservative estimate for the 10 year value and the analysis results, a judgment call is made concerning the price to put on the future value of the stock.

print('estimated price range in 5 years from EPS: ${:.2f} to ${:.2f}'.format(naic_price_eps_low,naic_price_eps_high))
print('estimated price range in 5 years from preferred method: ${:.2f} to ${:.2f}'.format(
    naic_price_pm_low,naic_price_pm_high))

print('intrinsic stock value, baseline case: ${:,.2f}'.format(isv_baseline))
print('intrinsic stock value, scenario 1 case: ${:,.2f}'.format(isv_S1))

print('current stock price: ${:,.2f}'.format(csp))
estimated price range in 5 years from EPS: $4.01 to $5.02
estimated price range in 5 years from preferred method: $27.62 to $34.57
intrinsic stock value, baseline case: $7.64
intrinsic stock value, scenario 1 case: $8.53
current stock price: $4.40

The estimated price range in 5 years from the preferred method is \$86.14 to \$116.85. Taking the average and using that value on the IRR calculations.

fsp = (naic_price_pm_low+isv_S1)/2 # estimated future stock price
print('estimated future stock price: ${:,.2f}'.format(fsp))
estimated future stock price: $18.07

7) Dividend payout

The dividend payout examines the amount shareholders are getting from the company relative to earnings or revenue. It is an important metric to determine how the business is operating and whether it has enough growth potential.

Dividend history

No dividends paid in 2010, 2011 and 2012. HBI Board of Directors eliminated the quarterly cash dividend as they recently shifted their capital allocation strategy to pay down debt to bring leverage back to a range that is no greater than two to three times on a net debt-to-adjusted EBITDA basis.

The code cells below have been set to raw since there is no dividend data and the yearly future cash flows are also set to zero.

calculate the percent change in dividends

pcd = np.zeros(len(df_metrics_data[‘dps’])) # percent change in dividend for i in range(len(df_metrics_data[‘dps’][0:-1])): pcd[i+1] = ((df_metrics_data[‘dps’][i+1] - df_metrics_data[‘dps’][i])/ df_metrics_data[‘dps’][i+1])*100

width = 100

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘Dividend per share, $’)

plot revenue as single bar

plt.bar(df_metrics_data[‘FY’],df_metrics_data[‘dps’], width,color=‘k’)

ax1.tick_params(axis=‘y’) plt.grid()

instantiate a second y-axes that shares the same x-axis

ax2 = ax1.twinx() color = ‘tab:green’

ax2.plot(year_ended_list,pcd,‘+-g’)

ax2.set_ylabel(‘% Change in dividend’,color=color) ax2.tick_params(axis=‘y’, labelcolor=color) ax2.set_ylim((0,20))

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘Dividend history per share’) plt.show()

adgr = pcd[-6:].mean() #last 6 years print(‘average dividend growth rate: {:.2f}%’.format(adgr))

Dividend yield

Dividend yield equals the annual dividend per share divided by the stock’s price per share. The plot below shows the history of dividend yield over the evaluation period.

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

width = 50 # the width of the bars plt.bar(df_metrics_data[‘FY’],(df_metrics_data[‘dps’]/fy_high-df_metrics_data[‘dps’]/fy_low)100, width,bottom=df_metrics_data[‘dps’]/fy_low100,label=‘yield’) X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.ylim((1,12)) plt.title(‘Range of dividend yield each year’) plt.ylabel(‘dividend yield, %’) #plt.legend() plt.grid()

show plot

plt.show()

The dividend yield for the past five years has been in the 2.5 to 3.5 percent range.

Dividend payout ratio

The dividend payout ratio is a relative measure of how much the company is paying to shareholders in dividends compared to other metrics such as revenue, earnings or cash flow. The dividend payout ratio is plotted as a ratio of dividends to net income, free cash flow (Net cash provided by operating activities) and NOP. The payout ratio is useful for assessing a dividend’s sustainability. Companies are extremely reluctant to cut dividends since it can drive the stock price down and reflect poorly on management’s abilities.

Payout ratio using net income
Payout ratio using net income plots the ratio of dividend payout divided by net income:
\(\frac {\text{Dividends}}{\text{Net income}}\)
Depending on how net income is listed in the financial statements, it may include large other charges.

Payout ratio using cash flow
Payout ratio using net cash flow plots the ratio of dividend payout divided by cash flow:
\(\frac {\text{Dividends}}{\text{cash flow}}\)
Cash flow from operating activities usually includes a long list of items. Some insight might be obtained from this ratio. The trend should be consistent.

Payout ratio using NOP
Payout ratio using NOP plots the ratio of dividend payout divided by NOP:
\(\frac {\text{Dividends}}{\text{NOP}}\)
NOP is calculated above and might be different from net income listed in the financial statements. This ratio should be the lowest numerically of the three plots.

\(\Large {\color {red} {\text {not applicable anymore}}}\)

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘Payout ratio’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘dividends’]/df_metrics_data[‘net_income’], ‘-+’, label=‘Payout ratio using net income’) ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘dividends’]/df_metrics_data[‘free_cash_flow’], ’-*‘, label=’Payout ratio using cash flow’) ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘dividends’]/nop, ‘-+’, label=‘dividends/NOP’)

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,5)) ax1.legend() plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘Payout ratio’) plt.show()

average the last three years

print(‘Dividends are paid at {:.1f}% of net income’.format( (df_metrics_data[‘dividends’]/df_metrics_data[‘net_income’])[-3:].mean()100)) print(‘Dividends are paid at {:.1f}% of cash flow’.format( (df_metrics_data[‘dividends’]/df_metrics_data[‘free_cash_flow’])[-3:].mean()100)) print(‘Dividends are paid at {:.1f}% of NOP’.format((df_metrics_data[‘dividends’]/nop)[-3:].mean()*100))

Payout ratio using net income: Net income includes large other charges and Amortization of acquired intangible assets. Large swings in ratio for net income indicates various charges against net income.
Payout ratio using cash flow: A ratio of greater than 1 for 2015. Currently below 33%.
Payout ratio using NOP: Follows ratio based on cash flow.
Dividend pay ratios for the last 3 years are near or below 50%.

Internal Rate of Return (IRR) calculations

The internal rate of return (IRR) is the discount rate that makes the net present value (NPV) of all cash flows equal to zero in a discounted cash flow analysis. Generally speaking, the higher an internal rate of return, the more desirable an investment is to undertake.

As explained above, the stock price fell when the dividend was elimated. The IRR calculations are based on average weighted cost plus the dividends actually received. The final stock price is based on ISV forecast.

The dividend growth rate has been set equal to zero.

adgr = 0 # setting the average dividend growth rate to zero
fdp = np.zeros(len(df_metrics_data['dps'])) # future dividend payments
fdp[0] = df_metrics_data['dps'].iat[-1]
for i in range(len(df_metrics_data['dps'][0:-1])):
    fdp[i+1] = fdp[i]+fdp[i]*adgr/100
print('current stock price: ${:,.2f}'.format(csp))
print('my weighted average cost: ${:,.2f}'.format(11.37))
print('dividend payout received: ${:,.2f}'.format(df_metrics_data['dps'].iat[-1]))
#fsp = 100 #csp #500 #(csp + 102.05 + 138.82)/3 # final stock price, $
print('final stock price: ${:,.2f}'.format(fsp))
current stock price: $4.40
my weighted average cost: $11.37
dividend payout received: $0.60
final stock price: $18.07
#est_cf = np.copy(fdp) # make a copy of the estimated cash flow
est_cf = np.zeros(len(df_metrics_data['dps']))

# cash flows, initial purchase, dividend payments and final sale
est_cf[0] = est_cf[0] - 11.37 + df_metrics_data['dps'].iat[-1] #csp # subtract purchase price from the first dividend payment
est_cf[-1] = est_cf[-1] + fsp # include the sale price with the final dividend payment
dividend_irr = np_financial.irr(est_cf) #np.irr(est_cf)
'''
this line generates an error
/tmp/ipykernel_2327/1130842036.py:1: DeprecationWarning: In accordance with NEP 32, the function irr was removed from NumPy version 1.20.  A replacement for this function is available in the numpy_financial library: https://pypi.org/project/numpy-financial
  dividend_irr = np.irr(est_cf)
'''

print('IRR: {:.2f}%'.format(dividend_irr*100))
IRR: 4.41%

According to global investment bank Goldman Sachs, 10-year stock market returns have averaged 9.2% over the past 140 years. and according to 10-Year Annualized Rolling Returns, the long term average is about 10%. However there are many years where the rolling 10 year average return is below 4%.

The calculated IRR is 4.4%, which is lower than current interest rates.

8) Management performance

The following analysis somewhat follows the Warren Buffett strategy as outlined in [3]. This strategy is essentially value investing where companies are chosen that meet a set of criteria and who’s stock price is below the intrinsic value plus a margin of safety. These investments are usually held for the long term.

  • Financial metrics
    The following analysis looks at financial ratios over the evaluation period. Financial ratios can be used to judge management performance. Consistent favorable trends are an indication that management is taking care of the company.
    • Total liabilities to total assets ratio
    • Debt to equity and debt to NOP ratios
    • Financial ratios: RoE, RoA and PM
    • NAIC section 2: Evaluating management
    • Normalized data from consolidated statements
  • Market metrics
    • One dollar premise
    • Share price vs EPS
    • Market capitalization
  • Qualitative metrics
    • Simple and understandable business model
    • Favorable long term prospects
    • Commodity reliance
    • Consistent operating history
    • rationality:
      1. focus on core aspects
      2. only invest in high ROE businesses
      3. focus on shareholder equity

Financial metrics

The following financial metrics are examined over the evaluation period. We are looking for favorable trends and evidence of consistent operations. Some red flags will also be evident in the plots.

Red flags:
- Shrinking gross profit margin
- Receivables growing faster than sales
- Rising debt-to-equity ratio
- Several years of revenue trending down
- Unsteady cash flow
- Rising accounts receivable or inventory in relation to sales
- Rising outstanding share count
- Consistently higher liabilities than assets
- Decreasing gross profit margin
- Increasing revenue while cash flow remains the same
- Unusual changes in key financial ratios

Total liabilities to total assets ratio

The ratio of liabilities to assets is plotted over the evaluation period. For most companies examined the liabilities are the total liabilities and the ratio is calculated using total assets and total tangible assets. Total tangible assets have goodwill and intangibles removed from the total. The ratio gives an indication of how much the company is worth versus how much the company owes. Ideally the ratio of liabilities to assets should be less than one.

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('ratio')

# plot revenue as single bar
ax1.plot(df_metrics_data['FY'],df_metrics_data['total_liabilities']/df_metrics_data['total_assets'], '-+',
    label='total liabilities to total assets')
ax1.plot(df_metrics_data['FY'],df_metrics_data['total_liabilities']/df_metrics_data['total_tangible_assets'], '-*',
    label='total liabilities to total tangible assets')

ax1.tick_params(axis='y')
ax1.legend(bbox_to_anchor=(1.8, 1))
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:green'

#ax2.plot(year_ended_list,pcd,'+-g')
ax2.plot(df_metrics_data['FY'],
    (df_metrics_data['total_assets']-df_metrics_data['total_tangible_assets'])/df_metrics_data['total_assets']*100,
    ':',color=color,label='intangible assets to total assets')
    
ax2.set_ylabel('% intangible assets',color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim((0,100))
ax2.legend(bbox_to_anchor=(1.7, 0))

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Total liabilities to total assets ratio')
plt.show()

HBI has significant goodwill and intangible assets. As of January 2, 2021, HBI had approximately \$1.3 billion of goodwill and \$1.6 billion of trademarks and other identifiable intangibles on the balance sheet, which together represent 37% of the total assets. HBI does not amortize goodwill, but they assess for impairment at least annually and more often as triggering events occur. The timing of annual goodwill impairment testing is the first day of the third fiscal quarter.

Equity computed using tangible assets is negative. This would made debt to equity ratios shown below negative.

Debt to equity and debt to NOP ratios

The debt-to-equity ratio (D/E) is another key characteristic Buffett considers carefully. Buffett prefers to see a small amount of debt so that earnings growth is being generated from shareholders’ equity as opposed to borrowed money. The D/E ratio is calculated as follows:

\(\text{Debt-to-Equity Ratio} = \frac {\text{Total Liabilities}} {\text{Shareholders' Equity}} \text{ OR } \frac {\text{Long term debt}} {\text{Shareholders' Equity}}\)

This ratio shows the proportion of equity and debt the company uses to finance its assets, and the higher the ratio, the more debt—rather than equity—is financing the company. A high debt level compared to equity can result in volatile earnings and large interest expenses. For a more stringent test, investors sometimes use only long-term debt instead of total liabilities in the calculation above.

D/E is the traditional way to look at a company’s debt. Some rules of thumb say that the D/E should not be above 2 or 3. However the D/E company’s typically vary by industry. The ratio of LT debt to NOP gives the number of years it would take the company to pay back debt from NOP, the lower the number the shorter amount of time.

\(\text{Debt-to-NOP Ratio} = \frac {\text{Total Liabilities}} {\text{NOP}}\)

tangible_equity = df_metrics_data['total_tangible_assets'] - df_metrics_data['total_liabilities']

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('ratio')

ax1.plot(df_metrics_data['FY'],df_dcf_data['long_term_debt']/df_metrics_data['shareholder_equity'],
    '-^',label='(LT debt)/Equity')
#ax1.plot(year_ended_list,df_dcf_data['long_term_debt']/tangible_equity, '-',label='(LT debt)/(Tangible Equity)')
ax1.plot(df_metrics_data['FY'],df_metrics_data['total_liabilities']/df_metrics_data['shareholder_equity'],
    '-*',label='(total liabilities)/Equity')
#ax1.plot(year_ended_list,total_liabilities/BV, '-^',label='(total liabilities)/BV')
ax1.plot(df_metrics_data['FY'],df_metrics_data['total_liabilities']/nop, '-+',label='(total liabilities)/NOP')
#ax1.plot(year_ended_list,total_liabilities/net_income, '-+',label='(total liabilities)/(net income)')
#ax1.plot(year_ended_list,df_dcf_data['current_liabilities']/nop, '-*',label='(current liabilities)/NOP')
#ax1.plot(year_ended_list,Liabilities_wo_deposits/nop, '-+',label='(Liabilities w/o deposits)/NOP')

ax1.tick_params(axis='y')
ax1.set_ylim((0,20))
#ax1.legend()
ax1.legend(bbox_to_anchor=(1.6, 1))
plt.grid()

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Various debt ratios')
plt.show()

\(\Large {\color {red} {\text {fix plot, why the spike in 2020?}}}\)

Three debt ratios are plotted above. Prior to 2020 the debt ratios were somewhat consistent from year to year. In 2020 the NOP fell to almost zero and the total liabilities to NOP ratio when off the chart. From 2019 to the present the debt ratios have been rising and are now at concerning levels. It will be challenging for the HBI to reduce debt and grow revenues in the coming years.

—- OLD (LT debt)/Equity is plotted and is below 2 for each year in the evaluation period. A threshold of 2 is traditionally the upper limit for a reasonable amount of debt that a company should carry.

(total liabilities)/Equity is plotted and except for 2020 has been below the threshold of 2.

(total liabilities)/NOP to is plotted for each year in the evaluation period and except for 2019 is below 10. A value of 10 has been chosen as the threshold for this ratio and indicates how many years it would take the company to pay off total liabilities from the NOP generated each year. A threshold of ten seems like a reasonable level of debt measured against NOP.

Financial ratios (change)

Financial returns

Various ratios can be used to judge management performance. Consistent favorable trends are an indication that management is taking care of the company.

Return on equity
Sometimes return on equity (RoE) is referred to as stockholder’s return on investment. It reveals the rate at which shareholders earn income on their shares. Buffett always looks at RoE to see whether a company has consistently performed well compared to other companies in the same industry. RoE is calculated as follows:

\(\text{Return on Equity} = \frac {\text{Net Income}} {\text{Shareholder's Equity}}\)

Looking at the RoE in just the last year isn’t enough. The investor should view the RoE from the past five to 10 years to analyze historical performance.

\(\text{Shareholders’ Equity} = \text{Total Assets} − \text{Total Liabilities}\)

For this company, this method of getting Shareholders’ Equity gives negative values. On the Consolidated Balance Sheets, there is a line for Total stockholders’ equity, which is used.

Return on Assets
Return on assets is a profitability ratio that provides how much profit a company is able to generate from its assets. In other words, return on assets (RoA) measures how efficient a company’s management is in generating earnings from their economic resources or assets on their balance sheet.

\(\text{Return on assets} = \frac {\text{Net Income}} {\text{Tangible Assets}}\)

Calculating the RoA of a company can be helpful in comparing a company’s profitability over multiple quarters and years as well as comparing to similar companies. However, it’s important to compare companies of similar size and industry.

For example, banks tend to have a large number of total assets on their books in the form of loans, cash, and investments. A large bank could easily have over \$2 trillion in assets while putting up a net income that’s similar to companies in other industries. Although the bank’s net income or profit might be similar to an unrelated company and the bank might have high-quality assets, the bank’s RoA will be lower. The larger number of total assets must be divided into the net income, creating a lower RoA for the bank.

Similarly, auto manufacturing requires huge facilities and specialized equipment. A lucrative software company that sells downloadable programs online may generate the same net profits, but it could have a significantly higher RoA than its more asset-heavy counterparts. When utilizing this metric to compare productivity across businesses, it’s important to take into account what types of assets are required to function in a given industry, rather than simply comparing the figures.

Goodwill is a historical cost that does not have to be constantly replaced. Therefore, in most cases, return on tangible capital alone (excluding goodwill) will be a more accurate reflection of a business’s return on capital going forward. The ROE and ROA calculations used by many investment analysts are therefore often distorted by ignoring the difference between reported equity and assets and tangible equity and assets.

Profit Margin
A company’s profitability depends not only on having a good profit margin, but also on consistently increasing it. This margin is calculated by dividing net income by net sales. For a good indication of historical profit margins, investors should look back at least five years. A high-profit margin indicates the company is executing its business well, but increasing margins mean management has been extremely efficient and successful at controlling expenses.

\(\text{Profit Margin} = \frac {\text{Net Income}} {\text{Revenue}}\)

New Section

Return on Capital
The Return on Capital (RoC) is plotted to compare to RoA and RoE. RoC shows how much capital is needed to conduct the company’s business. RoC is the ratio of NOP to Working Capital, Tangible Assets and Depreciation. In addition to working capital requirements, a company must also fund the purchase of fixed assets necessary to conduct its business, such as real estate, plant, and equipment. The depreciated net cost of these fixed assets was then added to the working capital requirements to arrive at an estimate for tangible capital employed. Return on Capital (RoC) is calculated as follows:

\(\text{Return on Capital} = \frac {\text{NOP}} {\text{Working Capital + Tangible Assets + Depreciation}}\)

The RoC calculation uses NOP instead of net income to filter distortions due to taxes and debt.

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('percent')

ax1.plot(df_metrics_data['FY'],df_metrics_data['net_income']/df_metrics_data['shareholder_equity']*100,
    '-+',label='Return on Equity')

#ax1.plot(df_metrics_data['FY'],df_metrics_data['net_income']/df_metrics_data['total_assets']*100,
#    '-*',label='Return on Assets')

ax1.plot(df_metrics_data['FY'],df_metrics_data['net_income']/df_metrics_data['total_tangible_assets']*100,
    '-*',label='Return on Tangable Assets')

ax1.plot(df_metrics_data['FY'],nop/(working_capital+df_metrics_data['total_tangible_assets']+df_dcf_data['depreciation'])*100,
    '-*',label='Return on Capital')

#ax1.plot(df_metrics_data['FY'],total_liabilities/shareholder_equity, '-^',label='D/E')

#ax1.plot(df_metrics_data['FY'],df_metrics_data['net_income']/df_dcf_data['revenue']*100,
#    '-^',label='Profit margin')

ax1.tick_params(axis='y')
#ax1.set_ylim((0,14))
#ax1.legend()
ax1.legend(bbox_to_anchor=(1.05, 1))
plt.grid()

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Financial Returns')
plt.show()

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘percent’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘shareholder_equity’]100, ‘-+’,label=‘Return on Equity’) ax1.plot(df_metrics_data[‘FY’],nop/df_metrics_data[‘shareholder_equity’]100, ‘-+’,label=‘Return on Equity w/ NOP’) #ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_assets’]100, # ’-’,label=‘Return on Assets’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_tangible_assets’]100, ‘-’,label=’Return on Tangable Assets’) ax1.plot(df_metrics_data[’FY’],nop/df_metrics_data[’total_tangible_assets’]100,’-’,label=‘Return on Tangable Assets w/ NOP’)

ax1.plot(df_metrics_data[‘FY’],nop/(working_capital+df_metrics_data[‘total_tangible_assets’]+df_dcf_data[‘depreciation’])100, ’-’,label=‘Return on Capital’)

#ax1.plot(df_metrics_data[‘FY’],total_liabilities/shareholder_equity, ‘-^’,label=‘D/E’)

#ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_dcf_data[‘revenue’]*100, # ‘-^’,label=‘Profit margin’)

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,14)) #ax1.legend() ax1.legend(bbox_to_anchor=(1.05, 1)) plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘Financial Returns’) plt.show()

Observation:
The trends for RoE, RoA (tangible) and RoC are shown above. RoE and RoA use net income in the equation show agree with results reported by analysts. RoC uses NOP instead of net income to eliminate the effects of taxes and debt. As shown in the plots, HBI is operating with negative RoE and RoA (tangible) in the current year. During the past few years the effects of the pandemic and global economic slowdown can be seen in the RoE and RoA (tangible) plots.

NAIC section 2: Evaluating management

This evaluating management section is patterned after the NAIC SSG report page 2; line A is percent pre-tax profit on sales and line B is percent earned on equity. The SSG section 2 looks to see if the trends are increasing or decreasing. In this report I’m going to look at the trends for profit margin and two measures of earnings yield.

Profit margin is a common measure of the degree to which a company or a particular business activity makes money. Expressed as a percentage, it represents the portion of a company’s sales revenue that it gets to keep as a profit, after subtracting all of its costs. The earnings yield refers to the earnings per share for for each 12-month period divided by the average price per share during the same period.

\(\text{Earning yield} = \frac {\text{EPS}} {\text{average closing price}}\)

If we use NOP in place of EPS and divide NOP by market capitalization (average share price multiplied by shares outstanding), we get another measure of earnings yield.

\(\text{Earning yield} = \frac {\text{NOP}} {(\text{shares outstanding} \times \text{average closing price}) + \text{long term debt}}\)

By using NOP, we can calculate the net operating profit yield on the full purchase price of a business.

\(\Large {\color {red} {\text {update this section, re-write}}}\)

See page 86, figure 9-1.
- % pretax profit on sales, (net before taxes)/rev - % earned on equity (another way of saying RoE, using calculated equity)

Percent earned on equity is a measure of financial performance calculated by dividing net income by equity. Because equity is equal to a company’s assets minus its debt, percent earned on equity is considered the return on net assets. Percent earned on equity is considered a gauge of a corporation’s profitability and how efficient it is in generating profits.

The following cells calculate the trends of the profit margin and earnings yield over the evaluation period and the most recent 5 years. The trend line is calculated using the numpy function, polyfit, which calculates the least squares polynomial fit with the degree of the fitting polynomial equal to 1.

y = df_metrics_data['net_income']/df_dcf_data['revenue']
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
pm_trend = m # save the slope of the least squared fit
print('Profit margin slope: {:.2f}%'.format(m*100))
print('Profit margin intercept: {:.3f}'.format(c))
pm_lstsq_fit = m*x + c  # data points for each year
Profit margin slope: -0.51%
Profit margin intercept: 0.078
left_yr = -6 # number of years to look back
y = df_metrics_data['net_income'].iloc[left_yr:]/df_dcf_data['revenue'].iloc[left_yr:]
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
pm1_trend = m # save the slope of the least squared fit
print('Profit margin slope over the last {:.0f} years: {:.2f}%'.format(-left_yr,m*100))
print('Profit margin intercept point for the last {:.0f} years: {:.3f}'.format(-left_yr,c))
pm1_lstsq_fit = m*x + c  # data points for each year
Profit margin slope over the last 6 years: -1.29%
Profit margin intercept point for the last 6 years: 0.058

The following cells calculate the earning yield based on EPS. The trend lines are also calculated.

y = df_metrics_data['eps']/fy_avg_close
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
y1_trend = m # save the slope of the least squared fit
print('y1 slope: {:.2f}%'.format(m*100))
print('y1 intercept: {:.3f}'.format(c))
y1_lstsq_fit = m*x + c  # data points for each year
y1 slope: -0.69%
y1 intercept: 0.087
y = df_metrics_data['eps'].iloc[left_yr:]/fy_avg_close[left_yr:]
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
y1a_trend = m # save the slope of the least squared fit
print('y1 slope: {:.2f}%'.format(m*100))
print('y1 intercept: {:.3f}'.format(c))
y1a_lstsq_fit = m*x + c  # data points for each year
y1 slope: -1.49%
y1 intercept: 0.063

The following cells calculate the earning yield based on NOP. The trend lines are also calculated.

y = nop/(df_dcf_data['shares_outstanding']*fy_avg_close+df_dcf_data['long_term_debt'])
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
y2_trend = m # save the slope of the least squared fit
print('y2 slope: {:.2f}'.format(m*100))
print('y2 intercept: {:.3f}'.format(c))
y2_lstsq_fit = m*x + c  # data points for each year
y2 slope: -0.28
y2 intercept: 0.088
y = nop[left_yr:]/(df_dcf_data['shares_outstanding'].iloc[left_yr:]*fy_avg_close[left_yr:]+df_dcf_data['long_term_debt'].iloc[left_yr:])
x = np.arange(len(y))
m, c = np.polyfit(x, y, 1)
y2a_trend = m # save the slope of the least squared fit
print('y2 slope: {:.2f}'.format(m*100))
print('y2 intercept: {:.3f}'.format(c))
y2a_lstsq_fit = m*x + c  # data points for each year
y2 slope: -0.23
y2 intercept: 0.072

The following cell displays the profit margin and yield data along with trend lines.

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

fig, ax1 = plt.subplots()
ax1.set_ylabel('percent')
#ax1.plot(year_ended_list,net_income, '-+',label='net income')
#ax1.plot(df_metrics_data['FY'],df_dcf_data['income_before_income_taxes']/df_dcf_data['revenue']*100, '-+',
#         label='income before taxes/rev')

#ax1.plot(df_metrics_data['FY'],nop/df_dcf_data['revenue']*100, '-+',
#         label='NOP/rev')

ax1.plot(df_metrics_data['FY'],df_metrics_data['net_income']/df_dcf_data['revenue']*100,
    '-^k',label='net income/revenue')
ax1.plot(df_metrics_data['FY'],pm_lstsq_fit*100, '-.k')
#ax1.plot(df_metrics_data['FY'],pm_lstsq_fit*100, '-k',label='pm least squares fit')
ax1.plot(df_metrics_data['FY'].iloc[left_yr:],pm1_lstsq_fit*100, '-k')

#ax1.plot(year_ended_list,df_dcf_data['revenue'], '-+',label='revenue')
#ax1.plot(year_ended_list,free_cash_flow, '-*',label='free cash flow')


ax1.plot(df_metrics_data['FY'],df_metrics_data['eps']/fy_avg_close*100,
    '-+b',label='EPS/(avg closing price)')
#ax1.plot(df_metrics_data['FY'],y1_lstsq_fit*100, '-b',label='y1 least squares fit')
ax1.plot(df_metrics_data['FY'],y1_lstsq_fit*100, '-.b')
ax1.plot(df_metrics_data['FY'].iloc[left_yr:],y1a_lstsq_fit*100, '-b')


ax1.plot(df_metrics_data['FY'],nop/(df_dcf_data['shares_outstanding']*fy_avg_close+df_dcf_data['long_term_debt'])*100,
    '-or',label='NOP/(so*avg closing price+long term debt)')
#ax1.plot(df_metrics_data['FY'],y2_lstsq_fit*100, '-r',label='y2 least squares fit')
ax1.plot(df_metrics_data['FY'],y2_lstsq_fit*100, '-.r')
ax1.plot(df_metrics_data['FY'].iloc[left_yr:],y2a_lstsq_fit*100, '-r')

ax1.tick_params(axis='y')
#ax1.set_ylim((0,18))
ax1.legend()
plt.grid()

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.title('Profit margin & earnings yield')
plt.show()

Observation:
Ideally the profit marging and yield trends should be growing or at least flat. In HBI’s case, the trends are negative.

Evaluating the treds.

\(\Large {\color {red} {\text {move these cells to section 9, decision model}}}\)

# check profit margin trends
if pm_trend < 0:
    print('FAIL, profit margin trend over the evaluation period is negative at {:.1f}%'.format(pm_trend*100))
else:
    print('PASS, profit margin trend over the evaluation period is positive at {:.1f}%'.format(pm_trend*100))

if pm1_trend < 0:
    print('FAIL, profit margin trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,pm1_trend*100))
else:
    print('PASS, profit margin trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,pm1_trend*100))    
FAIL, profit margin trend over the evaluation period is negative at -0.5%
FAIL, profit margin trend over the last 6 years is negative at -1.3%

Checking trends based on EPS and NOP.

# check yield trend based on EPS
if pm_trend < 0:
    print('FAIL, EPS yield trend over the evaluation period is negative at {:.1f}%'.format(y1_trend*100))
else:
    print('PASS, EPS yield trend over the evaluation period is positive at {:.1f}%'.format(y1_trend*100))

if pm1_trend < 0:
    print('FAIL, EPS yield trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,y1a_trend*100))
else:
    print('PASS, EPS yield trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,y1a_trend*100))    
FAIL, EPS yield trend over the evaluation period is negative at -0.7%
FAIL, EPS yield trend over the last 6 years is negative at -1.5%
# check yield trend based on NOP
if pm_trend < 0:
    print('FAIL, NOP yield trend over the evaluation period is negative at {:.1f}%'.format(y2_trend*100))
else:
    print('PASS, NOP yield trend over the evaluation period is positive at {:.1f}%'.format(y2_trend*100))

if pm1_trend < 0:
    print('FAIL, NOP yield trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,y2a_trend*100))
else:
    print('PASS, NOP yield trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,y2a_trend*100))    
FAIL, NOP yield trend over the evaluation period is negative at -0.3%
FAIL, NOP yield trend over the last 6 years is negative at -0.2%

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘percent’) #ax1.plot(year_ended_list,net_income, ‘-+’,label=‘net income’) ax1.plot(df_metrics_data[‘FY’],df_dcf_data[‘income_before_income_taxes’]/df_dcf_data[‘revenue’]100, ‘-+’, label=‘income before taxes/rev’) #ax1.plot(year_ended_list,df_dcf_data[‘revenue’], ‘-+’,label=‘revenue’) #ax1.plot(year_ended_list,free_cash_flow, ’-’,label=‘free cash flow’)

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,18)) #ax1.legend() plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘% pretax profit on sales’) plt.show()

\(\Large {\color {red} {\text {New section, also add to template}}}\)

Earnings yield

describe: - EPS/(avg closing price) - NOP/(so*avg closing price)

need to calculate the avg price in the period

fy_avg_price = (fy_high+fy_low)/2 fy_avg_price

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘percent’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘eps’]/fy_avg_close*100, ‘-+’,label=‘EPS/(avg closing price)’)

ax1.plot(df_metrics_data[‘FY’],nop/(df_dcf_data[‘shares_outstanding’]fy_avg_close)100, ‘-+’,label=’NOP/(so*avg closing price)’)

’’’ ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_assets’]100, ‘-’,label=’RoA’) ax1.plot(df_metrics_data[’FY’],nop/(working_capital+df_metrics_data[’total_tangible_assets’])100,’-’,label=‘RoC’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘shareholder_equity’]100, ‘-+’,label=‘RoE’) ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_assets’]100, ‘-’,label=’RoA’) ax1.plot(df_metrics_data[’FY’],df_metrics_data[’net_income’]/df_dcf_data[’revenue’]100,’-^‘,label=’Profit margin’) ’’’

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,14)) #ax1.legend() ax1.legend(bbox_to_anchor=(1.05, 1)) plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘Earnings yield’) plt.show()

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘percent’)

#ax1.plot(year_ended_list,shareholder_equity/df_dcf_data[‘revenue’]100, ‘-+k’, # label=‘shareholder equity/rev’) #ax1.plot(year_ended_list,net_income/shareholder_equity100, ‘-+’,label=‘RoE’) ax1.plot(df_metrics_data[‘FY’], df_metrics_data[‘net_income’]/(df_metrics_data[‘total_assets’]-df_metrics_data[‘total_liabilities’])*100, ‘-+’,label=‘RoE’)

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,12)) #ax1.legend() plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘% earned on equity’) plt.show()

Percent earned on equity (another way of saying RoE). Percent earned on equity trend has been flat up to 2015, then became erratic.

Percent earned on equity is a measure of financial performance calculated by dividing net income by equity. Because equity is equal to a company’s assets minus its debt, percent earned on equity is considered the return on net assets. Percent earned on equity is considered a gauge of a corporation’s profitability and how efficient it is in generating profits.

Set the locator

locator = mdates.YearLocator() # every year fmt = mdates.DateFormatter(‘%Y’)

fig, ax1 = plt.subplots() ax1.set_ylabel(‘percent’)

ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_assets’]100, ‘-’,label=’RoA’) ax1.plot(df_metrics_data[’FY’],nop/(working_capital+df_metrics_data[’total_tangible_assets’])100,’-’,label=‘RoC’) ax1.plot(df_metrics_data[‘FY’],nop/(df_dcf_data[‘shares_outstanding’]fy_avg_close)100, ‘-+’,label=‘earnings yield’)

’’’ ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘shareholder_equity’]100, ‘-+’,label=‘RoE’) ax1.plot(df_metrics_data[‘FY’],df_metrics_data[‘net_income’]/df_metrics_data[‘total_assets’]100, ‘-’,label=’RoA’) ax1.plot(df_metrics_data[’FY’],df_metrics_data[’net_income’]/df_dcf_data[’revenue’]100,’-^‘,label=’Profit margin’) ’’’

ax1.tick_params(axis=‘y’) #ax1.set_ylim((0,14)) #ax1.legend() ax1.legend(bbox_to_anchor=(1.05, 1)) plt.grid()

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

plt.title(‘RoA and RoC’) plt.show()

Plot normalized data from consolidated statements

The following charts examine data from the consolidated financial statements and compare normalized trends over the evaluation period. The first chart plots normalized revenue along with normalized EPS, NOP and free cash flow. All values are normalized to the starting value in the series. Change relative to the normalized starting value can be seen over the evaluation period. Ideally the normalized parameters plotted should track revenue. Any large departures indicate an area of concern.

Normalized consolidated statement of income

The following chart shows normalized revenue plotted with normalized parameters from the consolidated statement of income.

\(\Large {\color {red} {\text {look at BMI and update normalized plots}}}\)

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

# set look back range, left_yr is the index into the date range
left_yr = -10

plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['revenue'][left_yr:]-df_dcf_data['revenue'].iloc[left_yr])/np.abs(df_dcf_data['revenue'].iloc[left_yr])*100,
    '^-',label='Revenue')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['eps'][left_yr:]-df_metrics_data['eps'].iloc[left_yr])/np.abs(df_metrics_data['eps'].iloc[left_yr])*100,
    '-.',label='EPS')
plt.plot(df_metrics_data['FY'][left_yr:],
    (nop[left_yr:]-nop[left_yr])/np.abs(nop[left_yr])*100,
    '-.',label='NOP')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['free_cash_flow'][left_yr:]-df_metrics_data['free_cash_flow'].iloc[left_yr])/np.abs(df_metrics_data['free_cash_flow'].iloc[left_yr])*100,
    '-.',label='Free cash flow')
# net income
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['net_income'][left_yr:]-df_metrics_data['net_income'].iloc[left_yr])/np.abs(df_metrics_data['net_income'].iloc[left_yr])*100,
    '-.',label='Net income')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()
# Changes x-axis range
plt.gca().set_xbound(year_ended_list[left_yr], year_ended_list[-1])

#plt.ylim((-100,500))
plt.title('Normalized income statement data')
plt.ylabel('percent change')
#plt.legend()
plt.legend(bbox_to_anchor=(1.6, 1))

plt.grid()

# space between the plots
#plt.tight_layout(4)

# show plot
plt.show()

Observation
It’s concerning that free cash flow and EPS do not trend with revenue.

Normalized income statement 5 year look back

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

# set look back range, left_yr is the index into the date range
left_yr = -6

plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['revenue'][left_yr:]-df_dcf_data['revenue'].iloc[left_yr])/np.abs(df_dcf_data['revenue'].iloc[left_yr])*100,
    '^-',label='Revenue')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['eps'][left_yr:]-df_metrics_data['eps'].iloc[left_yr])/np.abs(df_metrics_data['eps'].iloc[left_yr])*100,
    '-.',label='EPS')
plt.plot(df_metrics_data['FY'][left_yr:],
    (nop[left_yr:]-nop[left_yr])/np.abs(nop[left_yr])*100,
    '-.',label='NOP')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['free_cash_flow'][left_yr:]-df_metrics_data['free_cash_flow'].iloc[left_yr])/np.abs(df_metrics_data['free_cash_flow'].iloc[left_yr])*100,
    '-.',label='Free cash flow')
# net income
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['net_income'][left_yr:]-df_metrics_data['net_income'].iloc[left_yr])/np.abs(df_metrics_data['net_income'].iloc[left_yr])*100,
    '-.',label='Net income')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()
# Changes x-axis range
plt.gca().set_xbound(year_ended_list[left_yr], year_ended_list[-1])

#plt.ylim((-100,100))
plt.title('Normalized income statement data')
plt.ylabel('percent change')
#plt.legend()
plt.legend(bbox_to_anchor=(1.6, 1))

plt.grid()

# space between the plots
#plt.tight_layout(4)

# show plot
plt.show()

Observation
This chart doesn’t provide any useful information, since changes in net income swamp the other parameters. Net income doesn’t trend with revenue over the last five years, neither does EPS.

Normalized consolidated balance sheet

The following chart shows normalized revenue plotted with normalized parameters from the consolidated balance sheet.

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

# set look back range, left_yr is the index into the date range
left_yr = -10

plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['revenue'][left_yr:]-df_dcf_data['revenue'].iloc[left_yr])/np.abs(df_dcf_data['revenue'].iloc[left_yr])*100,
    '^-',label='Revenue')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_liabilities'][left_yr:]-df_metrics_data['total_liabilities'].iloc[left_yr])/np.abs(df_metrics_data['total_liabilities'].iloc[left_yr])*100,
    '-.',label='Total liabilities')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_assets'][left_yr:]-df_metrics_data['total_assets'].iloc[left_yr])/np.abs(df_metrics_data['total_assets'].iloc[left_yr])*100,
    '-.',label='Total assets')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_tangible_assets'][left_yr:]-df_metrics_data['total_tangible_assets'].iloc[left_yr])/np.abs(df_metrics_data['total_tangible_assets'].iloc[left_yr])*100,
    '-.',label='Total tangible assets')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['long_term_debt'][left_yr:]-df_dcf_data['long_term_debt'].iloc[left_yr])/np.abs(df_dcf_data['long_term_debt'].iloc[left_yr])*100,
    '-.',label='Long term debt')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['current_liabilities'][left_yr:]-df_dcf_data['current_liabilities'].iloc[left_yr])/np.abs(df_dcf_data['current_liabilities'].iloc[left_yr])*100,
    '-.',label='Current liabilities')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['depreciation'][left_yr:]-df_dcf_data['depreciation'].iloc[left_yr])/np.abs(df_dcf_data['depreciation'].iloc[left_yr])*100,
    '-.',label='Depreciation & amortization')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()
# Changes x-axis range
plt.gca().set_xbound(year_ended_list[left_yr], year_ended_list[-1])

#plt.ylim((0,4))
plt.title('Normalized balance statement data')
plt.ylabel('percent change')
#plt.legend()
plt.legend(bbox_to_anchor=(1.6, 1))

plt.grid()

# show plot
plt.show()

Observation
Many balance sheet parameters do not trend with revenue.

Normalized balance statement 5 year look back

# Set the locator
locator = mdates.YearLocator()  # every year
fmt = mdates.DateFormatter('%Y')

# set look back range, left_yr is the index into the date range
left_yr = -6

plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['revenue'][left_yr:]-df_dcf_data['revenue'].iloc[left_yr])/np.abs(df_dcf_data['revenue'].iloc[left_yr])*100,
    '^-',label='Revenue')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_liabilities'][left_yr:]-df_metrics_data['total_liabilities'].iloc[left_yr])/np.abs(df_metrics_data['total_liabilities'].iloc[left_yr])*100,
    '-.',label='Total liabilities')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_assets'][left_yr:]-df_metrics_data['total_assets'].iloc[left_yr])/np.abs(df_metrics_data['total_assets'].iloc[left_yr])*100,
    '-.',label='Total assets')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_metrics_data['total_tangible_assets'][left_yr:]-df_metrics_data['total_tangible_assets'].iloc[left_yr])/np.abs(df_metrics_data['total_tangible_assets'].iloc[left_yr])*100,
    '-.',label='Total tangible assets')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['long_term_debt'][left_yr:]-df_dcf_data['long_term_debt'].iloc[left_yr])/np.abs(df_dcf_data['long_term_debt'].iloc[left_yr])*100,
    '-.',label='Long term debt')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['current_liabilities'][left_yr:]-df_dcf_data['current_liabilities'].iloc[left_yr])/np.abs(df_dcf_data['current_liabilities'].iloc[left_yr])*100,
    '-.',label='Current liabilities')
plt.plot(df_metrics_data['FY'][left_yr:],
    (df_dcf_data['depreciation'][left_yr:]-df_dcf_data['depreciation'].iloc[left_yr])/np.abs(df_dcf_data['depreciation'].iloc[left_yr])*100,
    '-.',label='Depreciation & amortization')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()
# Changes x-axis range
plt.gca().set_xbound(year_ended_list[left_yr], year_ended_list[-1])

#plt.ylim((0,4))
plt.title('Normalized balance statement data')
plt.ylabel('Percent change')
#plt.legend()
plt.legend(bbox_to_anchor=(1.6, 1))

plt.grid()

# space between the plots
#plt.tight_layout(4)

# show plot
plt.show()

Observation
The plots of relative change of financial statement data versus revenue show that many parameters do not trend with revenue. Trying to figure out why is probably more work than it’s worth, so we will just conclude that the lack of correlation is another reason to avoid this stock.

Market metrics

The share price is determined by the market. The value is determined by the analyst.

One dollar premise

This is a financial test that shows the strength of the business and how well management has rationality allocated to the company’s business.

From a company’s income, subtract all dividends paid to shareholders. What is left over is the company’s retained earnings. Now add the company’s retained earnings over a 10 year period. Next determine the difference between the company’s current market value and its market value 10 years ago. If the business has employed retained earnings unproductively over this ten year period, the market eventually catches up and will set a lower price on the business.

retained_earnings = df_metrics_data['net_income'].sum() - df_metrics_data['dividends'].sum()
print('retained earnings: ${:,.2f}B'.format(retained_earnings/1e9))
retained earnings: $1.69B

Retained earnings are \$1.7B

# Current market value, share price multiplied by number of shares
cmv_high = df_dcf_data['shares_outstanding'].iloc[-1]*fy_high[-1]
cmv_low = df_dcf_data['shares_outstanding'].iloc[-1]*fy_low[-1]
print('Current market value: ${:,.2f}B to ${:,.2f}B'.format(cmv_low/1e9,cmv_high/1e9))
Current market value: $2.04B to $6.06B
# Past market value, share price multiplied by number of shares
pmv_high = df_dcf_data['shares_outstanding'].iloc[0]*fy_high[0]
pmv_low = df_dcf_data['shares_outstanding'].iloc[0]*fy_low[0]
print('Past market value: ${:,.0f}B to ${:,.0f}B'.format(pmv_low/1e9,pmv_high/1e9))
Past market value: $2B to $3B
print('Difference in market value: ${:,.0f}B to ${:,.0f}B'.format((cmv_low-pmv_low)/1e9,(cmv_high-pmv_high)/1e9))
Difference in market value: $-0B to $3B
print('Average difference in market value: ${:,.2f}B'.format(((cmv_low-pmv_low)+(cmv_high-pmv_high))/2/1e9))
Average difference in market value: $1.53B

The difference in market value compared to what it was at the beginning of the evaluation period ranges from \$0 to \$3B. So the HBI was able to take \$1.7B in retained earnings and generate \$0 to \$3B market value. Depending on the time frame, HBI fails the one dollar premise.

Share price vs EPS

Looking at the one dollar premise in terms of share price and EPS.

The one dollar premise: one dollar of earning should translate into one dollar of market value - this seems the same as a plot of EPS versus share price.

# plotting the eps data points
ax = plt.bar(df_metrics_data['eps'],fy_high-fy_low,width = .05,bottom=fy_low)
plt.grid()
plt.ylim((0,40))
plt.ylabel('high and low share price range')
plt.xlabel('EPS')
plt.title('years from 2010 to 2021')

rects = ax.patches

# Make some labels.
labels = [year_ended_list[i].strftime("%Y") for i in range(len(year_ended_list))]
for rect, label in zip(rects, labels):
    y_top =  rect.get_y() + rect.get_height()
    plt.text(rect.get_x(), y_top+1, label, rotation=90,va='bottom')    

plt.show()

Observations:
The plot above shows the range of high and low stock prices for each year versus EPS for that year. There is no discernible correlation between stock price and EPS.

Market capitalization

Total value of common equity is calculated using the DCF model from scenario 1 inputs and it is a constant value for the year. The daily market capitalization is calculated from the formula:

\(\text{Market capitalization} = \text{(daily closing share price)} \times \text{(number of shares outstanding)}\)

Market capitalization refers to the total dollar market value of a company’s outstanding shares of stock. It measures the cost of buying all of a company’s shares. Comparing this value to the intrinsic value calculated from the DCF model shows whether the company can be purchased at a discount to its value.

#so = df_dcf_data[‘shares_outstanding’].iloc[-1] # shares outstanding print(‘shares outstanding, basic: {:,.0f}’.format(so))

get starting and ending dates for last calendar year in datetime format

start = year_ended_list[-2] end = start + relativedelta(years=2) p1 = df_price_history.truncate(before=start, after=end)

make an array

total_value_S1 = np.ones(len(p1))*tvce_S1 # the value is constant across all dates

add scenario 1 total value of common equity data to dataframe

#p1[‘total value avg’] = total_value_avg p1[‘total value S1’] = total_value_S1

start

end

year_ended_list

so

need to get the # of shares for each period, not just use the final share count

so = df_dcf_data[‘shares_outstanding’].iloc[-1] # shares outstanding print(‘shares outstanding, basic: {:,.0f}’.format(so))

df_dcf_data[‘shares_outstanding’]

Set the locator

locator = mdates.MonthLocator() # every month fmt = mdates.DateFormatter(‘%b-%Y’)

plt.plot(p1[‘Close’]so/1e9,label=‘Market capitalization’) plt.plot(p2[‘Close’]so/1e9,label=‘Market capitalization, current year’) #plt.plot(p1[‘total value base’]/1e9,label=‘total value of common equity, base’) plt.plot(p1[‘total value S1’]/1e9,label=‘Total value of common equity, scenario 1’) plt.plot(p1[‘total value S1’]/1e9/0.7,‘-.’,label=‘70% threshold decision model’)

X = plt.gca().xaxis X.set_major_locator(locator) # Specify formatter X.set_major_formatter(fmt) plt.gcf().autofmt_xdate()

#plt.ylim((2,8)) plt.title(‘Market Cap and total value of common equity’) plt.ylabel(‘dollars, $B’) plt.legend(bbox_to_anchor=(1.1, 1)) #plt.legend() plt.grid()

show plot

plt.show()

Plotting year of last 10K and current year stock prices

making changes to plot TVCE only for most recient 10K

print('shares outstanding, basic: {:,.0f}'.format(so))

# print total value of common equity for base case and scenario
print('total value of common equity, baseline case: ${:,.2f}B'.format(tvce_baseline/1e9))
print('total value of common equity, scenario 1: ${:,.2f}B'.format(tvce_S1/1e9))
shares outstanding, basic: 349,361,517
total value of common equity, baseline case: $2.67B
total value of common equity, scenario 1: $2.98B

Make a new data frame for price history covering year of 10K upto most recient date in saved price history. That is, last FY year and current year.

# get starting and ending dates for last calendar year in datetime format
start = year_ended_list[-1]
#end = start + relativedelta(years=2)
p1 = df_price_history.truncate(before=start)

Make a new data frame for price history covering only the time period of most recient 10K

end = start + relativedelta(years=1)
p2 = df_price_history.truncate(before=start,after=end)
# make an array 
total_value_S1 = np.ones(len(p2))*tvce_S1 # the value is constant across all dates

# add scenario 1 total value of common equity data to dataframe
p2['total value S1'] = total_value_S1
# Set the locator
locator = mdates.MonthLocator()  # every year
fmt = mdates.DateFormatter('%b-%Y')

plt.plot(p1['Close']*so/1e9,label='Market capitalization')
#plt.plot(p2['Close']*so/1e9,label='Market capitalization, current year')
#plt.plot(p1['total value base']/1e9,label='total value of common equity, base')
plt.plot(p2['total value S1']/1e9,label='Total value of common equity, scenario 1')
#plt.plot(p1['total value S1']/1e9/0.7,'-.',label='70% threshold decision model')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.ylim((1,6))
plt.title('Market Cap and total value of common equity')
plt.ylabel('dollars, $B')
plt.legend(bbox_to_anchor=(1.1, 1))
#plt.legend()
plt.grid()

# show plot
plt.show()

Need a write up for this graph.

#so = df_dcf_data['shares_outstanding'].iloc[-1] # shares outstanding
print('shares outstanding, basic: {:,.0f}'.format(so))

# get starting and ending dates for last calendar year in datetime format
start = year_ended_list[-1]
#end = start + relativedelta(years=2)
p1 = df_price_history.truncate(before=start)

# print total value of common equity for base case and scenario
print('total value of common equity, baseline case: ${:,.2f}B'.format(tvce_baseline/1e9))
print('total value of common equity, scenario 1: ${:,.2f}B'.format(tvce_S1/1e9))
#print('average value of common equity (base & scenario): ${:,.2f}B'.format((tvce_S1+tvce_base)/2/1e9))

# make an array 
total_value_S1 = np.ones(len(p1))*tvce_S1 # the value is constant across all dates

# add scenario 1 total value of common equity data to dataframe
#p1['total value avg'] = total_value_avg
p1['total value S1'] = total_value_S1
shares outstanding, basic: 349,361,517
total value of common equity, baseline case: $2.67B
total value of common equity, scenario 1: $2.98B
p1['Close']
datetime
2022-01-03    16.920000
2022-01-04    17.360001
2022-01-05    16.940001
2022-01-06    17.030001
2022-01-07    16.860001
                ...    
2023-03-06     5.610000
2023-03-07     5.480000
2023-03-08     5.490000
2023-03-09     5.350000
2023-03-10     5.100000
Name: Close, Length: 298, dtype: float64
p1
Date Open High Low Close Adj Close Volume total value S1
datetime
2022-01-03 2022-01-03 16.879999 16.990000 16.770000 16.920000 15.939794 3148900 2.980053e+09
2022-01-04 2022-01-04 17.139999 17.490000 17.080000 17.360001 16.354307 3454900 2.980053e+09
2022-01-05 2022-01-05 17.400000 17.549999 16.930000 16.940001 15.958636 3945900 2.980053e+09
2022-01-06 2022-01-06 17.080000 17.240000 16.850000 17.030001 16.043425 3738800 2.980053e+09
2022-01-07 2022-01-07 16.809999 17.010000 16.549999 16.860001 15.883271 3743100 2.980053e+09
... ... ... ... ... ... ... ... ...
2023-03-06 2023-03-06 5.900000 5.960000 5.600000 5.610000 5.610000 16682300 2.980053e+09
2023-03-07 2023-03-07 5.620000 5.700000 5.430000 5.480000 5.480000 10891900 2.980053e+09
2023-03-08 2023-03-08 5.490000 5.570000 5.430000 5.490000 5.490000 9305200 2.980053e+09
2023-03-09 2023-03-09 5.480000 5.620000 5.340000 5.350000 5.350000 11794000 2.980053e+09
2023-03-10 2023-03-10 5.310000 5.350000 5.070000 5.100000 5.100000 13896500 2.980053e+09

298 rows × 8 columns

end = start + relativedelta(years=1)
p2 = df_price_history.truncate(before=start,after=end)
p2
Date Open High Low Close Adj Close Volume
datetime
2022-01-03 2022-01-03 16.879999 16.990000 16.770000 16.920000 15.939794 3148900
2022-01-04 2022-01-04 17.139999 17.490000 17.080000 17.360001 16.354307 3454900
2022-01-05 2022-01-05 17.400000 17.549999 16.930000 16.940001 15.958636 3945900
2022-01-06 2022-01-06 17.080000 17.240000 16.850000 17.030001 16.043425 3738800
2022-01-07 2022-01-07 16.809999 17.010000 16.549999 16.860001 15.883271 3743100
... ... ... ... ... ... ... ...
2022-12-23 2022-12-23 5.920000 6.110000 5.860000 6.100000 6.100000 8091400
2022-12-27 2022-12-27 6.080000 6.330000 6.050000 6.230000 6.230000 8530700
2022-12-28 2022-12-28 6.240000 6.280000 5.990000 6.060000 6.060000 7358500
2022-12-29 2022-12-29 6.140000 6.340000 6.130000 6.260000 6.260000 7770400
2022-12-30 2022-12-30 6.170000 6.400000 6.160000 6.360000 6.360000 7638300

251 rows × 7 columns

p2['Close']
datetime
2022-01-03    16.920000
2022-01-04    17.360001
2022-01-05    16.940001
2022-01-06    17.030001
2022-01-07    16.860001
                ...    
2022-12-23     6.100000
2022-12-27     6.230000
2022-12-28     6.060000
2022-12-29     6.260000
2022-12-30     6.360000
Name: Close, Length: 251, dtype: float64
p1['total value S1']
datetime
2022-01-03    2.980053e+09
2022-01-04    2.980053e+09
2022-01-05    2.980053e+09
2022-01-06    2.980053e+09
2022-01-07    2.980053e+09
                  ...     
2023-03-06    2.980053e+09
2023-03-07    2.980053e+09
2023-03-08    2.980053e+09
2023-03-09    2.980053e+09
2023-03-10    2.980053e+09
Name: total value S1, Length: 298, dtype: float64
# Set the locator
locator = mdates.MonthLocator()  # every year
fmt = mdates.DateFormatter('%b-%Y')

plt.plot(p1['Close']*so/1e9,label='Market capitalization')
#plt.plot(p2['Close']*so/1e9,label='Market capitalization, current year')
#plt.plot(p1['total value base']/1e9,label='total value of common equity, base')
plt.plot(p1['total value S1']/1e9,label='Total value of common equity, scenario 1')
plt.plot(p1['total value S1']/1e9/0.7,'-.',label='70% threshold decision model')

X = plt.gca().xaxis
X.set_major_locator(locator)
# Specify formatter
X.set_major_formatter(fmt)
plt.gcf().autofmt_xdate()

plt.ylim((1,6))
plt.title('Market Cap and total value of common equity')
plt.ylabel('dollars, $B')
plt.legend(bbox_to_anchor=(1.1, 1))
#plt.legend()
plt.grid()

# show plot
plt.show()

As shown in the plot above, the market capitalization of HBI has steadily fallen over the past year, to the point where the market capitalization is less than the total value of common equity as calculated by DCF model scenario 1. By some measures, HBI is a value stock. Since the stock was purchased as a dividend paying stock, it doesn’t make sense to continue to hold the stock.

so

csp

so*csp/1e9

print(‘Current market capitalization: ${:.2f}B’.format(so*csp/1e9))

df_price_history

year_ended_list[-1]

p2 = df_price_history.truncate(before=year_ended_list[-1])

p2

#column names: fiscal years years_list = df_metrics_sheet.columns[1:].values.astype(‘str’)[::-1]

convert years to datetime format

year_ended_list = [] for i in years_list: year_ended_list.append(datetime.strptime(i, ‘%Y’))

make empty lists to store open, close, average close, high and low price data for each fiscal year

fy_open = [] fy_close = [] fy_avg_close = [] fy_high = [] fy_low = []

for i in year_ended_list: start = i end = i + relativedelta(years=1) p1 = df_price_history.truncate(before=start, after=end) if len(p1) == 0: fy_open.append(np.nan) fy_close.append(np.nan) fy_avg_close.append(np.nan) fy_high.append(np.nan) fy_low.append(np.nan) else: fy_open.append(p1[‘Open’].iloc[0]) fy_close.append(p1[‘Close’].iloc[-1]) fy_avg_close.append(p1[‘Close’].mean()) # could aslo use median fy_high.append(p1[‘Close’].max()) fy_low.append(p1[‘Close’].min())

convert from list to numpy array

fy_open = np.asarray(fy_open) fy_close = np.asarray(fy_close) fy_avg_close = np.asarray(fy_avg_close) fy_high = np.asarray(fy_high) fy_low = np.asarray(fy_low)

Qualitative metrics

Beyond the numbers in the financial statements, there are metrics that are qualitative in nature that are important to the investor. These are subjective measures of business and management operations that influence value. In this section a few qualitative metrics are discussed below.

\(\Large {\color {red} {\text {This section needs an update, remove BMI narrative}}}\)

  • Simple and understandable business model
    BMY is a pharmaceutical company that manufactures drugs in several therapeutic areas. Although the science is not simple, the business framework of R&D, patent protection, manufacturing and distribution is typical of other manufacturing firms operating in the technology sector.

  • Favorable long term prospects
    The company has a long history and the recent trends are favorable, except for the acquisition in 2019, which upset the trends.

  • Commodity reliance
    By commodity is meant a product or service that is easily reproducible by a competitor. Pharmaceuticals are the result of R&D and protected by patents. The barrier to entry is high for Pharmaceutical companies.

  • Consistent operating history
    The trends for RoE, RoA and profit margin have been plotted above. The effect of the acquisition of Celgene has caused these ratios to go negative in 2020. From 2016 to 2019, these ratios had wide variation year to year, with 2017 showing a decline followed by a large increase the following year. Normally steady performance is better than the erratic variation shown here. (LT debt)/Equity and (total liabilities)/Equity have been steady and below 2. (total liabilities)/NOP have been erratic over the evaluation period.

  • Rationality
    Do comments and discussion made by the management in the annual reports reflect an optimal level of benefit or utility to the company over the long term?

    1. Focus on core aspects
      The company operates in one segment engaged in the discovery, development, licensing, manufacturing, marketing, distribution and sale of biopharmaceutical products on a global basis.
    2. Only invest in high ROE businesses
      The principal strategy is to combine the resources, scale and capability of a pharmaceutical company with the speed and focus on innovation of the biotech industry. The acquisitions of Celgene in 2019 and MyoKardia in 2020 will further position us as a leading biopharmaceutical company, expanding our oncology, hematology, immunology and cardiovascular portfolios with several near-term assets and additional external partnerships.
    3. Focus on shareholder equity
      Adding value to the company The priorities are to continue to renew and diversify our portfolio through launching our new product portfolio, advancing our early, mid and late-stage pipeline, and executing disciplined business development. They remain committed to reducing our debt and returning capital to shareholders.

Back to Contents

9) Decision model

The decision model establishes thresholds that are to used in the purchase decision. There are three hard decision thresholds in this model which are:
1. Intrinic value
2. Debt
3. Dividend payout ratio
4. Dividend IIR
5. NACI managemet evaluation
6. One dollar premise

\(\Large {\color {red} {\text {update template}}}\)

The first threshold is based on the intrinisic value of the company as calculated by the DCF model semario 1. Reconizing that absolute intrinsic value is an elusive concept, judgement, justified by facts (assets, earnings, dividends, debt and cash flow), establishes the value by adjusting various rates, based on judgement and using a five year forward projection period. This should give a intrinsic value that is based on the historical data, modified by judgement.

I’m using a threshold of the intrinsic value calculated in senario 1 (isv_S1) that is greater than 70% of the current stock price, provided that the NAIC valuation is above the current stock price. This accounts for the inadequacy or incorrectness of the data, the uncertainties of the future, and considers the behavior of the market.

The second threshold is the level of debt. The ratios of (LT debt)/Equity, (total liabilities)/Equity and (total liabilities)/NOP are ploted for the evaluation period. Over the evaluation period the (LT debt)/Equity and (total liabilities)/Equity should be less than 2 and stable. A threshold of 2 has been discussed in the litureture as a level of debt that a company can reasonably take on.

The thereshold for (total liabilities)/NOP is set at 10. This means that the company can pay off all the liabilities with tens years worth of NOP, which seems like a reasonable timeframe for an established and stable company.

The third threshold is the dividend payout ratio and is a relative measure of how much the company is paying to shareholders in dividends compared to the metrics of NOP and free cash flow (Net cash provided by operating activities). The payout ratio is useful for assessing a dividend’s sustainability. Payout ratio for a REIT is established by tax law and not used as an evaluation criteria. For other industries a threshold of 50% has been set as the limit.

The dividend IRR threshold is the internal rate of return for investor dividend cash flow (divident_irr) should be greater than 10 year treasury bond yield (tby) plus the equity risk premium (eq_rp). Otherwise, other investment operatunities should be looked at.

In the decision model there are soft thresholds based on judgement. Soft thresholds are a collection of ratios and analysis that taken together tell a story of the performance of the conmpany and manatgments ability to run the company and support dividends over the long term. Use judgement and make an evalaution.

The third critiera is a collection of ratios and analysis that taken together tell a story of the performance of the conmpany and manatgments ability to run the company and support dividends over the long term. Use judgement and make an evalaution. These are the following:
1. Financial metrics
2. Market metrics
3. Qualitative metrics

The soft thresholds are discused in section 10.

Check DCF and NAIC value thresholds

# check DCF senario 1
dcf_score = isv_S1/csp #ratio of isv to csp
dcf_threshold = 0.7
if dcf_score < 0.7:
    print('FAIL, DCF score is less than {:.1f} at {:.1f}'.format(dcf_threshold,dcf_score))
else:
    print('PASS, DCF score is above {:.1f} at {:.1f}'.format(dcf_threshold,dcf_score))

# check NAIC
naic_score = np.array([naic_price_eps_low,naic_price_pm_low]).min()/csp
naic_threshold = 1
if naic_score < 1:
    print('FAIL, NAIC score is less than {:.1f} at {:.1f}'.format(naic_threshold,naic_score))
else:
    print('PASS, NAIC score is above {:.1f} at {:.1f}'.format(naic_threshold,naic_score))

# check both scores
if naic_score < 1 or dcf_score < 0.7:
    print('One or both DCF and NAIC scores failed')
else:
    print('Both DCF and NAIC scores pass')
PASS, DCF score is above 0.7 at 1.9
FAIL, NAIC score is less than 1.0 at 0.9
One or both DCF and NAIC scores failed

Check debt thresholds

debt_lookback = 4
avg_LT_debt2EQ = df_dcf_data['long_term_debt'][-debt_lookback:].mean()/df_metrics_data['shareholder_equity'][-debt_lookback:].mean()
avg_TLiability2EQ = df_metrics_data['total_liabilities'][-debt_lookback:].mean()/df_metrics_data['shareholder_equity'][-debt_lookback:].mean()
avg_TLiability2NOP = df_metrics_data['total_liabilities'][-debt_lookback:].mean()/nop[-debt_lookback:].mean()

print('long term debt to shareholder equity ratio = {:.2f}'.format(avg_LT_debt2EQ))
print('total liabilities to shareholder equity ratio = {:.2f}'.format(avg_TLiability2EQ))
print('total liabilities to NOP ratio = {:.2f}'.format(avg_TLiability2NOP))

if (avg_LT_debt2EQ > 2) or (avg_TLiability2EQ > 2) or (avg_TLiability2NOP > 10):
    print('FAILED one of the debt threshold limits')
long term debt to shareholder equity ratio = 4.42
total liabilities to shareholder equity ratio = 8.08
total liabilities to NOP ratio = 11.51
FAILED one of the debt threshold limits

Check dividend payout and IIR thresholds

\(\Large {\color {red} {\text {update comments about IIR}}}\)

# check dividend payout ratio average the last three years
print('Dividends are paid at {:.1f}% of cash flow'.format(
    (df_metrics_data['dividends']/df_metrics_data['free_cash_flow'])[-3:].mean()*100))
print('Dividends are paid at {:.1f}% of NOP'.format((df_metrics_data['dividends']/nop)[-3:].mean()*100))

if ((df_metrics_data['dividends']/nop)[-3:].mean() or (df_metrics_data['dividends']/df_metrics_data['free_cash_flow'])[-3:].mean()) > 0.5:
    print('FAIL, dividend payout ration too high')
Dividends are paid at 7.4% of cash flow
Dividends are paid at 1100.9% of NOP
FAIL, dividend payout ration too high
# Check dividend IRR limit
if dividend_irr < (tby+eq_rp):
    print('FAIL, dividend IRR is less than {:.2f} at {:.2f}'.format((tby+eq_rp)*100,dividend_irr*100))
else:
    print('PASS, dividend IRR is above {:.2f} at {:.2f}'.format((tby+eq_rp)*100,dividend_irr*100))
FAIL, dividend IRR is less than 6.48 at 4.41
# check DCF senario 1
dcf_score = isv_S1/csp #ratio of isv to csp
dcf_threshold = 0.7
if dcf_score < 0.7:
    print('FAIL, DCF score is less than {:.1f} at {:.1f}'.format(dcf_threshold,dcf_score))
else:
    print('PASS, DCF score is above {:.1f} at {:.1f}'.format(dcf_threshold,dcf_score))

# check NAIC
naic_score = np.array([naic_price_eps_low,naic_price_pm_low]).min()/csp
naic_threshold = 1
if naic_score < 1:
    print('FAIL, NAIC score is less than {:.1f} at {:.1f}'.format(naic_threshold,naic_score))
else:
    print('PASS, NAIC score is above {:.1f} at {:.1f}'.format(naic_threshold,naic_score))

# check both scores
if naic_score < 1 or dcf_score < 0.7:
    print('One or both DCF and NAIC scores failed')
else:
    print('Both DCF and NAIC scores pass')
PASS, DCF score is above 0.7 at 1.9
FAIL, NAIC score is less than 1.0 at 0.9
One or both DCF and NAIC scores failed

comments:

  1. NACI managemet evaluation
# check profit margin trends
if pm_trend < 0:
    print('FAIL, profit margin trend over the evaluation period is negative at {:.1f}%'.format(pm_trend*100))
else:
    print('PASS, profit margin trend over the evaluation period is positive at {:.1f}%'.format(pm_trend*100))

if pm1_trend < 0:
    print('FAIL, profit margin trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,pm1_trend*100))
else:
    print('PASS, profit margin trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,pm1_trend*100))    
FAIL, profit margin trend over the evaluation period is negative at -0.5%
FAIL, profit margin trend over the last 6 years is negative at -1.3%

Checking trends based on EPS and NOP.

# check yield trend based on EPS
if pm_trend < 0:
    print('FAIL, EPS yield trend over the evaluation period is negative at {:.1f}%'.format(y1_trend*100))
else:
    print('PASS, EPS yield trend over the evaluation period is positive at {:.1f}%'.format(y1_trend*100))

if pm1_trend < 0:
    print('FAIL, EPS yield trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,y1a_trend*100))
else:
    print('PASS, EPS yield trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,y1a_trend*100))    
FAIL, EPS yield trend over the evaluation period is negative at -0.7%
FAIL, EPS yield trend over the last 6 years is negative at -1.5%
# check yield trend based on NOP
if pm_trend < 0:
    print('FAIL, NOP yield trend over the evaluation period is negative at {:.1f}%'.format(y2_trend*100))
else:
    print('PASS, NOP yield trend over the evaluation period is positive at {:.1f}%'.format(y2_trend*100))

if pm1_trend < 0:
    print('FAIL, NOP yield trend over the last {:.0f} years is negative at {:.1f}%'.format(-left_yr,y2a_trend*100))
else:
    print('PASS, NOP yield trend over the last {:.0f} years is positive at {:.1f}%'.format(-left_yr,y2a_trend*100))    
FAIL, NOP yield trend over the evaluation period is negative at -0.3%
FAIL, NOP yield trend over the last 6 years is negative at -0.2%
  1. One dollar premise

retained_earnings = df_metrics_data[‘net_income’].sum() - df_metrics_data[‘dividends’].sum()

print(‘retained earnings: ${:,.2f}B’.format(retained_earnings/1e9))

retained earnings: $1.69B

Retained earnings are $1.7B

Current market value, share price multiplied by number of shares

cmv_high = df_dcf_data[‘shares_outstanding’].iloc[-1]*fy_high[-1]

cmv_low = df_dcf_data[‘shares_outstanding’].iloc[-1]*fy_low[-1]

print(‘Current market value: ${:,.2f}B to ${:,.2f}B’.format(cmv_low/1e9,cmv_high/1e9))

Current market value: $2.04B to $6.06B

Past market value, share price multiplied by number of shares

pmv_high = df_dcf_data[‘shares_outstanding’].iloc[0]*fy_high[0]

pmv_low = df_dcf_data[‘shares_outstanding’].iloc[0]*fy_low[0]

print(‘Past market value: ${:,.0f}B to ${:,.0f}B’.format(pmv_low/1e9,pmv_high/1e9))

Past market value: $2B to $3B

print(‘Difference in market value: ${:,.0f}B to ${:,.0f}B’.format((cmv_low-pmv_low)/1e9,(cmv_high-pmv_high)/1e9))

Difference in market value: $-0B to $3B

print('retained earnings: ${:,.2f}B'.format(retained_earnings/1e9))
print('Difference in market value: ${:,.1f}B to ${:,.1f}B'.format((cmv_low-pmv_low)/1e9,(cmv_high-pmv_high)/1e9))
retained earnings: $1.69B
Difference in market value: $-0.0B to $3.1B
print('Average difference in market value: ${:,.2f}B'.format(((cmv_low-pmv_low)+(cmv_high-pmv_high))/2/1e9))
Average difference in market value: $1.53B
if (cmv_low-pmv_low) < 0:
    print('FAIL: current market value is less than past market value')   
FAIL: current market value is less than past market value
np.abs(cmv_low-pmv_low)
44534972.47000027
cmv_high-pmv_high
3100777844.231517
if retained_earnings < ((cmv_low-pmv_low)+(cmv_high-pmv_high))/2:
    print('FAIL: one dollar premise')
else:
    print('PASS: one dollar premise')    
PASS: one dollar premise

10) Conclusion

The following is a summary of the results described above:

  • Stock screener results: This company was selected from the Fidelity stock screener results. The company had increasing revenues and a dividend yield above 2.38%.
  • Current news: A few new articles were noted, nothing of significance found.
  • Review quarterly results: Not applicable since 10K was just released.
  • Average daily volume: Above 1M per day.
  • Dividend yield: Above 3%.
  • Discounted cash flow analysis, baseline: The baseline DCF analysis yielded a very high ISV, driven primarily by revenue growth rate and low WACC. The baseline ISV doesn’t seem realistic.
  • DCF Scenarios: Adjustments were made and the ISV is now below the current price.
  • NACI stock selection guide analysis: Share price has been trading in the 50 to 70 dollar range the last 7 years, indicating that the market is not impressed with the company. Average EPS (ignoring 2020) has been flat. Based on EPS growth, the estimated price range in 5 years is \$8.99 to \$12.19 per share. Based on NAIC’s preferred method, the estimated price range in 5 years is \$86.14 to \$116.85 per share.
  • Dividend payout: Dividend payout has been increasing over the years. The dividend yield for the past five years has been in the 2.5 to 3.5 percent range.
    Dividend pay ratios for the last 3 years are near or below 50%. Dividend cash flow IRR is 8.01%.
  • Management performance:
  • Financial metrics: The value assigned to goodwill and intangibles is about \$1 billion. The ratio indicates the company has taken on a lot of debt relative to assets and is something of concern. Various debt ratios seem OK. Except for 2020 performance ratios and trends are acceptable. The divergence of total liabilities from revenue is of concern.
  • Market metrics: The range in share price is roughly the same across the range of EPS. This means that investors are not valuing the company’s EPS. The company’s market capitalization is higher than the total value of common equity as calculated using scenario 1 DCF data. This implies that the company is overvalued.
  • Qualitative metrics: see above

Concerns: increasing total liabilities, low ISV, negative retained earnings, 60% of the total assets are intangible.

Summary: The analysis presented in this report is based on the company’s fundamentals and tries to establish the value of the company. This strategy is essentially value investing where companies are chosen that meet a set of criteria and who’s stock price is below the intrinsic value plus a margin of safety. These investments are usually held for the long term. Company revenue, earnings, debt and dividends were examined. Adjustments were made to the DCF and the ISV is below the current price. The share price has been trading in the 50 to 70 dollar range the last 7 years, indicating that the market is not impressed with the company. The dividend payout has been increasing over the years and the dividend cash flow IRR is 8.01%. The value assigned to goodwill and intangibles is about $1 billion. The ratio indicates the company has taken on a lot of debt relative to assets. The divergence of total liabilities from revenue is of concern. Negative retained earnings is a concern.

Recommendation: Don’t buy above $50 per share.

11) Notes

The following notes outline the changes to the DCF model for financial and REIT companies.

Valuing a REIT
Notes from Valuepro Book, page 237

  • NOPM: To calculate operating income take rental revenue and subtracted total real estate expenses and G&A expenses. To arrive at the NOPM divide the adjusted income from real estate by real estate rental revenue. For the REIT, take income from real estate, which includes depreciation and amortization, and subtract GSA. Exclude other income, gains on sale of real estate and interest expenses.
  • REIT has no traditional R&D costs

REIT is not taxed at the corporate level, tax rate: should be near zero.

Depreciation and capital expenditures are significantly higher for REITs than in other companies.

New property acquisitions are not directly accounted for in the DCF model for a REIT.

  • Working capitol: accounts payable, rents and security deposits
  • Short term assets: cash, rents and other receivables and prepaid expenses
  • Short term liabilities: accounts payable, advance rents security deposits

Working capital is almost zero, which is similar to other financial companies.

The consolidated balance sheet lists the assets as:
- Real estate held for investment, at cost:
- Land
- Buildings and improvements
- Total real estate held for investment, at cost
- Less accumulated depreciation and amortization
- Real estate held for investment, net
- Real estate and lease intangibles held for sale, net
- Cash and cash equivalents <- current asset
- Accounts receivable, net <- current asset
- Lease intangible assets, net
- Other assets, net

The line items indicated above have been taken to be the current assets. Intangibles and long term items have been excluded.

The consolidated balance sheet lists the liabilities as:
- Distributions payable <- current liabilities
- Accounts payable and accrued expenses <- current liabilities
- Lease intangible liabilities, net
- Other liabilities
- Line of credit payable and commercial paper <- current liabilities
- Term loans, net
- Mortgages payable, net <- current liabilities
- Notes payable, net

The line items indicated above have been taken to be the current liabilities.

Valuing a financial company
Notes from Valuepro Book, page 206

  • Total revenue comes from the total interest and dividend income line on the income statement. The calculation of operating income is more inclusive for a financial company than for an industrial or high tech company. For financial companies, operating revenue includes all normal revenue items plus interest income, dividends received and other investment income.

  • Cost of Goods Sold (CGS) comes from the Total interest expense line on the statement of income.

  • General and Administrative (G&A) are set to zero since they are included in the interest expense line

  • A financial company has no traditional R&D costs

  • \(\text{Cost of Goods Sold (CGS)} = \text{Total interest expense} + \text{Total non-interest expense}\)

  • General and Administrative (G&A) are set to zero since they are included in the interest expense line

  • A financial company has no traditional R&D costs

  • Depreciation and amortization of premises and equipment from Consolidated Statements of Cash Flows.

  • Amortization of other acquisition-related intangible assets is not included.

  • New investment and Depreciation: Property, plant and equipment expenditures and depreciation charges are significantly lower for a financial company. A typical manufacturing company, in order to grow its business, invests a significant portion of its revenues in plant, property and equipment (PPE). Financial companies invest very little in the way of PPE. However, software, risk management systems and acquisitions of other businesses, need to be included.

From the Consolidated Statements of Cash Flows, under Cash Flows from Investing Activities
- Purchases of premises and equipment
- Purchases of leased equipment, net

  • Working capital supports manufacturing and service activities of nonfinancial companies. For financial companies, their principal liabilities and assets are financial claims that take the place of working capital. Because there is no differentiation between current and long term assets and liabilities for a financial company, we adjust working capital charges to zero. A financial company generally invests all of its funds in other financial assets, which have characteristics of current assets rather than PP&E.
    \(\text{Accounts Receivable} = 0\)
    \(\text{Inventories} = 0\)
    \(\text{Accounts Payable} = 0\)
    \(\text{working capital} = 0\)

  • Short term assets: The balance sheets of most financial companies do not separate assets and liabilities into current and long term categories. When calculating the short term assets take the total assets and subtract goodwill and intangible assets also subtract other assets of questionable value. Subtract long term assets such as PP&E from total assets.

\(\text{Short term assets} = \text{Total assets} - \text{good will and others of questionable value} - \text{Premises and equipment}\)

  • A financial company’s principal liabilities are deposits, Federal funds purchased, trading account liabilities, insurance policy and claims reserves, contract holder funds and short term borrowing. To be consistent with the treatment of interest and an operating expense for financial companies, include long term debt in the short term liability category.
  • Short term liabilities: Include long term debt.

\(\text{Long term debt} = 0\)

Excess return period
The excess return period is based on a judgment call. The authors of [2] use the 1-5-7-10 rule. They group companies into one of four general categories and excess return periods. They use a 10 year excess return period to calculate what they would consider the maximum value. They use a more conservative 1 year, 5 year or 7 year return period to calculate a more reasonable or minimum value.
- 1 year: Boring companies that operate in a highly competitive, low margin industry in which they have nothing particular going for them.
- 5 year: Decent companies that have a recognizable name and decent reputation and perhaps a regulatory benefit (utility company), but can’t control pricing or growth.
- 7 year: Good companies with good brand names, large companies of scale, good marketing channels and consumer identification (e.g. McDonald’s)
- 10 year: Great companies with great growth potential, tremendous marketing power, band names and in-place benefits (e.g. Intel, Microsoft, Coca Cola, Disney)

Notes about negative working capital
The company has a negative working capital rate. Negative working capital describes a situation where a company’s current liabilities exceed its current assets as stated on the firm’s balance sheet. In other words, there is more short-term debt than there are short-term assets.

Negative working capital most often arises when a business generates cash very quickly because it can sell products to its customers before it has to pay the bills to its vendors for the original goods or raw materials. In this way, the company is effectively using the vendor’s money to grow.

Dividend Aristocrat, Achiever & Champion
This company was selected for analysis because it is on the Dividend Aristocrat list and passes the quick look tests. This notebook will be used as a template when analyzing other companies.

  • Aristocrat: S&P 500 Dividend Aristocrats is designed to measure the performance of S&P 500 index constituents that have followed a policy of consistently increasing dividends every year for at least 25 consecutive years.
  • Achiever: The Broad Dividend Achievers Index. Eligible companies must be incorporated in the U.S. or its territories, trade on the NYSE, NASDAQ or AMEX, and have increased its annual regular dividend payments for the last 10 or more consecutive years.
  • https://dividendvaluebuilder.com/dividend-achievers-list/
  • https://www.marketbeat.com/dividends/achievers/
  • Champion: This list includes companies that had increased their dividend for at least 25 consecutive years, and includes additional companies that had paid higher dividends without having increased the payout in every calendar year.
  • https://dividendvaluebuilder.com/dividend-champions-list/
  • https://www.dividendgrowthinvestor.com/p/dividend-champions-list.html

12) References

  1. Gray, Gary, et al. Streetsmart Guide to Valuing a Stock: the Savvy Investors Key to Beating the Market. McGraw-Hill, 2004.
  2. O’Hara, Thomas E., and Ken Janke. Starting and Running a Profitable Investment Club: the Official Guide from the National Association of Investors Corporation. Times Business, 1998.
  3. Robert G. Hagstrom, The Warren Buffett Way, Wiley, 2013