期待利益がマイナスの戦略は捨てるべきか

本題に入る前に基本的なことを確認しておく。

期待利益とシャープレシオの関係

ここに1年当たり100トレード、1トレード当たりの期待利益が0.1%、リスクが1.0%の戦略があるとする。単純化して考えると、1年当たりの期待利益は0.1% * 100 = 10.0%、リスクは√Tルールに基づけば1.0% * sqrt(100) = 10.0%となる。したがって、シャープレシオは10.0 / 10.0 = 1.0となる。これを戦略Aとする。

一方、1年当たり100トレード、1トレード当たりの期待利益が0.2%、リスクが4.0%の戦略があるとする。同様に考えて、1年当たりの期待利益は0.2% * 100 = 20.0%、リスクは4.0% * sqrt(100) = 40.0%となる。したがって、シャープレシオは20.0 / 40.0 = 0.5となる。これを戦略Bとする。

戦略Bの期待利益は戦略Aの2倍である。では戦略Bのほうが優れているかといえばそういうわけではない。1年後の利益はリスクも考慮すると1年当たりの期待利益 ± 1年当たりのリスクであるから、戦略Aは10% ± 10%、つまり0%〜20%となる。一方、戦略Bは20% ± 40%、つまり-20%〜60%となる。

都合よく考えると、戦略Aは20%、戦略Bは60%の利益だから戦略Bのほうがいいということになるが、果たしてそうか。逆に都合悪く考えると、戦略Aは0%、戦略Bは-20%となり、戦略Aは単に利益が出ないだけだが、戦略Bは-20%の損失である。だが、リスクを等しくしないと比較できないのである。

戦略Aで戦略Bと同じ4.0%のリスクを覚悟できるなら、投資額を4倍にすればいい(資金があればだが)。すると、期待利益も4倍になり、1年当たりの期待利益は0.4% * 100 = 40%、リスクは4.0% *sqrt(100) = 40%となる。1年後のリスクは40% ± 40%、つまり0〜80%となり、都合よく考えても、都合悪く考えても戦略Aは戦略Bより優れている。

つまり、期待利益が大きいかどうかが大事なのではなく、期待利益とリスクの比、つまりシャープレシオが大きいかどうかが大事なのである。期待利益は小さいがシャープレシオが大きい戦略は、期待利益は大きいがシャープレシオが小さい戦略と同じリスクを負うことで後者より大きい利益を生むことができるのである(机上の計算では)。

期待利益がマイナスの戦略でも役に立つ場合がある

さて、期待利益とシャープレシオの関係を確認したところで本題に入る。

ここに勝つ場合は+1、負ける場合は-1で一定で、1年当たり12回勝ち、8回負けるという戦略Aがあるとする。計算すると、期待利益は0.2、リスクは0.98、シャープレシオは0.91となる。

一方、勝つ場合は+0.5、負ける場合は-0.5で一定で、戦略Aが勝てば必ず負け、負ければ必ず勝つという戦略Bがあるとする。計算すると、期待利益は-0.1、リスクは0.49、シャープレシオは-0.91となる。

戦略Aと戦略Bの相関係数を求めると-1.0となる。勝敗が正反対なのであるから当然である。

ここで戦略Aと戦略Bを合わせた戦略Cを考えてみる。計算すると、期待利益は0.1、リスクは0.49、シャープレシオは0.91となる。戦略Aと比べると、期待利益は半減したが、リスクも半減したのでシャープレシオは変わらない。したがって、戦略Cはシャープレシオにおいて戦略Aと同等である。戦略Cが投資額を倍にして戦略Aと同じリスクを負うなら、期待利益も同じになる(資金の使い方としては非効率だが)。

ところで、戦略Bの負けを1つだけ勝ちだったことにしてみる。再計算すると、期待利益は-0.05、リスクは0.49、シャープレシオは-0.45となる。元の戦略と比べると、期待利益は半減したが、リスクはそのままなので、シャープレシオも半減する。ただし、期待利益はマイナスなので、これは改善である。

戦略Aと新しい戦略Bの相関係数を求めると-0.91となる。勝敗が完全には反対でないので、これも当然である。

そして、戦略Aにこの新しい戦略Bを合わせて新しい戦略Cを考えてみる。再計算すると、期待利益は0.15、リスクは0.57、シャープレシオは1.17となる。戦略Aと比べると、期待利益は減少しているが、リスクはそれ以上に減少しているので、シャープレシオは大きくなっている。したがって、新しい戦略Cはシャープレシオにおいて戦略Aより優れている。

