期權

使用 Monte Carlo 為雙重障礙期權定價(包括 C++ 和 Python 程式碼)

  • June 14, 2020

我正在嘗試使用收益為 MC 為具有上下障礙的期權定價 $ B_u $ 什麼時候 $ S_t > B_u $ , $ B_l $ 什麼時候 $ S_t < B_l $ 和 $ S_t $ 什麼時候 $ B_l < S_t < B_u $ .

我用 Python 和 C++ 編寫了程式碼,每個結果都相同,但直覺上看起來並不正確。對於以下參數,價格 = 109.991。如果有人對錯誤可能在哪裡/分析解決方案有任何指示,我將不勝感激!

C++:

#include &lt;iostream&gt;
#include &lt;random&gt;
#include &lt;math.h&gt;

// Initialize variables
double s0 = 100;          // Price
double vol = 0.4;         // Volatility
double r = 0.01;          // Interest Rate
double t_ = 255;          // Year
int days = 2;             // Days
int N = pow(10,6);        // Simulations
double b_u = 110;         // Upper Barrier (Rebate)
double b_l = 90;          // Lower Barrier (Rebate)

using namespace std;

std::default_random_engine generator;

double asset_price(double p,double vol,int periods)
{
   double mean = 0.0;
   double stdv = 1.0;

   std::normal_distribution&lt;double&gt; distribution(mean,stdv);

   for(int i=0; i &lt; periods; i++)
   {
       double w = distribution(generator);
       p += s0 * exp((r - 0.5 * pow(vol,2)) * days + vol * sqrt(days) * w);
   }
   return p;
}

int main()
{
   // Monte Carlo Payoffs
   double avg = 0.0;

   for(int j=0; j &lt; N; j++)
   {
       double temp = asset_price(s0,vol,days);
       if(temp &gt; b_u)
       {
           double payoff = b_u;
           payoff = payoff * exp(-r/t_ * days);
           avg += payoff;
       }
       else if(temp &lt; b_l)
       {
           double payoff = b_l;
           payoff = payoff * exp(-r/t_ * days);
           avg += payoff;
       }
       else
       {
           double payoff = temp;
           payoff = payoff * exp(-r/t_ * days);
           avg += payoff;
       }
   }

   // Average Payoff Vector
   double price = avg/(double)N;

   // Results
   cout &lt;&lt; "MONTE CARLO BARRIER OPTION PRICING" &lt;&lt; endl;
   cout &lt;&lt; "----------------------------------" &lt;&lt; endl;
   cout &lt;&lt; "Option price: " &lt;&lt; price &lt;&lt; endl;
   cout &lt;&lt; "Price at t=0: " &lt;&lt; s0 &lt;&lt; endl;
   cout &lt;&lt; "Volatility: " &lt;&lt; vol*100 &lt;&lt; "%" &lt;&lt; endl;
   cout &lt;&lt; "Number of simulations: " &lt;&lt; N &lt;&lt; endl;

   return 0;
}

Python:

import numpy as np
from math import *


def asset_price(p, v, periods):
   w = np.random.normal(0, 1, size=periods)
   for i in range(periods):
       p += s0 * exp((r - 0.5 * v**2) * days + v * sqrt(days) * w[i])
   return p


# Parameters
s0 = 100  # Price
v = 0.4  # Vol
t_ = 255  # Year
r = 0.01  # Interest Rate
days = 2  # Days until option expiration
N = 100000  # Simulations
avg = 0

# Simulation loop
for i in range(N):
   B_U = 110  # Upper barrier
   B_L = 90  # Lower barrier
   temp = asset_price(s0, v, days)
   if temp &gt; B_U:
       payoff = B_U
       payoff = payoff * np.exp(-r / t_ * days)
       avg += payoff
   elif temp &lt; B_L:
       payoff = B_L
       payoff = payoff * np.exp(-r / t_ * days)
       avg += payoff
   else:
       payoff = temp
       payoff = payoff * np.exp(-r / t_ * days)
       avg += payoff

# Average payoffs vector
price = avg / float(N)

# Results
print "MONTE CARLO BARRIER OPTION PRICING"
print "----------------------------------"
print "Option price: ", price
print "Price at t=0: ", s0
print "Volatility: ", v * 100, "%"

您的程式碼中至少存在三個錯誤:

  1. p += s0 * exp(...)應該是p *= exp(...)
  2. 您的波動率和利率是每年,因此在您的函式中將天數除以 365(或 255)asset_price
  3. asset_price你乘以days循環內。但是,循環已經在幾天內迭代 - 因此在您的範例中,您不會採取一天的兩個步驟,而是採取兩天的兩個步驟。

更多建議/評論:

  1. 當您實施定價器時,檢查邊緣情況/限制行為總是有幫助的。例如,在您的情況下,您可以讓B_L = 0, B_H = 1000(high) 並且您的契約價格應該是現貨。這在您的原始程式碼中已經失敗。
  2. 使用全域變數daysr在你的函式asset_price中是不好的風格。函式參數應該代表它的介面。s0但是,您將傳入參數混合在一起,p而只是r從函式內部訪問全域變數。
  3. 請注意,您正在為歐洲障礙期權定價,其中障礙僅在到期時有效。不確定這是否是你的意圖。
  4. 從現在到到期,您每天都在模擬資產價格。由於您只對到期時的價格感興趣(請參閱前一點),您可以在更大的一步中模擬該值。即循環輸入asset_price是多餘的。

以下是修正後的asset_price樣子:

def asset_price(spot, vola, rate, period_count, delta_t):
   w = np.random.normal(0, 1, size=period_count)
   for i in range(period_count):
       spot *= exp((rate - 0.5 * vola**2) * delta_t + vola * sqrt(delta_t) * w[i])
   return spot

你會這樣通過1.0 / 255.0delta_t這是以年為單位的時間步長。同樣,這個函式中的循環實際上是完全多餘的(見備註 4)。

引用自:https://quant.stackexchange.com/questions/38375