2010年12月19日日曜日

ニューラルネットワーク、遺伝的アルゴリズムによる学習

トレードルールはシンプルであればあるほど良いと良く言われますが、私もきっとそのとおりだろうと思っています。RSIにしてもADXにしてもまた前回の記事で書いたボラティリティーのスクイーズや、しばらく前に書いたNaked Close等、それぞれ特有の相場の状況をより分かり易く表してくれていると思います。しかし実際にシステムにそれらを組み合わせて活かしきることは難しいなぁと感じています。

前々からニューラルネットワークとか遺伝アルゴリズムとかには興味があったのですが、今まではニューラルネットは複雑性を増してしまい「シンプル」からほど遠くなってしまいそうだったので手を出さずにいました。が今回はどうしてもニューラルネットワークを試してみたくなりました。というのも最近Webで情報集めをしていた時に見つけた海外の論文の中に、株価の予測(明日上がるか下がるか)を重回帰やARIMAなどの従来の手法で行う場合とニューラルネットワークを使う場合を比較研究したものがあり、興味をひかれたからです。それによるとニューラルネットワークの成績が他と比べてかなり良い感じで、その理由としてニューラルネットワークの非線形性をうたっていました。その論文を読んで即座に影響を受けてしまいとうとうニューラルネットワークを試すことにしました。手始めにニューラルネットワークについて書かれた情報をいろいろ集めました。取りあえず一番スタンダード(っぽい)一方向にだけ情報が流れる3層のニューラルネットワークを試すことにしました。

まずは指標の組み合わせにより、次の足で上がるか下がるかだけでもわかればと思って検証してみようと思いました。

今回は4年分16通貨ペア程度のデータで学習させて使っていない他のデータで検証するということを試みました。入力として与えてみたのは:
現在のRSI(9)、ひとつ前のRSI(9)、二つ前のRSI(9)、現在のCorrelation(24)、ひとつ前のCorrelation(24)、二つ前のCorrelation(24)の6つの値です。
※RSI(9)は期間=9のRSI、Correlation(24)は期間=24の終値とインクリメント値(現在が24、ひとつ前が23、その前が22というような一つずつ変わる数字)との相関値です。

ニューラルネットワークに学習させる方法として(これも標準的な方法なようですが)バックプロパゲーションなる方法をまず使って見ました。オーバーフィッティングを避ける方法として(これも海外のどこかの論文に書かれていて良く利用される方法なようです)学習用のデータとは別に検証用のデータでのパフォーマンスをウォッチしながら、検証用データでのパフォーマンスが伸びなくなったら学習をやめるという方法を用いました。

例えばEURUSD2004-2008を学習用データとしてニューラルネットワークに教え込んでいきます。教え込む際に現在のニューラルネットワークが答えとして返す値と実際の本当の値を比較して、その誤差が小さくなるように繰り返し処理を行います。学習用のデータであるEURUSD2004-2008では繰り返すほど誤差が小さくなっていくのですが、ある程度以上繰り返すとあとはいわゆるオーバーフィッティングになってしまうことになります。そこでEURUSD2004-2008とは別に例えばEURUSD2003を検証用に使うということを行います。(以下がそのイメージ)

学習用データの誤差(EURUSD2004-2008) 繰り返すごとに誤差が小さくなる
繰り返し1:100
繰り返し2:50
繰り返し3:30
繰り返し4:20
繰り返し5:17
繰り返し6:15
繰り返し7:14

検証用データの誤差(EURUSD2003) 繰り返しても誤差が小さくならない地点がある
繰り返し1:200
繰り返し2:110
繰り返し3:67
繰り返し4:50
繰り返し5:51  ★ここらへんで学習をやめる
繰り返し6:50
繰り返し7:52

この方法でバックプロパゲーションを用いて学習をさせて見ました。結果は少しだけ上手く行ったがいろいろ問題ありという感じでした。 学習にはある程度時間がかかることを覚悟していましたので数時間とかのレベルであれば良しとしようと当初から思っていました。また仮に1週間かかろうとよい学習をしてくれれば最終的には使えるはずと思っていました。

ところが実際にやってみると本当の問題は学習に時間をかけても必ずしも良い結果に行きつくとは限らないという点であることに気付きました。 Webでバックプロパゲーションについてもう少し詳しく調べるとバックプロパゲーションの弱点の一つに局所的な最適解にはまってしまう点があると書かれていました。 本当は日本海溝を探しだしたいのにそのあたりの溝に落ち込んでそこが一番深いところだと思い込んでいるような感じです。これを回避するための方法がいろいろ研究されているとのことでした。

そこで回避方法のなかで(プログラムを作る立場として)一番簡単そうな遺伝的アルゴリズムを利用してニューラルネットワークを学習させるという方法を試してみました。イメージとしてはバックプロパゲーションでニューラルネットワーク内のリンクの重みを決定するのではなく、遺伝的アルゴリズムで重みを決定するという感じです。

結果は以下の通りで個人的には「これならいけそうだ」と思えるものでした。今後につなげたいと思います。

データ:2003年~2006年(1時間足)
通貨ペア=15 "EURUSD", "GBPUSD", "USDCHF",
                      "USDJPY", "EURJPY", "GBPCHF",
                      "GBPJPY", "CHFJPY", "USDCAD",
                      "AUDUSD", "AUDJPY", "EURCAD",
                      "EURCHF", "EURGBP", "NZDJPY",
                      "NZDUSD"
※検証用は上記のうち 2003EURUSD, 2004GBPUSD, 2004CHFJPY, 2005EURJPY, 2005AUDJPY, 2006EURCADの6ペア/期間で残りを学習用データとして利用しました。
※検証用データにおいての勝率(上がるか下がるかがあたった確率)は52.68% (35,086本の足において) まだこれだと実戦には使えませんが、もう少し入力を工夫したりすればもっといけるのではないだろうかと感じています。(ちなみに学習用データでの勝率は53.08%でした。)

以下にニューラルネットワークを可視化してみた際の図を示します。(青が正の重み、赤が負の重みを表し、線の太さが重みの大きさを表しています。一番左の列が入力で上から(RSI現在、RSI一つ前、RSI二つ前、相関現在、相関ひとつ前、相関ふたつ前、そして一番下はバイアス(常に1)です)を表しています。真ん中の列は隠れ層、右側が出力です。)


