Scala
FX
MQL4
MT4

目指せ自動売買で800万円 : MT4のTick情報を収集する

Tickとは?

MQL4ではOnTick()という関数がTick情報が更新されるたびコールバックされるみたい。

Tickとは金融商品の値動き変化の最小単位、これを収集することでどんな足でも作れる。

色々探してみたが、TickをダウンロードできるサイトがなかったためMT4でTick情報を
サーバにひたすらアップロードするプログラムを作成した。

システム構成

基本的にMT4からWebサーバにTickの更新があるたびにGETメソットでリクエストを行う。

MT4は常時動かさないといけないので、お名前.comのWindows VPSを導入。合わせてWebサーバ用のVPSも導入。
(合計3000円/月、しかしWindows VPSは全然性能出ないな)

MT4側

BiD,ASK,時間情報をWebRequest関数を用いてひたすらGETリクエスト。

しかしMQL4は書きにくい(C++がベース、ポインタとか記憶の外)。

時間周りがMT4のシステム上GMT+2になっている(日本時間ではない)。
今までGMT+9(日本時間)しか考慮したことなかったので、冬時間→夏時間とかどう処理すればいいんだろう。

(サーバ時間 - ローカル時間)でGMTが演算できるので、それもGETパラメータに加えることにした。
その他時間処理がめんどくさいので、クラス化。

TimeObject *time_object = new TimeObject(last_tick.time); // 時間情報を保持する自作関数
SymbolInfoTick(Symbol(),last_tick)
string currencyPair = _Symbol;
string bid = (string)last_tick.bid;
string ask = (string)last_tick.ask;
string last = (string)last_tick.last;
string volume = (string)last_tick.volume;
string flags = (string)last_tick.flags;
string mt4DateTime = (string)time_object.getMT4DateTimeString();
string mt4UnixTime = (string)time_object.getMT4UnixTime();
string mt4Offset = (string)time_object.getMT4Offset();
string localDateTime = (string)time_object.getLocalDateTimeString();
string localUnixTime = (string)time_object.getLocalUnixtTime();
string localOffset = (string)time_object.getLocalOffset();
string tickCount = (string)GetTickCount();

WebRequest関数について

WebRequestで引っかかったことは二つ。

  1. ツール > オプション > エキスパートアドバーザの許可するURLにWebサーバのアドレスを追加
  2. 80 or 443のみ利用できる。

1は許そう。2は駄目だ。

サーバ側を機能(収集、オーダ)でポートを分けてSimpleServerで済まそうと思っていたが、
全て80で行う必要がある。そのため、サーバサイドをそれなりにしっかりしないといけなくなった。

GetTickCountについて

これはローカルでのMT4起動時からのカウンタ値らしい。

ミリセックオーダでも連続してTick更新があるときがあり、
順序把握のために高精度のカウンタとしてGetTickCountが利用できる。

しかし50日位でオーバーフローするらしい。

まあ1週間に1度は再起動するか。

サーバ側

全て80で行う必要があり、しかりとしたものを作るためPlayFramework 2.6(Scala)を導入

どうやらactivatorのサポートが終了したらしいので、seedからインストール
(brewが死んでいたのでアップデート、sbtも1系に、sbt1系に対応できないためIntelliJも最新に)

sbt new playframework/play-scala-seed.g8

uploadフォルダ

MT4からの情報収集するフォルダとして、uploadフォルダを作成。

保存するTick情報は下記のcase classとなっている。

case class MqlTick(mt4_id : String,
                    currencyPair : String,
                    bid : String,
                    ask : String,
                    last : String,
                    volume : String,
                    flags : String,
                    mt4DateTime : String,
                    mt4UnixTime : String,
                    mt4Offset : String,
                    localDateTime : String,
                    localUnixTime : String,
                    localOffset : String,
                    tickCount : String,
                    createdDateTime : String,
                    createdUnixTime : String)
 val csvHeader = classOf[MqlTick].getDeclaredFields.map(_.getName).mkString(",")

特に、localDateTimeはMT4側のローカル時間となるため、
アップロードにかかった時間やローカル時間が間違っている時の補正のためにサーバ側のローカル時間も保存する。

しかしscalaは書きやすいな。

今後について

とりあえずTickデータが集まってきた。

今後はランダムウォークでの機械学習を試してみよう。

QRNNでカオス時系列データ予測を試してみたい・