コツコツドカンはだめなのか (2018/04/07)

先月のトレードは絶不調だった。私は逆張り派なので、コツコツドカンが多い。だが、先月はドカンドカンドッカーンというのが2回あり、大きく負けてしまった。

コツコツドカンは嫌だ

さすがに2回も大きくやられると、別の手法も考えないといけないかなあと思う。逆張りは勝率こそ高い。だが、平均損失が平均利益を上回るので、時には1回の負けで10回の勝ちの利益を吹き飛ばしてしまうこともある。

「利食い幅=損切り幅」ならよさそう?

そこで、考えたのは「平均利益=平均損失」、つまり「ペイオフレシオ=1.0」となるような手法ならよいだろうか、ということである。例えば利食い幅と損切り幅を等しくするのである。するとトレードは単純に確率の問題に置き換えることができ、勝率が50%を超えれば利益になる。

「利食い幅=損切り幅」ならば、「コツコツ」もなければ「ドカン」もない。とにかく勝率が50%を超えることができる戦略を見い出せれば、もう二度と大きくやられることはないはず。だが、もう一度考え直してみると、それは錯覚じゃないかと思えてきた。

逆張りの場合

例えば、1本前の足が下がれば買い、上がれば売り、という逆張りのドテン戦略の場合を考えてみる。単純化して1本の足のボラティリティは常に1とし、取引コストは考慮しない。あるとき、足の騰落が以下のようだったとする(○は上昇、●は下落)

●|○●○●●●●●●○

すると「|」より右の足ごとの売買は

買売買売買買買買買買

足ごとの損益は

益益益益損損損損損益

となり、利益が5、損失が5で最終損益は0である。

また、トレードごとの勝敗は、足ごとで勝ったときしか決済しないので、

勝勝勝勝負

となり、勝率は80%(4勝1敗)、ペイオフレシオは0.25(平均利益1、平均損失4)となる。

コツコツが最後のドカンで全部持って行かれるという典型的なパターンである。こういうことがあると、「ああ、コツコツドカンは嫌だ」と思うわけである。

次に利益が1で利食い、損失が1で損切りした場合を考えてみる。これならコツコツドカンはないはずだが…。

戦略自体は同じなので、足ごとの売買と損益は同じだが、トレードごとの勝敗は

勝勝勝勝負負負負負勝

となり、勝率は50%(5勝5敗)、ペイオフレシオは1.0(平均利益1、平均損失1)となる。

こう見ると、ドカンは「利食い幅=損切り幅」バージョンで連敗のときにもたらされたものである。つまり、ドカンの代わりに連敗が来るだけで、中身は変わらない。

順張りの場合

ついでに1本前の足が上がれば買い、下がれば売り、という順張りのドテン戦略の場合も考えてみる。足ごとの騰落は上と同じとする。

すると「|」より右の足ごとの売買は

売買売買売売売売売

足ごとの損益は

損損損損益益益益益損

となり、利益が5、損失が5で最終損益は0である。

また、トレードごとの勝敗は、足ごとで負けたときしか決済しないので、

負負負負勝

となり、勝率は20%(1勝4敗)、ペイオフレシオは4.0(平均利益4、平均損失1)となる。

小さい負けが続いたが、最後で取り返すという損小利大の典型的なパターンである。こういうことがあると、「ああ、やっぱり損小利大だよな」と思うわけである。

次に利益が1で利食い、損失が1で損切りした場合を考えてみる。

戦略自体は同じなので、足ごとの売買と損益は同じだが、トレードごとの勝敗は

負負負負勝勝勝勝勝負

となり、勝率は50%(5勝5敗)、ペイオフレシオは1.0(平均利益1、平均損失1)となる。

こう見ると、利大は「利食い幅=損切り幅」バージョンで連勝のときにもたらされたものである。連勝すれば利益が大きくなるのは当たり前であって、やはり、中身は変わらないのである。

やはり錯覚か

こうして見ると、「利食い幅=損切り幅」にしても、勝率が上がった分、ペイオフレシオが下がるか、勝率が下がった分、ペイオフレシオが上がるかであって、最終損益に影響はなく、パフォーマンスの改善はただの錯覚のようである。

もちろん、上の例は極端に単純化しているから、一概に錯覚とは言えない。だが、「利食い幅=損切り幅」にしたからといって、劇的にパフォーマンスが改善するなどと期待はしないほうがよさそうだ。利食い、損切りはただの戦術であって、買いシグナル、売りシグナルをどう出すかという戦略のみが劇的にパフォーマンスを改善する。