今後やっていきたい事ですが:
※最終的には上がるか下がるかではなくて「今安全にエントリーできる場所かどうか」というような事を教え込みたいと思っています。
※データを年毎、カレンシーペア毎に分けて、あるいはもっと細かく分けてそれぞれのパフォーマンス(誤差二乗和で現在は測っている)だけでなく、それらのばらつきがより小さいものを探すようにさせたい。(ある年だけ上手く行くルールではなくてどんな年でも上手く行くようなものをより良いものとして判断するようにさせたい)


2010年12月13日月曜日

ボラティリティーの収縮(Volatility Squeeze)

ここ最近はボラティリティーのスクイーズ(収縮)を何とか利用できないものかと試行錯誤しています。いろいろなところでボラティリティーのスクイーズが発生した後にはボラティリティーの拡張が起こる等と書いてあります。例えば「ボリンジャーバンドの幅が狭くなったら値段が大きく動く前兆」というようなことやNR7などもこの現象をとらえようとするものだと思います。ボリンジャーバンド発案者であるボリンジャー氏の「ボリンジャー・バンド入門」という本でも「低ボラティリティーは高ボラティリティーを呼び高ボラティリティーは低ボラティリティーを呼ぶ」というようなことが書かれています。自分で実際にチャートを眺めていても(例えば以下)これはその通りだと思えます。

いろいろやってみたのですが以下の2つのインディケータが今のところ一番上手い具合にとらえているのかなと思うものです。

(式1=下記の黄色い線)   式 : 100 × ATR(N) ÷ (過去N足の高値-安値)
大体30を超えたらエネルギーが溜まっている(収縮している)という感じで考えています。

(式2=下記の赤い線)  式 : 400 × ATR(N) ÷ 標準偏差(N)
45を超えたらエネルギーが溜まっていると考えます。400は4σ分ということで400としています。(特にそれ以外の根拠はありません) (黄色線は式1のもの)


両方とも一長一短という感じですが(2)の方が収縮をより早くとらえる感じです。


これを実際にトレードシステムに組み込むにはどうすれば良いかという点は難しく今後の課題です。

2010年12月7日火曜日

為替相場はランダムウォーク (Random Walk)ではない!

いつもいろいろとWebで情報集めをしているのですが、しばらく前から「ランダムウォーク」というキーワードが気になっていろいろ調べています。というのも、もしも仮に相場がランダムウォークであれば、今自分がやっている検証が根本から意味がないという事になるからです。どうか「ランダムウォークでないでくれ」と思いながらいろいろ情報集めをしたのですが、いろいろ調べてみるとしっかりと研究している人たちが「ランダムウォークです」と結論付けたケースもあれば、「そうではありません」と結論付けた研究者もいるといった具合でした。

いろいろサイトを巡回しているとランダムウォークにより擬似的に作られたデータであっても、あたかもトレンドが発生したように見えたりして本物データと見分けが付きません。

そこでまずは自分でも「ランダムウォークデータを作ってみよう」と考えました。

現在私が検証しているデータは16通貨ペア、2001年から2010年の途中までの1時間足というものです。これらのファイルは全部で16x10年=160個(実際にはデータが無い年が若干あるので150個程度)で、各通貨ペア/年毎に別ファイルに保存して利用しています。

まずはこれらのそれぞれのファイル毎に足毎のリターン平均と標準偏差を求めました。例えば以下のような感じです。

EURUSD/2001 AVG= -0.000011, SD=  0.001283
GBPUSD/2001 AVG= -0.000008, SD=  0.001486
USDJPY/2001 AVG=  0.002737, SD=  0.156111

それに基づいて5秒に一回ランダムウォークをさせてみてデータを生成してみました。ランダムウォークは以下のように行いました。
現在のプライス = 5秒前のプライス + 正規乱数(@5秒枠に調整済みAVGとSD)
※5秒枠に調整済みAVG=上記で得られえたAVG÷(60分×12) (この調整の計算はこれでよいのかいまひとつ不安)
※5秒枠に調整済みSD=上記で得られたSD÷SQRT(60分×12)

各足(1時間)毎に始値から720回ランダムウォークを行い高値と安値を決定します。そして720回目のランダムウォークを終わった時点のプライスが終値ということになります。

以下はそのランダムウォークにより生成したデータの一例ですが、パッと見実際のデータと区別が付きません!

次に最近検証している回帰線の傾きでエントリーしてNCトレーリングでエグジットするという戦略でランダムウォークデータに対してこの戦略を適用した場合と、実際の2001年から2010年までのデータに対してこの戦略を適用した場合を比較してみました。

この戦略は期間Xの回帰線の傾きが下降から上昇に転じたらロングエントリーしてあとはファクターYのNCトレーリングを行ってストップに引っかかったらエグジットするというものです。(ショートはこの逆) 同時に最大一つのポジションを固定サイズでトレードし、エグジット後には次のトレードチャンスが来るまで待機します。 スプリットは0.025%(例えば1ドル100円ならば2.5pips分、1ポンド150円ならば3.75pips分ということになります)でシミュレートしました。

検証したパラメータは以下の通りです。
期間Xは20~30、刻み1
ファクターYは3.0~5.0を刻み0.25

合計でざっくりと 11期間 × 16通貨 × 10年 ×9ファクタ ≒15000とおりのパラメータ・データの組み合わせで行いました。以下がその結果で「ランダムウォークだと儲からないが本物の実データなら少し儲かる」という結果が出ました。(平均損益も上記のスプリットと同様に%ベースで計算しています)

実データの場合:
16通貨ペア全部、全パラメータ、全期間平均
1トレードあたりの平均損益:+0.028%、標準偏差=0.102%
プロフィットファクタ平均:1.10

ランダムウォークデータの場合:
16通貨ペア全部、全パラメータ、全期間平均
1トレードあたりの平均損益:-0.015%、標準偏差=0.126%
プロフィットファクタ平均:0.97

