Skip to content

Commit c57d95a

Browse files
committed
fix: _min_ratio_asset was fixed in multi_period.py
1 parent c6294e0 commit c57d95a

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

okama/frontier/multi_period.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,12 @@ def minimize_risk(self, target_value: float) -> Dict[str, float]:
486486
n = self.assets_ror.shape[1] # number of assets
487487
init_guess = np.repeat(1/n, n) # initial weights
488488

489-
min_ratio_data = self._best_ratio_asset
489+
min_ratio_data = self._min_ratio_asset
490490
max_ratio_data = self._max_ratio_asset_right_to_max_cagr
491491

492492
if min_ratio_data is not None and max_ratio_data is not None:
493493
init_guess = np.repeat(0, n) # clear weights
494-
init_guess[self._best_ratio_asset["list_position"]] = 1.0
494+
init_guess[self._min_ratio_asset["list_position"]] = 1.0
495495

496496
def objective_function(w):
497497
# annual risk
@@ -600,7 +600,7 @@ def _max_cagr_asset(self) -> dict:
600600
}
601601

602602
@property
603-
def _best_ratio_asset(self) -> Optional[dict]:
603+
def _min_ratio_asset(self) -> Optional[dict]:
604604
"""
605605
The asset with the minimum ratio between the CAGR
606606
(Compound Annual Growth Rate) and the risk for assets that are "to the left"
@@ -610,39 +610,36 @@ def _best_ratio_asset(self) -> Optional[dict]:
610610
risk_monthly = self.assets_ror.std()
611611
mean_return = self.assets_ror.mean()
612612
risk = helpers.Float.annualize_risk(risk_monthly, mean_return)
613-
tolerance = 0.01
614613

615614
global_max_cagr = self.global_max_return_portfolio["CAGR"]
616615
global_max_risk = self.global_max_return_portfolio["Risk"]
617-
618-
global_max_cagr_is_not_asset = (cagr < global_max_cagr * (1 - tolerance)).all()
619-
if global_max_cagr_is_not_asset:
620-
cagr_diff = global_max_cagr - cagr
621-
risk_diff = global_max_risk - risk
616+
617+
cagr_diff = global_max_cagr - cagr
618+
risk_diff = global_max_risk - risk
622619

623-
if risk_diff is not None and (risk_diff == 0).any():
624-
risk_diff += 0.0001 # to avoid division by zero
620+
if risk_diff is not None and (risk_diff == 0).any():
621+
risk_diff += 0.0001 # to avoid division by zero
625622

626-
ratio = cagr_diff / risk_diff
627-
left_assets = risk_diff > 0
623+
ratio = cagr_diff / risk_diff
624+
left_assets = risk_diff > 0
628625

629-
if left_assets.any():
630-
valid_ratios = ratio[left_assets]
631-
min_ticker = valid_ratios.idxmin()
632-
return {
633-
"min_asset_cagr": cagr[min_ticker],
634-
"ticker_with_smallest_ratio": min_ticker,
635-
"list_position": self.assets_ror.columns.get_loc(min_ticker)
636-
}
637-
if not left_assets.any():
638-
right_assets = risk_diff < 0
639-
valid_ratios = ratio[right_assets]
640-
min_ticker = valid_ratios.idxmin()
641-
return {
642-
"min_asset_cagr": cagr[min_ticker],
643-
"ticker_with_smallest_ratio": min_ticker,
644-
"list_position": self.assets_ror.columns.get_loc(min_ticker)
645-
}
626+
if left_assets.any():
627+
valid_ratios = ratio[left_assets]
628+
min_ticker = valid_ratios.idxmin()
629+
return {
630+
"min_asset_cagr": cagr[min_ticker],
631+
"ticker_with_smallest_ratio": min_ticker,
632+
"list_position": self.assets_ror.columns.get_loc(min_ticker)
633+
}
634+
if not left_assets.any():
635+
right_assets = risk_diff < 0
636+
valid_ratios = ratio[right_assets]
637+
min_ticker = valid_ratios.idxmin()
638+
return {
639+
"min_asset_cagr": cagr[min_ticker],
640+
"ticker_with_smallest_ratio": min_ticker,
641+
"list_position": self.assets_ror.columns.get_loc(min_ticker)
642+
}
646643
return None
647644

648645

@@ -701,7 +698,7 @@ def _target_cagr_range_left(self) -> np.ndarray:
701698
"""
702699
Full range of CAGR values (from min to max).
703700
"""
704-
min_ratio_data = self._best_ratio_asset
701+
min_ratio_data = self._min_ratio_asset
705702
max_ratio_data = self._max_ratio_asset_right_to_max_cagr
706703

707704
if min_ratio_data is not None and max_ratio_data is not None:

0 commit comments

Comments
 (0)