(補足)

なお、取引コストを考慮した場合、「利益が1で利食い、損失が1で損切り」バージョンではトレード数が増えるので、「利食い損切りなし」バージョンよりコストが増える。

また、例えば利益が0.5で利食い、損失が0.5で損切りとした場合、勝敗は変わりうるものの、必ず勝ちが増えるとか負けが増えるとかいった根拠はないから、サンプルを増やせば変わらないだろう。「利益が1で利食い、損失が1で損切り」バージョンとはコストは同じで、損益の絶対値は小さくなるから、相対的にコストの負担が大きくなる。

逆に、例えば利益が2で利食い、損失が2で損切りとした場合、逆張り戦略では2回損切りするのでトレード数は2回増え、順張り戦略では2回利食いするのでトレード数はやはり2回増える。したがって、「利食い損切りなし」バージョンよりはコストが多く、「利益が1で利食い、損失が1で損切り」バージョンよりはコストが少なくなる。

ETFメモ (2018/03/02)

ティッカー ETF名 取引通貨 終値時間
EWA iShares MSCI Australia ETF 米ドル 16:00 EST
EWJ iShares MSCI Japan ETF 米ドル 16:00 EST
EWU iShares MSCI United Kingdom ETF 米ドル 16:00 EST
FEZ SPDR EURO STOXX 50 ETF 米ドル 16:00 EST
SPY SPDR S&P 500 ETF 米ドル 16:00 EST

架空のミラートレード (2017/11/04)

ミラートレードのサービスを提供する架空の業者を考えてみる。この業者には5000のストラテジーが用意されている。だが、各ストラテジーは乱数によってシグナルを生成するデタラメなものである。

シミュレーション

それではシミュレーションを行う。いくつかの仮定を設けた。

  1. 1日に1回のトレードとする。
  2. 勝てば1%、負ければ-1%の損益とする。
  3. レバレッジは5倍とする。

各ストラテジーには0から4999までのナンバーが付いている。そして、各ストラテジーを収益率でランキング付けし、直近3年間の上位10位のパフォーマンスを見てみる。また全ストラテジーの平均パフォーマンスも参考として挙げておく。

○IPythonコンソールで以下のコマンドを実行する。

import numpy as np
import pandas as pd
import warnings;warnings.filterwarnings('ignore')

strategy = np.empty([5000, 2])
strategy = pd.DataFrame(strategy,
                        columns=['Rank', 'Profit(%)'])
n_strategies = 5000
n_trades = 260
n_year = 3
volatility = 0.01
leverage = 5
for i in range(n_year):
    for j in range(n_strategies):
        ret = np.random.randn(n_trades) * volatility * leverage
        ret = pd.Series(ret)
        cumret = ret.cumsum()
        strategy.iloc[j, 1] = cumret.iloc[n_trades-1] * 100
    strategy = np.round(strategy.sort_values(by='Profit(%)',
                                             ascending=False), 2)
    for j in range(n_strategies):
        strategy.iloc[j, 0] = str(int(j+1))
    print(str(i+1) + '年目')
    print(strategy.head(10))
    print('mean = ', np.round(strategy['Profit(%)'].mean(), 2))
    print('\n')

結果

乱数を使っているので結果は毎回違うが、例えば以下のようである

1年目
     Rank  Profit(%)
1772    1     270.38
1696    2     263.53
3149    3     250.18
435     4     242.58
2304    5     237.56
4300    6     234.59
1845    7     234.27
1872    8     232.77
2516    9     231.86
736    10     231.74
mean =  -0.57


2年目
     Rank  Profit(%)
1493    1     301.26
4252    2     280.34
4167    3     280.28
3802    4     239.77
4003    5     238.95
1981    6     233.97
1424    7     233.90
1496    8     232.59
840     9     232.05
3791   10     230.65
mean =  -0.37


3年目
     Rank  Profit(%)
2560    1     271.43
4984    2     270.60
599     3     262.50
368     4     254.48
2070    5     254.19
680     6     250.49
4990    7     249.19
1203    8     249.09
3834    9     240.19
232    10     239.21
mean =  -0.43

いずれの年においても上位10位のパフォーマンスは200%を超えている。全ストラテジーの平均パフォーマンスがほぼ0%であるにも関わらずである。だが、上位10位に複数回入ったストラテジーは一つもない。

見せかけのパフォーマンス

