how can i get stock data for one hour in python? - python

I am new to python. I tried to get data of VIX index of 1 hour from 1990-01-01 until now but i got this error. Could anyone help please?
ticker = '^VIX'
start = dt.datetime(1990, 1, 1)
for i in range(24):
end = dt.datetime(2022,1,1)
prices = web.DataReader(ticker, 'yahoo', start, end)['Close']
returns = prices.pct_change()
last_price = prices[-1]
print(prices)
start=end
KeyError: 'Date'

All problem is because you use for-loop with start = end so in second loop you try to get data from start='2022,1,1' to end='2022,1,1' and this range doesn't have any data and it makes problem.
You should run it without for-loop
import datetime as dt
import pandas_datareader.data as web
ticker = '^VIX'
start = dt.datetime(1990, 1, 1)
end = dt.datetime(2022, 5, 1) # almost today
data = web.DataReader(ticker, 'yahoo', start, end)
close_prices = data['Close']
print(close_prices)
last_price = close_prices[-1]
print('last:', last_price)
returns = data.pct_change()
print(returns)
close_returns = close_prices.pct_change()
print(close_returns)
EDIT:
DataReader doesn't have option to read 1hour data.
Module yfinance can read 1hour data but only for last 7-8 days.
import yfinance as yf
data = yf.download('^VIX', period="8d", interval='1h')
print(data)

Related

CPI data in python, create a dataframe

