/// <summary> /// downside risk (deviation, variance) of the return distribution /// Downside deviation, semideviation, and semivariance are measures of downside /// risk. /// </summary> // = "full" // = false //func DownsideDeviation(Ra *utils.SlidingWindow, MAR *utils.SlidingWindow, method string, potential bool) float64 { func DownsideDeviation(Ra *utils.SlidingWindow, MAR *utils.SlidingWindow) (float64, error) { if Ra == nil { return math.NaN(), errors.New("In DownsideDeviation, Ra == nil") } if Ra.Count() <= 0 { return math.NaN(), errors.New("In DownsideDeviation, Ra.Count() <= 0") } r, err := utils.NewSlidingWindow(Ra.Count()) if err != nil { return math.NaN(), err } newMAR, err := utils.NewSlidingWindow(Ra.Count()) if err != nil { return math.NaN(), err } len := 0.0 result := 0.0 for i := 0; i < Ra.Count(); i++ { if Ra.Data()[i] < MAR.Data()[i] { r.Add(Ra.Data()[i]) newMAR.Add(MAR.Data()[i]) } } potential := false method := "subset" if method == "full" { len = float64(Ra.Count()) } else if method == "subset" { len = float64(r.Count()) } else { return math.NaN(), errors.New("In DownsideDeviation, method default !!!") } if newMAR.Count() <= 0 || r.Count() <= 0 || len <= 0 { return math.NaN(), errors.New("In DownsideDeviation, newMAR.Count() <= 0 || r.Count() <= 0 || len <= 0") } if potential { sub_Sliding, err := utils.Sub(newMAR, r) if err != nil { return math.NaN(), err } result = sub_Sliding.Sum() / len } else { sub_Sliding, err := utils.Sub(newMAR, r) if err != nil { return math.NaN(), err } pow_Sliding, err := utils.Power(sub_Sliding, 2.0) if err != nil { return math.NaN(), err } result = math.Sqrt(pow_Sliding.Sum() / len) } return result, nil }
/// <summary> /// epsilon与R中不同,但似乎没有影响 /// Specific risk is the standard deviation of the error term in the /// regression equation. /// </summary> func SpecificRisk(Ra *utils.SlidingWindow, Rb *utils.SlidingWindow, scale float64, Rf float64) (float64, error) { //Period = Frequency(Ra) alpha, err := Alpha2(Ra, Rb, Rf) if err != nil { return math.NaN(), err } beta, err := Beta2(Ra, Rb, Rf) if err != nil { return math.NaN(), err } add_Ra_Sliding, err := utils.Add(-Rf, Ra) if err != nil { return math.NaN(), err } add_Rb_Sliding, err := utils.Add(-Rf, Rb) if err != nil { return math.NaN(), err } multi_beta_Slidinig, err := utils.Multi(beta, add_Rb_Sliding) if err != nil { return math.NaN(), err } sub_Ra_Beta, err := utils.Sub(add_Ra_Sliding, multi_beta_Slidinig) if err != nil { return math.NaN(), err } epsilon, err := utils.Add(-alpha, sub_Ra_Beta) if err != nil { return math.NaN(), err } var_eps, err := Variance(epsilon) if err != nil { return math.NaN(), err } var result = math.Sqrt(var_eps*float64(epsilon.Count()-1)/float64(epsilon.Count())) * math.Sqrt(float64(scale)) return result, nil }
/// <summary> /// Appraisal ratio is the Jensen's alpha adjusted for specific risk. The numerator /// is divided by specific risk instead of total risk. /// </summary> func AppraisalRatio(Ra *utils.SlidingWindow, Rb *utils.SlidingWindow, scale float64, Rf float64, method string) (float64, error) { var result = 0.0 switch method { case "appraisal": be_data, err := Beta2(Ra, Rb, Rf) if err != nil { return math.NaN(), err } multi_Sliding, err := utils.Multi(be_data, Rb) if err != nil { return math.NaN(), err } sub_Sliding, err := utils.Sub(Ra, multi_Sliding) if err != nil { return math.NaN(), err } al_data, err := Alpha2(Ra, Rb, Rf) if err != nil { return math.NaN(), err } epsilon, err := utils.Add(-al_data, sub_Sliding) if err != nil { return math.NaN(), err } add_Sliding, err := utils.Add(-epsilon.Average(), epsilon) if err != nil { return math.NaN(), err } pow_Sliding, err := utils.Power(add_Sliding, 2) if err != nil { return math.NaN(), err } specifikRisk := math.Sqrt(pow_Sliding.Sum()/float64(epsilon.Count())) * math.Sqrt(float64(scale)) jsa_data, err := JensenAlpha2(Ra, Rb, Rf, scale) if err != nil { return math.NaN(), err } result = jsa_data / specifikRisk break case "modified": jsa2_data, err := JensenAlpha2(Ra, Rb, Rf, scale) if err != nil { return math.NaN(), err } be2_data, err := Beta2(Ra, Rb, Rf) if err != nil { return math.NaN(), err } result = jsa2_data / be2_data break case "alternative": jsa2_data, err := JensenAlpha2(Ra, Rb, Rf, scale) if err != nil { return math.NaN(), err } sr_data, err := SystematicRisk(Ra, Rb, scale, Rf) if err != nil { return math.NaN(), err } result = jsa2_data / sr_data break default: return math.NaN(), errors.New("In AppraisalRatio, method is default !!!") } return result, nil }