つまり、新しい戦略Bを加えることによって戦略Aは改善されたのである。だが、新しい戦略Bの期待利益は-0.05であり、マイナスである。にもかかわらず、戦略Aを改善したのだ。

したがって、期待利益がマイナスの戦略でも役に立つ場合があると言える。ならば、いきなり捨てたりはせずに使い道がないか考えてみてもいいのではないだろうか。

a =  [ 1  1  1  1  1  1  1  1  1  1  1  1 -1 -1 -1 -1 -1 -1 -1 -1]
mean_a =  0.2
std_a =  0.979795897113
sharpe_a =  0.912870929175
b =  [-0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5  0.5  0.5  0.5
  0.5  0.5  0.5  0.5  0.5]
mean_b =  -0.1
std_b =  0.489897948557
sharpe_b =  -0.912870929175
cor_ab =  -1.0
c =  [ 0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5 -0.5 -0.5 -0.5
 -0.5 -0.5 -0.5 -0.5 -0.5]
mean_c =  0.1
std_c =  0.489897948557
sharpe_c =  0.912870929175
b2 =  [ 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5  0.5  0.5  0.5
  0.5  0.5  0.5  0.5  0.5]
mean_b2 =  -0.05
std_b2 =  0.497493718553
sharpe_b2 =  -0.449466574975
cor_ab2 =  -0.902670933848
c2 =  [ 1.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5 -0.5 -0.5 -0.5
 -0.5 -0.5 -0.5 -0.5 -0.5]
mean_c2 =  0.15
std_c2 =  0.572276157113
sharpe_c2 =  1.17219699775

サンプルプログラム

○以下のコマンドをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを2回押す。

# coding: utf-8

import numpy as np

a = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, -1, -1, -1, -1, -1, -1, -1, -1])
print('a = ', a)
mean_a = np.mean(a)
print('mean_a = ', mean_a)
std_a = np.std(a)
print('std_a = ', std_a)
sharpe_a = mean_a / std_a * np.sqrt(20)
print('sharpe_a = ', sharpe_a)

b = np.array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5,
              -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])
print('b = ', b)
mean_b = np.mean(b)
print('mean_b = ', mean_b)
std_b = np.std(b)
print('std_b = ', std_b)
sharpe_b = mean_b / std_b * np.sqrt(20)
print('sharpe_b = ', sharpe_b)

cor_ab = np.corrcoef(a, b)[0][1]
print('cor_ab = ', cor_ab)

c = a + b
print('c = ', c)
mean_c = np.mean(c)
print('mean_c = ', mean_c)
std_c = np.std(c)
print('std_c = ', std_c)
sharpe_c = mean_c / std_c * np.sqrt(20)
print('sharpe_c = ', sharpe_c)

b[0] = 0.5
b2 = b
print('b2 = ', b2)
mean_b2 = np.mean(b2)
print('mean_b2 = ', mean_b2)
std_b2 = np.std(b2)
print('std_b2 = ', std_b2)
sharpe_b2 = mean_b2 / std_b2 * np.sqrt(20)
print('sharpe_b2 = ', sharpe_b2)

cor_ab2 = np.corrcoef(a, b2)[0][1]
print('cor_ab2 = ', cor_ab2)

c2 = a + b2
print('c2 = ', c2)
mean_c2 = np.mean(c2)
print('mean_c2 = ', mean_c2)
std_c2 = np.std(c2)
print('std_c2 = ', std_c2)
sharpe_c2 = mean_c2 / std_c2 * np.sqrt(20)
print('sharpe_c2 = ', sharpe_c2)
(2016/11/15更新)

週単位、月単位で勝つためのシャープレシオ

あるトレード戦略が週単位、月単位で勝つためにはどの程度のシャープレシオが求められるかということを考えてみる。

もし年単位の利益が10%、年単位のリスクが10%だとすると、シャープレシオは0.1 / 0.1 = 1.0となる。1年後の利益は10±10%であるから、0~20%と予測される。

ところで、リスクは1σで計算されるから、68.27%の確率で、予測はその範囲内に収まると考えられる。つまり1年後の利益がプラスである確率は68.27%以上となる。なぜ68.27%「以上」になるかというと、年単位20%を越える利益となる可能性も含まれるからである。

もう少し正確には

68.27 + (100 - 68.27) / 2 = 84.135

で、84.135%となる(手計算なので誤差あり)。もちろん、これは机上の空論だが、一応の目安にはなる。

