Skip to content

Commit 8e3587f

Browse files
committed
refactor: format code with black
1 parent bfa528c commit 8e3587f

26 files changed

+1231
-586
lines changed

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ nbsphinx-link>=1.3.0
66
pandoc>=1.1.0
77
recommonmark==0.7.1
88
ipython>=7.20.0
9-
jinja2<3.1
9+
jinja2<3.0.0

okama/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@
3939
from okama.common.helpers.helpers import Float, Frame, Rebalance, Date
4040
import okama.settings
4141

42-
__version__ = version('okama')
42+
__version__ = version("okama")

okama/api/api_methods.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class API:
99
"""
1010
Set of methods to get data from API.
1111
"""
12+
1213
# TODO: introduce 'from' & 'to' for dates.
1314

1415
api_url = "http://api.okama.io:5000"
@@ -39,20 +40,24 @@ def connect(
3940
period: str = "d",
4041
) -> str:
4142
session = requests.session()
42-
retry_strategy = Retry(total=3,
43-
backoff_factor=0.1,
44-
status_forcelist=[429, 500, 502, 503, 504])
43+
retry_strategy = Retry(
44+
total=3, backoff_factor=0.1, status_forcelist=[429, 500, 502, 503, 504]
45+
)
4546
adapter = HTTPAdapter(max_retries=retry_strategy)
4647
request_url = cls.api_url + endpoint + symbol
4748
params = {"first_date": first_date, "last_date": last_date, "period": period}
4849
session.mount("https://", adapter)
4950
session.mount("http://", adapter)
5051
try:
51-
r = session.get(request_url, params=params, verify=False, timeout=cls.default_timeout)
52+
r = session.get(
53+
request_url, params=params, verify=False, timeout=cls.default_timeout
54+
)
5255
r.raise_for_status()
5356
except requests.exceptions.HTTPError as errh:
5457
if r.status_code == 404:
55-
raise requests.exceptions.HTTPError(f"{symbol} is not found in the database.", 404) from errh
58+
raise requests.exceptions.HTTPError(
59+
f"{symbol} is not found in the database.", 404
60+
) from errh
5661
raise requests.exceptions.HTTPError(
5762
f"HTTP error fetching data for {symbol}:",
5863
r.status_code,

okama/api/data_queries.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ def get_adj_close(
110110

111111
@staticmethod
112112
def get_dividends(
113-
symbol: str, first_date: str = "1913-01-01", last_date: str = "2100-01-01",
113+
symbol: str,
114+
first_date: str = "1913-01-01",
115+
last_date: str = "2100-01-01",
114116
) -> pd.Series:
115117
"""
116118
Dividends time series daily data (dividend payment day should be considered).

okama/api/namespaces.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ def get_namespaces():
1414

1515

1616
@lru_cache()
17-
def symbols_in_namespace(namespace: str = settings.default_namespace, response_format: str = 'frame') -> pd.DataFrame:
17+
def symbols_in_namespace(
18+
namespace: str = settings.default_namespace, response_format: str = "frame"
19+
) -> pd.DataFrame:
1820
string_response = api_methods.API.get_symbols_in_namespace(namespace.upper())
1921
list_of_symbols = json.loads(string_response)
20-
if response_format.lower() == 'frame':
22+
if response_format.lower() == "frame":
2123
df = pd.DataFrame(list_of_symbols[1:], columns=list_of_symbols[0])
2224
return df.astype("string", copy=False)
23-
elif response_format.lower() == 'json':
25+
elif response_format.lower() == "json":
2426
return list_of_symbols
2527
else:
2628
raise ValueError('response_format must be "json" or "frame"')

okama/api/search.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,29 @@
88

99

1010
@lru_cache()
11-
def search(search_string: str, namespace: Optional[str] = None, response_format: str = 'frame') -> json:
11+
def search(
12+
search_string: str, namespace: Optional[str] = None, response_format: str = "frame"
13+
) -> json:
1214
# search for string in a single namespace
1315
if namespace:
1416
df = namespaces.symbols_in_namespace(namespace.upper())
15-
condition1 = df['name'].str.contains(search_string, case=False)
16-
condition2 = df['ticker'].str.contains(search_string, case=False)
17-
condition3 = df['isin'].str.contains(search_string, case=False)
17+
condition1 = df["name"].str.contains(search_string, case=False)
18+
condition2 = df["ticker"].str.contains(search_string, case=False)
19+
condition3 = df["isin"].str.contains(search_string, case=False)
1820
frame_response = df[condition1 | condition2 | condition3]
19-
if response_format.lower() == 'frame':
21+
if response_format.lower() == "frame":
2022
return frame_response
21-
elif response_format.lower() == 'json':
22-
return frame_response.to_json(orient='records')
23+
elif response_format.lower() == "json":
24+
return frame_response.to_json(orient="records")
2325
else:
2426
raise ValueError('response_format must be "json" or "frame"')
2527
# search for string in all namespaces
2628
string_response = api_methods.API.search(search_string)
2729
json_response = json.loads(string_response)
28-
if response_format.lower() == 'frame':
30+
if response_format.lower() == "frame":
2931
df = pd.DataFrame(json_response[1:], columns=json_response[0])
3032
return df
31-
elif response_format.lower() == 'json':
33+
elif response_format.lower() == "json":
3234
return json_response
3335
else:
3436
raise ValueError('response_format must be "json" or "frame"')

okama/asset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def close_daily(self):
105105
Series
106106
Time series of close price historical data (daily).
107107
"""
108-
return data_queries.QueryData.get_close(self.symbol, period='D')
108+
return data_queries.QueryData.get_close(self.symbol, period="D")
109109

110110
@property
111111
def close_monthly(self):
@@ -142,7 +142,7 @@ def adj_close(self):
142142
Series
143143
Time series of adjusted close price historical data (daily).
144144
"""
145-
return data_queries.QueryData.get_adj_close(self.symbol, period='D')
145+
return data_queries.QueryData.get_adj_close(self.symbol, period="D")
146146

147147
@property
148148
def dividends(self) -> pd.Series:

okama/asset_list.py

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def semideviation_annual(self) -> pd.Series:
218218
SHV.US 0.000560
219219
dtype: float64
220220
"""
221-
return helpers.Frame.get_semideviation(self.assets_ror) * 12 ** 0.5
221+
return helpers.Frame.get_semideviation(self.assets_ror) * 12**0.5
222222

223223
def get_var_historic(self, time_frame: int = 12, level: int = 1) -> pd.Series:
224224
"""
@@ -365,14 +365,16 @@ def recovery_periods(self) -> pd.Series:
365365
max_recovery_periods = pd.Series(dtype=int)
366366
for name in self.symbols:
367367
namespace = name.split(".", 1)[-1]
368-
if namespace == 'INFL':
368+
if namespace == "INFL":
369369
continue
370370
s = growth[name]
371371
s1 = s.where(s == 0).notnull().astype(int)
372372
s1_1 = s.where(s == 0).isnull().astype(int).cumsum()
373373
s2 = s1.groupby(s1_1).cumsum()
374374
# Max recovery period date should not be in the border (it's not recovered)
375-
max_period = s2.max() if s2.idxmax().to_timestamp() != self.last_date else np.NAN
375+
max_period = (
376+
s2.max() if s2.idxmax().to_timestamp() != self.last_date else np.NAN
377+
)
376378
ser = pd.Series(max_period, index=[name])
377379
max_recovery_periods = pd.concat([max_recovery_periods, ser])
378380
return max_recovery_periods
@@ -491,7 +493,9 @@ def get_rolling_cagr(self, window: int = 12, real: bool = False) -> pd.DataFrame
491493
df = self._add_inflation()
492494
if real:
493495
df = self._make_real_return_time_series(df)
494-
return helpers.Frame.get_rolling_fn(df, window=window, fn=helpers.Frame.get_cagr)
496+
return helpers.Frame.get_rolling_fn(
497+
df, window=window, fn=helpers.Frame.get_cagr
498+
)
495499

496500
def get_cumulative_return(
497501
self, period: Union[str, int, None] = None, real: bool = False
@@ -553,7 +557,9 @@ def get_cumulative_return(
553557
"Real cumulative return is not defined (no inflation information is available)."
554558
"Set inflation=True in AssetList to calculate it."
555559
)
556-
cumulative_inflation = helpers.Frame.get_cumulative_return(self.inflation_ts[dt:])
560+
cumulative_inflation = helpers.Frame.get_cumulative_return(
561+
self.inflation_ts[dt:]
562+
)
557563
cr = (1.0 + cr) / (1.0 + cumulative_inflation) - 1.0
558564
cr.drop(self.inflation, inplace=True)
559565
return cr
@@ -602,7 +608,10 @@ def get_rolling_cumulative_return(
602608
if real:
603609
df = self._make_real_return_time_series(df)
604610
return helpers.Frame.get_rolling_fn(
605-
df, window=window, fn=helpers.Frame.get_cumulative_return, window_below_year=True
611+
df,
612+
window=window,
613+
fn=helpers.Frame.get_cumulative_return,
614+
window_below_year=True,
606615
)
607616

608617
@property
@@ -692,7 +701,9 @@ def describe(
692701
ytd_return = self.get_cumulative_return(period="YTD")
693702
row = ytd_return.to_dict()
694703
row.update(period="YTD", property="Compound return")
695-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
704+
description = pd.concat(
705+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
706+
)
696707
# CAGR for a list of periods
697708
if self.pl.years >= 1:
698709
for i in years:
@@ -702,32 +713,46 @@ def describe(
702713
else:
703714
row = {x: None for x in df.columns}
704715
row.update(period=f"{i} years", property="CAGR")
705-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
716+
description = pd.concat(
717+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
718+
)
706719
# CAGR for full period
707720
row = self.get_cagr(period=None).to_dict()
708721
row.update(period=self._pl_txt, property="CAGR")
709-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
722+
description = pd.concat(
723+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
724+
)
710725
# Dividend Yield
711726
row = self.assets_dividend_yield.iloc[-1].to_dict()
712727
row.update(period="LTM", property="Dividend yield")
713-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
728+
description = pd.concat(
729+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
730+
)
714731
# risk for full period
715732
row = self.risk_annual.to_dict()
716733
row.update(period=self._pl_txt, property="Risk")
717-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
734+
description = pd.concat(
735+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
736+
)
718737
# CVAR
719738
if self.pl.years >= 1:
720739
row = self.get_cvar_historic().to_dict()
721740
row.update(period=self._pl_txt, property="CVAR")
722-
description = pd.concat([description,pd.DataFrame(row, index=[0])], ignore_index=True)
741+
description = pd.concat(
742+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
743+
)
723744
# max drawdowns
724745
row = self.drawdowns.min().to_dict()
725746
row.update(period=self._pl_txt, property="Max drawdowns")
726-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
747+
description = pd.concat(
748+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
749+
)
727750
# max drawdowns dates
728751
row = self.drawdowns.idxmin().to_dict()
729752
row.update(period=self._pl_txt, property="Max drawdowns dates")
730-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
753+
description = pd.concat(
754+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
755+
)
731756
# inception dates
732757
row = {}
733758
for ti in self.symbols:
@@ -737,7 +762,9 @@ def describe(
737762
row.update(period=None, property="Inception date")
738763
if hasattr(self, "inflation"):
739764
row.update({self.inflation: self.inflation_first_date.strftime("%Y-%m")})
740-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
765+
description = pd.concat(
766+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
767+
)
741768
# last asset date
742769
row = {}
743770
for ti in self.symbols:
@@ -747,11 +774,15 @@ def describe(
747774
row.update(period=None, property="Last asset date")
748775
if hasattr(self, "inflation"):
749776
row.update({self.inflation: self.inflation_last_date.strftime("%Y-%m")})
750-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
777+
description = pd.concat(
778+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
779+
)
751780
# last data date
752781
row = {x: self.last_date.strftime("%Y-%m") for x in df.columns}
753782
row.update(period=None, property="Common last data date")
754-
description = pd.concat([description, pd.DataFrame(row, index=[0])], ignore_index=True)
783+
description = pd.concat(
784+
[description, pd.DataFrame(row, index=[0])], ignore_index=True
785+
)
755786
# rename columns
756787
if hasattr(self, "inflation"):
757788
description.rename(columns={self.inflation: "inflation"}, inplace=True)
@@ -929,7 +960,9 @@ def get_dividend_mean_growth_rate(self, period=5) -> pd.Series:
929960
growth_ts = self.dividends_annual.pct_change().iloc[
930961
1:-1
931962
] # Slice the last year for full dividends
932-
growth_ts.replace([np.inf, -np.inf, np.nan], 0, inplace=True) # replace possible nan and inf
963+
growth_ts.replace(
964+
[np.inf, -np.inf, np.nan], 0, inplace=True
965+
) # replace possible nan and inf
933966
dt0 = self.last_date
934967
dt = helpers.Date.subtract_years(dt0, period)
935968
return ((growth_ts[dt:] + 1.0).prod()) ** (1 / period) - 1.0
@@ -1011,12 +1044,12 @@ def tracking_difference_annual(self) -> pd.DataFrame:
10111044
>>> al.tracking_difference_annual.plot(kind='bar')
10121045
"""
10131046
result = pd.DataFrame()
1014-
for x in self.assets_ror.resample('Y'):
1047+
for x in self.assets_ror.resample("Y"):
10151048
df = x[1]
10161049
wealth_index = helpers.Frame.get_wealth_indexes(df)
10171050
row = helpers.Index.tracking_difference(wealth_index).iloc[[-1]]
10181051
result = pd.concat([result, row], ignore_index=False)
1019-
result.index = result.index.asfreq('Y')
1052+
result.index = result.index.asfreq("Y")
10201053
return result
10211054

10221055
@property
@@ -1390,11 +1423,14 @@ def get_sharpe_ratio(self, rf_return: float = 0) -> pd.Series:
13901423
BND.US 0.390814
13911424
dtype: float64
13921425
"""
1393-
mean_return = self.mean_return.drop(self.inflation) if self.inflation else self.mean_return
1426+
mean_return = (
1427+
self.mean_return.drop(self.inflation)
1428+
if self.inflation
1429+
else self.mean_return
1430+
)
13941431
return ratios.get_sharpe_ratio(
1395-
pf_return=mean_return,
1396-
rf_return=rf_return,
1397-
std_deviation=self.risk_annual)
1432+
pf_return=mean_return, rf_return=rf_return, std_deviation=self.risk_annual
1433+
)
13981434

13991435
def get_sortino_ratio(self, t_return: float = 0) -> pd.Series:
14001436
"""
@@ -1421,9 +1457,17 @@ def get_sortino_ratio(self, t_return: float = 0) -> pd.Series:
14211457
BND.US 0.028969
14221458
dtype: float64
14231459
"""
1424-
mean_return = self.mean_return.drop(self.inflation) if self.inflation else self.mean_return
1425-
semideviation = helpers.Frame.get_below_target_semideviation(ror=self.assets_ror, t_return=t_return) * 12 ** 0.5
1460+
mean_return = (
1461+
self.mean_return.drop(self.inflation)
1462+
if self.inflation
1463+
else self.mean_return
1464+
)
1465+
semideviation = (
1466+
helpers.Frame.get_below_target_semideviation(
1467+
ror=self.assets_ror, t_return=t_return
1468+
)
1469+
* 12**0.5
1470+
)
14261471
return ratios.get_sortino_ratio(
1427-
pf_return=mean_return,
1428-
t_return=t_return,
1429-
semi_deviation=semideviation)
1472+
pf_return=mean_return, t_return=t_return, semi_deviation=semideviation
1473+
)

0 commit comments

Comments
 (0)