Real-time data from yfinance - python

I am trying to get real rime data from yfinance with following code.
But I just get the same close/high/low/open results.
I am starting to think that it is impossible with yfinance. Is there any free and european alternatives?
Thanks a lot in advance!!
#import libraries
import schedule
import time
import alpaca_trade_api as tradeapi
import yfinance as yf
import pandas as pd
# Ask what stocks you want to check
pd = pd.DataFrame()
n = int(input("Enter the size of the list "))
print("\n")
numList = list(num for num in input("Enter the list numbers separated by space ").strip().split())[:n]
print("User List: ", numList)
# Get info for every stock chosen.
def get_data():
for ticker in numList:
ticker_yahoo = yf.Ticker(ticker)
data = ticker_yahoo.history(period = "1d", interval="1m")
data = (data.tail(1).iloc[0])
pd[ticker] = data
print(pd)
get_data()

It is faster to do it with Pandas Datareader by using get_quote_yahoo() method
import pandas_datareader as web
tickers = ["MSFT", "XOM", "KKR"]
current_price = web.get_quote_yahoo(tickers)["regularMarketPrice"]
If you insist on using yfinance, you can use the following code, but beware that it will be MUCH SLOWER This is because 1) instantiating Ticker object and pulling the info property takes time, and 2) it is inconvenient to use Tickers class (as opposed to Ticker), so you have to use a for a loop.
import yfinance as yf
tickers = ["MSFT", "XOM", "KKR"]
current_price = list()
for i in range(len(tickers)):
company = yf.Ticker(ticker[i])
current_price[i] = company.info["regularMarketPrice"]
Obviously, these solutions apply to other types of securities as well. Note though that using this (or any other free) data source for algorithmic trading with real money is impossible at best due to requests limit, high latency, stability issues etc.

Related

Can't access tickers with dots using yfinance

I cannot access tickers of football clubs that include dots using yfinance (specifically the Tickers function). For example, when looking for BVB.DE, it says "No timezone found, symbol may be delisted". How should I fix this?
Please see my code below. I have seen some answers claiming that removing the dot or including a dash instead should work, but it does not.
import yfinance as yf
import pandas as pd
etiquetas = yf.Tickers('MANU JVTSF GSRAY-IS')
ticker_club1 = 'MANU'
ticker_club2 = 'JVTSF'
ticker_club3 = 'GSRAY-IS'
hist = etiquetas.history(start=fecha_entrada, end=fecha_salida)
precios = hist['Open']
pd.DataFrame.tail(precios)
pd.set_option('display.max_rows', 20)
print(precios)

Big O notation : limited input

As an exercise, I am trying to set Monte Carlo Simulation on a chosen ticker symbol.
from numpy.random import randint
from datetime import date
from datetime import timedelta
import pandas as pd
import yfinance as yf
from math import log
# ticker symbol
ticker_input = "AAPL" # change
# start day + endday for Yahoo Finance API, 5 years of data
start_date = date.today()
end_date = start_date - timedelta(days=1826)
# retrieve data from Yahoo Finance
data = yf.download(ticker_input, end_date,start_date)
yf_data = data.reset_index()
# dataframe : define columns
df = pd.DataFrame(columns=['date', "ln_change", 'open_price', 'random_num'])
open_price = []
date_historical = []
for column in yf_data:
open_price = yf_data["Open"].values
date_historical = yf_data["Date"].values
# list order: descending
open_price[:] = open_price[::-1]
date_historical[:] = date_historical[::-1]
# Populate data into dataframe
for i in range(0, len(open_price)-1):
# date
day = date_historical[i]
# ln_change
lnc = log(open_price[i]/open_price[i+1], 2)
# random number
rnd = randint(1, 1258)
# op = (open_price[i]) open price
df.loc[i] = [day, open_price[i], lnc, rnd]
I was wondering how to calculate Big O if you have e.g. nested loops or exponential complexity but have a limited input like one in my example, maximum input size is 1259 instances of float number. Input size is not going to change.
How do you calculate code complexity in that scenario?
It is a matter of points of view. Both ways of seeing it are technically correct. The question is: What information do you wish to convey to the reader?
Consider the following code:
quadraticAlgorithm(n) {
for (i <- 1...n)
for (j <- 1...n)
doSomethingConstant();
}
quadraticAlgorithm(1000);
The function is clearly O(n2). And yet the program will always run in the same, constant time, because it just contains one function call with n=1000. It is still perfectly valid to refer to the function as O(n2). And we can refer to the program as O(1).
But sometimes the boundaries are not that clear. Then it is up to you to choose if you wish to see it as an algorithm with a time complexity as some function of n, or as a piece of constant code that runs in O(1). The importance is to make it clear to the reader how you define things.

What is the fastest way to iterate through a list of yfinance tickers?

Im using the python yfinance yahoo API for stock data retrieval. Right now im getting the peg ratio, which is an indicator of a company price related to its growth and earnings. I have a csv downloaded from here: https://www.nasdaq.com/market-activity/stocks/screener.
It has exactly 8000 stocks.
What I do is get the symbol list, and iterate it to access to the yahoo ticker. Then I get a use the ticker.info method which returns a dictionary. I iterate this process through the 8000 symbols. It goes at a speed of 6 symbols per minute, which is not viable. Is there a faster way with another API or another structure? I dont care about the API as long as I can get basic info as the growth, earnings, EPS and those things.
Here is the code:
import pandas as pd
import yfinance as yf
data = pd.read_csv("data/stock_list.csv")
symbols = data['Symbol']
for symbol in symbols:
stock = yf.Ticker(symbol)
try:
if stock.info['pegRatio']:
print(stock.info['shortName'] + " : " + str(stock.info['pegRatio']))
except KeyError:
pass
It seems that when certain data are needed from the Ticker.info attribute, HTTP requests are made to acquire them. Multithreading will help to improve matters. Try this:-
import pandas as pd
import yfinance as yf
import concurrent.futures
data = pd.read_csv('data/stock_list.csv')
def getPR(symbol):
sn = None
pr = None
try:
stock = yf.Ticker(symbol)
pr = stock.info['pegRatio']
sn = stock.info['shortName']
except Exception:
pass
return (sn, pr)
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = {executor.submit(getPR, sym): sym for sym in data['Symbol']}
for future in concurrent.futures.as_completed(futures):
sn, pr = future.result()
if sn:
print(f'{sn} : {pr}')