仮にプラスとなる確率が84.135%以上であれば「勝てる戦略」とすることができるとしたら、シャープレシオが1.0以上なら年単位では「勝てる戦略」と言える。同様に週単位、月単位のシャープレシオが1.0であれば、1週間後、あるいは1ヶ月後の利益がプラスである確率は84.135%となる。つまり、週単位、月単位で「勝てる戦略」と言える。

ただ、シャープレシオは年単位で計算するのが普通であるから、そこで、簡易的に週単位、月単位のシャープレシオが1.0以上であるためには、年単位のシャープレシオがどのくらい以上でなければならないかということを考えてみる。

ここでは1週間を5営業日、1ヶ月を20営業日、1年を260営業日としておく。また、1日単位の利益をr、1日単位のリスクをsとする。さらに、√をsqrtとする。

√Tルールに基づけば、

週単位のシャープレシオ = 5r / sqrt(5s)

月単位のシャープレシオ = 20r / sqrt(20s)

年単位のシャープレシオ = 260r / sqrt(260s)

となる。ここでは簡単にするため、リスクフリーレートは考慮しないことにする。

週単位で勝つためのシャープレシオ

先ず、週単位のシャープレシオが1.0以上であるには、年単位のシャープレシオがどのくらい以上でなければならないかを考える。

年単位のシャープレシオ / 週単位のシャープレシオ = 260r / sqrt(260s) / (5r / sqrt(5s))

年単位のシャープレシオ / 週単位のシャープレシオ = 260r / sqrt(260s) * (sqrt(5s) / 5r)

年単位のシャープレシオ / 週単位のシャープレシオ = (260r * sqrt(5s)) / (sqrt(260s) * 5r)

年単位のシャープレシオ / 週単位のシャープレシオ = (52 * sqrt(5s)) / sqrt(260s)