何が言いたいのかというと、パフォーマンスのいいストラテジーをいくつも擁する業者が実際にあったとしても、そのサービスを利用して利益を上げられるということは全く保証されていないということである。

「このストラテジーは今後も勝ち続ける」と見抜くことは容易ではない。あたかも「この銘柄は今後も上昇し続ける」と見抜くことが容易ではないようにである。

ミラートレードのようなサービスを利用しようとする人は銘柄の騰落が分からないからだろう。それなのに、ストラテジーの良し悪しは分かるとでも言うのだろうか。不思議なことだ。

Ku-Chartのグラフ (2017/08/05)

今年の値動きをKu-Chartでグラフにしてみる。直近の値動きを見ると、ユーロの上昇が少し異常な気がした。それで、ユーロ、円、ドルの3通貨モデルのKu-Chartではどうなっているか気になったのである。

import forex_system as fs
import matplotlib.pyplot as plt
from datetime import datetime

start = datetime.strptime('2017.01.01 00:00', '%Y.%m.%d %H:%M')
end = datetime.strptime('2017.08.04 23:59', '%Y.%m.%d %H:%M')
ku_close = fs.i_ku_close(1440, 0, eur=1, jpy=1, usd=1)[start:end]
ku_close = ku_close - ku_close.iloc[0, :]
plt.title('Ku-Chart (EUR, JPY, USD)')
plt.ylabel('Change')
plt.xlabel('Date')
plt.plot(ku_close['EUR'], label='EUR', color='red')
plt.plot(ku_close['JPY'], label='JPY', color='turquoise')
plt.plot(ku_close['USD'], label='USD', color='orange')
plt.legend()
plt.savefig('ku_chart.png', dpi=150)
plt.show()

グラフを見ると特に異常ということはなさそうだ。ドルがだらだらと下落する中で、ユーロと円は反対の動きをしている。直近ではユーロが上昇、円が下落だから、やたらと対円、対ドルで強く見えただけのようだ。

相関係数とトレンド

相関係数とトレンドとの関係を考えてみる。

正相関ならトレンド的か?

時系列データにおいて、データの階差とその前のデータの階差とが正相関、つまり相関係数がプラスの場合、トレンド的と言えるだろうか。

また、逆にデータの階差とその前のデータの階差とが逆相関、つまり相関係数がマイナスの場合、平均回帰的と言えるだろうか。

この問いに対して何となく「そうだろう」と考えている人は少なくないのではないかと思われる。というか、私がそうだった(笑)。

ただ、共和分の時系列データは平均回帰的だが、必ずしも逆相関ではない。したがって、完全に対応しているわけではない。しかし、それでも対応しているケースが多いのではないかと私は考えていたのである。

y = sin(x)における相関係数

そういうケースが多いか少ないかということは置いておく。ここでは正相関であり、かつ平均回帰的であって、しかも、それが極端であるデータを作成してみる。これはいたって簡単で、「y = sin(x)」のデータを作成すればいいだけである。

先ず、データを作成して相関係数を見てみる。

In [1]:
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-360, 360, 1)
y = np.sin(x / 180 * np.pi)

diff = y[1:] - y[:-1]
diff0 = diff[1:]
diff1 = diff[:-1]
cor = np.corrcoef(diff1, diff0)[0, 1]
print('cor = ', cor)


cor =  0.999846842234


相関係数はほぼ1.0で、完全に近い正相関となっている。考えてみれば、これは当然である。sin(x)の向きはずっとプラスか、ずっとマイナスで、プラスからマイナス、またはマイナスからプラスに転じるのは頂点だけだからだ。

y = sin(x)のグラフ

では次に、同じデータを使ってグラフを作成して見てみる。

In [2]:
plt.plot(x, y, label='y = sin(x)')
plt.title('y = sin(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.xticks([-360, -270, -180, -90, 0, 90, 180, 270, 360])
plt.legend(loc='upper right')
plt.axvline(x=0.0, color='black')
plt.axhline(y=0.0, color='black')
plt.tight_layout()
plt.savefig('sinx.png', dpi=150)
plt.show()



高校数学でよく見かけるグラフだが、改めて見ると完全に平均回帰的である。-1で買い、+1で売れば百戦百勝だ。

相関係数とトレンドは別物

ほぼ完全な正相関でありながら完全に平均回帰的であるデータを作成できるということを考えると、相関係数とトレンド(あるいは平均回帰)は全くの別物と見たほうがいいだろう。

(2017/03/20更新)