Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions isthisstockgood/Active/MSNMoney.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ def parse_annual_report_data(self, content):
return
self.total_debt = float(most_recent_statement.get('longTermDebt', 0))
self.shares_outstanding = float(most_recent_statement.get('sharesOutstanding', 0))

key_metrics = data.get('analysis', {}).get('keyMetrics', {})
self.last_year_net_income = key_metrics.get('latestIncome', '')


def parse_ratios_data(self, content):
Expand All @@ -108,6 +105,16 @@ def parse_ratios_data(self, content):

# Debt
self._parse_debt_to_equity(quarterly_data)

# Quarterly EPS for MOSP valuation
self.quarterly_eps = _extract_data_for_key(quarterly_data, "earningsPerShare")

# For Payback Time valuation:
# "EPS is calculated by dividing a company's net income
# by the total number of outstanding shares."
# - https://www.investopedia.com/terms/e/eps.asp
ttm_eps = sum(self.quarterly_eps[-4:])
self.last_year_net_income = ttm_eps * self.shares_outstanding

return True

Expand Down
1 change: 1 addition & 0 deletions isthisstockgood/CompanyInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class CompanyInfo:
revenue: float
revenue_growth_rates: [float]
eps: float
quarterly_eps: [float]
eps_growth_rates: [float]
debt_equity_ratio: float
last_year_net_income: float
Expand Down
18 changes: 10 additions & 8 deletions isthisstockgood/DataFetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ def fetchDataForTickerSymbol(ticker):
if not ticker:
return None

data_fetcher = DataFetcher()
data_fetcher.ticker_symbol = ticker
data_fetcher = DataFetcher(ticker)

# Make all network request asynchronously to build their portion of
# the json results.
Expand All @@ -59,9 +58,13 @@ def fetchDataForTickerSymbol(ticker):
yahoo_finance_analysis.five_year_growth_rate if yahoo_finance_analysis \
else zacks_analysis.five_year_growth_rate if zacks_analysis \
else 0
# TODO: Use TTM EPS instead of most recent year
margin_of_safety_price, sticker_price = \
_calculateMarginOfSafetyPrice(msn_money.equity_growth_rates[-1], msn_money.pe_low, msn_money.pe_high, msn_money.eps[-1], five_year_growth_rate)
margin_of_safety_price, sticker_price = _calculateMarginOfSafetyPrice(
msn_money.equity_growth_rates[-1],
msn_money.pe_low,
msn_money.pe_high,
sum(msn_money.quarterly_eps[-4:]),
five_year_growth_rate
)
payback_time = _calculatePaybackTime(msn_money.equity_growth_rates[-1], msn_money.last_year_net_income, msn_money.market_cap, five_year_growth_rate)
free_cash_flow_per_share = float(msn_money.free_cash_flow[-1])
computed_free_cash_flow = round(free_cash_flow_per_share * msn_money.shares_outstanding)
Expand Down Expand Up @@ -105,7 +108,6 @@ def _calculateMarginOfSafetyPrice(one_year_equity_growth_rate, pe_low, pe_high,
return margin_of_safety_price, sticker_price


# TODO: Figure out how to get TTM net income instead of previous year net income.
def _calculatePaybackTime(one_year_equity_growth_rate, last_year_net_income, market_cap, analyst_five_year_growth_rate):
if not one_year_equity_growth_rate or not last_year_net_income or not market_cap or not analyst_five_year_growth_rate:
return None
Expand All @@ -126,10 +128,10 @@ class DataFetcher():
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
]

def __init__(self,):
def __init__(self, ticker):
self.lock = Lock()
self.rpcs = []
self.ticker_symbol = ''
self.ticker_symbol = ticker
self.msn_money = None
self.yahoo_finance_analysis = None
self.zacks_analysis = None
Expand Down
6 changes: 2 additions & 4 deletions tests/test_DataSources.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ def test_future_growth_rate():
assert float(data.five_year_growth_rate) > 0.0

def get_msn_money_data(ticker):
data_fetcher = DataFetcher()
data_fetcher.ticker_symbol = ticker
data_fetcher = DataFetcher(ticker)

# Make all network request asynchronously to build their portion of
# the json results.
Expand All @@ -56,8 +55,7 @@ def get_msn_money_data(ticker):
return CompanyInfo(**vars(data_fetcher.msn_money))

def get_growth_rate(ticker):
data_fetcher = DataFetcher()
data_fetcher.ticker_symbol = ticker
data_fetcher = DataFetcher(ticker)

# Make all network request asynchronously to build their portion of
# the json results.
Expand Down