Skip to content

Instantly share code, notes, and snippets.

@Kazanskyi
Last active June 7, 2022 19:43
Show Gist options
  • Save Kazanskyi/b727840467543b18cf293dd49a2e77bb to your computer and use it in GitHub Desktop.
Save Kazanskyi/b727840467543b18cf293dd49a2e77bb to your computer and use it in GitHub Desktop.
import pandas as pd #data manipulation and analysis package
import numpy as np
import datetime
from datetime import date
import requests
#Enter TIINGO
print("Enter 40 signs tiingo API: ")
Tiingo_API = input()
def get_last_historic_date(last_date = date.today(), historical_days = 1450):
'''
Takes one date and range of days as an input
As output come 2 variables: the min/max dates as str value
'''
todays_year = last_date.year
todays_month = last_date.month
todays_day = last_date.day
historical_date = last_date-datetime.timedelta(days=historical_days)
historical_year = historical_date.year
historical_month = historical_date.month
historical_day = historical_date.day
#Transfrom dates to str
historical_date_str =str(historical_year) + "-" + str(historical_month) + "-" + str(historical_day)
latest_date_str = str(todays_year) + "-" + str(todays_month) + "-" + str(todays_day)
return historical_date_str, latest_date_str
def fetch_stock(symbol, last_date = date.today(), historical_days = 1450):
'''
Get the trading information about a stock for a range of days in "historical_days" before the "last_date"
The output is a DataFrame with columns "close","high","low","open","volume","splitFactor"
The output are adjusted prices
'''
#Get latest and historical day, month, year for API request
historical_date_str, latest_date_str = get_last_historic_date(last_date, historical_days)
#The request itself
url = f'https://api.tiingo.com/tiingo/daily/{symbol}/prices?startDate={historical_date_str}&endDate={latest_date_str} '
headers = {
'Content-Type': 'application/json',
'Authorization' : f'Token {Tiingo_API}'
}
r = requests.get(url, headers=headers)
response = r.json()
response = pd.DataFrame(response)
response.set_index(["date"], inplace = True)
response.index = pd.to_datetime(response.index)
response.drop(columns = ["close","high","low","open","volume","splitFactor"],axis = 1, inplace = True)
response.rename(columns = {"adjClose":"close","adjHigh":"high","adjLow":"low","adjOpen":"open","adjVolume":"volume"}, inplace = True)
return response
def fetch_fundamentals(symbol, last_date = date.today(), historical_days = 1450):
'''
The output is a dataframe with daily fundamentals:
Market_Cap, Enterprise_Value, PE_Ratio, PB_Ratio, Trailing PEG
'''
#Get latest and historical day, month, year for API request
historical_date_str, latest_date_str = get_last_historic_date(last_date, historical_days)
url = f'https://api.tiingo.com/tiingo/fundamentals/{symbol}/daily?token={Tiingo_API}?startDate={historical_date_str}&endDate={latest_date_str}'
headers = {
'Content-Type': 'application/json',
'Authorization' : f'Token {Tiingo_API}'
}
r = requests.get(url, headers=headers)
response = r.json()
response = pd.DataFrame(response)
response.set_index(["date"], inplace = True)
response.index = pd.to_datetime(response.index)
return response
def fetch_definitions():
'''
The output is the Dataframe with the definitions of parameters
from the fetch_statements function
'''
url = f'https://api.tiingo.com/tiingo/fundamentals/definitions?token={Tiingo_API}'
headers = {
'Content-Type': 'application/json',
'Authorization' : f'Token {Tiingo_API}'
}
r = requests.get(url, headers=headers)
response = r.json()
response = pd.DataFrame(response)
response.to_csv("Definitions.csv")
return response
def fetch_statements(symbol, last_date = date.today(), historical_days = 1450):
'''
Gets historical financial data about the stock like Total Assets, Accounts Payable, Short & Long term Debts etc.
'''
#Get latest and historical day, month, year for API request
historical_date_str, latest_date_str = get_last_historic_date(last_date, historical_days)
url = f'https://api.tiingo.com/tiingo/fundamentals/{symbol}/statements?token={Tiingo_API}?startDate={historical_date_str}&endDate={latest_date_str}'
headers = {
'Content-Type': 'application/json',
'Authorization' : f'Token {Tiingo_API}'
}
r = requests.get(url, headers=headers)
response = r.json()
final_df = pd.DataFrame()
for i in range(len(response)):
balanceSheet_df = pd.DataFrame(response[i]["statementData"]["balanceSheet"]).T
overview_df = pd.DataFrame(response[i]["statementData"]["overview"]).T
cashFlow_df = pd.DataFrame(response[i]["statementData"]["cashFlow"]).T
incomeStatement_df = pd.DataFrame(response[i]["statementData"]["incomeStatement"]).T
dfs = [balanceSheet_df, overview_df, cashFlow_df, incomeStatement_df]
general_df = pd.concat(dfs, axis =1)
#Make 1st row a header
new_header = list(general_df.loc["dataCode"]) #grab the first row for the header
general_df.drop("dataCode",axis = 0, inplace = True) #take the data less the header row
general_df.columns = new_header
general_df["date"] = response[i]["date"]
general_df["quarter"] = response[i]["quarter"]
general_df["year"] = response[i]["year"]
print(f'Combining Statements for {response[i]["year"]} and {response[i]["quarter"]}')
final_df = pd.concat([final_df, general_df], axis = 0)
final_df.set_index(["date"], inplace = True)
#converting date from str to datetime object
final_df.index = pd.to_datetime(final_df.index, yearfirst = True, utc = True, origin = "unix")
final_df_copy = final_df.copy()
#Dealing with duplicated indexes of datetime
if final_df.index.duplicated().sum()>0:
duplicates_in_df = final_df.index.duplicated()
final_df.dropna(axis = 0, inplace = True)
final_df = final_df.apply(pd.to_numeric, errors='ignore')
return final_df
def fetch_metadata():
'''
Get's metadata about all available stocks, like:
Industry, Location, Full Name, Ticker, etc.
'''
url = f'https://api.tiingo.com/tiingo/fundamentals/meta?token={Tiingo_API}'
headers = {
'Content-Type': 'application/json',
'Authorization' : f'Token {Tiingo_API}'
}
r = requests.get(url, headers=headers)
response = r.json()
response = pd.DataFrame(response)
return response
def combine_tables(stock_df, statemets_data, fundamentals_data, dates_range, metadata, todays_date = date.today()):
'''
Combining into one Dataframe information about daily trading values, statements, fundamentals
'''
#We create an index of dates range
dates = pd.date_range(todays_date-datetime.timedelta(days=dates_range),todays_date,freq='d')
#We change the name to make join with other dataframes available by the same index
dates.rename('date', inplace = True)
#Convert index to dataframe
dates_df = pd.DataFrame(index = dates)
#Delete timezone from the statements to make join available
statemets_data.index = statemets_data.index.tz_convert(None)
stock_df.index = stock_df.index.tz_convert(None)
fundamentals_data.index = fundamentals_data.index.tz_convert(None)
#Joining two dataframes
dates_and_statemts = dates_df.join(statemets_data, how = 'left')
#Statements table contains data about quarters only while dates DF is much bigger. We populate quarter results to days
dates_and_statemts.ffill(axis = 0, inplace = True)
stock_df = stock_df.join(dates_and_statemts, how = 'left')
stock_df = stock_df.join(fundamentals_data, how = 'left')
stock_df[["sector","industry"]] = metadata[["sector","industry"]].iloc[-1]
return stock_df
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment