株価が〇円以下になると失効する(ダウン・アンド・アウト)

二項モデルで評価するコード

 プレーンバニラのコードに、失効した場合の処理が33行目から37行目に追加されているだけです。また、満期までの期間の一部期間のみで判定する場合も、その一部期間内でのみ失効の判定がなされるよう変更するだけです。なお、インプットにはバリア\(H\)が追加されています。

library(Rcpp)

cppFunction('
double BM_do(double S0, double K, double H, int end_step, int ex_start, double u, double d, double df, double p) {

  NumericMatrix c_step((end_step+1), 7);
  NumericMatrix n_step((end_step+1), 7);
  
  for(int step = end_step; step >= 0; step--) {
  
    for(int node_no = 0; node_no <= step; node_no++) {
      double S = S0 * pow(u, (step - node_no)) * pow(d, node_no);
      double hd_v = 0; // 保有価値
      double ex_v = 0; // 行使価値
      double op_v = 0; // オプション価値

      if(step == end_step) {
        // 満期時のノードの場合
        hd_v = 0;
        ex_v = S - K;
        op_v = (ex_v > hd_v) ? ex_v : hd_v;
        c_step(node_no, 6) = (S > K) ? 1 : 0;
        
      } else if (step == 0) {
        // t=0(評価基準日)のノードの場合
        hd_v = df * (p*n_step(node_no, 5) + (1-p)*n_step(node_no+1, 5));
        ex_v = 0;
        op_v = (ex_v > hd_v) ? ex_v : hd_v;
        op_v = hd_v;
        
      } else {
        // 0<t<Tのノードの場合
        if(S < H) { // プレーンと比べて、ここが追加されるだけ
          hd_v = 0; 
          ex_v = 0;
          op_v = 0;
          c_step(node_no, 6) = 2; // 失効は「2」を入れることにする

        } else {
          hd_v = df * (p*n_step(node_no, 5) + (1-p)*n_step(node_no+1, 5));
        
          if(step < ex_start) {
            // 待機期間中の場合
            ex_v = 0;
            op_v = hd_v;
            c_step(node_no, 6) = 0;
          } else {
            // 行使可能期間中の場合
            ex_v = S - K;
            op_v = (ex_v > hd_v) ? ex_v : hd_v;
            c_step(node_no, 6) = (ex_v > hd_v) ? 1 : 0;
           }
         }
       }
      
      c_step(node_no, 0) = step;
      c_step(node_no, 1) = node_no;
      c_step(node_no, 2) = S;
      c_step(node_no, 3) = hd_v;
      c_step(node_no, 4) = ex_v;
      c_step(node_no, 5) = op_v;
    }
    
    // ファイルの出力
    // Function f("write.csv");
    // String file_name = "testcase/check"; file_name += step; file_name += ".csv";
    // f(c_step(Range(0, step) , _ ), Named("file")=file_name);
    
    n_step = clone(c_step);
  }
  
  return(c_step(0, 5));

}
')

ある時点(barrier start step)以降でのみバリア判定を行いたい場合は、33行目

if(S < H) {

 を

if( step > barrier _ start _ step & S < H) {

 とするだけです。

使い方

 インプットにバリア\(H\)を追加するだけです。

# インプット
{
  # バリア
  H <- 500
}

BM_do(S0, K, H, end_step, ex_start, u, d, df, p)

行使行動についての考察

 プレーンバニラの場合と同様、testcase フォルダに出力されるcheck〇.csvファイルを辿っていくことにより行使境界を可視化できます。

  1. \( K \ge H \)で配当がない場合
    早期行使は起こりません。解析解で評価を行うことで問題なさそうです。
  2. \( K \ge H \)で配当がある場合
    早期行使が起こりますので、その影響を反映するためには二項モデルを採用します。
  3. \( K < H \)の場合(1円SOの場合、また、未上場企業で\( K < H=S(0) \)とする場合など) 配当がゼロであっても早期行使が起こりえます。発行後即時行使可能である場合、ダウン・アンド・アウト条件が付いていても失効することはなく(注)、評価額の圧縮効果は限定的となります。行使可能となるまでに待機期間がある場合には、待機期間中の失効により評価額はいくらか圧縮されます
  4. (注)\( H \)のすぐ上の株価に到達した時点で行使されます。