#!/usr/bin/env python #-*- coding:utf-8 -*- from black_scholes import BS_Call, BS_Put, BS_Call_IV, BS_Put_IV import random,math def effectiveWeight_Call(S0,C0,K,T,DT,R,V1=None,V=None,mu=None,cacheNum=20000,newtonNum=10,seed=0): """対数最適戦略に基づいた、無リスク資産とコールオプションのポートフォリオにおける最適比率を求めます。 引数: S0:現在の原資産の価格 C0:現在のコール価格 K:権利行使価格 T:現在における、満期までの残り時間 DT:1期間の長さ R:無リスク利率 V1:1期間における原資産のボラティリティ (指定されない場合は原資産のボラティリティから推定します。) V:原資産のボラティリティ (指定されない場合はコール価格からインプライドボラティリティを算出します。) mu:原資産の1期間後における予想成長率 (指定されない場合は原資産の変動の期待値が0となるような値に調整されます。) cacheNum:キャッシュする量 newtonNum:ニュートン法を行なう回数 seed:シード 戻り値: コールオプションのウェイト、対数期待予想成長比率、予想成長比率のタプルを返します。 """ #各自初期化 cache = [] random.seed(seed) vol = float(V) if V else BS_Call_IV(S0,K,T,R,C0,HV=0.2,maxNum=200) vol1 = float(V1) if V1 else vol*math.sqrt(DT) avg = float(mu) if mu else -0.5*vol1*vol1 for i in range(cacheNum): #対数正規分布に基づいて未来の価格を算出 S = S0*random.lognormvariate(avg, vol1) cnd = C0 / (BS_Call(S,K,T-DT,R,vol)-C0) cache.append(cnd) best_alpha = _newtonsMethod(newtonNum,0,cache) best_m = _m(best_alpha,cache) return (best_alpha,best_m,math.exp(best_m)) def _newtonsMethod(num,init_alpha,cache,i=1): """ニュートン法を用いて対数最適戦略でmを最大にするαの値を求めます。 """ if i > num: return init_alpha else: delta = _m_alpha(init_alpha, cache)/_m2_alpha2(init_alpha, cache) new_alpha = init_alpha - delta return _newtonsMethod(num, new_alpha, cache, i+1) def _m(alpha,cache): """対数成長率mの値を求めます。 """ total = sum([math.log( (alpha/x) + 1 ) for x in cache]) return total / len(cache) def _m_alpha(alpha,cache): """mをαで偏微分した関数です。 """ total = sum([1.0/(alpha + x) for x in cache]) return total / len(cache) def _m2_alpha2(alpha,cache): """mの2階偏微分関数です。 """ total = sum([-1.0/((alpha + x)**2) for x in cache]) return total / len(cache)