2013-11-15 82 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 
}