ランダムウォークデータの平均損益は理想的(?)にはスプリット分である-0.025%になるはずですがデータ数が足りないのかそこまでの精度はないようです。(今回のデータ数は上記のとおり15,000程度です。あと原因として考えられるのはプログラムのバグですが…)  以前今回の意図とは全く別の意図で検証したランダムシミュレーションにおいて、データ数=150,000程度(今回の10倍)に対して-0.025%の桁までがきっちりと計算できた事がありますので今回はサンプル数が少ないという事かなぁと思っています。

通貨ペア毎の結果は以下のような感じで、この結果を見る限りにおいて為替相場はランダムウォークではないと言えるのではないでしょうか。 (※この結果は今後も検証を続けて行こうと思えるもので個人的にはとてもうれしい結果です!)

実データの場合(通貨ペア毎、全パラメータ、全期間平均):※平均損益は1トレードあたりの損益平均
EURUSD:平均損益= 0.033%、 PF= 1.13
GBPUSD:平均損益= 0.024%、 PF= 1.10
USDCHF:平均損益= 0.024%、 PF= 1.12
USDJPY:平均損益= 0.030%、 PF= 1.13
EURJPY:平均損益= 0.051%、 PF= 1.18
GBPCHF:平均損益= -0.004%、 PF= 0.97
GBPJPY:平均損益= 0.055%、 PF= 1.19
CHFJPY:平均損益= 0.001%、 PF= 1.01
USDCAD:平均損益= 0.001%、 PF= 1.03
AUDUSD:平均損益= 0.054%、 PF= 1.16
AUDJPY:平均損益= 0.047%、 PF= 1.10
EURCAD:平均損益= -0.016%、 PF= 0.99
EURCHF:平均損益= 0.011%、 PF= 1.04
EURGBP:平均損益= 0.008%、 PF= 1.04
NZDJPY:平均損益= 0.100%、 PF= 1.25
NZDUSD:平均損益= 0.062%、 PF= 1.19

ランダムウォークデータの場合(通貨ペア毎、全パラメータ全期間平均):
EURUSD:平均損益= -0.027%、 PF= 0.96
GBPUSD:平均損益= -0.009%、 PF= 0.94
USDCHF:平均損益= -0.045%、 PF= 0.92
USDJPY:平均損益= -0.016%、 PF= 0.98
EURJPY:平均損益= -0.007%、 PF= 1.03
GBPCHF:平均損益= -0.046%、 PF= 0.87
GBPJPY:平均損益= 0.010%、 PF= 1.03
CHFJPY:平均損益= 0.038%、 PF= 1.12
USDCAD:平均損益= 0.038%、 PF= 1.12
AUDUSD:平均損益= 0.010%、 PF= 1.06
AUDJPY:平均損益= -0.031%、 PF= 0.99
EURCAD:平均損益= -0.033%、 PF= 0.93
EURCHF:平均損益= -0.026%、 PF= 0.87
EURGBP:平均損益= -0.045%、 PF= 0.83
NZDJPY:平均損益= -0.047%、 PF= 0.92
NZDUSD:平均損益= -0.006%、 PF= 1.00






























2010年11月28日日曜日

レンジ判別フィルター

レンジとトレンドの判別をするフィルターはいろいろな方法があると思うのですがなかなか実際に組み合わせて使おうとすると上手くいかないなぁーと常々思っています。例えば長期の移動平均が示す方向だけにエントリーするというようなことが本に書かれていたりしますが、実際に組み合わせてみると今一つ上手く行きません。

この間の記事に書いたNC(Naked Close)トレーリングをいろいろ試していたときに、ふとNaked Closeがレンジ判別に使えるかもしれないと思ったので早速試してみました。

ちなみにNaked Closeとは現在の終値がひとつ前の足の高値を超えているかあるいはひとつ前の安値より下の場合を言います。Naked Closeが発生する状況とはどういう状況なのか考えてみると、(ロングの場合)少なくともひとつ前の高値を超えた状況(新値)で且つある程度の勢いがある状況と言えるかと思います。Naked Closeがよく発生するのはトレンドが発生した時と、後はトレンドが終わる前に急上昇するような場合のようです。

Naked Closeをフィルターにどう使うかということは前述のとおりNCトレーリングをもう少し改良できないかということを考えながらチャートを眺めていた時にひらめきました。チャートを眺めていると例えば上昇トレンドが発生した状態ではロング方向のNCトレーリングの値もショート方向のNCトレーリングの値も実値の下にある状態になります。一方でレンジの場合にはロング方向のトレーリングとショート方向のトレーリングの間に実値があるような状態となります。

これを利用してトレーリングラインのロング方向とショート方向の間に実値がある場合をレンジとし、どちらのトレーリングラインよりも上に実値がある場合を上昇トレンド状態、下にある場合を下降トレンド状態として表示させて見ました。以下の緑の線と赤の線がトレーリングラインで、この2本の線の両方の上に実値(今回は (High+Low+Close)÷3で計算しています)がある場合は上昇OK、両方の下に実値がある場合は下降OK,そうでない場合はレンジとしています。下の赤と緑がフィルター状況を表しています。赤が下降トレンド状態、緑が上昇トレンド、何もないところ(黒)はレンジを表しています。

補足でもう一枚画像を載せておきます。水色でSMA(20)を表示しています。また一番下の赤と緑はSMA(20)の傾きがプラスかマイナスかを表しています。SMAではだましが発生するような横ばいの状況でそこそこ上手くフィルタリングができている感じです。


自分では「これは結構面白いフィルターかもしれない!」と思っているのですが、実際に上手く組み合わせて使えるかどうかを今後はもう少し検証したいと思っています。こういう検証をやっていると「自分の発見は大発見!」と思いたい発見(?)が多々ありますが、実際にしばらく検証すると全然使えない代物ということが良くありますねー。これもその一つかもしれません。

2010年11月25日木曜日

NCトレーリングExit+ボリンEntryを検証

