I can get one stock ticker into my URL...but how do I create a list and loop through the URL. Please see a failed attempt...it's for a tweepy project i'm fiddling with. Mostly worried about getting through multiple urls.
ticker=["AAPL","XOM"]
For i < len(ticker):
responeData = requests.get("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol="+str(ticker[i])+"&apikey=XXXXXX")
symbol = str(responeData.json()['Meta Data']['2. Symbol'])
refresh = str(responeData.json()['Meta Data']['3. Last Refreshed'])
checkclose = str(responeData.json()['Time Series (Daily)'])
close=str(responeData.json()['Time Series (Daily)'][refresh]['4. close'])
api.update_status(status=symbol+' '+refresh+' Close Price: $'+close)
You can use a for loop to iterate your list.
tickers=["AAPL","XOM"]
for ticker in tickers:
responeData = requests.get("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol="+ticker+"&apikey=XXXXXX")
symbol = str(responeData.json()['Meta Data']['2. Symbol'])
refresh = str(responeData.json()['Meta Data']['3. Last Refreshed'])
checkclose = str(responeData.json()['Time Series (Daily)'])
close=str(responeData.json()['Time Series (Daily)'][refresh]['4. close'])
api.update_status(status=symbol+' '+refresh+' Close Price: $'+close)
Related
I'm trying to build a cryptocurrency price tracker in Python (see code below). I'm working with Python 3.10.1 in Visual Studio Code.
import pandas_datareader.data as web
import datetime as dt
currency = 'EUR'
metric = 'Close'
crypto = ['BTC','ETH']
colnames = []
first = True
start = dt.datetime(2020,1,1)
end = dt.datetime.now()
for ticker in crypto:
data = web.DataReader(f'{crypto}-{currency}', 'yahoo', start, end)
if first:
combined = data[[metric]].copy()
colnames.append(ticker)
combined.columns = colnames
first = False
else:
combined = combined.join(data[metric])
colnames.append(ticker)
combined.columns = colnames
When I execute this code, I get the following error notification:
RemoteDataError: No data fetched for symbol ['BTC', 'ETH']-EUR using YahooDailyReader
When I change the variable crypto to only pull the prices for BTC the code works, but the output looks like this:
Date
B
T
C
2020-01-01
6417.781738
6417.781738
6417.781738
2020-01-02
6252.938477
6252.938477
6252.938477
2020-01-03
6581.735840
6581.735840
6581.735840
In the scenario of only pulling BTC, the variable colnames looks like this: colnames = ['B','T', 'C']. I suspect, there's something wrong with that variable and it's potentially the reason why my code fails when I try to pull the data for multiple cryptocurrencies but I can't quite figure it out and solve my problem.
Project is to identify, rank and classify dividend paying stocks on multiple exchanges.
In a nutshell, program flow (using python 3.8) is as follows:
Stage 1 - read Master List of stocks on exchange from a spreadhseet.
Stage 2 - download info and dividends from Yahoo Finance and run series of tests to identify those which meet the criteria and classified as targets now, or could be in the near/far future if one of the criteria changes.
Stage 3 - Master List and Targets are saved in a spreadsheet, and targets are graphed to give visual clues to dividends trend and annual growth.
Previous versions of this program were done in 3 different scripts, and yahoo finance was called to download stock info for each stage. These worked just fine, but I am trying to consolidate all of this in 1 script.
As seen in the full program code provided below, I am going through my list of stocks and saving the information in a dictionary:
graph_dict = {'Name':[],'Symbol':[],'Avg Div Growth':[],'Dividends':[],'Annual Dividends':[]}
Name and symbol are strings, Avg Div Growth is a float, and Dividends / Annual Dividends are pandas dataframes
As the list of names is looped through, and yahoo finance obtains dividends, the dictionary is appended. Effectively, each 'row' in the dictionary contains all the information I require to graph the stock.
I have no problems populating the dictionary, but I have 3 problems when I try to access the dictionary.
How do I extract a 'row' from the dictionary? I can access individual values from a specific 'row' using:
graph_dict['Name'][row_num]
so, graph_dict['Name'][0] is 'Keppel REIT in the code below.
I can not figure out how to extact all items in the row. I am looking for the equivalent to:
graph_dict.items()[row_num]
which would give me the name, symbol, avg div growth, all dividends and annual dividends for the stock in gthat row number.
How can I sort the 'rows' by values in the key [Avg Div Growth]?
I want to graph the securities in order from highest average dividend growth to the lowest. This is how I am ranking the securities on the list.
Using sorted() : sorted_dict = sorted(graph_dict, key = lambda item: item['Avg Div Growth']))
and itemgetter() : sorted_dict = sorted(graph_dict, key = itemgetter('Avg Div Growth')))
does not work with my dictionary format.
Based on how I declared the dictionary, how can I sort the 'rows' within the dictionary?
Or do I need to declare my dictionary differently?
How to slice the dictionary so I can send a group of 'rows' to my graph function?
I am graphing the list of securities with a number of securities per page. So, I need to group or slice my dictionary so that I can send the group of securities and their dividend data to the graphing function and graph one page at a time (collection of pages is saved as a .pdf doc for future reference)
One answer I saw suggested the following:
group_to_graph = dict(list(sorted_graph_dict.items())[group_start:group_end])
where group start and end are the limits for the slice and reference the 'row' number in the dictionary.
doing that just gave me the values of the keys at group_start as follows:
Stock Group on page # 0 - start row (group_start) = 0 , (end row (group_end) = 1
{'Name': ['Keppel REIT', 'UMS', 'SPH REIT', 'Frasers Hospitality Trust']}
Stock Group on page # 1 - start row (group_start) = 2 , (end row (group_end) = 3
{'Avg Div Growth': [6.77852254732552, 25.0433491073197, 32.833907784854, -20.4956238784202]}
I suspect that once I understand how to access a complete 'row' in the dictionary vs. individual keys as in Q1 above that this may answer itself, but please feel free to peruse the code below and suggest options for how to declare my dictionary and access all items in a 'row'.
import pandas as pd
import yfinance as yf
## basic information on each stock
name = ['Keppel REIT','UMS','SPH REIT','Frasers Hospitality Trust']
symbol = ['K71U.SI','558.SI','SK6U.SI','ACV.SI']
avg_div_growth = [6.77852254732552,25.0433491073197,32.833907784854,-20.4956238784202]
## create dataframe to hold stock info (downloaded from yahoo finance)
df = pd.DataFrame (columns = ['Name','Symbol','Avg Div Growth (%)'])
df = df.astype( dtype = {'Name': str, 'Symbol': str, 'Avg Div Growth (%)': float})
df['Name'] = name
df['Symbol'] = symbol
df['Avg Div Growth (%)'] = avg_div_growth
## create dictionary to hold all relevant info for graphing. Each stock has its own 'row' in the lists within the dictionary
graph_dict = {'Name':[],
'Symbol':[],
'Avg Div Growth':[],
'Dividends':[],
'Annual Dividends':[]}
## download dividend info from Yahoo Finance using yfinance
start = 0
end = len(df)
for count in range (start, end): # loops through list of securities contained in the dataframe
stock = yf.Ticker(df.loc[count,'Symbol'])
div = stock.dividends # is type Series by default
div_df = pd.DataFrame(div) # change to Dataframe
## make annual dividends dataframe
annual_divs_df = div_df.resample('Y').sum()
annual_divs_df.rename(columns = {'Dividends':'Annual Dividends'}, inplace = True)
## populate each 'row' of the dictionary with the relevant data
graph_dict['Name'].append(df.loc[count,'Name'])
graph_dict['Symbol'].append(df.loc[count,'Symbol'])
graph_dict['Avg Div Growth'].append(df.loc[count,'Avg Div Growth (%)'])
graph_dict['Dividends'].append(div_df)
graph_dict['Annual Dividends'].append(annual_divs_df)
print ('\nNumber of Names in dictionary is:',len(graph_dict['Name'])) # testing
## loop through dictionary to print each 'row' for testing purposes
for num in range(len(graph_dict['Name'])):
print('\nStock Number:',num+1)
print('Name is:', graph_dict['Name'][num])
print('Symbol is:',graph_dict['Symbol'][num])
print('Avg Annual Div Growth is:',graph_dict['Avg Div Growth'][num],'%')
print('\nAll Dividends declared:\n',graph_dict['Dividends'][num])
print('\nAnnual Dividends:\n',graph_dict['Annual Dividends'][num])
## sort the dictionary by Avg Div Growth from highest to lowest
''' How to sort the dictionary lists such that they are in order from highest Avg Div Growth to lowest ??? '''
sorted_graph_dict = graph_dict # change once how to sort is figuired out
## get first row in Dictionary
''' How to extract all items in a single row of the list within the complete dictionary ??? '''
## group the entries in the dictionary into groups (pages in graph) of set size
graph_rows = 2
number_of_securities = len(sorted_graph_dict['Name'])
page_pad = number_of_securities % graph_rows
if page_pad == 0: # all pages have full number of securities
number_of_pages = number_of_securities // graph_rows
else: # last page needs to be padded out to send proper number of securities to graph function
number_of_pages = number_of_securities // graph_rows + 1
print ('\n\npage_pad = ',page_pad, 'number of pages is: ',number_of_pages) # testing
start_page = 0
end_page = number_of_pages
group_to_graph = {} # empty dictionary to hold group of stocks to send to graph function
for page_number in range(start_page, end_page):
group_start = (page_number + 1) * graph_rows - graph_rows
group_end = group_start + graph_rows -1
''' how to slice dictionary so 'rows' within group start and end are isolated and sent to graphing_function??? '''
group_to_graph = dict(list(sorted_graph_dict.items())[group_start:group_end]) # DOES NOT WORK AS INTENDED
print ('\nStock Group on page #',page_number + 1,' - start row (group_start) = ',group_start, ', (end row (group_end) =',group_end, '\n',group_to_graph)
'''
Should print out items in each row,instead it it prints:
Names (key = 0 which is same as group_start) on 1st time through loop, and
Avg Div Growth on ( key = 2 which is same as group_start) on 2nd time through loop
'''
I'm a beginner in Python and I've been doing a project on a stock screener for one of my classes. I create a csv list of several tickers, run through those lists to get data from yfinance and then use that to go through a set of criteria. Here's the loop I use to get data from yfinance:
for i in allrecs:
stock = yf.Ticker(i[0])
PriceEarning = stock.info["forwardPE"]
cap = stock.info["marketCap"]
dividend = stock.info["dividendYield"]
dividend_output = formatpercentage(dividend)
cap_formatted = "${:,.0f}".format(cap)
beta = stock.info['beta']
# result = condition(EPS_forward)
# rec = i[0], result
print(i[0],PriceEarning, cap, dividend, beta)
The problem I'm having is, on different times of days I receive different numbers. For example, when I was working on the file at 2pm they returned dividend yield and beta, but now at 4pm they all return "None". Also, when I retrieve the data from individual ticker, I got the number but when I was running it through the loop, it returned "None". How should I fix it?
I am researching the impact of news article sentiment related to a financial instrument and its potenatial effect on its instruments's price. I have tried to get the timestamp of each news item, truncate it to minute data (ie remove second and microsecond components) and get the base shareprice of an instrument at that time, and at several itervals after that time, in our case t+2. However, program created twoM to the file, but does not return any calculated price changes
Previously, I used Reuters Eikon and its functions to conduct the research, described in the article below.
https://developers.refinitiv.com/article/introduction-news-sentiment-analysis-eikon-data-apis-python-example
However, instead of using data available from Eikon, I would like to use my own csv news file with my own price data from another csv file. I am trying to match the
excel_file = 'C:\\Users\\Artur\\PycharmProjects\\JRA\\sentimenteikonexcel.xlsx'
df = pd.read_excel(excel_file)
sentiment = df.Sentiment
print(sentiment)
start = df['GMT'].min().replace(hour=0,minute=0,second=0,microsecond=0).strftime('%Y/%m/%d')
end = df['GMT'].max().replace(hour=0,minute=0,second=0,microsecond=0).strftime('%Y/%m/%d')
spot_data = 'C:\\Users\\Artur\\Desktop\\stocksss.csv'
spot_price_10 = pd.read_csv(spot_data)
print(spot_price_10)
df['twoM'] = np.nan
for idx, newsDate in enumerate(df['GMT'].values):
sTime = df['GMT'][idx]
sTime = sTime.replace(second=0, microsecond=0)
try:
t0 = spot_price_10.iloc[spot_price_10.index.get_loc(sTime),2]
df['twoM'][idx] = ((spot_price_10.iloc[spot_price_10.index.get_loc((sTime + datetime.timedelta(minutes=10))),3]/(t0)-1)*100)
except:
pass
print(df)
However, the programm is not able to return the twoM price change values
I assume that you got a warning because you are trying to make changes on views. As soon as you have 2 [] (one for the column, one for the row) you can only read. You must use loc or iloc to write a value:
...
try:
t0 = spot_price_10.iloc[spot_price_10.index.get_loc(sTime),2]
df.loc[idx,'twoM'] = ((spot_price_10.iloc[spot_price_10.index.get_loc((sTime + datetime.timedelta(minutes=10))),3]/(t0)-1)*100)
except:
pass
...
I have this code to download data from yahoo:
#gets data from yahoo finance
stocks = list(newmerge.index)
start = dt.datetime(2012,1,1)
end = dt.datetime.today()
yahoodata = pdr.get_data_yahoo(stocks,start,end)
cleanData = yahoodata.loc['Adj Close']
dataFrame = pd.DataFrame(cleanData, columns=stocks)
It works fine but I noticed a problem recently, it doesn't download data for stocks "BRK.B" , and "BR.B" .
I have a list of all the stocks called "stocks" , and here's what I've done, but it still doesn't show data for stocks w/ dot in them:
def stocksdot(stocks):
stocks_dash = str(stocks).replace('.','-')
stockslist = stocks_dash.split(',')
return stockslist
stocksdot(stocks)
My expected output would be to download all stocks, even those with a dot in them. Any ideas how to circumvent?
Your problem is Yahoo Finance doesn't use the "." notation to track shares of different classes. So, "BRK.B" and "BR.B" are actually "BRKB" and "BRB".
Using the Yahoo Finance python SDK I made a little script to test whether or not Yahoo Finance could find information about a stock with the ticker "BRK.B" or "BR.B".
from yahoo_finance import Share
stock = Share('BRK.B')
print(stock.get_price())
This results is:
>>>> None
Stock tickers with a dot in them are used as a shorthand for a type or class of a specific stock. You can learn more here.
To circumvent it looks like you can remove the ".". For example when I use "BRKB" instead of "BRK.B" I get the result:
>>>> 173.05
Which is the current price of Berkshire Hathaway class B stock.
To replace the "." programatically use Python's .replace() method.
for stock in stocks:
stock = stock.replace(".", "") # Replaces all "." with "" in the string
# stock
Your problem is Yahoo Finance doesn't use the "." notation to track shares of different classes. So, "BRK.B" and "BR.B" are actually "BRKB" and "BRB". --- My comment: Now "BRK.B" and "BR.B" are actually "BRK-B" and "BR-B".