2013-11-15 55 views
1

我的问题是关于计算条件收益加班。这有点难以描述,如果某些部分不清楚,请让我澄清。我有一个C#WinForm应用程序,它读取两个数据系列,一个是产品返回数超时,另一个是索引返回数超时。当指数收益率为正数时,我称该时期为“上涨市场”。我创建了一个子列表来存储与每个“上市”相对应的所有产品退货编号,以及另一个子列表来存储与每个“减少市场”相对应的所有产品退货编号。C#计算条件收益

for (int i = 0; i < ProductReturnRawData.Count; i++) 
{ 
    if (primaryIndexReturnRawData[i] >= 0) 
    { 
     upMarketWealth.Add(1 + ProductReturnRawData[i]/100); 
    } 

    else if (primaryIndexReturnRawData[i] < 0) 
    { 
     downMarketWealth.Add(1 + ProductReturnRawData[i]/100); 
    } 
} 

在创建upMarketWealth列表后,我使用另一个函数来计算产品的回报,因为市场已经到了。

private double check_period_upMarket(
    List<double> upMarketWealth, int months, int go_back = 0) 
{ 
    double return_calc = 1; 
    for (int i = upMarketWealth.Count - 1 - go_back; 
     i > upMarketWealth.Count - (1 + months + go_back); i--) 
    return_calc *= upMarketWealth[i]; 
    return Math.Pow(return_calc, 12.0/upMarketWealth.Count) - 1; 
} 

最后,我把这个check_period_upMarket功能是这样的:

StatsTable[Tuple.Create(period, "Up-Market Return")] = 
    check_period_upMarket(upMarketWealth, 12); 

所以在这里我想在过去的12个月内知道,多少个月均达到市场(upMarketWealth.Count想给我的答案),以及市场上涨时产品的年化收益。

我手动计算Excel上的数字,它不符合此代码的结果。

实施例:索引返回在过去12个月{-0.08 0.95 -1.34 -2.36 3.25 5.24 -0.88 -0.38 1.39 0.48 0.73 0.57 } 产品回流过同期{-0.03 0.12 -0.06 -2.03 1.15 2.06 0.35 0.47 1.65 -0.20 0.79 1.17 }。

所以upMarket清单应该有{0.12,1.15,2.06,1.65,0.20,0.79,1.17}。创建由

upMarketWealth.Add(1 + ProductReturnRawData[i]/100); 

丰富的名单,然后

return_calc *= upMarketWealth[i]; 
return Math.Pow(return_calc, 12.0/upMarketWealth.Count) - 1; 

正确的答案应该是12.16%,而代码中有10%。请帮我在这里找到错误。请问我澄清,如果有什么不明确的。

+0

也许你已经有了整数除法发生的地方,你没有想到。什么类型是'primaryIndexReturnRawData'? –

+0

这是一个列表 Eddie

+0

您是否尝试将d追加到所有常量的末尾,例如upMarketWealth.Add(1d + ProductReturnRawData [i]/100d);? –

回答

0

如前所述,代码完全不能工作,只能扔IndexOutOfRangeException

问题是通过构建upMarketWealthdownMarketWealth列表你有效地收缩数据 - 省略分别为'上'或'下'的月份项。您应该将1.0放入列表中。另一方面,check_period_upMarket中的for循环不尊重此行为,并计算不正确的界限。此外,Math.Pow呼叫在当时结束时错误地假定列表中项目的数量对应于“最多”月份的数量。相反,这应该作为参数传入。

工作小例子,产生预期的输出:

private double check_period_upMarket(List<double> upMarketWealth, int upMonths, int months, int go_back = 0) 
{ 
    double return_calc = 1; 
    for (int i = upMarketWealth.Count - 1 - go_back; i > upMarketWealth.Count - 1 - go_back - months; i--) 
    { 
     return_calc *= upMarketWealth[i]; 
    } 
    return Math.Pow(return_calc, 12.0/upMonths) - 1; 
} 

void Main() 
{ 
    List<double> primaryIndexReturnRawData = new List<double> {-0.08, 0.95, -1.34, -2.36, 3.25, 5.24, -0.88, -0.38, 1.39, 0.48, 0.73, 0.57 }; 
    List<double> ProductReturnRawData = new List<double> {  -0.03, 0.12, -0.06, -2.03, 1.15, 2.06, 0.35, 0.47, 1.65, -0.20, 0.79, 1.17 }; 

    List<double> upMarketWealth = new List<double>(); 
    List<double> downMarketWealth = new List<double>(); 

    int upMonths = 0; 
    int downMonths = 0; 

    for (int i = 0; i < ProductReturnRawData.Count; i++) 
    { 
     if (primaryIndexReturnRawData[i] >= 0) 
     { 
      upMarketWealth.Add(1 + ProductReturnRawData[i]/100); 
      downMarketWealth.Add(1.0); 
      upMonths++; 
     } 
     else if (primaryIndexReturnRawData[i] < 0) 
     { 
      upMarketWealth.Add(1.0); 
      downMarketWealth.Add(1 + ProductReturnRawData[i]/100); 
      downMonths++; 
     } 
    } 

    Console.WriteLine(check_period_upMarket(upMarketWealth, upMonths, 12)); 
    // output: 0.121499259430152 
}