Skip to content

Commit 69dbf74

Browse files
committed
Handle dividends with FX, convert if repair=True
1 parent 4f9b6d6 commit 69dbf74

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

yfinance/scrapers/history.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,24 @@ def history(self, period="1mo", interval="1d",
328328
splits = utils.set_df_tz(splits, interval, tz_exchange)
329329
if dividends is not None:
330330
dividends = utils.set_df_tz(dividends, interval, tz_exchange)
331+
if 'currency' in dividends.columns:
332+
# Rare, only seen with Vietnam market
333+
price_currency = self._history_metadata['currency']
334+
if price_currency is None:
335+
price_currency = ''
336+
f_currency_mismatch = dividends['currency'] != price_currency
337+
if f_currency_mismatch.any():
338+
if not repair or price_currency == '':
339+
# Append currencies to values, let user decide action.
340+
dividends['Dividends'] = dividends['Dividends'].astype(str) + ' ' + dividends['currency']
341+
else:
342+
# Attempt repair = currency conversion
343+
dividends = self._dividends_convert_fx(dividends, price_currency, repair)
344+
if (dividends['currency'] != price_currency).any():
345+
# FX conversion failed
346+
dividends['Dividends'] = dividends['Dividends'].astype(str) + ' ' + dividends['currency']
347+
dividends = dividends.drop('currency', axis=1)
348+
331349
if capital_gains is not None:
332350
capital_gains = utils.set_df_tz(capital_gains, interval, tz_exchange)
333351
if start is not None:
@@ -1019,6 +1037,45 @@ def _standardise_currency(self, df, currency):
10191037

10201038
return df, currency2
10211039

1040+
def _dividends_convert_fx(self, dividends, fx, repair=False):
1041+
bad_div_currencies = [c for c in dividends['currency'].unique() if c != fx]
1042+
major_currencies = ['USD', 'JPY', 'EUR', 'CNY', 'GBP', 'CAD']
1043+
for c in bad_div_currencies:
1044+
fx2_tkr = None
1045+
if c == 'USD':
1046+
# Simple convert from USD to target FX
1047+
fx_tkr = f'{fx}=X'
1048+
reverse = False
1049+
elif fx == 'USD':
1050+
# Use same USD FX but reversed
1051+
fx_tkr = f'{fx}=X'
1052+
reverse = True
1053+
elif c in major_currencies and fx in major_currencies:
1054+
# Simple convert
1055+
fx_tkr = f'{c}{fx}=X'
1056+
reverse = False
1057+
else:
1058+
# No guarantee that Yahoo has direct FX conversion, so
1059+
# convert via USD
1060+
# - step 1: -> USD
1061+
fx_tkr = f'{c}=X'
1062+
reverse = True
1063+
# - step 2: USD -> FX
1064+
fx2_tkr = f'{fx}=X'
1065+
1066+
fx_dat = PriceHistory(self._data, fx_tkr, self.session)
1067+
fx_rate = fx_dat.history(period='1mo', repair=repair)['Close'].iloc[-1]
1068+
if reverse:
1069+
fx_rate = 1/fx_rate
1070+
dividends.loc[dividends['currency']==c, 'Dividends'] *= fx_rate
1071+
if fx2_tkr is not None:
1072+
fx2_dat = PriceHistory(self._data, fx2_tkr, self.session)
1073+
fx2_rate = fx2_dat.history(period='1mo', repair=repair)['Close'].iloc[-1]
1074+
dividends.loc[dividends['currency']==c, 'Dividends'] *= fx2_rate
1075+
1076+
dividends['currency'] = fx
1077+
return dividends
1078+
10221079
@utils.log_indent_decorator
10231080
def _fix_unit_mixups(self, df, interval, tz_exchange, prepost):
10241081
if df.empty:

yfinance/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,10 @@ def parse_actions(data):
519519
dividends.set_index("date", inplace=True)
520520
dividends.index = _pd.to_datetime(dividends.index, unit="s")
521521
dividends.sort_index(inplace=True)
522-
dividends.columns = ["Dividends"]
522+
if 'currency' in dividends.columns and (dividends['currency'] == '').all():
523+
# Currency column useless, drop it.
524+
dividends = dividends.drop('currency', axis=1)
525+
dividends = dividends.rename(columns={'amount': 'Dividends'})
523526

524527
if "capitalGains" in data["events"] and len(data["events"]['capitalGains']) > 0:
525528
capital_gains = _pd.DataFrame(

0 commit comments

Comments
 (0)