/* 課題５ */

/* ［数値処理］→［自動的に数値で出力］*/
if numer#false then numer:false else numer:true;
/*浮動小数点の桁数=7に指定 */
fpprec : 7;
/* 浮動小数点表示桁数を7に指定*/
fpprintprec:7;

/* (I) */
mart_call(r,u,d,S,K):=
(
q : (r-d) / (u-d) /* リスク中立測度を計算する */,
C0 : (q*max(S *(1+u)-K,0) + (1-q)*max(S * (1+d)-K,0))/(1+r) 
/* リスク中立測度による期待値を計算 */, 
print(" コールオプション価格 =", C0 )
);

mart_call(0.02,0.1,-0.09,100,100);

/* (II)  */
mart_call2(r,u,S0,K,T,dt):=
(
d : 1/(1+u)-1,
q : (r*dt-d) / (u-d) /*リスク中立測度*/, 
N : truncate(T/dt) /* truncate () は引数の整数部分を返す関数 */, 
C0 :sum(max((1+u) ^j* (1+d) ^ (N-j) *S0-K,0) * binomial(N,j) *q^j* (1-q) ^ (N-j) / (1+r*dt)^N, j, 0, N),
print( " コールオプション価格=", C0 )
);

mart_call2(0.02,0.1,100,110,1,0.02);

/* (II) An Alternative */
mart_call_2a(r,u,S0,K,T,dt):=
(
d : 1/(1+u)-1,
N : truncate (T/dt), 
q : (r*dt -d) / (u-d), 
/* 危険資産の下方推移が行使価格を下回らない回数の最小値を求める*/
a : ceiling(log(K/S0/(1+d)^N )/ log((1+u)/(1+d))), 
/* そのときのコールオプションのペイオフを期待値へと加算していく*/
tmp : sum(
((1+u) ^j* (1+d) ^ (N-j) *S0-K) * binomial(N,j) *q^j* (1-q) ^ (N-j) / (1+r*dt)^N, j, a, N),
print(" マルチンゲール測度 q_u=",q, ", ", " コールオプション価格 =", tmp )
);

mart_call_2a(0.02,0.1,100,110,1,0.02);