2013-01-10 3 views
0

C++ 클래스를 C#으로 변환하려고하는데이 과정에서 C++에 대해 배웁니다. 나는 전에 벡터 <에 뛰어 들어 본 적이 없다. 그리고 내 이해는 C#의 List <> 함수와 같다. 클래스를 변환하는 동안 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#과 같은 C# 코드를 작성하도록 제안하는 것입니다. var, Integer.Parse(), CamelCase 메소드 이름 및 속성 등을 사용하십시오. 다른 소스 코드를 보면 좋은 생각을 얻을 수 있습니다. – rikkit

답변

0

SLaks에 따르면,이 상황에서 Array를 사용하는 것이 좋습니다. 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>가 비어 밖으로 시작

다음은 전체 코드입니다. (생성자 인수를 전달하면 값 비싼 크기 조정을 막기 위해 용량이 설정됩니다.)

Add()까지는 [0]에 액세스 할 수 없습니다.

그대로 사용하려면 대신 배열을 사용하십시오.

+0

아, 그래서이 기능을 제대로하려면 다시 써야합니다. 나는 핵심 부분을 놓치고있는 것을 본다. – JAS

관련 문제