Got things to work finally.
Still things to do (one bug discovered, see TODOs)
This commit is contained in:
parent
62cbceba6f
commit
9dff170bb7
@ -3,7 +3,7 @@ import pandas as pd
|
|||||||
|
|
||||||
|
|
||||||
class SimpleStockData:
|
class SimpleStockData:
|
||||||
def __init__(self, ticker_list: list, period_start: str, period_end: str, to_currency: str = ""):
|
def __init__(self, ticker_list: list, period_start: str, period_end: str, to_currency: str, ohcl: str = "Close"):
|
||||||
"""
|
"""
|
||||||
:param period_start:
|
:param period_start:
|
||||||
start date (format YYYY-MM-DD)
|
start date (format YYYY-MM-DD)
|
||||||
@ -11,14 +11,16 @@ class SimpleStockData:
|
|||||||
end date (format YYYY-MM-DD)
|
end date (format YYYY-MM-DD)
|
||||||
:param ticker_list:
|
:param ticker_list:
|
||||||
list containing all stocks/exchange rates (yfinance considers both as "Tickers")
|
list containing all stocks/exchange rates (yfinance considers both as "Tickers")
|
||||||
|
Example: []
|
||||||
:param to_currency:
|
:param to_currency:
|
||||||
currency to convert rates to
|
currency to convert rates to (e.g. EUR)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ticker_list = ticker_list
|
self.ticker_list = ticker_list
|
||||||
self.to_currency = to_currency
|
self.to_currency = to_currency.upper() # make it uppercase
|
||||||
self._period_start = period_start
|
self._period_start = period_start
|
||||||
self._period_end = period_end
|
self._period_end = period_end
|
||||||
|
self._ohcl = ohcl.capitalize()
|
||||||
|
|
||||||
self._exchange_df = None # Mapping: time mapped to conversion factor, to get the right converted value per date
|
self._exchange_df = None # Mapping: time mapped to conversion factor, to get the right converted value per date
|
||||||
self._create_exchange_dataframe() # initialize self.exchange_df attribute
|
self._create_exchange_dataframe() # initialize self.exchange_df attribute
|
||||||
@ -43,7 +45,7 @@ class SimpleStockData:
|
|||||||
The mapping is recreated by this function following the information in the
|
The mapping is recreated by this function following the information in the
|
||||||
_from_currency_list.
|
_from_currency_list.
|
||||||
return:
|
return:
|
||||||
boolean
|
boolean - success or not
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# check if a to_currency is even given
|
# check if a to_currency is even given
|
||||||
@ -54,26 +56,29 @@ class SimpleStockData:
|
|||||||
_from_currency_list = []
|
_from_currency_list = []
|
||||||
for i in range(len(self.ticker_list)): # to get all indexes; this adds an entry for each currency
|
for i in range(len(self.ticker_list)): # to get all indexes; this adds an entry for each currency
|
||||||
add_currency = f"{self.get_info(i, 'currency')}{self.to_currency}=X" # Format: "fffttt=X" f=from, t=to
|
add_currency = f"{self.get_info(i, 'currency')}{self.to_currency}=X" # Format: "fffttt=X" f=from, t=to
|
||||||
|
add_currency = add_currency.upper() # make everything uppercase
|
||||||
# for the case that FROM and TO are equal, just don't download the data (as conversion factor's 1)
|
# for the case that FROM and TO are equal, just don't download the data (as conversion factor's 1)
|
||||||
if add_currency == f"{self.to_currency}{self.to_currency}=X":
|
if add_currency == f"{self.to_currency}{self.to_currency}=X":
|
||||||
pass
|
pass
|
||||||
elif add_currency not in _from_currency_list: # add a new item if not already there
|
elif add_currency not in _from_currency_list: # add a new item if not already there
|
||||||
_from_currency_list.append(add_currency)
|
_from_currency_list.append(add_currency)
|
||||||
|
|
||||||
print(_from_currency_list)
|
|
||||||
|
|
||||||
# now the real process begins
|
# now the real process begins
|
||||||
tickers = yf.Tickers(" ".join(_from_currency_list)) # create a new Ticker instance with all wanted currencies
|
tickers = yf.Tickers(" ".join(_from_currency_list)) # create a new Ticker instance with all wanted currencies
|
||||||
exchange_rates = []
|
|
||||||
for i in tickers.tickers: # get all the history of each currency conversion factors
|
|
||||||
# for simplicity: using the conversion factor of closing (.Close at the end)
|
|
||||||
exchange_rates.append(tickers.tickers[i].history(start=self._period_start, end=self._period_end).Close)
|
|
||||||
|
|
||||||
self._exchange_df = pd.DataFrame(
|
exchange_rates = [] # temporary variable where all exchange rates are stored in (as objects of pd.Series)
|
||||||
exchange_rates).T # transpose the dataframe (imagine just switching rows and columns)
|
for er_name in tickers.tickers: # get all the history of each currency conversion factors
|
||||||
self._exchange_df.columns = _from_currency_list # set the right names for the columns in the dataframe
|
# for simplicity: using the conversion factor of closing (.Close at the end)
|
||||||
self._exchange_df[
|
exchange_rates.append((tickers.tickers[er_name].history(start=self._period_start, end=self._period_end)[self._ohcl], er_name))
|
||||||
f"{self.to_currency}{self.to_currency}=X"] = 1.0 # for FROM and TO being equal: set factor to 1
|
# now exchange_rates contains tuples of the form (ticker, er_name) where er_name is the name of the
|
||||||
|
# currency ticker, used only internal in this method (_from_currency_list variable). The index is now taken
|
||||||
|
# to set the right names for every row in the dataframe
|
||||||
|
|
||||||
|
# now, the rates are taken from the exchange_rates list and are all wrapped up in a beautiful DataFrame
|
||||||
|
self._exchange_df = pd.DataFrame()
|
||||||
|
for exchange_rate, er_name in exchange_rates:
|
||||||
|
self._exchange_df[er_name] = exchange_rate
|
||||||
|
self._exchange_df[f"{self.to_currency}{self.to_currency}=X"] = 1.0 # for FROM and TO being equal: set factor to 1
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -102,20 +107,45 @@ class SimpleStockData:
|
|||||||
:param convert:
|
:param convert:
|
||||||
decides if the resulting values should be converted to the specified to_convert currency (given at
|
decides if the resulting values should be converted to the specified to_convert currency (given at
|
||||||
object creation)
|
object creation)
|
||||||
:return: pandas.DataFrame
|
:return: pandas.DataFrame (with extra columns for the converted value if wanted)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: Not working. Something is wrong with the access to the _exchange_df via [].
|
result = self._get_history(idx, interval)[self._ohcl].to_frame()
|
||||||
|
|
||||||
result = self._get_history(idx, interval)
|
|
||||||
result["Ticker Index"] = idx
|
result["Ticker Index"] = idx
|
||||||
ticker_currency = self.get_info(idx, "currency")
|
ticker_currency = self.get_info(idx, "currency").upper() # upper it as sometimes it doesn't fit
|
||||||
|
|
||||||
if convert:
|
if convert:
|
||||||
value_list = ["Open", "High", "Low", "Close"]
|
exrate_name = f"{ticker_currency}{self.to_currency}=X"
|
||||||
for value in value_list:
|
result["ex_rate_name"] = exrate_name
|
||||||
result["rating_name"] = f"{ticker_currency}{self.to_currency}=X"
|
ex_rate_series = self._exchange_df[exrate_name]
|
||||||
result["rating"] = self._exchange_df[f"{ticker_currency}{self.to_currency}=X"]
|
|
||||||
result[f"{value}.conv"] = result[value] / result["rating"]
|
# now there's a result dataframe with ticker, currency, rate name etc. as column names
|
||||||
|
# to add only matching ex rates per day (sometimes there are more days with exchange rates recorded than
|
||||||
|
# share prices), the result df has to be transposed so that the following function df.append can select
|
||||||
|
# by columns. TODO: implement the bug fix when not the exact same timestamps and amount of data are given in both the series and the df
|
||||||
|
"""
|
||||||
|
result = result.T
|
||||||
|
|
||||||
|
ex_rate_df = ex_rate_df.to_list()
|
||||||
|
print(ex_rate_df)
|
||||||
|
result.append(ex_rate_df[result.columns], ignore_index=True) # magic - see above :)
|
||||||
|
result = result.T # transpose back
|
||||||
|
result[f"{self._ohcl} in {self.to_currency}"] = result[self._ohcl] / result["ex_rate"]
|
||||||
|
"""
|
||||||
|
|
||||||
|
result["ex_rate"] = ex_rate_series.to_list()
|
||||||
|
result[f"{self._ohcl} in {self.to_currency}"] = result[self._ohcl] / result["ex_rate"]
|
||||||
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
ssd = SimpleStockData(["RHM.DE", "BAS.DE", "AZN.L"], "2024-01-02", "2024-01-18", "EUR")
|
||||||
|
print(ssd.get_info(0))
|
||||||
|
print(ssd.get_info(1))
|
||||||
|
print(ssd.get_info(2))
|
||||||
|
|
||||||
|
print(ssd.get_history(0))
|
||||||
|
print(ssd.get_history(1))
|
||||||
|
print(ssd.get_history(2))
|
Loading…
Reference in New Issue
Block a user