Skip to content

Commit

Permalink
Merge pull request #255 from renatomello/fundamental_data
Browse files Browse the repository at this point in the history
Fundamental data
  • Loading branch information
PatrickAlphaC committed Sep 3, 2020
2 parents c1e76d8 + 03484a3 commit 62db439
Show file tree
Hide file tree
Showing 5 changed files with 1,006 additions and 2 deletions.
23 changes: 21 additions & 2 deletions alpha_vantage/alphavantage.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,11 @@ def _format_wrapper(self, *args, **kwargs):
self, *args, **kwargs)
if 'json' in self.output_format.lower() or 'pandas' \
in self.output_format.lower():
data = call_response[data_key]
if data_key is not None:
data = call_response[data_key]
else:
data = call_response


if meta_data_key is not None:
meta_data = call_response[meta_data_key]
Expand All @@ -232,7 +236,22 @@ def _format_wrapper(self, *args, **kwargs):
output_format = override.lower()
# Choose output format
if output_format == 'json':
return data, meta_data
if isinstance(data, list):
# If the call returns a list, then we will append them
# in the resulting data frame. If in the future
# alphavantage decides to do more with returning arrays
# this might become buggy. For now will do the trick.
if not data:
data_pandas = pandas.DataFrame()
else:
data_array = []
for val in data:
data_array.append([v for _, v in val.items()])
data_pandas = pandas.DataFrame(data_array, columns=[
k for k, _ in data[0].items()])
return data_pandas, meta_data
else:
return data, meta_data
elif output_format == 'pandas':
if isinstance(data, list):
# If the call returns a list, then we will append them
Expand Down
117 changes: 117 additions & 0 deletions alpha_vantage/fundamentaldata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from .alphavantage import AlphaVantage as av

from datetime import datetime
search_date = datetime.now().date().strftime('%Y-%m-%d')

class FundamentalData(av):

"""This class implements all the api calls to fundamental data
"""
def __init__(self, *args, **kwargs):
"""
Inherit AlphaVantage base class with its default arguments.
"""
super(FundamentalData, self).__init__(*args, **kwargs)
self._append_type = False
if self.output_format.lower() == 'csv':
raise ValueError("Output format {} is not compatible with the FundamentalData class".format(
self.output_format.lower()))

@av._output_format
@av._call_api_on_func
def get_company_overview(self, symbol):
"""
Returns the company information, financial ratios,
and other key metrics for the equity specified.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'OVERVIEW'
return _FUNCTION_KEY, None, None

@av._output_format
@av._call_api_on_func
def get_income_statement_annual(self, symbol):
"""
Returns the annual and quarterly income statements for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'INCOME_STATEMENT'
return _FUNCTION_KEY, 'annualReports', 'symbol'

@av._output_format
@av._call_api_on_func
def get_income_statement_quarterly(self, symbol):
"""
Returns the annual and quarterly income statements for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'INCOME_STATEMENT'
return _FUNCTION_KEY, 'quarterlyReports', 'symbol'

@av._output_format
@av._call_api_on_func
def get_balance_sheet_annual(self, symbol):
"""
Returns the annual and quarterly balance sheets for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'BALANCE_SHEET'
return _FUNCTION_KEY, 'annualReports', 'symbol'

@av._output_format
@av._call_api_on_func
def get_balance_sheet_quarterly(self, symbol):
"""
Returns the annual and quarterly balance sheets for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'BALANCE_SHEET'
return _FUNCTION_KEY, 'quarterlyReports', 'symbol'

@av._output_format
@av._call_api_on_func
def get_cash_flow_annual(self, symbol):
"""
Returns the annual and quarterly cash flows for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'CASH_FLOW'
return _FUNCTION_KEY, 'annualReports', 'symbol'

@av._output_format
@av._call_api_on_func
def get_cash_flow_quarterly(self, symbol):
"""
Returns the annual and quarterly cash flows for the company of interest.
Data is generally refreshed on the same day a company reports its latest
earnings and financials.
Keyword Arguments:
symbol: the symbol for the equity we want to get its data
"""
_FUNCTION_KEY = 'CASH_FLOW'
return _FUNCTION_KEY, 'quarterlyReports', 'symbol'
25 changes: 25 additions & 0 deletions test_alpha_vantage/test_alphavantage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ..alpha_vantage.techindicators import TechIndicators
from ..alpha_vantage.sectorperformance import SectorPerformances
from ..alpha_vantage.foreignexchange import ForeignExchange
from ..alpha_vantage.fundamentaldata import FundamentalData

from pandas import DataFrame as df, Timestamp

Expand Down Expand Up @@ -200,3 +201,27 @@ def test_foreign_exchange(self, mock_request):
from_currency='BTC', to_currency='CNY')
self.assertIsInstance(
data, dict, 'Result Data must be a dictionary')

