def _read_company_data_point(ticker: str, tag: str): """ Helper function that will read the Intrinio company API for the supplied ticker and return the value Returns ------- The numerical value of the datapoint """ # check the cache first cache_key = "%s-%s-%s-%s" % (INTRINIO_CACHE_PREFIX, "company_data_point_number", ticker, tag) api_response = cache.read(cache_key) if api_response is None: # else call the API directly try: api_response = COMPANY_API.get_company_data_point_number( ticker, tag) cache.write(cache_key, api_response) except ApiException as ae: raise DataError( "Error retrieving ('%s') -> '%s' from Intrinio Company API" % (ticker, tag), ae) except Exception as e: raise ValidationError( "Error parsing ('%s') -> '%s' from Intrinio Company API" % (ticker, tag), e) return api_response
def _get_company_historical_data(ticker: str, start_date: str, end_date: str, tag: str): """ Helper function that will read the Intrinio company API for the supplied date range Parameters ---------- ticker : str Ticker symbol. E.g. 'AAPL' start_date : str Start date of the metric formatted as YYYY-MM-DD end_date : str End date of the metric formatted as YYYY-MM-DD tag : the metric name to retrieve Raises ------- DataError in case of any error calling the intrio API ValidationError in case of an unknown exception Returns ------- The 'historical_data_dict' portion of the 'get_company_historical_data' [ {'date': datetime.date(2018, 9, 29), 'value': 265595000000.0}, {'date': datetime.date(2017, 9, 30), 'value': 229234000000.0} ] """ frequency = 'yearly' # check the cache first cache_key = "%s-%s-%s-%s-%s-%s-%s" % (INTRINIO_CACHE_PREFIX, "company_historical_data", ticker, start_date, end_date, frequency, tag) api_response = cache.read(cache_key) if api_response is None: # else call the API directly try: api_response = COMPANY_API.get_company_historical_data( ticker, tag, frequency=frequency, start_date=start_date, end_date=end_date) except ApiException as ae: raise DataError( "Error retrieving ('%s', %s - %s) -> '%s' from Intrinio Company API" % (ticker, start_date, end_date, tag), ae) except Exception as e: raise ValidationError( "Error parsing ('%s', %s - %s) -> '%s' from Intrinio Company API" % (ticker, start_date, end_date, tag), e) if len(api_response.historical_data) == 0: raise DataError( "No Data returned for ('%s', %s - %s) -> '%s' from Intrinio Company API" % (ticker, start_date, end_date, tag), None) else: # only write to cache if response has some valid data cache.write(cache_key, api_response) return api_response.historical_data_dict
def _read_historical_financial_statement(ticker: str, statement_name: str, year_from: int, year_to: int, tag_filter_list: list): """ This helper function will read standardized fiscal year end financials from the Intrinio fundamentals API for each year in the supplied range, and normalize the results into simpler user friendly dictionary, for example: { 'netcashfromcontinuingoperatingactivities': 77434000000.0, 'purchaseofplantpropertyandequipment': -13313000000 } results may also be filtered based on the tag_filter_list parameter, which may include just the tags that should be returned. Parameters ---------- ticker : str Ticker Symbol statement_name : str The name of the statement to read. year_from : int Start year of financial statement list year_to : int End year of the financial statement list tag_filter_list : list List of data tags used to filter results. The name of each tag must match an expected one from the Intrinio API. If "None", then all tags will be returned. Returns ------- A dictionary of tag=>value with the filtered results. For example: { 'netcashfromcontinuingoperatingactivities': 77434000000.0, 'purchaseofplantpropertyandequipment': -13313000000 } Note that the name of the tags are specific to the Intrinio API """ # return value hist_statements = {} ticker = ticker.upper() statement_type = 'FY' try: for i in range(year_from, year_to + 1): satement_name = ticker + "-" + \ statement_name + "-" + str(i) + "-" + statement_type cache_key = "%s-%s-%s-%s-%s-%d" % ( INTRINIO_CACHE_PREFIX, "statement", ticker, statement_name, statement_type, i) statement = cache.read(cache_key) if statement is None: statement = FUNDAMENTALS_API.get_fundamental_standardized_financials( satement_name) cache.write(cache_key, statement) hist_statements[i] = _transform_financial_stmt( statement.standardized_financials, tag_filter_list) except ApiException as ae: raise DataError( "Error retrieving ('%s', %d - %d) -> '%s' from Intrinio Fundamentals API" % (ticker, year_from, year_to, statement_name), ae) return hist_statements
def get_sma_indicator(ticker: str, start_date: datetime, end_date: datetime, period_days: int): ''' Returns a dictionary of SMA (simple moving average) indicators given a ticker symbol, a date range and the period. Currently only returns one page of 100 results Parameters ---------- ticker : str Ticker Symbol start_date : object The beginning price date as python date object end_date : object The end price date as python date object period_days: int The number of price days included in this average Returns ----------- a dictionary of date->price like this { "2020-05-29": 282.51779999999997, "2020-05-28": 281.09239999999994, "2020-05-27": 279.7845999999999, "2020-05-26": 278.26659999999987, "2020-05-22": 277.4913999999999, "2020-05-21": 276.07819999999987, "2020-05-20": 275.2497999999999 } ''' start_date_str = intrinio_util.date_to_string(start_date).replace( '-', '').replace('-', '') end_date_str = intrinio_util.date_to_string(end_date).replace('-', '').replace( '-', '') sma_dict = {} cache_key = "%s-%s-%s-%s-%d-%s" % (INTRINIO_CACHE_PREFIX, ticker, start_date_str, end_date_str, period_days, "tech-sma") api_response = cache.read(cache_key) if api_response is None: try: api_response = SECURITY_API.get_security_price_technicals_sma( ticker, period=period_days, price_key='close', start_date=start_date, end_date=end_date, page_size=100) cache.write(cache_key, api_response) except ApiException as ae: raise DataError( "API Error while reading SMA indicator from Intrinio Security API: ('%s', %s - %s (%d))" % (ticker, start_date_str, end_date_str, period_days), ae) except Exception as e: raise ValidationError( "Unknown Error while reading SMA indicator from Intrinio Security API: ('%s', %s - %s (%d))" % (ticker, start_date_str, end_date_str, period_days), e) sma_list = api_response.technicals if len(sma_list) == 0: raise DataError( "No SMA indicators returned from Intrinio Security API: ('%s', %s - %s (%d))" % (ticker, start_date_str, end_date_str, period_days), None) for sma in sma_list: sma_dict[intrinio_util.date_to_string(sma.date_time)] = sma.sma return sma_dict
def get_macd_indicator(ticker: str, start_date: datetime, end_date: datetime, fast_period: int, slow_period: int, signal_period: int): ''' Returns a dictionary of MACD indicators given a ticker symbol, a date range and necessary MACD parameters. Currently only returns one page of 100 results Parameters ---------- ticker : str Ticker Symbol start_date : object The beginning price date as python date object end_date : object The end price date as python date object fast_period: int the MACD fast period parameter slow_perdiod: int the MACD slow period parameter signal_period: the MACD signal period parameter Returns ----------- a dictionary of date->price like this { "2020-05-29": { "macd_histogram": -0.5565262759342229, "macd_line": 9.361568685377279, "signal_line": 9.918094961311501 }, "2020-05-28": { "macd_histogram": -0.3259226480613542, "macd_line": 9.731303882233703, "signal_line": 10.057226530295058 } } ''' start_date_str = intrinio_util.date_to_string(start_date).replace( '-', '').replace('-', '') end_date_str = intrinio_util.date_to_string(end_date).replace('-', '').replace( '-', '') macd_dict = {} cache_key = "%s-%s-%s-%s-%d.%d.%d-%s" % ( INTRINIO_CACHE_PREFIX, ticker, start_date_str, end_date_str, fast_period, slow_period, signal_period, "tech-macd") api_response = cache.read(cache_key) if api_response is None: try: api_response = SECURITY_API.get_security_price_technicals_macd( ticker, fast_period=fast_period, slow_period=slow_period, signal_period=signal_period, price_key='close', start_date=start_date, end_date=end_date, page_size=100) cache.write(cache_key, api_response) except ApiException as ae: raise DataError( "API Error while reading MACD indicator from Intrinio Security API: ('%s', %s - %s (%d, %d, %d))" % (ticker, start_date_str, end_date_str, fast_period, slow_period, signal_period), ae) except Exception as e: raise ValidationError( "Unknown Error while reading MACD indicator from Intrinio Security API: ('%s', %s - %s (%d, %d, %d))" % (ticker, start_date_str, end_date_str, fast_period, slow_period, signal_period), e) macd_list = api_response.technicals if len(macd_list) == 0: raise DataError( "No MACD indicators returned from Intrinio Security API: ('%s', %s - %s (%d, %d, %d))" % (ticker, start_date_str, end_date_str, fast_period, slow_period, signal_period), None) for macd in macd_list: macd_dict[intrinio_util.date_to_string(macd.date_time)] = { "macd_histogram": macd.macd_histogram, "macd_line": macd.macd_line, "signal_line": macd.signal_line } return macd_dict
def get_daily_stock_close_prices(ticker: str, start_date: datetime, end_date: datetime): ''' Returns a list of historical daily stock prices given a ticker symbol and a range of dates. Currently only returns one page of 100 results Parameters ---------- ticker : str Ticker Symbol start_date : object The beginning price date as python date object end_date : object The end price date as python date object Returns ----------- a dictionary of date->price like this { '2019-10-01': 100, '2019-10-02': 101, '2019-10-03': 102, '2019-10-04': 103, } ''' start_date_str = intrinio_util.date_to_string(start_date).replace('-', '') end_date_str = intrinio_util.date_to_string(end_date).replace('-', '') price_dict = {} cache_key = "%s-%s-%s-%s-%s" % (INTRINIO_CACHE_PREFIX, ticker, start_date_str, end_date_str, "closing-prices") api_response = cache.read(cache_key) if api_response is None: try: api_response = SECURITY_API.get_security_stock_prices( ticker, start_date=start_date_str, end_date=end_date_str, frequency='daily', page_size=100) cache.write(cache_key, api_response) except ApiException as ae: raise DataError( "API Error while reading price data from Intrinio Security API: ('%s', %s - %s)" % (ticker, start_date_str, end_date_str), ae) except Exception as e: raise ValidationError( "Unknown Error while reading price data from Intrinio Security API: ('%s', %s - %s)" % (ticker, start_date_str, end_date_str), e) price_list = api_response.stock_prices if len(price_list) == 0: raise DataError( "No prices returned from Intrinio Security API: ('%s', %s - %s)" % (ticker, start_date_str, end_date_str), None) for price in price_list: price_dict[intrinio_util.date_to_string(price.date)] = price.close return price_dict
def __read_financial_metrics__(ticker: str, start_year: int, end_year: int, tag: str): """ Helper function that will read the Intrinio company API for the supplied date range and convert the resulting list into a more friendly dictionary. Specifically a result like this [ { 'date': datetime.date(2010, 1, 1), 'value': 123 }, ] into this: [{ 2010: 123, }] Parameters ---------- ticker : str Ticker symbol. E.g. 'AAPL' start_year : int Start year of the metric data end_year : int End year of the metric data tag : the metric name to retrieve Raises ------- DataError in case of any error calling the intrio API ValidationError in case of an unknown exception Returns ------- A dictionary of year=>value with the filtered results. For example: { 2010: 123, 2012: 234, 2013: 345, 2014: 456, } """ (start_date, x) = intrinio_util.get_fiscal_year_period(start_year, 0) (x, end_date) = intrinio_util.get_fiscal_year_period(end_year, 0) frequency = 'yearly' # check the cache first cache_key = "%s-%s-%s-%d-%d-%s-%s" % (INTRINIO_CACHE_PREFIX, "metric", ticker, start_year, end_year, frequency, tag) api_response = cache.read(cache_key) if api_response == None: # else call the API directly try: api_response = company_api.get_company_historical_data( ticker, tag, frequency=frequency, start_date=start_date, end_date=end_date) cache.write(cache_key, api_response) except ApiException as ae: raise DataError( "Error retrieving ('%s', %d - %d) -> '%s' from Intrinio Company API" % (ticker, start_year, end_year, tag), ae) except Exception as e: raise ValidationError( "Error parsing ('%s', %d - %d) -> '%s' from Intrinio Company API" % (ticker, start_year, end_year, tag), e) if len(api_response.historical_data) == 0: raise DataError( "No Data returned for ('%s', %d - %d) -> '%s' from Intrinio Company API" % (ticker, start_year, end_year, tag), None) historical_data = api_response.historical_data converted_response = {} for datapoint in historical_data: converted_response[datapoint.date.year] = datapoint.value return converted_response