MQL4でXorShiftによる疑似乱数生成。-2147483648 > -2147483647-1 という不思議。

真面目な用途での乱数生成は、メルセンヌ・ツイスターが推奨で、MT4 であれば これExcel であれば、Excel乱数生成アドインがあります。


ただ、どうしても MQL4のみで、MathRand() より良さそうな乱数を使いたい時のために、XorShift による実装を用意しました。

int XorShiftRand(int seed = 123456789) { 
  static int x = 123456789;
  static int y = 362436069;
  static int z = 521288629;
  static int w = 88675123; 
  if(seed != 123456789) x = seed;
  
  int t;
 
  t = x ^ (x << 11);
  x = y; y = z; z = w;
  w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); 
  return(w);// w = -2147483648~2147483647
}

使い方は、

XorShiftRand(GetTickCount());

で、最初に seedを設定し、以降は、XorShiftRand() で、-2147483648〜2147483647 の整数乱数を得ることができます。


ちなみに、1億回実行した時の実行時間は以下の傾向です。

関数 実行時間(ms)
MathRand 3479
XorShiftRand 7660
gsl_rng_uniform 16724

極端に遅くなることは無いようです。



-2147483648 > -2147483647-1 という不思議。

実用性はさておき、XorShift を調べていて気づいたのが MQL4 の不思議な挙動です。

int a = -2147483648;
int b = -2147483647-1;
if(a > b) Print("a > b");// TRUE 

↑ a と b は等しいはずなのに、a が大きくなります。


この現象は、int 型の最小値 -2147483648 のときのみ起こる・・・と信じたいところですが、未確認です。

int a = -2147483648.0; // 実数表記
int a = 0x80000000; // 16進表記

↑変則的に、このように宣言すれば、a == b が成立します。
これは苦肉の策ですが、、変数の型で定義される末端の数値を扱うときは注意しましょう。。orz






ランダムチャートのその後。


出来高に凶悪なコーシー分布のノイズを加えて、高騰/急落を再現してみました。
1.5秒毎にローソク足1本を追加して自動更新する機能も追加しました。
乱数に GSL も使えるようにしました。
http://ux.getuploader.com/fai_fx/download/318/RandomChart.zip
あくまでも、ベースとなる動きはコイントス方式のランダムウォークで、横軸=時間軸を出来高の調整で歪めているだけです。
実験用途や、週末に動くチャートを見たい時に活用ください。