def fundamentals_from_fids(fids_list, sandbox=False): if sandbox == False: intrinio_sdk.ApiClient().configuration.api_key['api_key'] = config('INTRINIO_KEY') security_api = intrinio_sdk.SecurityApi() elif sandbox == True: intrinio_sdk.ApiClient().configuration.api_key['api_key'] = config('INTRINIO_SANDBOX_KEY') security_api = intrinio_sdk.SecurityApi() # Initialize api's fapi = intrinio_sdk.FundamentalsApi() fund_dict = {} for id in fids_list: for attempt in range(5): try: fundamentals_ret = fapi.get_fundamental_standardized_financials(id) except: print('Connection error. Retry attempt {}'.format(attempt)) sleep(2) else: break fund_get = fundamentals_ret.standardized_financials_dict fund_info = fundamentals_ret.fundamental_dict funds = {} funds['date'] = fund_info['filing_date'] funds['fiscal_year'] = fund_info['fiscal_year'] funds['quarter'] = fund_info['fiscal_period'] for f in fund_get: funds[f['data_tag']['tag'].lower()] = f['value'] fund_dict[id] = funds return fund_dict
import pandas as pd import intrinio_sdk intrinio_sdk.ApiClient().configuration.api_key[ 'api_key'] = 'OjJiZDM3OWU0ZTI0YmM5YTdhNzY1NjIwZjczZGRjMjg0' security_api = intrinio_sdk.SecurityApi() company_api = intrinio_sdk.CompanyApi() fundamentals_api = intrinio_sdk.FundamentalsApi() def get_intrinio_hp(query): identifier = str(query).upper() tag = 'adj_close_price' api_response = security_api.get_security_historical_data(identifier, tag, page_size=100) hist_prices = pd.DataFrame(api_response.historical_data_dict) return hist_prices def get_intrinio_volume(query): identifier = str(query).upper() api_response = security_api.get_security_price_technicals_adtv(identifier, page_size=1, period=20) volume = pd.DataFrame(api_response.technicals_dict) return volume def get_intrinio_wr(query): identifier = str(query).upper()
def find_fundamentals(tkr_id, sandbox=False, nocomm=False): """ Returns a list of available fundamental financial indicators for the specified company. -- tkr_id: stock ticker name. 'AAPL' for Apple inc, 'XOM' for Exxon Mobile Corp. etc. (if using a developer sandbox key, only DOW 30 will be available) -- sandbox: Use this to turn sandbox mode on and off if you have a developers sandbox api key. Limited to DOW 30, but much less strict limits on api calls. *In .env file name main key INTRINIO_KEY and developer sandbox key INTRINIO_SANDBOX_KEY """ # Sandbox check and get env key if sandbox == False: intrinio_sdk.ApiClient().configuration.api_key['api_key'] = config( 'INTRINIO_KEY') security_api = intrinio_sdk.SecurityApi() elif sandbox == True: intrinio_sdk.ApiClient().configuration.api_key['api_key'] = config( 'INTRINIO_SANDBOX_KEY') security_api = intrinio_sdk.SecurityApi() # Initialize api's capi = intrinio_sdk.CompanyApi() fapi = intrinio_sdk.FundamentalsApi() # Set parameters to get most recent financial report fund_params = { 'identifier': tkr_id, 'filed_after': '2018-06-01', 'filed_before': '2018-11-01', 'reported_only': False, # 'fiscal_year' :fiscal_year, 'statement_code': 'income_statement', 'type': '', 'start_date': '', 'end_date': '', 'page_size': 1, 'next_page': '' } # Get most recent financials report fundamentals = capi.get_company_fundamentals(**fund_params) id_to_check = fundamentals.fundamentals[0].id fun_check = fapi.get_fundamental_standardized_financials(id_to_check) available_fun = [] common = ['date', 'fiscal_year', 'quarter'] # Make list of available fundamentals and add above for fun in fun_check.standardized_financials: available_fun.append(fun.data_tag.tag) if nocomm == False: for fun in common: available_fun.append(fun) else: available_fun.append('date') return (available_fun)
def gather_financial_statement_company_compare(api_key, ticker, statement, year, period, output_format='dict'): """ Given the tickers, statement, year and period returns all the information from the Intrinio API fundamental reported financials for that time and those tickers in either a dictionary or a pandas dataframe format. Parameters ----------- api_key : str API key (sandbox or production) from Intrinio ticker : list a list of the ticker symbols you would like to study statement : str the statement that you want to study options: 'income_statement', 'cash_flow_statement', 'balance_sheet_statement' year : str the year you want the information from period : str the period you want the information from output_format : str (optional, default = 'dict') the output format for the data, options are 'dict' for dictionary or 'pddf' for pandas dataframe Returns ----------- object of type output_format information about the given statement for the given tickers at the given time in the specified output format Example ----------- >>> gather_financial_statement_company_compare(api_key, ['AAPL', 'CSCO'], 'income_statement', '2019', 'Q1') """ statements = ['income_statement', 'balance_sheet_statement', 'cash_flow_statement'] inputs = {'api_key': api_key, 'statement': statement, 'year': year, 'period': period} intrinio_sdk.ApiClient().configuration.api_key['api_key'] = api_key fundamentals_api = intrinio_sdk.FundamentalsApi() # Check if api_key, statement, year, period are strings for inst in inputs.keys(): if not isinstance(inputs[inst], str): raise TypeError("Invalid data format: " + inst + " must be a string") # test if the API Key works try: fundamentals_api.get_fundamental_reported_financials( 'AAPL-income_statement-2019-Q1') except Exception: msg_apy = "Invalid API Key: please input a valid API key as a string" return msg_apy # Check if ticker is a list if not isinstance(ticker, list): raise TypeError("Invalid data format: ticker must be a list") # Check if the elements in the ticker list are strings for comp in ticker: if not isinstance(comp, str): raise TypeError( 'Invalid data format: ticker must be a list of strings') # Check if the year is a 4-digits number if not len(year) == 4: raise Exception( "Invalid data format: year must be a string of 4 digits") # Check if the output_format is either 'dict' or 'pddf' if output_format not in ['dict', 'pddf']: raise Exception( "Invalid data format: output_format must be 'dict' or 'pddf'" ) # Check if the statement is valid if statement not in statements: raise Exception( "Invalid data format: statement must be a valid type" ) # link with the API intrinio_sdk.ApiClient().configuration.api_key['api_key'] = api_key fundamentals_api = intrinio_sdk.FundamentalsApi() # result will contain a dictionnary for each company. # This dictionnary will contain all the information for one company result = [] # for every company for comp in ticker: # key is the appropriate key to select the information we want key = comp + '-' + str(statement) + '-' + str(year) + '-' + str(period) try: # get the object that we want from the API fund = fundamentals_api.get_fundamental_reported_financials( key) except Exception: msg = "Invalid agruments: please make sure that your statement" msg = msg + "/year/period are valid" return msg my_fund = fund.reported_financials # This dictionary will contain all the information for one company dict = {} dict['ticker'] = comp dict['statement'] = statement dict['year'] = year dict['period'] = period # we store all the values, balances, names and the tags for i in range(len(my_fund)): value = my_fund[i].value tag_dic = my_fund[i].xbrl_tag balance = tag_dic.balance name = tag_dic.name tag = tag_dic.tag # tag is a key of this dictionnary # if the tag is several times in the original object, we keep # one tag and the value is the sum or the substraction of # all the values of this tag (depending on the value of balance) if tag in dict.keys(): if balance == 'credit': value = dict[tag]['value'] - value else: value = dict[tag]['value'] + value dict[tag] = {'value': value, 'balance': balance, 'name': name} result.append(dict) if output_format == 'dict': return result # if the wanted type of the output is a dataframe else: # initialize a new empty dictionnary that we will convert into a # dataframe # this dictionnary will have the following structure # {'name': [name1, name2], 'revenue' : # [revenu_company_1, revenue_company_2], ...} df = {} # for every company for i in range(len(result)): # select all the information about this company sub_dict = result[i] # For all the tags that we have for this company for val in sub_dict.keys(): # if the key is already in the df dictionary if val in df.keys(): # if the value that corresponds to the key is a string # which means that the key is 'ticker', 'statement', # 'year' or 'period' if type(sub_dict[val]) == str: # We append the value of the key df[val].append(sub_dict[val]) # if the value of the key is a dictionary else: # only take the value that corresponds to the key # 'value' df[val].append(sub_dict[val]['value']) # This step is to make sure that all the values in this # dictionary (which are lists) are the same length # if the tag of the company is not already in the df dictionary else: if type(sub_dict[val]) == str: # We have to put as many 'None' as the number of # companies for which we already collected the # information df[val] = [None for j in range(i)] + [sub_dict[val]] else: df[val] = [None for j in range( i)] + [sub_dict[val]['value']] # We add some 'None' to make sure that all the values # are the same length in this dictionary for val in df.keys(): # The length of each value should be i+1 # (=number of companies we studied) if len(df[val]) != i+1: df[val].append(None) return pd.DataFrame(df)
def gather_financial_statement_time_series( api_key, ticker, statement, year, period, output_format='pddf'): """ Given the tickers, statement, year and period returns the complete financial information from the Intrinio API stock data Parameters ----------- api_key : str API key (sandbox or production) from Intrinio ticker : str the ticker symbol you would like to get information for statement : str the statement that you want to study options: 'income_statement', 'cash_flow_statement', 'balance_sheet_statement' year : list the list containing the years as strings period : list the list of quarters (as strings) for which you want information output_format : str (optional, default = 'pddf') the output format for the data, options are 'dict' for dictionary or 'pddf' for pandas dataframe Returns ----------- object of type output_format information about the given statement for the given ticker at the given times in the specified output format Example ----------- >>> gather_financial_statement_time_series(api_key, ticker='AAPL', statement='income_statement', year=['2018', '2019'], period=['Q1'], output_format='dict') """ # https://data.intrinio.com/data-tags available_statements = [ 'income_statement', 'cash_flow_statement', 'balance_sheet_statement' ] inputs = {'api_key': api_key, 'ticker': ticker, 'statement': statement} # Check if api_key, ticker and statement are strings for inst in inputs.keys(): if isinstance(inputs[inst], int): raise TypeError( "Invalid data format: " + inst + " must be a string") elif isinstance(inputs[inst], float): raise TypeError( "Invalid data format: " + inst + " must be a string") elif not isinstance(inputs[inst], str): raise NameError("Invalid data format: " + inst + " must be a string") # Check if the output_format is either 'dict' or 'pddf' if output_format not in ['dict', 'pddf']: raise Exception( "Invalid data format: output_format" + "must be 'dict' or 'pddf'") # Check that the value of statement is valid if statement not in available_statements: raise Exception( "Invalid data format: statement must be one of" + "'income_statement', 'cash_flow_statement' or " + "'balance_sheet_statement'") # Check that year is a list if isinstance(year, int): raise TypeError("Invalid data format: year must be a string") elif isinstance(year, float): raise TypeError("Invalid data format: year must be a string") if not type(year) is list: raise NameError("Invalid data format: year must be a list of strings") # Check that period is a list if not type(period) is list: raise NameError( "Invalid data format: " + "period must be a list of strings") # Check that the length of year is 4 for y in year: if not len(y) == 4: raise Exception( "Invalid data format: " + "year must be a string of 4 digits") # Initialize API key intrinio_sdk.ApiClient().configuration.api_key['api_key'] = api_key fundamentals_api = intrinio_sdk.FundamentalsApi() # Empty list to store results: reformat later to dataframe results = [] # Outer loop over years, inner loop over quarters for i in year: for j in period: # define key to obtain relevant information key = str(ticker) + '-' + str(statement) + \ '-' + str(i) + '-' + str(j) # Obtain req. object from API try: # put stock prices into a variable funda = fundamentals_api.get_fundamental_reported_financials( key) except Exception: print( "Invalid API Key: please input a valid API key as a string" ) return my_fund = funda.reported_financials # Empty dictionary to append the results : convert to df at the # last stage my_dict = {} my_dict['ticker'] = ticker my_dict['statement'] = statement my_dict['year'] = i my_dict['period'] = j for n in range(0, len(my_fund)): my_dict[str(my_fund[n].xbrl_tag.tag)] = [] # add values to the dictionary for k in range(0, len(my_fund)): for key, val in my_dict.items(): if my_fund[k].xbrl_tag.tag == key: my_dict[key].append(my_fund[k].value) my_dict[key] = [sum(my_dict[key])] results.append(my_dict) final_df = pd.DataFrame(results) # if_else for output format if output_format == 'pddf': return final_df else: return results
from intrinio_sdk.rest import ApiException from exception.exceptions import DataError, ValidationError from connectors import intrinio_util from support.financial_cache import cache from datetime import timedelta log = logging.getLogger() try: API_KEY = os.environ['INTRINIO_API_KEY'] except KeyError as ke: raise ValidationError("INTRINIO_API_KEY was not set", None) intrinio_sdk.ApiClient().configuration.api_key['api_key'] = API_KEY FUNDAMENTALS_API = intrinio_sdk.FundamentalsApi() COMPANY_API = intrinio_sdk.CompanyApi() SECURITY_API = intrinio_sdk.SecurityApi() INTRINIO_CACHE_PREFIX = 'intrinio' ''' Testing APIs using requests package ''' def retry_server_errors(func): ''' decorator that will retry intrinio server side errors, and let others pass through. Retries the error up to 5 times and sleeps 2 seconds between retries