ランダムチャートの意味
MT5にはカスタムシンボル(カスタム銘柄)という便利な機能があるので、好きなようにCSVファイルでティックデータ作ってインポートしてあげれば良い。
MQLでランダムチャートを生成するスクリプトを書く事もできる。
カスタムシンボルを扱うための関数は、下記のリファレンスから確認できる。
カスタム銘柄 – MQL5 リファレンス – MetaTrader 5 のためのアルゴリズムの/自動化されたトレーディング言語のリファレンス
具体的には下記のようなScriptを書いて、適当なチャートに適用して走らせるとカスタムシンボルが作成される。
#property copyright "nisai" #property link "https://nisaifx.com" #property version "1.00" string SYMBOL_NAME = "RandomChart"; //カスタムシンボル名 datetime START_DATE = D'2000.01.01 00:00:00'; //生成するデータの開始日(時分秒は必ず00:00:00から) datetime LIMIT_DATE = D'2000.01.01 23:59:59'; //生成するデータの終了日 double START_RATE = 1.0; //シンボルの初期レート int DIGITS = 5; //シンボルの少数桁 int SPREAD = 3; //シンボルのスプレッド(ポイント) double POINT = 0.00001; //1ティックで変動させるレート int TICK_COUNT_LIMIT = 10; //1秒間に生成するティック数の上限 void OnStart() { MathSrand(GetTickCount()); CustomSymbolCreate(SYMBOL_NAME); SymbolSelect(SYMBOL_NAME, true); CustomSymbolSetInteger(SYMBOL_NAME, SYMBOL_DIGITS, DIGITS); double bid = START_RATE; int count = 0; int addSeconds = 0; MqlRates rates[1]; while(START_DATE <= LIMIT_DATE) { int tickCount = MathRand() % (TICK_COUNT_LIMIT + 1); if(tickCount > 0) { int milliseconds[]; ArrayResize(milliseconds, tickCount); for(int i=0; i<tickCount; i++) { milliseconds[i] = MathRand() % 1000; } ArraySort(milliseconds); MqlTick ticks[]; ArrayResize(ticks, tickCount); for(int i=0; i<tickCount; i++) { long timeMsc = ((long)START_DATE * 1000) + milliseconds[i]; ticks[i].bid = NormalizeDouble(bid, DIGITS); ticks[i].ask = NormalizeDouble(bid + SPREAD * POINT, DIGITS); ticks[i].flags = 6; ticks[i].time_msc = timeMsc; ticks[i].last = 0; ticks[i].volume = 0; ticks[i].volume_real = 0; if(rates[0].open == 0) { rates[0].open = bid; rates[0].high = bid; rates[0].low = bid; rates[0].close = bid; rates[0].spread = SPREAD; rates[0].time = START_DATE; } else { if(rates[0].high < bid) { rates[0].high = bid; } else if(rates[0].low > bid) { rates[0].low = bid; } rates[0].close = bid; } bid = MathRand() % 2 == 0 ? bid + POINT : bid - POINT; } if(CustomTicksAdd(SYMBOL_NAME, ticks) == -1) { break; } else { count += tickCount; } if((addSeconds+1) % 60 == 0) { CustomRatesUpdate(SYMBOL_NAME, rates); rates[0].open = 0; rates[0].high = 0; rates[0].low = 0; rates[0].close = 0; rates[0].spread = 0; rates[0].time = 0; } } START_DATE++; addSeconds++; } Print("total:", count); }
以下の流れで処理している。
- カスタムシンボルを作成して選択する(選択しないとティック追加の処理が出来ない)。
- 1秒間に生成するティック上限数を元に、何ティック生成するかを乱数で決める。
- 決めたティック数の分だけ、ミリ秒数を乱数で生成して配列に入れ、昇順ソートする。
- 決めたティック数の分だけティックの構造体(MqlTick)にレートと時間を設定して、作成したカスタムシンボルに追加する。
- 次のティックが1ポイントだけ上げるか下げるかを乱数で決める。
- 上記を開始日時~終了日時まで1秒ごとに繰り返す。
- 60秒ごとに1分足データを追加する。
コンパイル済みのスクリプトファイルとソースコードは下のリンクからどうぞ。
実行するには、適当なチャートに対してドラッグ&ドロップ。
実行させると、気配値表示のウィンドウに「RandomChart」が追加され、処理終了までの間、この銘柄の売気配/買気配のレートが動く。
ツールボックスのエキスパートタブに「total:********」と表示されたら処理が終わっている。
出来上がった銘柄をチャートウィンドウで開けば、ランダムなチャートが表示される。
下図は、上記コードをそのまま動かして出来上がったチャート。
なお、乱数のシード値にGetTickCount関数を使用しているため、同じチャートが生まれることはまず無い。
少し注意していただきたいのは、上記は土日祝日を無視してレートを生成している点と、1ティックごとに必ず1ポイントだけ上下させている点。
また、レートには際限を設けていないため、期間が長くなればマイナスのレートを記録するだろうし、政府介入なんてものもない。
もっとリアルに近づけるのであれば、もっとコーディングが必要だと思うが、それをやる価値があるかどうかは不明。
ランダムチャートが出来上がったら適当にインジケーターを適用して見るもよし、水平線を引いてみるもよし、好きに分析してみる。
ランダムチャートであっても、巷にあふれる所謂売買サインが出現することが分かる。
これは不思議な事では無く、寧ろそれらのサインが出現しない方が異常だ。
ランダムチャートだろうとレートが上昇すれば、MAはゴールデンクロスし、バンドウォークも発生する。
レート変動が完全にランダムであるという事は、いかなる分析を行ったところで有利な売買は出来はしない。
そもそもロジックをバックテストするまでも無く、結果は計算できることになる。
ランダムチャートをトレードに活かすとすれば、それはリアルのチャートとの差異が何かを検証する事だろう。
先に述べた通り、ランダムチャートにはあらゆるパターンが出現し得るが、リアルチャートとのそれとは明確に傾向の異なる”何か”が存在すると思う。