2012/10/30

続・相関係数

2012/10/30追記
前回の内容にて、相関係数は、計算コストが高すぎてリアルタイムで随時処理していくには不向きなものと記述しましたが、kartzさんからコメントを頂き、それが誤りであったことがわかりましたので記述します。
内容は、私が説明するよりkartzさんのコメントを見て頂いた方が良いと思いますのでそちらをご覧ください。
※正直完全に理解できたか疑問が残るというのが本音だったりしますが。。(汗

コード化

kartzさんのコメントをコード化すると以下の様になりました。
//+------------------------------------------------------------------+
//|                                                   相関係数_i.mq4 |
//|                         Copyright 2012, MetaQuotes Software Corp.|
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Yellow

extern int pd = 100;//期間

double Sx[]; //S(x,a,b) := Σ[i=a~b; x[i]]: xの総和
double Sy[]; //S(y,a,b) := Σ[i=a~b; y[i]]: yの総和
             //M(v,a,b) := S(v,a,b) / (b-a+1): 相加平均
double Fxy[];//F(x,y,a,b) := Σ[i=a~b; (x[i] - M(x,a,b)) * (y[i] - M(y,a,b))]
double Fxx[];//F(x,x,a,b) := Σ[i=a~b; (x[i] - M(x,a,b)) * (x[i] - M(y,a,b))]
double Fyy[];//F(y,y,a,b) := Σ[i=a~b; (y[i] - M(x,a,b)) * (y[i] - M(y,a,b))]
double p[];//相加係数
//+------------------------------------------------------------------+
// | Custom indicator initialization function                        |
//+------------------------------------------------------------------+
int init() {
//---- indicators
   IndicatorBuffers(6);
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexStyle(2,DRAW_NONE);
   SetIndexStyle(3,DRAW_NONE);
   SetIndexStyle(4,DRAW_NONE);
   SetIndexStyle(5,DRAW_NONE);
   SetIndexBuffer(0,p);
   SetIndexBuffer(1,Sx);
   SetIndexBuffer(2,Sy);
   SetIndexBuffer(3,Fxy);
   SetIndexBuffer(4,Fxx);
   SetIndexBuffer(5,Fyy);
//----
   return(0);
  }

//+------------------------------------------------------------------+
//|初期値計算                                                        |
//+------------------------------------------------------------------+
 void Base(int index            //開始位置 
             ,int range           //適用範囲
             ,double &S_x[]     //Sx[];
             ,double &S_y[]     //Sy[];
             ,double &F_xy[]   //Fxy[];
             ,double &F_xx[]   //Fx[];
             ,double &F_yy[]   //Fy[];
                                   ){
   
   int i;
   double x,y,avx,avy,sigxy,sigx,sigy;
   
   //x.yの相加平均
   for(i=range;i>0;i--){
      //xの加算
      avx += High[index+i-1] - Low[index+i-1];
      //yの加算
      avy += Volume[index+i-1];
   }
   avx /=range;
   avy /=range;
            
   for(i=range;i>0;i--){
      x = High[index+i-1] - Low[index+i-1];
      y = Volume[index+i-1];
      sigxy += (x-avx)*(y-avy);
      sigx   += (x-avx)*(x-avx);
      sigy   += (y-avy)*(y-avy);
   }
   S_x[index]  = avx*range;
   S_y[index]  = avy*range;
   F_xy[index] = sigxy;
   F_xx[index] = sigx;
   F_yy[index] = sigy;
}
 
//+------------------------------------------------------------------+
//|相関係数                                                          |
//+------------------------------------------------------------------+
int start(){
   double x,y,xn,yn;
   int    counted_bars=IndicatorCounted();
   int limit=Bars-counted_bars -1;//2012/10/30変更
   //初期設定
   if(counted_bars<=0){
   limit -=pd;//2012/10/30追記
   Base(limit+1,pd,Sx,Sy,Fxy,Fxx,Fyy);
      p[limit+1] = Fxy[limit+1]/MathSqrt(Fxx[limit+1]*Fyy[limit+1]);
   }
   for(int i=limit; i>=0; i--){
      //追加項
      x      = High[i] - Low[i];
      y      = Volume[i];
   //削除項(2012/10/30変更) 
      xn    = High[i+pd] - Low[i+pd];//変更前 xn= High[i+pd+1] - Low[i+pd+1];
      yn    = Volume[i+pd];          //変更前  yn= Volume[i+pd+1];
      //総和の更新
      Sx[i]     = Sx[i+1] + x -xn;
      Sy[i]     = Sy[i+1] + y - yn;
      //F項の更新
       Fxy[i]   = Fxy[i+1] + (Sx[i+1]*Sy[i+1] - Sx[i]*Sy[i])/pd - xn*yn +x*y;
      Fxx[i]   = Fxx[i+1] + (Sx[i+1]*Sx[i+1] - Sx[i]*Sx[i])/pd - xn*xn +x*x;
      Fyy[i]   = Fyy[i+1] + (Sy[i+1]*Sy[i+1] - Sy[i]*Sy[i])/pd - yn*yn + y*y;
      //相関係数
       p[i] = Fxy[i]/MathSqrt(Fxx[i]*Fyy[i]);
   }
return(0);
}
  

表示・確認

従来の計算方法で求めた結果を赤線で表示させ、今回の計算結果を黄線で重ね合わせてみました。
(変更前)
photo


(変更後)※わかりやすくするために従来の計算方法を途中で終了させています。

 

まとめ

この方法なら、随時処理しても十分に使用できます。また、一つ勉強になりました。kartzさんありがとうございました。
//2012/10/30追記
kartzさんから指摘して頂いた、【削除項】の変更の結果、ほぼ一致したラインを作ることが出来ました。

9 件のコメント :

kartz さんのコメント...

お疲れさまでした。ですが、、怪しい箇所がw…

添付の画像で赤線と黄線がズレすぎているのが気になったので少し見てみました。実数計算の丸め誤差の違いによる値のズレは避けられないのですが、目で見てわかるほどズレません。

(1) 今回のコードに関して

> //削除項
> xn = High[i+pd-1] - Low[i+pd-1];
> yn = Volume[i+pd-1];

[i]~[i+pd-1] が現在の対象範囲なので、削除されるのは「もう1つ向こう側」にあるものです。

(2) 前回の記事中のコードに関して

相関係数を定義式通りに実装している部分で、avx, avy の(再)初期化が抜けています。

これらを直しても赤線と黄線がズレるようなら、他にもバグがあるでしょう。。。

bighope さんのコメント...

あらら^^;
確認してみます。
なんともすみません。

bighope さんのコメント...

kartzさんへ
ご指摘のとおり削除項の対象位置が間違っていました。ご指摘ありがとうございます。

kartz さんのコメント...

(2) は「前回の記事中のコードに関して」と書いていますように、
前回の記事に関するものであって、Base() のコードではありません。
MQL4 の仕様 (変数は自動的に0で初期化されている) は知ってます。

int start(){
double x,y,avx,avy,sigxy,sigx,sigy;
int i,q;
for(i=limit; i>=0; i--){
// x:(High[i] - Low[i]) y:Volume[i];
// ★ ここで avx,avy を(再)初期化しないと、例えば、i = limit - 1 のとき、
// i = limit で計算した値が残っているので、それに足し込んでいってしまう。
for(q=pd;q>0;q--){
//xの加算
avx += High[i+q-1] - Low[i+q-1];
//yの加算
avy += Volume[i+q-1];
}
//x.yの相加平均
avx /=pd;
avy /=pd;

上の★をご参照ください。
ここまで書かないと伝わらないとは思いませんでしたので、
1行でコメントしたのですが。

修正を要求しているわけではありません。
私には何のメリットもないのでこれにて終了です。お疲れさまでした。

bighope さんのコメント...

kartzさんへ
私の記載した内容で不快な思いをさせてしまいました。申し訳ありません。
私は、情報処理やプログラムなどの専門的な学習(大学や仕事で)をしたことがなく、教えて頂いた内容が十分に理解できていなかったようです。
また、ブログの修正は、何の利益にもならない事を私の為にして頂いているのに、私が何もしないのは、無礼だと思いしてしまいました。
私の周りには、専門知識を持っている方がおらず、指摘して頂いたことが本当に嬉しかったです。
私がこのブログを書く理由の一つが、間違いを指摘してほしいからです。
公開しないと間違いが解らないという理由で全コード公開しています。
ほとんどの閲覧者が、間違いに気づいても、鼻で笑っているだけだと思いますが....
今後、気づいた点がありましたら、『どあほ、ちゃうやろ』の一言だけでもコメントを頂けないでしょうか?
違うことが解るだけでもありがたいです。
今回の件に関し、不快な思いをさせて申し訳ありませんでした。

さとしぃ さんのコメント...

今回のご対応やコード公開の理由を拝見させて頂いて、私とはレベルが違うなと思わされました。
私は鼻で笑われるのが嫌でコード公開しておりませんし、誰かから指摘されても直さないかもしれません。私はSEですが、、、。こういう性格だと、間違った答えを得たまま直進してしまうリスクが特大です(汗
私も見習わさせて頂きます。そして、bighopeさんの
投資での成功(もうしてらっしゃるかもしれませんが)を応援しております。

bighope さんのコメント...

さとしぃさんへ
コメントありがとうございます。
この方法が一番早い上達方法かもしれませんが、余り称賛されるべきではないと思っています。単なる弱者の奇策です。

一度でいいので諸先輩方にしたり顔が出来る様な記事を書いてみたいです。
( ̄ー ̄)

くーちゃん さんのコメント...

bighopeさん
お久しぶりです。GWかけて色々興味のある記事を読み直していました。

kartzさんありがとうございました。大変参考になりました。

1年半も前の記事で恐縮なのですが、
ざっと拝見したところ、この計算では高値-安値と出来高(テックの回数)の相関をみています。
(疑似)出来高と値動きの絶対値(H-Lは常に正。H-Lでは時間的前後関係はわかりません)の相関を市場構造から考えると、「正の相関があるだろう・・・」ということは容易に想像できます。
ただ、その相関係数とその変化が「一体何を意味するのか」はちょっと意味を考えずらいところです。

例えば、株価には逆ウオッチ曲線
http://kabu.com/investment/technical/17.asp
http://www.kabudream.com/technical/gyakuwatch.html
という考え方があります。

FX的に考えると、FXに於いて売買されるのは(KU-Power分解するまでもなく)交換比率です。
ですので、終値-終値の変化(率)(始値-終値でもOK)と出来高の変化(率)を考えると、得られるチャートは
相関minでは「(ストップを巻き込んだ)セリングクライマックス」、相関Maxではその逆・・・のタイミングが捉えられるかも・・・と妄想していました(笑)
(FXであればEURUSDで考えてもUSDEURで考えても「上下鏡像反転して同じ」なので、株価よりも出来高との上昇・下降の関係ががきれいにでるかもという淡い期待)

で、試してみたのですが・・・、

出来高0だったり、業者によって違ったり、0近辺ウロウロだったりで、これだけでOKの指数とは言えないようですね♪(笑)


またの更新を楽しみにしています!

bighope さんのコメント...

くーちゃん さんへ
お久しぶりです。
>>その相関係数とその変化が「一体何を意味するのか」はちょっと意味を考えずらいところです。
私も何をやりたかったか?当時の事を思い返しても理解に苦しみます^^;
ただ、kartzさんにご指導して頂いたおかげで、相関係数の計算の仕方を勉強できて、私自身は、やってよかった試行の一つだと考えています。

話は変わりますが、最近の検証して、『時間単位の出来高(ティック回数)は、ある程度予測可能ではないか?』と仮定しています。出来高が予測できれば、ボラリティーの予測にも。。。。
ある程度まとまりましたら、更新したいと思っております。その際は、また、ご指摘頂けると嬉しいです。
それでは、コメントありがとうございました。