OANDのこのページには、通貨の相関関係というチャートがあります。
通貨ペアが互いにどのように関連して動くかを赤・青の色、円の大きさで表しています。2つの通貨に正の相関関係(片方の価格が上昇すると、もう一方も上昇する)にあれば、赤色が濃く・大きくなり、負の相関関係(片方の価格が上昇すると、もう一方は下降する)にあれば、青色が濃く・大きくなるというモノです。
どのようにトレードに活かすかは、ひとまず置いといてMT4上に表示されると面白そうです。
(どうでもいいですが、Currenseeというネーミングもいいですね)
ロジック
そもそも、この相関はどのようなロジックで計算されているのでしょう?
OANDのページの下のほうに、ロジックが数式で掲載されています。
頭が痛くなってきました。。数学は苦手なので正直さっぱりわかりません。
こういうときは、机上で考えてうんうん言ってても進まないことが多いので、テストコードを書いて手を動かしてトライ&エラーを繰り返すのが近道です。
とりあえず、何か書いてみましょう。
仕様
とりあえず、手を動かしてコードを書けばいいのですが、最低限必要な項目を整理、理解しないと進みません。
まずは、数式の「記号の意味」は読み解かなくてはなりません。式のロジック・理屈はそういうもんだ・・・でスルーできますが、記号の意味がわかっていないとプログラムに落とし込むことができませんので。
どんなプログラムを書く場合もそうですが、先に簡単でもいいので設計図・概要を整理しておけば、結果的に近道で不具合の少ないものを作るコトができます。
1行目、Correlation coefficient(相関係数)の√(ルート)は、どうやって計算するのでしょうか。MathSqrt関数というのが、どうやらルート、平方根を計算してくれるようです。
1 2 3 |
double MathSqrt( double value // positive number ); |
引数と戻り値は、迷いようがないほどシンプルです。
注意するのは、平方根を求めたい値(value)は、positive number(正の数)でなくてはならないということです。
先に書いておきますが、今回引数に与える値(SSxyとSSxy)は、二乗の合計であるので負数になることはないので、気にする必要はありません。
2行目SSxyを見ていきましょう。
イコールの次、Σ(シグマ)とは何でしょう。シグマは、数列の和を表す数式です。「1,3,5,7,9」という数列がある場合は、1+3+5+7+9=25が答えとなります。
シグマの右下と右上にある添え字(i=1とn)は、シグマ以降に書かれている数式の変数にiという添え字があるので、それを1からnまで足せよ、ということです。「1,3,5,7,9」の場合は、n=1と5(1番目から5番目まで)と表記するイメージです。
これをプログラムにする場合はどうですればよいでしょうか。
繰り返して足す・・・for文を使えばよさそうな気がします。for(i=1; i < n; i++)みたいなイメージです。
次に、シグマのかっこの中を読み解いて行きましょう、まずは最初のかっこ(Xi-X)みたいなやつ。
Xiはさっきシグマの説明のところで書きました、数列のi番目の数です。さっきの数列の例だと、1,3,5,7,9となるところです。
そのあとのXの上に棒があるやつは何でしょうか?調べてみると、xの加重平均・・・ただの平均のようです。つづくYについても同様ですね。
3行目SSxx、4行目SSyyは基本的に同じです。
2行目はXとYの各要素と平均の差を掛けて足していっていましたが、Xの各要素と平均の差を二乗しています。
プログラムに書くべき要素は、すべてそろいました。
テストコード
とりあえず、任意の2つの通貨ペアを決めうちして、適当な本数の終値を取得して相関関係を出してみましょう。
初期化OnInit関数ですべて計算して、ログにPrint関数で表示してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
#property copyright "" #property link "" #property version "1.00" #property strict #property indicator_chart_window // 比較する通貨ペアの数 #define NUM_SYMBOL 2 // 比較する価格の数 #define NUM_PRICE 64 // 通貨ペアのシンボル名称 string gSymbolTbl[NUM_SYMBOL]; // 価格テーブル(通貨ペア × 比較する価格の数分) double gPriceTbl[ NUM_SYMBOL ][ NUM_PRICE ]; // 平均値テーブル(通貨ペア分) double gAveTbl[ NUM_SYMBOL ]; int OnInit() { // 比較する通貨ペアのシンボル gSymbolTbl[0] = "USDJPY"; gSymbolTbl[1] = "EURUSD"; double ave; // N本分の通貨ペアの終値 と 平均値を求める for (int i = 0; i < NUM_SYMBOL; i++) { ave = 0; for (int j = 0; j < NUM_PRICE; j++) { gPriceTbl[i][j] = iClose(gSymbolTbl[i], 0, j); ave += gPriceTbl[i][j]; } ave /= NUM_SYMBOL; gAveTbl[i] = ave; } double SSxy, SSxx, SSyy; double tmp1, tmp2; SSxx = 0; for (int j = 0; j < NUM_PRICE; j++) { tmp1 = gPriceTbl[0][j] - gAveTbl[0]; tmp1 *= tmp1; SSxx += tmp1; } SSyy = 0; for (int j = 0; j < NUM_PRICE; j++) { tmp1 = gPriceTbl[1][j] - gAveTbl[1]; tmp1 *= tmp1; SSyy += tmp1; } SSxy = 0; for (int j = 0; j < NUM_PRICE; j++) { tmp1 = gPriceTbl[0][j] - gAveTbl[0]; tmp2 = gPriceTbl[1][j] - gAveTbl[1]; tmp1 = tmp1 * tmp2; SSxy += tmp1; } double CC_Bunshi = SSxy; double CC_Bunbo = MathSqrt(SSxx * SSxy); double CC = CC_Bunshi / CC_Bunbo; Print("CC_Bunshi = " + CC_Bunshi); Print("CC_Bunbo = " + CC_Bunbo); Print(gSymbolTbl[0] + " - " + gSymbolTbl[1] + " = " + DoubleToStr(CC, 2)); return(INIT_SUCCEEDED); } |
テストコードなので、わかりやすさ重視のため後半(44行目以降)は、本来for文で処理する(SSxxとSSyy)ところをあえて、2回書いています。
30行目から41行目は、まずUSDJPNとEURUSDの64本分の終値を配列(gPriceTbl)に格納して、それぞれの平均値(gAveTbl)を求めています。
価格がすべてそろったところで、SSxx、SSyyを求めています(44行目〜59行目)。
具体的に数式の中身を計算しているところは、以下です。
49 50 51 |
tmp1 = gPriceTbl[0][j] - gAveTbl[0]; tmp1 *= tmp1; SSxx += tmp1; |
49行目で各要素と平均の差を求め、50行目で二乗、51行目で和(シグマ)を求めています。
SSxyもSSxx、SSyyと同様に求めています(61行目〜67行目)。
そして最後に相関係数(CC)の計算をして(69行目〜71行目)、ログに表示(73行目〜75行目)しています。
実行すると以下のように表示されます。
それっぽく表示されていますね。
さいごに
このロジックが完成してしまえば、あとは任意の通貨ペア・時間足・対象とする価格の本数、表示の仕方を整理すれば、使えるインジケーターになると思います。