ATRトレーリングよりも良いトレーリングで説明したNCトレーリングをエグジットに使って、エントリーをボリンジャーの2σタッチでその方向へエントリーするという方法で検証して見ました。前回はエントリーは(方向もタイミングも)ランダムにて検証しましたが今回はエントリーにもう少し意味を持たせて見ての検証です。 ボリンジャーの期間は20から34の範囲で、そしてNCトレーリングのFactor(どれだけはなれてトレーリングするか)は2.5から6.0の範囲で検証を行いました。

例によって16通貨ペア、1時間足、2001年から2010年の途中までのデータで検証を行いました。結果は以下の通りでした。

平均PF=1.06
平均利益=0.015%
利益の標準偏差=0.101%


ランダムにエントリーしてNCトレーリングでエグジットした場合の平均利益は0.001%だったので今回の方が少し意味のあるエントリーになっているようです。この小さな数値の変化にどれだけ意味があるのか?とも思いますが、最近は「実はこの小さな違いも結構意味があるのでは」と思うようになっています。

パラメータ(2つ)と平均利益の関係図は以下のような感じでした。
これによればボリンジャーの期間は24から28の範囲でトレーリングのFactorは4.5から5.5のあたりが良いようです。これだけ範囲がきれいに出ているというのは良いことだと思うのですが、平均利益が0.02%とかだとまだまだ勝てないですね。これをどうすればもっと勝てるようにできるのかが課題です。

ちなみにボリンジャー以外のエントリー方法(平均移動クロス、ストキャスティックを使ったエントリー、などなど)もいろいろ試しつつあります。エントリーは少しタイミングが違うだけでどれでも同じようなものというような意識を持っていましたが、実際にいろいろ試すと結構違います。特にこの違いは平均利益とかProfitFactorではほぼ同じような数値であっても、上記のようなパラメータの関係図には結構違いがはっきり現れるようです。(上記のように比較的きれいに最適パラメータの範囲が見えるものとそうでないものがある) 参考までに以下は平均移動を終値がまたいだらその方向へエントリーといつ方法で検証を行った場合の結果です。


平均PF=1.04
平均利益=0.008%
利益の標準偏差=0.109%


以下はパラメータと利益の関係図です。








Pivot、R1,S1のヒット確率

本屋でしろふくろうさんという方の本を見かけ、その中に書かれていたPIVOTに到達する確率についての記述に興味をひかれました。しろふくろうさんはフィボナッチピボットを用いて5年分の日足データでPivot、R1,S1等のラインにどのくらいの確率で到達するのかを検証してみたとのことでした。それによればPivotラインにはかなりの確率(確か70%くらいだったと思います。記憶が定かではありません)でタッチするとのことで、その上下のR1、S1ラインにそれよりも少ない確率ですが何%かの確率で到達するというものです。興味深かったのは前日が上昇(前々日のClose<前日のClose)の場合にはR1への到達確率がS1への到達確率よりも大分大きいということ(前日が下降の場合はその反対)でした。

これは面白い!と思い早速自分でも検証してみました。私は現在1時間足のデータでいろいろ検証しているのでとりあえず1時間足で検証してみました。使ったのは例によって16通貨ペアで1時間足、2001年から2010年の途中までのデータです。Pivotの計算は以下のように行いました。(この計算はワイルダー氏の方法ではなくてフィボナッチピボットと呼ばれるものらしいです)

Pivot = (ひとつ前の足のH + ひとつ前の足のL + ひとつ前の足のC) ÷ 3
Range = ひとつ前の足H - ひとつ前の足L
R1=Pivot+Range*0.5
S1=Pivot-Range*0.5

ひとつ前の足の上下でR1とS1への到達確率が半々の確率でなくなるのであれば、あとは回数をこなせば勝てるということだと思って、そんなに簡単なことなのか?と思ってしまいました。(当然そんな簡単ではないということがいろいろやってみてわかりました。下記参照)

まずはPivotとR1、S1を計算して集計を行いました。結果は以下の通りで、確かに前日の上下によって到達確率にかなりの違いが見られます。例えばひとつ前が上昇の場合にはR1への到達確率がS1の到達確率と比較して結構違います。(下記のパーセントのカラムを足して100%にならないのは例えばR1とS1の両方に到達するケース等の重複があるからです)

おおよそ上下の方向によって53%対33%ということでこのままトレードの数をこなせば勝てるということだと早合点しました。

これはすごいと思って「いったい一回あたりのトレードでいくら勝っているのだろうか?」という点を次に調べようと思いました。上昇もしくは下降でCloseした足の次の足の始値でエントリーすると仮定して、始値からR1およびS1までの価格差(距離)を測ったところ以下のような集計結果が出ました。(下記は距離をパーセンテージベースの価格で表しています。)

これはつまり前日が上昇だった場合は(少し考えると当然なのですが...)始値からR1までの距離が始値からS1までの距離よりも短くなり、逆に前日が下降だった場合は始値からS1までの距離がR1までの距離よりも短くなるので、必然的に到達確率が良くなるということでした。距離と到達確率を掛け算してみるとほぼトントンという結果でした。

ということで今回は「そんな上手い話しがあるはずないか」という結論でした。

こう言ったぬかよろこびは検証をしていると良くありますね。 多くの場合はプログラムミスとかそんな結論なのですが今回も少し残念でした。

しかしこの確率を検証してみると言う考え方は今後活用したいと思いました。

2010年11月20日土曜日

ATRトレーリングよりも良いトレーリング (NCトレーリング)

前回の投稿からいろいろ考えてATRトレーリングよりも良くするにはどうするのかを考えました。良いトレーリングはトレーリング幅を狭めるべく時と狭めずに待つべき時の状況判断が良くできるトレーリングだと考えて、まずはどのタイミングでトレーリング幅を狭めて良いのかを考えました。