I am fairly new to python and I am trying to create a data frame with all the CPI data in it.
Nonetheless I do not manage to increase the month in the function.
Can anybody help?
\>import cpi
\>from datetime import date
\>cpi.get(date(2022, 11, 1))
\>n = 12
I suppose it should be something like this:
for i in range(n):
cpi.get(date(2022,n+1,1)
But no idea how to increase this and put into a dataframe.
For a single year's worth of data:
import cpi
import datetime as dt
import pandas as pd
date_list = []
cpi_list = []
for i in range(12):
date_list.append(dt.date(2022, i + 1, 1)) # i + 1 to avoid 0 value
cpi_list.append(cpi.get(date_list[i]))
df = pd.DataFrame({'Date': date_list, 'CPI': cpi_list})
Hope that helps,
--K

Yfinance Dividend sumation issue

I am trying to write a simple screener searching for buy signals among Dividend Aristocrats uploaded from a .csv file. The screener ought to iterate for each ticker and upload the dividends paid in the last year period (a setting). Then it should calculate three conditions
the amount of dividends paid within a year x100 should be above the 4 % of the current price
The last price should be at least 10 % or above the last year minimum price
The price should be above 50 SMA
I have two issues
First issue is that my ticker iteration does not start. It only iterates the first ticker. No code alarms of any kind, it just does not do the work.
Second issue is with my 1.st condition. I can not retrieve the dividends for the defined period of time nor do any kind of sumation.
Please advise
Thanks
Stock Screener
import pandas as pd
import yfinance as yf
import pandas_datareader as web
import datetime
from datetime import timedelta
import numpy as np
import talib as ta
# List of tickers
index_to_keep = [1]
data = pd.read_csv('/home/ata/MEGAsync/Python/DAI.csv',error_bad_lines = False,
engine = 'python',usecols = [0],skiprows=2)
# timeframe definition
st_dni=400 # one year + (can be changed)
end = datetime.date.today() # from today
start = end-timedelta(days=st_dni) # back
for ticker in data:
df = web.DataReader(ticker,'yahoo',start, end) # ticker data
stock=yf.Ticker(ticker,start) # dividend data
div = stock.dividends(period='st_dni')
sum(div) # dividend (1st cond)
dataframe = np.array(df) # np array conversion
hi = np.round(dataframe[:,1])
lo = np.round(dataframe[:,2])
hl = (hi+lo)/2 # hi/lo values
df_min = np.min(lo) # year low (2nd cond)
mabig = ta.SMA(ohlc,50) # SMA (3rd cond)
CSV file is available on this link
Problem solved
First issue solved with
...
for ticker in data:
ticker = data.loc[i,'SYMBOL']
...
Second issue solved with
...
stock = yf.Ticker(ticker)
temp = pd.DataFrame(stock.dividends)
div = temp.loc[start:end]
...
I hope someone find this useful.

How to see stock's symbol when using pandas

import pandas as pd
import pandas_datareader.data as web
from datetime import datetime
start_date = '2019-11-26'
end_date = str(datetime.now().strftime('%Y-%m-%d'))
tickers = ['IBM', 'AAPL','GOOG']
df = pd.concat([web.DataReader(ticker, 'yahoo', start_date, end_date) for ticker in tickers]).reset_index()
with pd.option_context('display.max_columns', 999):
print(df)
When I run my code, I can see only "Date High Low Open Close Volume Adj Close" values.
What I want to see is the stocks' names before the Date!
Please, help me out...
It always gives data without stocks' names so you have to add names before you concatenate data.
tickers = ['IBM', 'AAPL','GOOG']
data = []
for ticker in tickers:
df = web.DataReader(ticker, 'yahoo', start_date, end_date)
df['Name'] = ticker
data.append(df)
df = pd.concat(data).reset_index()

Pandas DataReader handle RemoteError yahoo finance

I am using the below code to parse a large tickers list to yahoo datareader, I am trying to get back a dataframe as per below. If the list is large, I often get a RemoteError back but on different tickers each time. I am not sure how to handle the RemoteError and I am happy to drop the ticker and continue with the next ticker in the list. I would, however, like to try again to get adj close ticker data. I thought using a for loop and adding a time delay would help with yahoo requests but I am still getting a Remote error. Any ideas?
IBM MSFT ORCL TSLA YELP
Date
2014-01-02 184.52 36.88 37.61 150.10 67.92
2014-01-03 185.62 36.64 37.51 149.56 67.66
2014-01-06 184.99 35.86 37.36 147.00 71.72
2014-01-07 188.68 36.14 37.74 149.36 72.66
2014-01-08 186.95 35.49 37.61 151.28 78.42
import pandas_datareader.data as web
import datetime as dt
import pandas as pd
import time
from pandas_datareader._utils import RemoteDataError
Which_group = ['Accident & Health Insurance'] ##<<<<put in group here
df = pd.read_csv('/home/ross/Downloads/UdemyPairs/stocks1.csv')
df.set_index('categoryName', inplace = True)
df1 = df.loc[Which_group]
tickers = df1.Ticker.tolist()
print(tickers)
#tickers = ['SPY', 'AAPL', 'MSFT'] # add as many tickers
start = dt.datetime(2013, 1,1)
end = dt.datetime.today()
# Function starts here
def get_previous_close(strt, end, tick_list, this_price):
""" arg: `this_price` can take str Open, High, Low, Close, Volume"""
#make an empty dataframe in which we will append columns
adj_close = pd.DataFrame([])
# loop here.
for idx, i in enumerate(tick_list):
try:
# time.sleep(0.01)
total = web.DataReader(i, 'yahoo', strt, end)
adj_close[i] = total[this_price]
except RemoteDataError:
pass
return adj_close
#call the function
print(get_previous_close(start, end, tickers, 'Adj Close'))
Maybe you can look at this question. This proposes a solution that it might work for you.
Pandas Dataframe - RemoteDataError - Python

Selecting specific date from pandas data-frame

From the daily stock price data, I want to sample and select end of the month price. I am accomplishing using the following code.
import datetime
from pandas_datareader import data as pdr
import pandas as pd
end = datetime.date.today()
begin=end-pd.DateOffset(365*2)
st=begin.strftime('%Y-%m-%d')
ed=end.strftime('%Y-%m-%d')
data = pdr.get_data_yahoo("AAPL",st,ed)
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-2])).set_index(data.index)
The line above selects end of the month data and here is the output.
If I want to select penultimate value of the month, I can do it using the following code.
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-2]))
Here is the output.
However the index shows end of the month value. When I choose penultimate value of the month, I want index to be 2015-12-30 instead of 2015-12-31.
Please suggest the way forward. I hope my question is clear.
Thanking you in anticipation.
Regards,
Abhishek
I am not sure if there is a way to do it with resample. But, you can get what you want using groupby and TimeGrouper.
import datetime
from pandas_datareader import data as pdr
import pandas as pd
end = datetime.date.today()
begin = end - pd.DateOffset(365*2)
st = begin.strftime('%Y-%m-%d')
ed = end.strftime('%Y-%m-%d')
data = pdr.get_data_yahoo("AAPL",st,ed)
data['Date'] = data.index
mon_data = (
data[['Date', 'Adj Close']]
.groupby(pd.TimeGrouper(freq='M')).nth(-2)
.set_index('Date')
)
simplest solution is to take the index of your newly created dataframe and subtract the number of days you want to go back:
n = 1
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-1-n]))
mon_data.index = mon_data.index - datetime.timedelta(days=n)
also, seeing your data, i think that you should resample not to ' month end frequency' but rather to 'business month end frequency':
.resample('BM')
but even that won't cover it all, because for instance December 29, 2017 is a business month end, but this date doesn't appear in your data (which ends in December 08 2017). so you could add a small fix to that (assuming the original data is sorted by the date):
end_of_months = mon_data.index.tolist()
end_of_months[-1] = data.index[-1]
mon_data.index = end_of_months
so, the full code will look like:
n = 1
mon_data=pd.DataFrame(data['Adj Close'].resample('BM').apply(lambda x: x[-1-n]))
end_of_months = mon_data.index.tolist()
end_of_months[-1] = data.index[-1]
mon_data.index = end_of_months
mon_data.index = mon_data.index - datetime.timedelta(days=n)
btw: your .set_index(data.index) throw an error because data and mon_data are in different dimensions (mon_data is monthly grouped_by)

Categories