Skip to content

Commit 3d9387c

Browse files
committed
Add in robustness for Yahoo Finance
1 parent 1e10adc commit 3d9387c

File tree

2 files changed

+69
-83
lines changed

2 files changed

+69
-83
lines changed

financetoolkit/portfolio/overview_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def create_transactions_overview(
4646
percentage_return = []
4747
value_return = []
4848

49-
for row, ticker in enumerate(portfolio_volume.index):
50-
bought_value = portfolio_volume.iloc[row] * portfolio_price.iloc[row] + abs(
49+
for row, (_, ticker) in enumerate(portfolio_volume.index):
50+
bought_value = portfolio_volume.iloc[row] * portfolio_price.iloc[row] - abs(
5151
portfolio_costs.iloc[row]
5252
)
5353

financetoolkit/portfolio/portfolio_controller.py

Lines changed: 67 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,15 @@ def toolkit(self) -> Toolkit:
282282

283283
if self._weekly_historical_data.empty:
284284
self.collect_historical_data()
285+
286+
if self._daily_historical_data.empty:
287+
return pd.DataFrame()
285288
if self._weekly_benchmark_data.empty:
286289
self.collect_benchmark_historical_data()
287290

291+
if self._daily_historical_data.empty:
292+
return pd.DataFrame()
293+
288294
symbols = list(self._tickers) + ["Portfolio"] # type: ignore
289295

290296
historical_columns = self._daily_historical_data.columns.get_level_values(
@@ -609,6 +615,9 @@ def collect_benchmark_historical_data(
609615
if self._weekly_historical_data.empty:
610616
self.collect_historical_data()
611617

618+
if self._daily_historical_data.empty:
619+
return pd.DataFrame()
620+
612621
benchmark_ticker = (
613622
benchmark_ticker
614623
if benchmark_ticker
@@ -793,41 +802,38 @@ def collect_historical_data(
793802
period="daily", progress_bar=progress_bar
794803
)
795804

796-
if self._daily_historical_data.empty:
797-
api_key_check = (
798-
"\nConsider obtaining an API key from FinancialModelingPrep to potentially "
799-
"avoid this issue. You can get 15% "
800-
"off by using the following affiliate link which also supports the project: "
801-
"https://www.jeroenbouma.com/fmp"
802-
if not self._api_key
803-
else ""
804-
)
805-
raise ValueError(
806-
"No historical data found for the provided tickers and therefore no further calculations are possible."
807-
+ api_key_check
805+
if self._daily_historical_data.empty and not self._api_key:
806+
logger.error(
807+
"Failed to collect historical data. Please ensure you have provided valid tickers. "
808+
"Yahoo Finance is unstable and has rate limits which you could have reached.\n"
809+
"Therefore, consider obtaining an API key with the following link: "
810+
"https://www.jeroenbouma.com/fmp. You can get 15% off by using the "
811+
"affiliate link which also supports the project."
808812
)
813+
return pd.DataFrame()
809814

810815
self._daily_historical_data = self._daily_historical_data.rename(
811816
columns=self._ticker_combinations, level=1
812817
)
813818

814819
currency_conversions = {}
815-
if self._currency_column and not self._historical_statistics.empty: # type: ignore
820+
if self._currency_column: # type: ignore
816821
self._historical_statistics = self._toolkit.get_historical_statistics(
817822
progress_bar=False
818823
)
819824
self._historical_statistics = self._historical_statistics.rename(
820825
columns=self._ticker_combinations, level=0
821826
)
822827

823-
for (_, ticker), currency in self._portfolio_dataset[
824-
self._currency_column # type: ignore
825-
].items():
826-
data_currency = self._historical_statistics.loc["Currency", ticker]
827-
if self._historical_statistics.loc["Currency", ticker] != currency:
828-
currency_conversions[ticker] = (
829-
f"{currency}{data_currency}=X".upper()
830-
)
828+
if not self._historical_statistics.empty:
829+
for (_, ticker), currency in self._portfolio_dataset[
830+
self._currency_column # type: ignore
831+
].items():
832+
data_currency = self._historical_statistics.loc["Currency", ticker]
833+
if self._historical_statistics.loc["Currency", ticker] != currency:
834+
currency_conversions[ticker] = (
835+
f"{currency}{data_currency}=X".upper()
836+
)
831837

832838
if currency_conversions:
833839
self._currency_toolkit = Toolkit(
@@ -962,20 +968,16 @@ def get_positions_overview(self, rounding: int | None = None):
962968
| 2025-02-28 | 101 | -14 | 1747.63 | 4932.84 | 2.8226 | 0.0126 | 0.0054 |
963969
"""
964970
if self._weekly_historical_data.empty:
965-
try:
966-
self.collect_historical_data()
967-
except ValueError as error:
968-
raise ValueError(
969-
f"Failed to collect historical data due to {error}"
970-
) from error
971+
self.collect_historical_data()
972+
973+
if self._daily_historical_data.empty:
974+
return pd.DataFrame()
971975

972976
if self._weekly_benchmark_data.empty:
973-
try:
974-
self.collect_benchmark_historical_data()
975-
except ValueError as error:
976-
raise ValueError(
977-
f"Failed to collect benchmark historical data due to {error}"
978-
) from error
977+
self.collect_benchmark_historical_data()
978+
979+
if self._daily_historical_data.empty:
980+
return pd.DataFrame()
979981

980982
if self._transactions_overview.empty:
981983
try:
@@ -1093,20 +1095,16 @@ def get_portfolio_overview(
10931095
| Portfolio | 2142 | -532 | 59.8406 | 128710 | 368.549 | 789432 | 5.1334 | 660721 | 2.0773 | 0.4187 | 0.1937 | 3.0561 | 1.3272 | 1 |
10941096
"""
10951097
if self._weekly_historical_data.empty:
1096-
try:
1097-
self.collect_historical_data()
1098-
except ValueError as error:
1099-
raise ValueError(
1100-
f"Failed to collect historical data: {error}"
1101-
) from error
1098+
self.collect_historical_data()
1099+
1100+
if self._daily_historical_data.empty:
1101+
return pd.DataFrame()
11021102

11031103
if self._weekly_benchmark_data.empty:
1104-
try:
1105-
self.collect_benchmark_historical_data()
1106-
except ValueError as error:
1107-
raise ValueError(
1108-
f"Failed to collect benchmark historical data: {error}"
1109-
) from error
1104+
self.collect_benchmark_historical_data()
1105+
1106+
if self._daily_historical_data.empty:
1107+
return pd.DataFrame()
11101108

11111109
if self._portfolio_volatilities.empty:
11121110
self._portfolio_volatilities = pd.concat(
@@ -1237,20 +1235,16 @@ def get_portfolio_performance(
12371235
period = "quarterly" if self._quarterly else "yearly"
12381236

12391237
if self._weekly_historical_data.empty:
1240-
try:
1241-
self.collect_historical_data()
1242-
except ValueError as error:
1243-
raise ValueError(
1244-
f"Failed to collect historical data: {error}"
1245-
) from error
1238+
self.collect_historical_data()
1239+
1240+
if self._daily_historical_data.empty:
1241+
return pd.DataFrame()
12461242

12471243
if self._weekly_benchmark_data.empty:
1248-
try:
1249-
self.collect_benchmark_historical_data()
1250-
except ValueError as error:
1251-
raise ValueError(
1252-
f"Failed to collect benchmark historical data: {error}"
1253-
) from error
1244+
self.collect_benchmark_historical_data()
1245+
1246+
if self._daily_historical_data.empty:
1247+
return pd.DataFrame()
12541248

12551249
if self._positions_overview.empty:
12561250
try:
@@ -1377,20 +1371,16 @@ def get_transactions_overview(
13771371
)
13781372

13791373
if self._weekly_historical_data.empty:
1380-
try:
1381-
self.collect_historical_data()
1382-
except ValueError as error:
1383-
raise ValueError(
1384-
f"Failed to collect historical data: {error}"
1385-
) from error
1374+
self.collect_historical_data()
1375+
1376+
if self._daily_historical_data.empty:
1377+
return pd.DataFrame()
13861378

13871379
if self._weekly_benchmark_data.empty:
1388-
try:
1389-
self.collect_benchmark_historical_data()
1390-
except ValueError as error:
1391-
raise ValueError(
1392-
f"Failed to collect benchmark historical data: {error}"
1393-
) from error
1380+
self.collect_benchmark_historical_data()
1381+
1382+
if self._daily_historical_data.empty:
1383+
return pd.DataFrame()
13941384

13951385
try:
13961386
new_columns = overview_model.create_transactions_overview(
@@ -1519,20 +1509,16 @@ def get_transactions_performance(
15191509
period = "quarterly" if self._quarterly else "yearly"
15201510

15211511
if self._weekly_historical_data.empty:
1522-
try:
1523-
self.collect_historical_data()
1524-
except ValueError as error:
1525-
raise ValueError(
1526-
f"Failed to collect historical data: {error}"
1527-
) from error
1512+
self.collect_historical_data()
1513+
1514+
if self._daily_historical_data.empty:
1515+
return pd.DataFrame()
15281516

15291517
if self._weekly_benchmark_data.empty:
1530-
try:
1531-
self.collect_benchmark_historical_data()
1532-
except ValueError as error:
1533-
raise ValueError(
1534-
f"Failed to collect benchmark historical data: {error}"
1535-
) from error
1518+
self.collect_benchmark_historical_data()
1519+
1520+
if self._daily_historical_data.empty:
1521+
return pd.DataFrame()
15361522

15371523
if not period:
15381524
raise ValueError(

0 commit comments

Comments
 (0)