例えば新値(5)を更新したタイミングでトレーリング幅を狭めるとかそういう考えも良いかもしれませんが、今回は別のところ(Larry Williams氏のサイトでhttp://www.ireallytrade.com/というサイトがあるのですがそこでメールアドレスを登録すると読める記事)でヒントを得たFalse Breakの条件の一つをきっかけとしてトレーリング幅を狭める方法を試みました。(種明かしは一番下です) そのサインになぞらえて「NCトレーリング」という名前で以下に説明します。

ATRトレーリング(Factor=1.0)とNCトレーリング(Factor=1.0)をチャート上でみると以下のような感じです。
例えば★の地点でロングエントリーをしたとします。ATRトレーリングはATR(14)の距離だけ離れてトレーリングしていきます。なので赤い矢印の箇所で引っかかってしまいます。 一方NCトレーリングはATRに近い考え方で距離自体は決めますがATRトレーリングのようにやみくもに近づいては行きません。安全と判断した時にだけ近づいて行くようにしました。なのでここでは青の矢印までストップに引っかかることなく到達しました。この図ではNCトレーリングに軍配が上がりますがATRの方が結果的にたくさん利益が残せるパターンももちろん多々ありましたので実際どちらが良いのか判断がつきかねます。

そこで前回やったランダムエントリー&ATRトレーリングエグジット対ランダムエントリー&NCトレーリングエグジットを比較してどちらが良いのかを調べることにしました。結果は以下のような感じでNCトレーリングはやはり良いようです。(今まで同様に16通貨ペア2001年から2010年途中までの1時間足のデータで、スプリットは0.025%として計算しています)

上記の結果は面白いなと感じています。前回のATRトレーリングの検証もそうですが今回もエントリーはでたらめなタイミングででたらめな方向にエントリーしています。にもかかわらずエグジットだけで少しではありますがスプリット分の0.025%を稼ぎ出しているという点です。(ちなみに0.025%といえば例えばEURJPYの今現在の値で換算すると2.8 pipsということになります)

最後にNCの種明かしですが、NCはNaked Closeの略です。なのでNCトレーリングは最新終値が一つ前の高値を超えた(Naked Close)タイミングで近づくということをやっています。

---------------------------------

その後NCトレーリングの場合の距離計算(上記の「ATRに近い考え方で距離の計算」)をATRトレーリングとまったく同様のATR(14)で計算させたらどうなるのかなとふっと思ったのでやってみました。ちなみに上記のNCトレーリングではNaked Closeが起こった時のTRで距離の計算を行っています。

ほんの軽い気持ちで試したのですがこの距離の計算方法で結構結果が変わりました。

この結果とチャートをながめていて思うところはNCトレーリングでせっかく見極めたはずの近づくタイミングの効果が、近づかないでいることで取り損なうマイナス効果で相殺されてしまっているという事です。一気に大きくあるいはその反対に今まで以上に小さく値が動いた時の変化のスピードについていくためにはATRの期間は短い方が良いという事かもしれません。

2010年11月19日金曜日

ATRによるトレーリングを検証

私はトレーリングの考え方が性にあっているようで以前から興味がありました。

「トレーリングエグジットの考え方に優位性はあるのだろうか?」
というのが今回の検証目的です。

エントリーはランダムでエグジットをトレーリングストップで行うという事をやってみました。

以前にランダムエントリー&ランダムエグジットを試しに行ってみた時に確率はちょうど50/50でトレードあたりの平均利益も(スプリットを除いて)0になることを確認してありますので、今回はエントリーを同条件にしてエグジットをトレーリングで行い、以前のそれよりも少し良くなるだろうかという考えで検証を行います。エントリーは以前と同条件ということでBUYで入るかSELLで入るかもランダムで決定します。つまりランダムに決定されるある時点でSELLもしくはBUYでエントリーしてとにかくその方向にトレーリングをするといったやり方で検証を行いました。

トレーリングはATRをベースにした方法で検証しました。ここで言うATRトレーリングとは例えばロングをトレーリングする場合には:
現在の安値 - ATR(14)×Factor
をストップに設定するというものです。Factorはパラメータで例えば1とか2.5とか設定したい幅によって決定します。Factorを小さくすればするほどよりきつい(実値に近い)トレーリングとなります。例えばFactor=3.0で現在の安値が80.00でATR(14)が0.25の場合にはトレーリングストップを79.25に設定するといった具合です。

実は以前にATRトレーリングをいろいろなFactorでやってみたことがあり、その時の印象として今一つ実際の値動きをとらえていないという悪いイメージがあります。今後これよりも良いトレーリングを研究したいので今回はこのATRトレーリングを一番ダメなパターンとしてデータを取りたいと考えました。

今回も以前からと同様に2001年から2010年の途中までのデータ(1時間足16通貨ペア)を用いてスプリットを0.025%として行いました。その結果が以下の通りです。上が以前行ったランダムエントリ&ランダムエグジットの結果で下が今回行ったランダムエントリ&ATRトレーリングの結果です。ここで平均利益は1トレードあたりのパーセンテージベースの利益を示しています。(パーセンテージベースの価格についてはこちらの記事に少し書きました)ランダムエントリーランダムエグジットの平均利益が-0.025なのはスプリット分を除けばトントンであるということが表れているからと思われます。 エントリー条件を変えずにATRトレーリングを採用したことで平均利益が少しだけ良く(-0.025%から-0.009%へ、つまりスプリットを除いてトントンだったのが少しプラスに)なりました。それから標準偏差も小さくなってよりリスクが小さくなったとも言えます。平均利益がたったこれだけ良くなったことに何か意味があるのか?と思ってしまいますが以前にもまして現在ではこの小さい違いでも実は思ったよりも意味があるかもしれないと考えるようになりました。


今回のATRトレーリングではFactorを1.0から4.0までの範囲で0.2きざみ毎に変化させながら検証を行いました。上記数値はFactor1~4までの範囲の平均です。またランダムエントリーのタイミングも何種類かの異なる確率で行いました。なのでトータルで10万回以上のトレード数での結果なので小さな違いでも有意となりました。(U検定にて

今後はトレーリングでもっと良いものを目指したいと思っています。良いトレーリングというのは「こういう形になったらトレーリング幅を狭めて良い、こういう形の時は狭めずに待たなければいけない」という状況判断が的確にできるトレーリングということになると考えています。 ATRトレーリングはあくまでここ最近の値幅をベースに幅を決定し特に状況判断をせずに一定の距離を保つといった感じのトレーリングですが、良いトレーリングはおそらく何か別の状況判断でもってトレーリング幅を狭めて良い時とそうでない時を区別できるのだと思っています。今後研究していきます。




2010年11月2日火曜日

平均移動からの乖離率を正規化

(例えばRSI等の指標が0-100の範囲で正規化されているのに対し)モーメントや平均移動からの乖離率等の指標は正規化されていないので今一つ使い勝手が良くないと思っていました。しかしモーメントにしても乖離にしても今後システムの中で利用したいなと考えている指標なので何か良い正規化の方法はないかなと考えていました。

いろいろ考えたのですが私の結論としては過去のデータに頼るのがベストなのかなと。

過去のデータでこれらの指標の値を毎足(例えば1時間足であれば毎時)計算してその平均と標準偏差を求めておいて、それらの平均と標準偏差を使った正規化を行うというものです。

具体的には例えば単純平均移動(20)からの乖離率をデータがある分だけすべて計算させたくさん計算された乖離率の平均と標準偏差を求めます。この例で実際に過去10年分16通貨ペアすべての1時間足で計算を行うと平均はほぼゼロ、標準偏差は0.382681との結果がでました。

この数値を使って得られた乖離率の正規化を行おうと考えたのですが、ボリンジャーバンド入門(ボリンジャー氏著)という本に載っていた %b というボリンジャーバンドベースの指標と同じような考え方で±2.0×標準偏差をそれぞれ0と100に対応させるように計算させようと考えました。例えばRSI等のように0を下限、100を上限とするのであれば以下の式で得られた乖離率から0から100の範囲の数値が求められるはずです。(ボリン等と同様確率的に100を超える(ボリンでいうところの2σ超え)こともありますし0以下になることもありますが概ねこの範囲に収まることで良しとすることにしようと考えて計算させてみました)
得られた乖離率÷標準偏差×25+50

結果は以下のとおりで良好な感じです。0以下で結構-方向に乖離しているとわかり、100以上で結構+方向に乖離しているということがわかる(はず)です。

同時期のSMA(20)と終値は以下のとおりです。

もう少し調べてヒストグラムを見てみました。1時間足でSMA(20)からの乖離率を16通貨ペア10年分程のデータ調べたところ以下のような感じです。

分布は正規分布でないようでとても尖がっています。(尖度=18.4215) 正規分布を仮定できない場合の信頼区間はどうやって計算させればよいかいろいろ調べてやっとたどり着いたあるサイトに97.5%と2.5%のパーセンンタイルを求めてそれを使えば良いというようなことが書いてありました。

そこで2×標準偏差の場合とパーセンタイルベースの場合でどのくらい違う結果になるかを見てみました。パーセンタイルベースだと95%信頼区間は -0.78368~0.73508 という結果で標準偏差×2.0だと信頼区間は -0.76536~0.76536 なので自分の中では標準偏差×2.0を使って問題無しと結論づけました。

その後乖離率以外でもやってみようと思い、手始めに標準偏差(20)をやってみました。標準偏差は乖離率と違って分布が以下のように左右対称ではありません。(※標準偏差(20)の20は期間を表しています。今回は時間足なので過去20時間の平均からのばらつきを表しています)

左右対称でないためか乖離率の時のような標準偏差×2.0というやり方は通用しませんでした。今回の平均は 0.2223、標準偏差(標準偏差の標準偏差ということです)は 0.1864でした。そのまま標準偏差×2.0を計算すると下限が0より小さくなって明らかにおかしいことになっています。 なのでパーセンタイルベースで95%信頼区間と99%信頼区間を求めて見ました。95%信頼区間は0.04459~0.69156ということが分かりました。この値を上限下限にして正規化してみた標準偏差と同時期の価格変動(及び参考にボリンバンド)は以下のような感じでなかなか良い感じです。

ボリンで+2σもしくは-2σにタッチしている箇所が何か所かありますがそこでの真ん中の線から2σまでの距離÷2が即ち標準偏差ということなのですが、正規化(と言えるか分かりませんが...)されていた標準偏差を見たほうがこのバンドの幅の部分については良く分かりやすい感じです。

2010年10月25日月曜日

時間帯別ボラティリティー

ふと思いついてヒストリカルデータから時間帯別のボラティリティーを調べてみました。ここで言うところのボラティリティーとは高値-安値のことですがいろいろな通貨ペアの平均を見たかったので、パーセンテージベースの価格で計算を行いました。例えば9時から9時59分までのUSDJPYの高値が85.82で安値が85.22だった場合は85.82-85.22=0.60。これをパーセンテージベースに変換するためにその足の終値で割ります。例えば終値が85.50とすると0.60÷85.50=0.00702となります。

下記のグラフで例えば0.0025は0.25パーセントの値動きを表します。なので例えばUSDJPYのレートが90円であったと過程して逆算(90円×0.0025)すると22.5pips程度の値動きが平均的にあるという事がわかります。

用いたデータは2001年1月から2010年9月までの15通貨ペアのデータです。日本時間ベースで表にしてみました。(夏時間が採用される時期とそうでない場合の2パターン)


上記は15通貨ペア(EURUSD, GBPUSD, USDCHF, USDJPY, EURJPY, GBPCHF, GBPJPY, CHFJPY, USDCAD, AUDUSD, AUDJPY, EURCAD, EURCHF, EURGBP, NZDJPY, NZDUSD)の平均です。通貨ペア毎に活発に取引される時間が違うのかもしれないと思ったので何となく異なった結果になりそうな3つの通貨ペア(USDJPY/GBPCHF/EURUSD)でもグラフにしてみました。

これによれば大体どの通貨ペアも似たような傾向にあるようですね。あとUSDJPYは日本の昼間の時間帯で多く取引されるという傾向も見て取れます。

2010年10月17日日曜日

CBOを検証してみた

今までランダムトレードで自作検証プログラムの動作がOKかを何となく確認してきたのですが今回やっとランダムではないものを試してみました。チャネルブレークアウト (CBO) というものをまずはやってみて、ランダムより良ければ良しということでやってみました。

使ったデータは2001年1月~2010年9月までの1時間足のデータを1年区切りにしたものを利用しました。合計で10年弱分のデータ × 16通貨ペア=160年分のデータでやってみました。

CBOのエントリー時のパラメータEntryPeriod(過去何時間の最高値をつかうか)は20,25,30,35,..,75,80までの13パターンとしました。ExitのパラメータはEntryPeriodを一とした場合の比率として定義(ExitRatio)して0.2~0.8までを0.1ステップ刻みで変化させました。(例えばEntryPeriod=20の場合でExitRatioが0.5の場合Exitに使う期間は10本(時間足を使っているので10時間)ということになります)合計13エントリー期間 × 7Exit比率 ×160年 =14560の結果が得られました。(合計2パラメータ)

今回の設定ではロングもショートもチャンスがくればエントリーするという設定になっていますが以下がそのルール(ロングの場合)です。
  • エントリーはEntryPeriod期間中の最高値を終値ベースで更新した次の始値でエントリーとしました。
  • エグジットは 切り捨て(EntryPeriod×ExitRatio) とし、その期間中の最安値を終値ベースで更新した次の始値でエグジットとしました。

下記の結果はその全ての結果の平均です。CBOがチャネルブレークアウト(今回)の結果で、RANDOMがランダムトレード(今までやっていたやつ)の結果です。(あとPF=プロフィットファクター、AvProf=%ベースのトレードあたりの平均利益をそれぞれ示しています)

たったこれだけのちがい?と思いましたがあくまでこれは16通貨ペアでかつ良い年も悪い年も含め、そしてさらに良いパラメータも悪いパラメータも全部含めての全平均なのでこんなもんなのかもしれません。この2つでU検定を行うと(前回の記事参考)とりあえず意味のある差がある(P値=0.0001)との結果です。(サンプル数が多いのでP値も相当小さいです)

尚上記のデータはすべて0.025%のスプリットが考慮してあります。ランダムのAvProf(パーセンテージベースの平均利益)が-0.025となっているのはまさにそのためでです。(ランダムトレードは(スプリット等を除いて)とんとんになる) ですのでCBOではスプリット等考慮しなければ確率的には+が見込めるということです。

この次のステップとしてはまずはEntryPeriodとExitRatioの各パラメータの指定範囲をもう少し小さくしていってそれでAvProf等の平均値を上げていくことだと思っています。各パラメータは最初は(点ではなく)範囲で指定することが良いことだと考えています。これによってオーバーフィッティングを避けることができてより堅固なシステムができれば良いなぁなどと現時点では考えています。

<1日経過>

まずはEntryPeriodとExitRatioそれぞれと平均利益の関係を見てみたいと思ってグラフにしてみました。以下のような結果が出ました。
これによれば(アバウトですが)EntryPeriodは50~75の範囲、ExitRatioは0.5以上で0.8以上も今後検証したほうがよいといった感じに見受けられます。

そこで次はEntryPeriodを狭めて且つExitRatioは0.5~1.4くらいまででやってみようと思います。

<半日経過>

やってみた結果は以下の通りでした。

少し良くなりましたが微々たるもの。こんなもんなんでしょうかね。今回もまたEntryPeriodとExitRatioそれぞれのパラメータ値毎の平均利益を出してみました。今回はパラメータによっては平均利益がプラスに振れているものが出てきました。
最後に一番良さそうなEntryPeriod=50, ExitRatio=1.3での集計もとってみると以下のような感じでした。また少しだけ良くなりました。

この結果は持ってるデータの10年弱×16通貨ペアの平均なのですが、これじゃ儲かりませんね。平均でそこそこのPF(1.4程度?)もしくはAvProf(0.20%程度?)が出てそして且つ標準偏差が小さいというようものを目指したいと考えています。(これがどのくらい大変なことかは現時点では皆目見当もつきませんが、簡単ではないのだろうなぁと思っています。)

(※後で気が付いたのですが標準偏差の計算が間違っていました!平方根取り忘れてた!なのでこの記事を含め今までの記事で標準偏差とあるものはすべて不偏分散でした。)


2010年10月13日水曜日

統計的な検定をもう少し

前回の投稿でT検定(分散が同じ)、T検定(分散が異なる)、マンホイットニーのU検定を計算してみましたが、今回はもう少し追加で「ためし検定」をやってみました。今まで取った以下の5種類のランダムトレードシミュレーション結果を基にそれぞれを比較(検定)してちゃんと検定ができているかを見てみました。
  • sm00 - サンプル数200程度、スプリット=0.000%
  • sm25 - サンプル数200程度、スプリット=0.025%
  • mid00 - サンプル数2000程度、スプリット=0.000%
  • mid25 - サンプル数2000程度、スプリット=0.025%
  • bg25 - サンプル数20000程度、スプリット=0.025%
上手く行っていればサンプルサイズに関係無くスプリットが違う場合のみP値が小さくなるはずです。
その結果は以下のとおりでした。(AvProfは平均利益です)

やはり正規分布を仮定しなくてよいU検定が一番良いのかなとの結論に達しました。

ちなみに参考までに他の指標(例えばプロフィットファクターとか最大ドローダウンとかで検定した場合はどうなのかと言うことでやってみました。以下がその結果です。

興味深いですね。Sharpe比の場合だとかなりどの検定でも上手くいっています。Sharpe比のヒストグラムはそういえば正規分布に近かったなぁと思い出しました。以下がSharpe比のヒストグラムですがこれが正規分布っぽいのでSharpe比ではU検定でもT検定でも上手くいくのかもしれませんね。統計の専門家に聞きたいところです。


統計の力

前回の投稿でスプリットを変えて計算結果の確認をしましたが本当は統計の力を借りないといけないのかもしれないと思いいろいろ調べてみました。2つの結果の比較に利用できそうだと思ったものはT検定(分散が同じ)、T検定(分散が異なる)、U検定(マンホイットニーのU検定と言うらしい)等です。調べによるとそれぞれ前提条件が違います。
T検定(分散が同じ):サンプルが正規分布であること
T検定(分散が異なる):サンプルが正規分布であること
マンホイットニーにU検定:2つのサンプルの分布の形が同じであること

ランダムトレードの結果で平均利益のヒストグラムは以下のようにだいぶ尖がっていて正規分布じゃないんじゃないかとの結論に達しました。なのでU検定?かなと思っていたのですが、いろいろWebを見ているとT検定でもいいんじゃないかというようなことが書いてあったりまぁよくわからないのでとりあえず上記全部を計算させてみることにしました。

結果は以下の通りでした。(平均利益の比較)

T検定(分散が同じ)のP値=0.0000
T検定(分散が異なる)のP値=0.0000
マンホイットニーにU検定のP値=0.0001

P値が0.05(5%)もしくはより厳しく判断するのであれば0.01(1%)以下であれば結果に統計的に意味のある違いがみられるということらしいです。今回は明らかに違い過ぎてものすごく小さいということだと思います。が、本当に計算がうまくいっているのだろうか?と少し疑問に思い、もう少しサンプル数の少ないパターンでの比較をやってみようと思いました。上記の結果はサンプル数がそれぞれ2000前後のサンプルA(スプリット0.0%)とサンプルB(スプリット0.025%)の比較だったので今度はサンプル数を200程度に落として再度計算をさせてみました。その結果は

T検定(分散が同じ)のP値=0.051937
T検定(分散が異なる)のP値=0.051937
マンホイットニーにU検定のP値=0.015005


でした。上手くいっているような感じです。しかし分散が異なる場合と同じ場合でなぜか答えが同じでした。(分散が同じということだろうか?)

続きはこちら

2010年10月11日月曜日

ランダムトレードシミュレーション動作確認

この前からやっているランダムトレードシミュレーションの続きです。

今回はスプリットの効果が効いているかということをチェックしました。 というのも今回のシミュレーションソフトはまだ作成中のしろものでうまく計算ができているか等まだまだ自信が持てないからです。今までここに載せた数値はすべてスプリットを0.025%で計算していたものなので必然的に利益平均は若干マイナスであるはずで、実際にもそれらしくマイナスになっていました。

※参考までにここでスプリット0.025%を実際の金額ベースのスプリットに換算するには例えば以下のように現在のレートとパーセンテージベースの値をかけ合わせます。
例)
  • USDJPY 81.88円ならば: 81.88 × 0.00025 = 0.02047 → 約100分の2円(2銭)
  • GBPJPY 130.55円ならば: 130.55 × 0.00025 = 0.0326 → 約100分の3.3円(3.3銭)
  • EURUSD 1.3929ならば: 1.3929 × 0.00025 = 0.000348 → 約100分の3.5セント
パーセンテージベースで計算しているのは、通貨ペアが異なっても一括で同じ計算ができるようにするためです。(これはトレーディングシステム入門(トーマス・ストリズマン著)という本からのネタです。)

今回は一応プログラムでのsplitの計算がうまくいっていそうかどうかをチェックしようということでスプリット0.0%の場合とスプリット0.025%と念のために0.075%の3パターンでの結果を出してみました。

スプリット0%の場合
profit factor = 1.05
平均利益 = 0.004%




スプリット0.025%の場合
profit factor = 0.9621239,
平均利益 = -0.021%




スプリット0.075%の場合
profit factor = 0.81
平均利益 = -0.071%


大体予想通りの結果でまずまず上手く計算できているようでした。今回でスプリット=0.025%は少し甘すぎかもしれないと改めて思いました。





収益曲線の回帰残差の標準誤差

この間からやっているランダムトレード(いろんな通貨ペアでランダムにトレードを行って収益やプロフィットファクタ、勝率等を計算)して算出された結果の相関関係をみるということを少し通貨ペアを増やしてやってみました。今回は通貨ペアを増やして(合計16ペア)でまたまた相関をとってみました。

あと今回は「売買システム入門(Turshar S. Chande著)」からネタを仕入れた「収益曲線の回帰残差標準誤差」なる指標も計算させてみました。 この指標はどれだけなめらかに収益が伸びているかということを表すというもので小さければ小さいほどよいというものです。今回はその数値で平均利益を割った数値をRSEという名前で算出しました。それからもう一つ収益曲線の回帰残差から算出するRSDなる数値(過去の投稿でRSSとか読んでいたやつを少し変更)も合わせて出しています。

今後これらの数値のどれかがシステムの良し悪しの評価に使えないかなと考えています。

相関の結果は以下のような感じでした。


追加情報としてランダムトレードにおいてのRSEと平均利益の散布図を描いてみました。

システムの良し悪しの判断に使えそうな指標のもう一つにSharpe比というものがあるのですがこちらも比較対象として以下に載せてみます。Sharpe比は1を超えると良いモデルということらしいです。

参考までに他の数値の例として勝率と平均利益(AveProf)の散布図は以下のような感じでした。

更にランダムトレードにおいてのRSEのヒストグラムは以下のような感じです。

Sharpe比のヒストグラムは以下のような感じでした。

今後の記録のためにとっておきたいと思います。



2010年10月10日日曜日

散布図 (平均利益:勝率、最大ドローダウン、平均ドローダウン、etc.)

この間から検証用のプログラムを書いていて、現在はまだランダムトレードがやっとできるようになった状態です。 ランダムトレードの結果はExcelでグラフにしていたのですが、なかなか面倒なので何とか自動的にできないかなぁと思って少ししらべたところ、グラフを簡単に生成してくれるGnuPlot(フリー)を見つけてありがたく利用させてもらうことにしました。

GnuPlotはいわゆるCSVで出てくる検証結果を簡単にプロットして画像を作成してくれるという優れもので、これの利用方法がわかったおかげで、この間から掲載している散布図のようなグラフもあっという間にできるように! こんな良いソフトがただなんてありがたいですね。

その結果例をいくつか以下に掲載します。今回は平均利益(%価格ベース)対他の指標値の散布図です。

プロフィットファクターとの散布図よりこっちのほうがわかりやすいかもしれません。今後はこっち(平均利益 v.s 他の数値)のプロット図を作成しようと考えています。

あと各項目のヒストグラムも自動生成できるようにしたいと考えています。

最大ドローダウン:平均利益

CDD(平均利益÷トレードあたりの平均ドローダウン):平均利益


RSS(平均利益÷収益曲線の回帰残差の標準偏差:平均利益

Sharpe比:平均利益

勝率:平均利益