ストックドッグ

KatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。サービスも運営してます→http://fmbrain.work

非対称な収益率

収益率の計算方法についての話。(時間も時間なので最低限でまとめます)

収益率の計算は、だいたい2種類あります。

  • 収益率(ノーマル)
  • 対数収益率


よく使われる収益率は、これ↓

ほげほげ銘柄を2018/7/2、100円で買いました。

10日間持っていると、200円になりました。

このときのリターンは、

200円 / 100円 = 2.0 = 200%


この収益率の計算方法がめじゃーではあるのですが、問題点が一つあります。

それは非対称なところです。


例えば、ほげほげ銘柄がこんな値動きをしていたとします。

日付 2018/07/02 2018/07/03 2018/07/04 2018/07/05 2018/07/06 2018/07/07
ほげほげ銘柄 100円 99円 90円 100円 110円 100円

2018/07/02 ~ 2018/07/07まで、毎日ほげほげ銘柄を売買したとします。
100円で買い、次の日に99円で売る。 -1円の損失
その日のうちに99円で買い、次の日に90円で売る。 - 9円の損失
その日のうちに90円で買い、次の日に100円で売る。 +10円の利益
その日のうちに100円で買い、次の日に110円で売る。 +10円の利益
その日のうちに110円で買い、次の日に100円で売る。 -10円の損失

2018/07/07には、この取引の利益と損失はプラスマイナスゼロになります。


しかし、これを収益率で表すとそうはならないです。これが非対称性のことやねん。

収益率の計算式は、↓これです↓。

今日の株価 / 前日の株価

日付 2018/07/02 2018/07/03 2018/07/04 2018/07/05 2018/07/06 2018/07/07
ほげほげ銘柄 100円 99円 90円 100円 110円 100円
収益率 - 0.99 0.9090909090909091 1.1111111111111112 1.1 0.9090909090909091


この収益率をトータルすると、+1.003858585858586となります。

%に変換すると+0.3%になります。

取引の収益は、ゼロなのに収益率にするとプラスになってしまい、これが非対称性と呼ばれています。


そのため、収益率を計算するときは対数に変換して、収益率は計算されます。

日付 2018/07/02 2018/07/03 2018/07/04 2018/07/05 2018/07/06 2018/07/07
ほげほげ銘柄 100円 99円 90円 100円 110円 100円
ほげほげ銘柄(対数) 4.605170185988092 4.59511985013459 4.499809670330265 4.605170185988092 4.700480365792417 4.605170185988092
収益率 - 0.99 0.9090909090909091 1.1111111111111112 1.1 0.9090909090909091


対数で計算をするので、計算式は↓これです↓。

今日の株価(対数) - 前日の株価(対数)

日付 2018/07/02 2018/07/03 2018/07/04 2018/07/05 2018/07/06 2018/07/07
ほげほげ銘柄 100円 99円 90円 100円 110円 100円
ほげほげ銘柄(対数) 4.605170185988092 4.59511985013459 4.499809670330265 4.605170185988092 4.700480365792417 4.605170185988092
収益率 - 0.99 0.9090909090909091 1.1111111111111112 1.1 0.9090909090909091
対数収益率 -0.010050335853502013 -0.09531017980432477 0.10536051565782678 0.09531017980432477 -0.09531017980432477


対数収益率はトータルしても、プラスマイナスゼロとなり、取引の結果と一致します。

まとめ

収益率の計算は、必ず対数収益率を使いましょう。


検証に使ったコードです。

import math
import numpy as np


# logに変換
def calc_log(num):
	log = [math.log(i) for i in num]
	return log


# 対数収益率を計算
def calc_return(log):
	r_list = [log[i+1] - log[i] for i in range(len(log)-1)]
	print(r_list)
	r = sum(r_list) / len(r_list)
	return r

# 収益率を計算
def calc_return_int_ver(log):
	r_list = [log[i+1] / log[i] for i in range(len(log)-1)]
	print(r_list)
	r = sum(r_list) / len(r_list)
	return r


# データセット
x = [100, 99, 90, 100, 110, 100]

# logに変換したデータセット
log_x = calc_log(x)
print("log(x)")
print(log_x)

# 収益率
return_x_int_ver = calc_return_int_ver(x)
print("x return int ver : ", return_x_int_ver)

# 対数収益率
return_x = calc_return(log_x)
print("x return : ", return_x)