@requests_mock.Mocker()
def test_fundamental_data(self, mock_request):
"""Test that api call returns a json file as requested
"""
fd = FundamentalData(key=TestAlphaVantage._API_KEY_TEST)
url = 'https://www.alphavantage.co/query?function=INCOME_STATEMENT&symbol=IBM&apikey=test'
path_file = self.get_file_from_url("mock_fundamental_data")
with open(path_file) as f:
mock_request.get(url, text=f.read())
data, _ = fd.get_income_statement_annual(symbol='IBM')
self.assertIsInstance(data, df, 'Result Data must be a pandas data frame')

@requests_mock.Mocker()
def test_company_overview(self, mock_request):
"""Test that api call returns a json file as requested
"""
fd = FundamentalData(key=TestAlphaVantage._API_KEY_TEST)
url = "https://www.alphavantage.co/query?function=OVERVIEW&symbol=IBM&apikey=test"
path_file = self.get_file_from_url("mock_company_overview")
with open(path_file) as f:
mock_request.get(url, text=f.read())
data, _ = fd.get_company_overview(symbol='IBM')
self.assertIsInstance(data, dict, 'Result Data must be a dictionary')
61 changes: 61 additions & 0 deletions test_alpha_vantage/test_data/mock_company_overview
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"Symbol": "IBM",
"AssetType": "Common Stock",
"Name": "International Business Machines Corporation",
"Description": "International Business Machines Corporation operates as an integrated solutions and services company worldwide. Its Cloud & Cognitive Software segment offers software for vertical and domain-specific solutions in health, financial services, and Internet of Things (IoT), weather, and security software and services application areas; and customer information control system and storage, and analytics and integration software solutions to support client mission critical on-premise workloads in banking, airline, and retail industries. It also offers middleware and data platform software, including Red Hat, which enables the operation of clients' hybrid multi-cloud environments; and Cloud Paks, WebSphere distributed, and analytics platform software, such as DB2 distributed, information integration, and enterprise content management, as well as IoT, Blockchain and AI/Watson platforms. The company's Global Business Services segment offers business consulting services; system integration, application management, maintenance, and support services for packaged software; finance, procurement, talent and engagement, and industry-specific business process outsourcing services; and IT infrastructure and platform services. Its Global Technology Services segment provides project, managed, outsourcing, and cloud-delivered services for enterprise IT infrastructure environments; and IT infrastructure support services. The company's Systems segment offers servers for businesses, cloud service providers, and scientific computing organizations; data storage products and solutions; and z/OS, an enterprise operating system, as well as Linux. Its Global Financing segment provides lease, installment payment, loan financing, short-term working capital financing, and remanufacturing and remarketing services. The company was formerly known as Computing-Tabulating-Recording Co. and changed its name to International Business Machines Corporation in 1924. The company was founded in 1911 and is headquartered in Armonk, New York.",
"Exchange": "NYSE",
"Currency": "USD",
"Country": "USA",
"Sector": "Technology",
"Industry": "Information Technology Services",
"Address": "One New Orchard Road, Armonk, NY, United States, 10504",
"FullTimeEmployees": "352600",
"FiscalYearEnd": "December",
"LatestQuarter": "2020-06-30",
"MarketCapitalization": "114234572800",
"EBITDA": "15576999936",
"PERatio": "14.1327",
"PEGRatio": "8.7525",
"BookValue": "23.076",
"DividendPerShare": "6.52",
"DividendYield": "0.0529",
"EPS": "8.811",
"RevenuePerShareTTM": "85.058",
"ProfitMargin": "0.1043",
"OperatingMarginTTM": "0.1185",
"ReturnOnAssetsTTM": "0.0362",
"ReturnOnEquityTTM": "0.4097",
"RevenueTTM": "75499003904",
"GrossProfitTTM": "36489000000",
"DilutedEPSTTM": "8.811",
"QuarterlyEarningsGrowthYOY": "-0.458",
"QuarterlyRevenueGrowthYOY": "-0.054",
"AnalystTargetPrice": "135.19",
"TrailingPE": "14.1327",
"ForwardPE": "11.2867",
"PriceToSalesRatioTTM": "1.4762",
"PriceToBookRatio": "5.4017",
"EVToRevenue": "2.2076",
"EVToEBITDA": "11.0349",
"Beta": "1.2071",
"52WeekHigh": "158.75",
"52WeekLow": "90.56",
"50DayMovingAverage": "124.9097",
"200DayMovingAverage": "122.2713",
"SharesOutstanding": "890579008",
"SharesFloat": "889189445",
"SharesShort": "21600483",
"SharesShortPriorMonth": "23242369",
"ShortRatio": "4.51",
"ShortPercentOutstanding": "0.02",
"ShortPercentFloat": "0.0243",
"PercentInsiders": "0.108",
"PercentInstitutions": "58.555",
"ForwardAnnualDividendRate": "6.52",
"ForwardAnnualDividendYield": "0.0529",
"PayoutRatio": "0.7358",
"DividendDate": "2020-09-10",
"ExDividendDate": "2020-08-07",
"LastSplitFactor": "2:1",
"LastSplitDate": "1999-05-27"
}

0 comments on commit 62db439

Please sign in to comment.