2013-01-10 180 views
0

我想C++类转换为C#和在这个过程中学习的C++的东西。我从来没有遇到之前载体<>和我的理解是,这是像在C#中的列表<>功能。在类的转换过程中,我使用List futures_price = New List(Convert.ToInt32(no_steps)+ 1);重写了代码。只要我运行代码,我会得到一个“索引超出范围”的错误。C# - 索引超出范围

说完看了看周围的SOF,我相信这个问题是关于该参数是出与该指数的范围,但我没有看到一个简单的解决方案与下面的代码解决这个问题。

特别地,这是触发错误的行:futures_prices [0] = spot_price * Math.Pow(d,no_steps);

以下是完整代码:

public double futures_option_price_call_american_binomial(double spot_price, double option_strike, double r, double sigma, double time, double no_steps) 
     { 

      //double spot_price, // price futures contract 
      //double option_strike, // exercise price 
      //double r, // interest rate 
      //double sigma, // volatility 
      //double time, // time to maturity 
      //int no_steps 

      List<double> futures_prices = new List<double>(Convert.ToInt32(no_steps) + 1); 
       //(no_steps+1); 
      //double call_values = (no_steps+1); 
      List<double> call_values = new List<double>(Convert.ToInt32(no_steps) + 1); 

      double t_delta = time/no_steps; 
      double Rinv = Math.Exp(-r*(t_delta)); 
      double u = Math.Exp(sigma * Math.Sqrt(t_delta)); 
      double d = 1.0/u; 
      double uu= u*u; 
      double pUp = (1-d)/(u-d); // note how probability is calculated 
      double pDown = 1.0 - pUp; 

      futures_prices[0] = spot_price * Math.Pow(d, no_steps); 

      int i; 

      for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes 
      for (i=0; i<=no_steps; ++i) call_values[i] = Math.Max(0.0, (futures_prices[i]-option_strike)); 
      for (int step = Convert.ToInt32(no_steps) - 1; step >= 0; --step) 
      { 
       for (i = 0; i <= step; ++i) 
       { 
        futures_prices[i] = d * futures_prices[i + 1]; 
        call_values[i] = (pDown * call_values[i] + pUp * call_values[i + 1]) * Rinv; 
        call_values[i] = Math.Max(call_values[i], futures_prices[i] - option_strike); // check for exercise 
       }; 
      }; 

      return call_values[0]; 
     } 

这里是C++的原始来源:

double futures_option_price_call_american_binomial(const double& F, // price futures contract 
          const double& K, // exercise price 
          const double& r, // interest rate 
          const double& sigma, // volatility 
          const double& time, // time to maturity 
          const int& no_steps) { // number of steps 
    vector<double> futures_prices(no_steps+1); 
    vector<double> call_values (no_steps+1); 
    double t_delta= time/no_steps; 
    double Rinv = exp(-r*(t_delta)); 
    double u = exp(sigma*sqrt(t_delta)); 
    double d = 1.0/u; 
    double uu= u*u; 
    double pUp = (1-d)/(u-d); // note how probability is calculated 
    double pDown = 1.0 - pUp; 
    futures_prices[0] = F*pow(d, no_steps); 
    int i; 
    for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes 
    for (i=0; i<=no_steps; ++i) call_values[i] = max(0.0, (futures_prices[i]-K)); 
    for (int step=no_steps-1; step>=0; --step) { 
     for (i=0; i<=step; ++i) { 
    futures_prices[i] = d*futures_prices[i+1]; 
    call_values[i] = (pDown*call_values[i]+pUp*call_values[i+1])*Rinv; 
    call_values[i] = max(call_values[i], futures_prices[i]-K); // check for exercise 
     }; 
    }; 
    return call_values[0]; 
}; 
+0

为什么'no_steps'是双重的? – SLaks

+0

..以及哪条线产生错误? –

+0

@ SLaks的答案是正确的,这只是一个建议你写C#代码而不是C++的评论。使用var,Integer.Parse(),CamelCase方法名称和属性等等。您可以通过查看其他源代码来获得一个好主意。 – rikkit

回答

0

由于SLaks说,最好在这种情况下使用数组。 C#列表中填充了Add方法,并通过Remove方法删除值...这会更复杂,并且内存/性能也很昂贵,因为您也在替换值。

public Double FuturesOptionPriceCallAmericanBinomial(Double spotPrice, Double optionStrike, Double r, Double sigma, Double time, Double steps) 
{ 
    // Avoid calling Convert multiple times as it can be quite performance expensive. 
    Int32 stepsInteger = Convert.ToInt32(steps); 

    Double[] futurePrices = new Double[(stepsInteger + 1)]; 
    Double[] callValues = new Double[(stepsInteger + 1)]; 

    Double tDelta = time/steps; 
    Double rInv = Math.Exp(-r * (tDelta)); 
    Double u = Math.Exp(sigma * Math.Sqrt(tDelta)); 
    Double d = 1.0/u; 
    Double uu = u * u; 
    Double pUp = (1 - d)/(u - d); 
    Double pDown = 1.0 - pUp; 

    futurePrices[0] = spotPrice * Math.Pow(d, steps); 

    for (Int32 i = 1; i <= steps; ++i) 
     futurePrices[i] = uu * futurePrices[(i - 1)]; 

    for (Int32 i = 0; i <= steps; ++i) 
     callValues[i] = Math.Max(0.0, (futurePrices[i] - optionStrike)); 

    for (Int32 step = stepsInteger - 1; step >= 0; --step) 
    { 
     for (Int32 i = 0; i <= step; ++i) 
     { 
      futurePrices[i] = d * futurePrices[(i + 1)]; 
      callValues[i] = ((pDown * callValues[i]) + (pUp * callValues[i + 1])) * rInv; 
      callValues[i] = Math.Max(callValues[i], (futurePrices[i] - option_strike)); 
     } 
    } 

    return callValues[0]; 
} 
+0

哇!谢谢。这对于了解它是如何构建的非常有帮助。我在上面错过了很多。 – JAS

3

一个List<double>开始是空的,直到你添加项目。 (通过构造参数只是设置容量,防止代价大小调整)

你不能访问[0],直到你Add()它。

要使用它,你的方式,使用数组来代替。

+0

啊,所以我真的应该重新写这个来正确运行。我看到我在这里错过了一些关键部分。 – JAS