yfinance api return multiple ticker data

I am trying to pull out multiple ticker data from the yfinance API and save it to a csv file (in total I have 1000 tickers I need to get the data for, that data being the entire table of date, open, high, low, close, volume, etc etc), so far I am able to successfully get data for 1 ticker by using the following Python code:
import yfinance as yf
def yfinance(ticker_symbol):
ticker_data = yf.Ticker(ticker_symbol)
tickerDF = ticker_data.history(period='1d', start='2020-09-30', end='2020-10-31')
print(tickerDF)
yfinance('000001.SS')
However if I try on multiple tickers this doesn't work. Following the yfinance docs which say for multiple tickers use:
tickers = yf.Tickers('msft aapl goog')
# ^ returns a named tuple of Ticker objects
# access each ticker using (example)
tickers.tickers.MSFT.info
tickers.tickers.AAPL.history(period="1mo")
tickers.tickers.GOOG.actions
I have a couple of issue here, the docs use a string such as 'aapl' my tickers are all of digit format like '000001.SS', the ".SS" part is proving to be an issue when passing it into the code:
tickers.tickers.000001.SS.history(period="1mo")
# Clearly this wont for for a start
The next issue I am having is, even if I pass in for example 3 tickers to my function like so:
yfinance('000001.SS 000050.KS 00006.KS')
# similar to yfinance docs of tickers = yf.Tickers('msft aapl goog')
I get errors like:
AttributeError: 'Tickers' object has no attribute '000001.SS'
(I have also tried to run these into a for loop and pass each on to the Tickers object but get the same error.)
Im stuck now, I dont know how to pass in multiple tickers to yfinance and get back data that I want and the docs aren't very helpful.
Is anyone able to help me with this?
Could you not just store them in an array specifying the type as dtype object then use that pull the data from.
import yfinance as yf
import numpy as np
tickers = ['msft', 'aapl', 'goog']
totalPortfolio = np.empty([len(tickers)], dtype=object)
num = 0
for ticker in tickers:
totalPortfolio[num] = yf.download(ticker, start='2020-09-30', end='2020-10-31', interval="1d")
num = num + 1
Take a look at the code below:
test = yf.Tickers("A B C")
# creates test as a yf.tickers object
test_dict = test.tickers
# creates a dict object containing the individual tickers. Can be checked with type()
You are trying to use "tickers.tickers.MSFT.info" to retrieve the ticker data from your dictionary "tickers.tickers" but like your error message says, a dict object has no attributes named after your specific ticker names. This is in general not how you access elements in a dictionary.
Instead you should use the code as below (like with all dict objects):
#old code from above
test = yf.Tickers("A B C")
test_dict = test.tickers
#new code accessing the dict correctly
a_data = test_dict["A"]
a_data = test.tickers["A"] #does the same as the line above
b_data = test.tickers["B"] #and so on for the other tickers
In a loop this could look something like this:
ticker_list = ["A", "B", "C"] #add tickers as needed
tickers_data = {}
tickers_history = {}
for ticker in ticker_list:
tickers_data[ticker] = yf.Ticker(ticker)
tickers_history = tickers_data[ticker].history(period='1d', start='2020-09-30', end='2020-10-31')
#access the dicts as needed using tickers_data[" your ticker name "]
alternatively you can also use the "yf.Tickers" function to retrieve multiple tickers at once, but because you save the history seperately I don't think this will necessarily improve your code much.
You should pay attention however, that "yf.Ticker()" and "yf.Tickers()" are different functions from each other with differing syntax and are not interchangeable.
You did mix that up when you tried accessing multiple tickers with your custom "yfinance()" function, that has been previously defined with the "yf.Ticker()" function and thus only accepts one symbol at a time.

Pandas: 52 week high from yahoo or google finance

Does anyone know if you can get the 52 week high in pandas from either yahoo or google finance? Thanks.
It is possible, please check out pandas documentation. Here's an example:
import pandas.io.data as web
import datetime
symbol = 'aapl'
end = datetime.datetime.now()
start = end - datetime.timedelta(weeks=52)
df = web.DataReader(symbol, 'yahoo', start, end)
highest_high = df['High'].max()
One can also use yfinance(from yahoo)
pip install finance
import yfinance as yf
stock = "JNJ"
dataframe = yf.download(stock, period="1y", auto_adjust=True, prepost=True, threads=True)
max = dataframe['High'].max()
You could also use other libraries such as yahoo_fin. This one works better sometimes, it would depend on what you want to do, but it's good to bear in mind other possibilities : )
import yfinance as yf
import yahoo_fin.stock_info as si
stock = 'AAPL'
df = yf.download(stock, period="1y")
print("$",round(df['High'].max(), 2))
df2 = si.get_data(stock, interval="1mo")
print("$",round(df2['high'].tail(12).max(), 2))
Output:
$ 182.94
$ 182.94
You can use the info keyword to return lots of aggregated data like P/E Ratio, 52-Week High,etc.
import yfinance as yf
data = yf.Ticker(ticker).info
print(data.fiftyTwoWeekHigh)

Categories

Resources