非対称な収益率
収益率の計算方法についての話。(時間も時間なので最低限でまとめます)
収益率の計算は、だいたい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)