年単位のシャープレシオ / 週単位のシャープレシオ = (52 * sqrt(5s) * sqrt(260s) / (sqrt(260s * sqrt(260s))

年単位のシャープレシオ / 週単位のシャープレシオ = (52 * sqrt(1300 * s^2)) / 260s

年単位のシャープレシオ / 週単位のシャープレシオ = (52 * sqrt(1300) * s) / 260s

年単位のシャープレシオ / 週単位のシャープレシオ = (10 * sqrt(13)) / 5

年単位のシャープレシオ / 週単位のシャープレシオ = 2 * sqrt(13)

年単位のシャープレシオ / 週単位のシャープレシオ = 約7.21

週単位のシャープレシオ = 1.0であるから

年単位のシャープレシオ = 約7.21

となる。つまり、週単位のシャープレシオが1.0以上であるには、年単位のシャープレシオが約7.21以上である必要がある。

月単位で勝つためのシャープレシオ

次に、月単位のシャープレシオが1.0以上であるには、年単位のシャープレシオがどのくらい以上でなければならないかを考える。

年単位のシャープレシオ / 月単位のシャープレシオ = 260r / sqrt(260s) / (20r / sqrt(20s))

年単位のシャープレシオ / 月単位のシャープレシオ = 260r / sqrt(260s) * (sqrt(20s) / 20r)

年単位のシャープレシオ / 月単位のシャープレシオ = (260r * sqrt(20s)) / (sqrt(260s) * 20r)

年単位のシャープレシオ / 月単位のシャープレシオ = (13 * sqrt(20s)) / sqrt(260s)

年単位のシャープレシオ / 月単位のシャープレシオ = (13 * sqrt(20s) * sqrt(260s) / (sqrt(260s * sqrt(260s))

年単位のシャープレシオ / 月単位のシャープレシオ = (13 * sqrt(5200 * s^2)) / 260s

年単位のシャープレシオ / 月単位のシャープレシオ = (13 * sqrt(5200) * s) / 260s

年単位のシャープレシオ / 月単位のシャープレシオ = sqrt(5200)) / 20

年単位のシャープレシオ / 月単位のシャープレシオ = (20 * sqrt(13)) / 20

年単位のシャープレシオ / 月単位のシャープレシオ = sqrt(13)

年単位のシャープレシオ / 月単位のシャープレシオ = 約3.61

月単位のシャープレシオ = 1.0であるから

年単位のシャープレシオ = 約3.61

となる。つまり、月単位のシャープレシオが1.0以上であるには、年単位のシャープレシオが約3.61以上である必要がある。

まとめ

年単位のシャープレシオが2.0前後の戦略でもなかなか素晴らしいパフォーマンスだと思うが、それでも週単位、月単位ではけっこう負けることもあるわけで、少なくとも単体の戦略で週単位、月単位で勝つということはなかなか容易ではない。逆に言えば、週単位、月単位で勝つためには複数の戦略が必要ということになるだろう。

しかし、複数の戦略を用いるにしても、互いの戦略が正の相関であれば、つまり同じようなタイミングで勝ち負けする似たような戦略の組み合わせであれば、あまり意味がない。無相関、できれば負の相関の戦略と組み合わせたいが、実際にやってみようとすると、これもなかなか難しいのである。

(2016/11/15更新)

EAの使い方

EAの基本的な使い方を説明する。

EA使用の準備

「執行専用EAの作成」で作成した「ExecutionOnly」をドル円5分足チャートで使用する場合を例とする。

①MT4のメニューバーで「ファイル」をクリックする。

②「新規チャート」をクリックする。

新規チャート内部の構成や通貨ペアの名前はどのFX会社のサーバーを使うかで違ってくる。ここではOANDAのデモ口座を使用した場合の例である。

③「USDJPY」をクリックする。

「USDJPY,H1」(ドル円1時間足)チャートが表示される。

④ツールバーで「M5」ボタンをクリックする。

「USDJPY,M5」(ドル円5分足)チャートに変更される。

チャートの変更

私の好みなので、このようにする必要はない。

①ツールバーで「ローソク足」ボタンをクリックする。

小さくて分からないが、足がバーチャートからローソク足に変更される。

②ツールバーで「ズームイン」ボタンを数回クリックして好みの大きさにする。

大きくしすぎたと思ったら、同じくツールバーで「スームアウト」ボタンをクリックして調整する。

EAのロード

上に続けて実行する。

①「ナビゲーター」で「エキスパートアドバイザ」をダブルクリックして展開する。

初めから展開していれば必要ない。また、ナビゲーターが表示されていなければ、メニューバーで「表示」→「ナビゲーター」の順にクリックして表示させる。

②「ExecutionOnly」を「USDJPY,M5」チャート上にドラッグ&ドロップする。

③「Expert - ExecutionOnly」で「全般」タブをクリックする。

④「自動売買を許可する」にチェックを入れる。

⑤「OK」ボタンをクリックする。

「USDJPY,M5」チャートの右上隅に「ExecutionOnly」と表示される。

EAの稼働

○(EAが停止状態の場合、つまりMT4のツールバーの「自動売買」ボタンが赤の停止マークの場合、)「自動売買」ボタンをクリックして緑の再生マークに変える(稼動状態となる)。

停止状態から稼動状態になった場合、他のチャートにロードしているEAがあれば、そのEAも稼動する。

EAの停止

○(EAが稼動状態の場合、つまりMT4のツールバーの「自動売買」ボタンが緑の再生マークの場合、)「自動売買」ボタンをクリックして赤の停止マークに変える(停止状態となる)。

稼動状態から停止状態になった場合、他のチャートにロードしているEAがあれば、そのEAも停止する。

EAの削除

ここにおけるEAの削除とはチャート上にロードしているEAをロードしていない状態に戻すという意味であり、以下の手順でEAのソースファイル、実行ファイルが削除されることはない。

①「USDJPY,M5」チャートを右クリックする。

②「エキスパートアドバイザ」にカーソルを合わせる。

③「削除」をクリックする。

「USDJPY,M5」チャートの右上隅の「ExecutionOnly」が消える。

(2016/11/14更新)

MT4のインストール

「プロキシサーバ」から進まない問題

WineでMT4をインストールしようとすると「プロキシサーバ」というウィンドウが出てきて、そこから先に進めないという問題が起きている。最新版のWineを使えば無事にMT4をインストールできるので、ここでは最新版をインストールする。今後、この問題は解消するかもしれないが、当面は最新版でいいだろう。

Wineのインストール

旧バージョンのWineを使っていた場合、先ず必要なデータを移動した上で「~/.wine」フォルダーを削除してからインストールする。

①端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

sudo dpkg --add-architecture i386

②「[sudo] **** のパスワード:」でパスワードを入力して「Enter」キーを押す。

③端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

sudo add-apt-repository ppa:wine/wine-builds

④「[ENTER] を押すと続行します。ctrl-c で追加をキャンセルできます」で「Enter」キーを押す。

⑤端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

sudo apt-get update

⑥端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

sudo apt-get -y install winehq-devel

MT4用デモ口座の開設

①「OANDA REST APIの準備」の記事に基づき、OANDAのデモ口座を開設する。

②以下のアドレスをクリックする。

https://www.oanda.jp/

③右上の「ログイン」ボタンをクリックする。

④「口座をご選択ください:」で「デモ口座」を選択する。

⑤「お客様のIDを入力してください」でIDを入力する。

⑥「パスワードを入力してください」でパスワードを入力する。

⑦「ログイン」ボタンをクリックする。

⑧「MT4/API関連」で「MT4アカウントの作成」をクリックする。

⑨「MT4 サブアカウントの作成」の「パスワードを作成:」でMT4用のパスワードを入力する。

⑩「パスワードを再入力:」でもう一度MT4用のパスワードを入力する。

⑪「続ける」ボタンをクリックする。

⑫(ブラウザがFirefoxの場合のみ)「このログイン情報を Firefox に記憶させますか?」で「記憶」ボタンをクリックする。

⑬「ライセンス規約同意画面」で「同意する」ボタンをクリックする。

⑭OANDAからのメールを確認する。

メールにはMT4用デモ口座にログインするための「ID」(7桁の数字)と「PW」(⑨、⑩で設定したパスワード)が書かれてある。

MT4のインストール

上の手順から続けて行う。

①「MT4 サブアカウント」で「こちらをクリック」をクリックする。

②「oanda4setup.exe を開く」で「プログラムで開く」を選択する。

③右のボタンをクリックする。

④「その他...」をクリックする。

⑤「アプリケーションの選択」で「すべてのアプリケーションを表示」ボタンをクリックする。

⑥「Wine Windowsプログラムローダー」を選択する。

⑦「選択」ボタンをクリックする。

初めてWineでexeファイルを開く場合はこのように選択するが、次回からは初めから選択されている。

⑧「oanda4setup.exe を開く」に戻って「OK」ボタンをクリックする。

もし「OK」ボタンをクリックしても何も起きない場合、「~/.wine」フォルダーを削除し、もう一度①から実行してみる。

⑨「OANDA - MetaTrader 4 セットアップ (32 ビット)」で「□□□□□□□□□□□□□□□□□□□□□□」にチェックを入れる。

文字化けしているかもしれないが「はい、上記の全てのライセンス条項に同意します」という項目である。

⑩右下の3つのボタンのうち、真ん中の「□□(N) >」みたいなボタンをクリックする。

文字化けしているかもしれないが「次へ」というボタンである。「MQL5」のウェブページが勝手に開くが気にしない。

MT4がインストールされ、起動する。デスクトップには「OANDA - MetaTrader」という設定ファイルが生成する。次からは「OANDA - MetaTrader」ファイルをダブルクリックすればMT4を起動できる。

MT4用デモ口座のサーバーの選択

上の手順から続けて行う。

①サーバーを選択するウィンドウで「OANDA-Japan Practice」を選択する。

②「次へ」ボタンをクリックする。

③「既存のアカウント」を選択する。

④「ログイン:」にOANDAからメールで送られた「ID」を入力する。

⑤「パスワード:」に同じくOANDAからメールで送られた「PW」を入力する。

⑥「パスワードを保存」にチェックを入れる。

⑦「完了」ボタンをクリックする。

(2017/02/09更新)

OANDA用設定ファイルの作成

①以下のプログラムをテキストエディターにコピー&ペーストし、ファイル名を「settings.ini」として「~/py」フォルダーに保存する。

[DEFAULT]
environment = practice
account_id = 1234567
access_token = 1234567890123456789012345678901-2345678901234567890123456789012
fromaddr = abcd@yahoo.co.jp
password = 12345678
toaddr =abcd@example.com
folder_ea = .wine/drive_c/"Program Files (x86)"/"OANDA - MetaTrader"/mql4/Files

②自分の環境に合わせて設定内容を変更し、保存する。

「environment」は口座の種類を設定するもので、デモ口座の場合は「practice」と入力する。

「account_id」には「OANDA REST APIの準備」でメモしたアカウントIDを入力する。

「access_token」には同じく「OANDA REST APIの準備」でメモしたアクセストークンを入力する。

「fromaddr」には送信元メールアドレスを入力する。戦略のシグナルをメールで送信したい場合、このアドレスで送信する。また、ここではyahooメールを利用することとする。

「password」には送信元メールアドレスのパスワードを入力する。

「toaddr」には送信先メールアドレスを入力する。戦略のシグナルをメールで受信したい場合、このアドレスで受信する。これはどこのメールでも構わない。

「folder_ea」にはMT4の「Files」フォルダーのパスを入力する。

パスはMT4のインストール先によって設定例と違う場合もある。これは戦略のシグナルをEAに送信し、EAで執行したい場合に使う。

(2017/02/08更新)