技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

ヨーロピアンオプションの価格計算(ブラックショールズモデル)

ブラックショールズモデルを使ってヨーロピアンオプションを計算するpythonコード

ブラックショールズモデル

※無配当の原資産を前提としている

S:スポット価格
x:行使価格
\sigmaボラティリティ
\tau:満期までの期間
r金利

\displaystyle d_1 = \frac{\mathrm{ln}(S/x) + (r  + \sigma^2/2)\tau}{\sigma \sqrt{\tau}}
\displaystyle d_2 = \frac{\mathrm{ln}(S/x) + (r  - \sigma^2/2)\tau}{\sigma \sqrt{\tau}}
として

コールオプション価格:\displaystyle \mathrm{P}_{call} = S\Phi(d_1) - e^{-r\tau}x\Phi(d_2)
プットオプション価格:\displaystyle \mathrm{P}_{put} = e^{-r\tau}x\Phi(-d_2) - S\Phi(-d_1)

となる。
ただし、\Phi()正規分布の累積分布関数を表す。

コード

import numpy as np
from scipy import stats
def bs_model(S,x,r,sigma,T):
    d1 = (np.log(S/x) + (r + 0.5 * sigma ** 2)*T)/(sigma*pow(T, 1/2))
    d2 = (np.log(S/x) + (r - 0.5 * sigma ** 2)*T)/(sigma*pow(T, 1/2))
    call = S * stats.norm.cdf(d1) - x * np.exp(-r*T) * stats.norm.cdf(d2)
    put  = x * np.exp(-r*T) * stats.norm.cdf(-d2) - S * stats.norm.cdf(-d1)
    return call,put
bs_model(50, 50, 0.1, 0.5, 0.5)
(8.131599054232979, 5.693070279268685)

関連
swdrsker.hatenablog.com

【java】ある文字列がEnumメンバのString属性に含まれるかどうかを調べる

javaで、String型の属性を持ったEnumを扱う際、該当するStringがそこに含まれるかどうかを知りたいことがある。
Enumのクラス内に以下のように文字列を取得する関数を用意しておいてメンバーかどうかを判定する関数isMemberを作る。

public enum Status {
	QUIT("Q"),
	WORKING("W");

	private final String text;

	Status(final String text) {
		this.text = text;
	}

	public String getString() {
		return this.text;
	}

	public static boolean isMember(String str) {
		for (Status status : Status.values()) {
			if (status.getString().equals(str)) {
				return true;
			}
		}
		return false;
	}
}

また、文字列からEnumをゲットするにはこうすれば良い。

         public static Status getTypeByString(String str) {
		for (Status status : Status.values()) {
			if (status.getString().equals(str)) {
				return status;
			}
		}
		return null;
	}

pythonでゴールデンクロスデッドクロスを可視化(2)

前回の続き

前回のものを改良し、

長期移動平均線が上向きで短期移動平均が長期移動平均を下から上へクロスする場合、買い。(ゴールデンクロス
長期移動平均線が下向きで短期移動平均が長期移動平均を上から下へクロスする場合、売り。(デッドクロス
引用: http://fx.kakaku.com/fx/articleview/?no=21

の定義に対応させた。
長期移動平均線の増減がない場合(傾きが0の場合)も含めることにした。

コードとしては、
前回のコードの以下の部分を変えただけ。

< # ゴールデンクロス、デッドクロスを見つける
< cross        = sma5 > sma20
< d_sma20      = sma20.shift(1) - sma20
< golden       = (cross != cross.shift(1)) & (cross == True) & (d_sma20 <= 0)
< dead         = (cross != cross.shift(1)) & (cross == False) & (d_sma20 >= 0)
---
> #ゴールデンクロス、デッドクロスを見つける
> cross  = sma5 > sma20
> golden = (cross != cross.shift(1)) & (cross == True)
> dead   = (cross != cross.shift(1)) & (cross == False)

    【結果】
f:id:swdrsker:20180531003137p:plain

たしかに、前回の結果であった”長期移動平均が下向きの時にゴールデンクロスになっていたところ”がなくなっている。
    【前回の結果】
f:id:swdrsker:20180518013058p:plain