4

BS モデルの金融ギリシャ語を計算する関数をコーディングしようとしています。
私は次のようなことから始めました:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    tau = np.linspace(t, T, num = T)
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
    d2 = d1 - sigma*np.sqrt(tau)

    delta_call = np.exp(-q*tau) * norm.cdf(d1)
    delta_put = -np.exp(-q*tau) * norm.cdf(-d1)
    ...

    return {'d1':d1, 'd2': d2, 'delta_call': delta_call, 'delta_put': delta_put, ...}

「...」は、より多くのギリシャ語が計算されていることを意味しますが、ここでは重要ではありません。
それは正常に機能していました。妥当な値、素敵なプロットなどがありました。しかし、私の先生は、これらの値を時間 (x 軸のタウ) だけでなく、S (S - 株価、x 軸) に対しても見たいと言いました。言い換えれば、タウと S の両方の変化に対してギリシャ語を計算する必要があります。

私は次のことを試しました:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    S = np.linspace(1, S, num = S)

    tau = np.linspace(t, T, num = T)
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
    d2 = d1 - sigma*np.sqrt(tau)

    delta_call = np.exp(-q*tau) * norm.cdf(d1)
    delta_put = -np.exp(-q*tau) * norm.cdf(-d1)
    ...

両方のバージョンで、次のパラメーターを初期化して実行しました(変数):

S = 30.0 #Stock price
K = 50.0 #Strike price
r = 0.05 #Risk-free rate
q = 0.01 #also called delta, annual dividend yield
t = 1.0
T = 100.0
sigma = 0.15
a = greeks_vanilla(S, K, r, q, t, T, sigma)

最初のケースでは問題なく動作しますが、S (2 番目の関数) を変化させたい場合、次のエラーが発生します。

     File "greeks.py", line 11, in greeks_vanilla
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
ValueError: operands could not be broadcast together with shapes (30,) (100,) 

私は少しグーグルで調べました.Numpyライブラリとそれはデータ型(配列)に何かがあるようです. 私は熟練したプログラマーでも経験豊富なプログラマーでもありません (まだ学習中です)。
S == 100 (S = T) でのみ動作するように見えますが、これは望ましい解決策ではありません。
私はもう試した:

S = list(S)

しかし、それは出力するだけです:

File "greeks.py", line 11, in greeks_vanilla
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
TypeError: unsupported operand type(s) for /: 'list' and 'float'

これの実用的な解決策を見つけるのを手伝ってください。S をループする必要があるかどうか (試行して失敗しました...)、データ型のトリックを実行するか、別の方法で計算するか (どのように?)、または何か他のことを行うべきかどうかはわかりません。

4

1 に答える 1

1

私が理解できることから、これは 1D ケースで機能し、 a の各値で関数を評価しましたnp.linspace。今、あなたはそれを 2D で動作させようとしていて、まだ を使用していnp.linspaceます。

Numpy は、要素ごとに作業したいと考えています。したがって、サイズの異なる 2 つの s を与えるとlinspace、要素を一方の要素から他方の要素にマップする方法がわかりませんlinspace。しかし、何が必要かを考えると、 と のすべてのペアの組み合わせ(s, t)で関数を評価する必要があることに気付くはずです。これらのペアはすべて 2D グリッド上の点です。したがって、使用したいツールは.s in St in taunp.meshgrid

グラフィカルに、あなたが書いた方法では、# でのみ式を評価しようとしています。

#...................
#...................
#...................
#...................
#...................
####################

numpy が不平を言っているのはそのためです。 のどの値が のどの値にtau対応するかわからないと言っていますS。私がやりたいのは、 の 1 つの値を のtauすべてと一致させるSか、ペアにすることlen(tau)==len(S)です。あなたが本当に望んでいるのは、そのグリッド上のすべてのポイントで式を評価することであり、それが可能になりnp.meshgridます。

Numpy のメッシュグリッドは、最初は使い方を理解するのが難しい場合があります。2 つのベクトル (例: linspaces) を入力すると、2 つのベクトルがまたがるすべてのグリッド ポイントの座標を指定する 2 つの 2D 配列が返されます。おそらく次のようなことをしたいと思うでしょう:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    v1 = np.linspace(1, S, num = S)
    v2 = np.linspace(t, T, num = T)

    S, TAU = np.meshgrid(v1, v2)

    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*TAU ) / (sigma * np.sqrt(TAU))
    d2 = d1 - sigma*np.sqrt(TAU)

    delta_call = np.exp(-q*TAU) * norm.cdf(d1)
    delta_put = -np.exp(-q*TAU) * norm.cdf(-d1)
    ...

もうエラーは発生しません。

于 2015-10-12T20:52:35.283 に答える