@@ -1968,10 +1968,11 @@ def kstest(self, distr: str = "norm") -> Dict[str, float]:
19681968
19691969 Parameters
19701970 ----------
1971- distr : {'norm', 'lognorm'}, default 'norm'
1971+ distr : {'norm', 'lognorm', 't' }, default 'norm'
19721972 The name of a distribution to fit.
19731973 'norm' - for normal distribution.
19741974 'lognorm' - for lognormal distribution.
1975+ 't' - for Student's T distribution
19751976
19761977
19771978 Notes
@@ -2159,17 +2160,19 @@ def plot_hist_fit(self, distr: str = "norm", bins: int = None) -> None:
21592160 if distr == "norm" : # Generate PDF
21602161 mu , std = scipy .stats .norm .fit (data )
21612162 p = scipy .stats .norm .pdf (x , mu , std )
2163+ title = f"Fit results: mu = { mu :.3f} , std = { std :.3f} "
21622164 elif distr == "lognorm" :
21632165 std , loc , scale = scipy .stats .lognorm .fit (data )
21642166 mu = np .log (scale )
21652167 p = scipy .stats .lognorm .pdf (x , std , loc , scale )
2168+ title = f"Fit results: mu = { mu :.3f} , std = { std :.3f} "
21662169 elif distr == "t" :
21672170 df , loc , scale = scipy .stats .t .fit (data )
21682171 p = scipy .stats .t .pdf (x , loc = loc , scale = scale , df = df )
2172+ title = f"Fit results: df = { df :.3f} , loc = { loc :.3f} , scale = { scale :.3f} "
21692173 else :
21702174 raise ValueError ('distr must be "norm" (default) or "lognorm".' )
21712175 plt .plot (x , p , "k" , linewidth = 2 )
2172- title = "Fit results: mu = %.3f, std = %.3f" % (mu , std )
21732176 plt .title (title )
21742177 plt .show ()
21752178
@@ -2741,11 +2744,11 @@ def cashflow_pv(self) -> Optional[float]:
27412744 return None
27422745
27432746 @property
2744- def monte_carlo_wealth (self ) -> pd .DataFrame :
2747+ def monte_carlo_wealth_fv (self ) -> pd .DataFrame :
27452748 """
2746- Portfolio random wealth indexes with cash flows (withdrawals/contributions) by Monte Carlo simulation.
2749+ Portfolio not discounted random wealth indexes with cash flows (withdrawals/contributions) by Monte Carlo simulation.
27472750
2748- Monte Carlo simulation generates n random monthly time series.
2751+ Monte Carlo simulation generates n random monthly time series (not discounted) .
27492752 Each wealth index is calculated with rate of return time series of a given distribution.
27502753
27512754 First date of forecasted returns is portfolio last_date.
@@ -2768,7 +2771,7 @@ def monte_carlo_wealth(self) -> pd.DataFrame:
27682771 >>> ind.amount = -500 # set withdrawal size
27692772 >>> ind.frequency = "year" # set withdrawal frequency
27702773 >>> pf.dcf.cashflow_parameters = ind # assign cash flow strategy to portfolio
2771- >>> pf.dcf.monte_carlo_wealth .plot()
2774+ >>> pf.dcf.monte_carlo_wealth_fv .plot()
27722775 >>> plt.legend("") # don't show legend for each line
27732776 >>> plt.show()
27742777 """
@@ -2836,7 +2839,7 @@ def monte_carlo_wealth_pv(self) -> pd.DataFrame:
28362839 >>> plt.legend("") # no legend is required
28372840 >>> plt.show()
28382841 """
2839- wealth_df = self .monte_carlo_wealth .copy ()
2842+ wealth_df = self .monte_carlo_wealth_fv .copy ()
28402843 wealth_df_pv = pd .DataFrame ()
28412844 for n , row in enumerate (wealth_df .iterrows ()):
28422845 w = row [1 ]
@@ -2902,13 +2905,13 @@ def plot_forecast_monte_carlo(
29022905 years = months / settings ._MONTHS_PER_YEAR
29032906 periods = years / settings .frequency_periods_per_year [self .cashflow_parameters .frequency ]
29042907 self .cashflow_parameters .amount *= (1.0 + self .cashflow_parameters .indexation ) ** periods
2905- s2 = self .monte_carlo_wealth
2908+ s2 = self .monte_carlo_wealth_fv
29062909 for s in s2 :
29072910 s2 [s ].plot (legend = None )
29082911 self .cashflow_parameters = backup_obj
29092912 self .use_discounted_values = backup
29102913 else :
2911- s2 = self .monte_carlo_wealth
2914+ s2 = self .monte_carlo_wealth_fv
29122915 s2 .plot (legend = None )
29132916 self .cashflow_parameters ._clear_cf_cache ()
29142917
@@ -2957,7 +2960,7 @@ def monte_carlo_survival_period(self, threshold: float = 0) -> pd.Series:
29572960 >>> s.quantile(50 / 100)
29582961 np.float64(17.5)
29592962 """
2960- s2 = self .monte_carlo_wealth
2963+ s2 = self .monte_carlo_wealth_fv
29612964 dates : pd .Series = helpers .Frame .get_survival_date (s2 , self .discount_rate , threshold )
29622965 return dates .apply (helpers .Date .get_period_length , args = (self .parent .last_date ,))
29632966
@@ -3147,7 +3150,7 @@ def distribution(self) -> str:
31473150 @distribution .setter
31483151 def distribution (self , distribution ):
31493152 validators .validate_distribution (distribution )
3150- self .parent . _monte_carlo_wealth = pd . DataFrame ()
3153+ self ._clear_cf_cache ()
31513154 self ._distribution = distribution
31523155
31533156 @property
@@ -3164,7 +3167,7 @@ def period(self) -> int:
31643167 @period .setter
31653168 def period (self , period ):
31663169 validators .validate_integer ("period" , period )
3167- self .parent . _monte_carlo_wealth = pd . DataFrame ()
3170+ self ._clear_cf_cache ()
31683171 self ._period = period
31693172
31703173 @property
@@ -3181,10 +3184,10 @@ def number(self) -> int:
31813184 @number .setter
31823185 def number (self , mc_number ):
31833186 validators .validate_integer ("mc_number" , mc_number )
3184- self .parent . _monte_carlo_wealth = pd . DataFrame ()
3187+ self ._clear_cf_cache ()
31853188 self ._mc_number = mc_number
31863189
3187- def _clear_wealth_data (self ):
3190+ def _clear_cf_cache (self ):
31883191 self .parent ._monte_carlo_wealth = pd .DataFrame ()
31893192
31903193
@@ -3207,7 +3210,7 @@ def __init__(self, parent: Portfolio):
32073210 @property
32083211 def frequency (self ) -> str :
32093212 """
3210- The frequency of regualr withdrawals or contributions in the strategy.
3213+ The frequency of regular withdrawals or contributions in the strategy.
32113214
32123215 Allowed values for frequency:
32133216
0 commit comments