MQL4の新機能
Build 600バージョンから、MQL4言語は完全にMQL5レベル相当に変更されました。
統一されたメタエディタ開発環境で、MQL4/MQL5の自動売買システムの開発・デバッグを行う事が出来ます。
MQL4は簡単にラーニング出来る為、自動売買システム開発者の間で人気があります。
また、MT4ターミナルを使用して多くの年月をかけて膨大な量のソースコードが生成されています。
しかし言語は主要な利点に起因するいくつかの欠点を持っています。
簡単なプログラミング言語は複雑なシステム開発を許容できません、
また高レベル言語からのデバッグライブラリの移植を妨げます。
その為MQL4機能の特徴を完全に維持し、MQL5言語関数の機能を実装しました。
つまりMQL5の機能(OOP・ネイティブコードコンパイラ等)がMQL4で利用できるようになります。
これを実現する為、MQL4とMQL5の両方の言語をサポートする統一コンパイラを開発しました。
メタエディターはMT4とMT5プラットフォーム用の統合アプリケーションになります。
したがって任意のバージョンからMQL4とMQL5の両方をコンパイルする事が可能になります。
MQL5ストレージも利用可能になります。
MQL4アプリケーションのプロテクションはMQL5レベルになります。
新しいex4/ex5ファイルは、改定されたプロテクションを提供しています。
MQL4は現在チャートを操作する為の新しいグラフィカルオブジェクトと新機能を備えています。
MQL5標準ライブラリはMQL4に移植されます。
MT4で
リソースを使用して本格的なアプリケーションを作成する事が出来ます。
MQL4言語の変更
新しいデータ型(
char, short, long, uchar, ushort, uint, ulong ,
double)を追加しました。
データ型によって異なる速度で処理されます。
整数データの処理速度が最速になります。
doubleデータは特別なコプロセッサを使用して処理されます。
浮動小数点データの内部表現が複雑な為、整数データよりも処理が遅くなります。
型キャストも実装されています。
現在、文字列はUnicode形式(2byte)を使用しています(以前は1byteのANSI形式)。
DLLを使用したプログラムは文字列変数を渡す場合に、この事を考慮しなければなりません。
現在、
Volume変数はlong型です。
古いMQL4プログラムコードのVolume変数は型のオーバーフローエラーを回避する為、明示的キャストする事をお勧めします。
構造体・クラス・オブジェクトポインタ・
void型・
thisキーワード、
全ての
オブジェクト指向プログラミング(OOP)規格がサポートされています。
OOPはクラスを使用してプログラムを開発する事が出来ます。
これはデバッグや大規模アプリケーションの開発・デバッグを容易にします。
同様に継承によって以前生成したコードを複数回再利用する機能が使用出来ます。
しかし、これは以前のスタイルでMQL4コードを作成する事が出来ないという意味ではありません。
新しい機能を必要としない場合は、以前のスタイルのままプログラム開発を行う事が出来ます。
init(), deinit(),start()関数(事前定義された関数)は互換性の為に残されています。
しかし、現在は
OnInit(), OnDeinit(), OnStart(), OnCalculate(), OnTick()関数を使用します。
他に、
OnTimer(), OnChartEvent(), OnTester() 関数が実装されています。
以前のMQL4で事前定義された関数は任意の引数と戻り値型を持つ事ができ、それらはその名前ではなくシグネチャによって呼び出される可能性があります。
新しいMQL4では事前定義された全ての関数は厳密にシグネチャに対応する必要があります。
言い換えれば、正確に引数や戻り値型を定義しておく必要があります。
現在、変数名に特殊文字やポイント(.)を含める事が出来ません。
また新しいMQL4言語のキーワードも変数名に使用する事は出来ません。
古いMQL4プログラムは新しいコンパイラのメッセージに従って簡単にそのようなエラー修正をする事が出来ます。
優先順位のルールはC言語に一致します。
現在、
論理演算を使用した短縮条件のチェックは、古いMQL4とは異なります。
古いMQL4では全ての式が計算された後にチェックが行われました。
論理積を用いた2つの条件チェックがあるとします。
サンプルソース:
void OnStart(){
if ( test1() && test2() ) {
Print("if条件true");
}
}
bool test1() {
Print(__FUNCTION__);
return false;
}
bool test2() {
Print(__FUNCTION__);
return true;
}
結果:
test_script EURUSD,M5: test1
test1()がfalseの場合、test2()の計算は行われず、チェック結果はfalseになります。
ArrayCopyRates()関数の動作が変更されました。
古いMQL4バージョンでは、double型の二次元配列(double[][6])を使用していましたが、
現在は
MqlRates構造体を使用します。
新しい関数フォーマットも仮想コピーを使用する為、コピーされた値にアクセスすると実際の価格データにアクセス出来ます。
古いMQL4プログラムとの互換性の為に前の呼び出しフォーマット(二次元配列渡し)も保持されますが、仮想コピーでは無く実際のコピーになります。
ヒストリーデータ格納用のRateInfo構造体は変更されました。
新しいRateInfo構造体はspreadとtrade volumeが追加されました。
したがって、MQL4プログラムにRateInfo構造体を使用したDLLが含まれている場合、フォーマット変更を考慮した修正を行う必要があります。
古いRateInfo構造体フォーマットに基づいて作成されたDLLは、新しいターミナルで動作しません。
新しい構造体フォーマットに対応した変更が必要です。
ファイル操作では、同時に開けるファイル数上限は64になりました。
古いMQL4の上限は32でした。
またファイルは常に
FILE_SHARE_READ や
FILE_SHARE_WRITEモードで開かれていましたが、現在は明示的にモード指定する必要があります。
FileWrite(),
FileWriteArray(),
FileWriteDouble(),
FileWriteInteger(),
FileWriteString()関数の戻り値型は
intから
uintに変更されました。
戻り値はバイト数を返し、エラーの場合は0を返します(古いMQL4ではエラー時に負数を返していました)。
関数のローカル配列の変数有効範囲とメモリ解放が変更されました。
#property strict
「#property strict」は明確な理由がなければ絶対に消さないで下さい。
絶対に消さないで下さいと言っているのにも関わらず、初心者はエラー発生時に何故かこれを削除します。
そして「エラーが出るので#property strictを消してエラーが出なくなるようにしたのですが、動作が変になります」という意味不明な問い合わせをしてくる人が尋常じゃないくらい多いです。
これって何なんですか?初心者が何故突然#property strictを消して対応するのか意味不明なのですが、
もしかして誰かのブログか何かで#property strictを消す事を推奨するような事が記載されているのでしょうか?
#property strictを消してエラーが出なくなったのは、エラーが解消されたのでは無く、エラー検出が出来なくなっただけであって、エラー自体は残っています。
だから異常動作するのは当然なのですが、ただ単純に臭いものに蓋をしただけの行為なのに何故それに気が付かないのか皆目検討がつきません。
今まで機械的にエラー検出してくれて修正するべき場所を明示してくれていたにも関わらず、それを出ないようにして
デバッグの難易度をワザワザ上げる行為が本当に理解できません。
「#property strict」は明確な理由がなければ絶対に消さないで下さい。
何度も言いますが「#property strict」は
明確な理由がなければ絶対に消さないで下さい。
何度も何度も言いますが
「#property strict」は明確な理由がなければ
絶対に消さないで下さい。
これだけデカデカと赤字で記載しても
天才ギフテッドは「#property strict」を削除して、エラーを見つける難易度を上げます。
自分でわざわざ難易度を上げているのですから、「なんか変になります」とか意味不明な問い合わせして来ないで下さい。
天才ギフテッドなんですから自力で問題を特定して自力で解決して下さい。
エラーが検出されたら「#property strict」を削除するのでは無く、エラーの内容を読んでエラー修正対応をしなければなりません。
ですが天才ギフテッドはそんな常識的な当たり前の行動をせずに、「#property strict」削除というブッ飛んだ行動に走ります。
何度も言っているのですが、プログラムは1から10まで全て指示しなければならないのと同様に、
不具合も一つ一つ地道に修正するという泥臭い作業をやり続けなければなりません。
変更量が多いので、新しいプロパティ#property strictが導入されました。
これにより以前のMQL4プログラム開発の互換性を提供します。
MQLウィザードを使用して新しいMQL4プログラムを作成した場合、このプロパティは常に追加されます。
datetime型の文字列表現はコンパイルモードによって異なります。
サンプルソース:
datetime date = D'2014.03.05 15:46:58';
string str = "mydate="+date;
Print(str);
表:新旧コンパイラと#property strictプロパティ有無の相違点
\ |
古いMQL4 |
新しいMQL4(#property strict無し) |
新しいMQL4(#property strict有り) |
イベント関数 |
init(), start(), deinit()関数は任意の引数と戻り値型を指定出来ます。 |
init(), start(), deinit()関数は互換性の為、そのまま残っています。
OnInit(), OnStart(), OnCalculate(), OnTick(), OnTimer(), OnChartEvent(), OnTester(), OnDeinit()の新しい関数は、
厳格にシグネチャに対応する必要があります。 |
左記と同じ |
initイベント |
init()関数の戻り値結果はランタイムサブシステムで解析されません |
init()関数とOnInit()関数の戻り値結果はランタイムサブシステムで解析されません |
OnInit()関数からの戻り値が0以外の場合、EAまたはインジケータの動作は停止しプログラムをアンロードします |
変数名 |
予約語を除く変数名に特殊文字やポイント(.)を含める事が可能 |
変数名に特殊文字やポイントを含める事は出来ません。
予約語リストが増え、short, long, const等の予約語と同じ単語は変数名に使用出来ません。 |
左記と同じ |
可視範囲 |
変数の可視範囲は宣言位置(ネストされたブロック内を含む)から関数の最後まで。 |
左記と同じ |
変数の可視範囲は宣言位置からブロック(変数が宣言されたブロック)の最後まで。 |
暗黙的初期化 |
変数はゼロで暗黙的に初期化されます(グローバル・ローカル変数の両方共) |
左記と同じ |
グローバル変数のみ初期化されます。ローカル変数はstring型のみ暗黙的に初期化されます。 |
ローカル配列 |
関数終了時にローカル配列は解放されません |
関数終了時にローカル配列は解放されす |
{}ブロック終了時にローカル配列が解放されます |
範囲外アクセス |
配列の範囲外アクセス("Array out of range")で致命的なエラーが発生しません |
構造体配列とクラス配列を除いて、左記と同じ。 |
配列の範囲外アクセスは致命的なエラーが発生し、プログラムを停止します。 |
構造体・クラス |
構造体・クラス無し |
構造体・クラス有り |
左記と同じ |
データサイズ |
文字列は1byteデータ。 datetimeは32bit整数。Volume変数はdouble型 |
文字列は2byte(Unicode)データ。 datetimeは64bit整数。Volume変数はlong型 |
左記と同じ |
ArrayCopyRates() 関数 |
ArrayCopyRates()関数はdouble[][6]配列に仮想コピー |
ArrayCopyRates()関数はMwlRates[]配列に仮想コピー。 double[][6]配列コピーは互換性の為に残されているが仮想コピーでは無い。
|
左記と同じ |
戻り値 |
戻り値を持っている関数で戻り値を返さなかった場合、コンパイラによって自動的に0を返します。 |
左記と同じ |
戻り値を持っている関数は、戻り値を返す必要があります |
ファイル操作 |
同時に開けるファイル数上限は32 |
同時に開けるファイル数上限は64 |
左記と同じ |
ファイル操作 |
ファイルは常にFILE_SHARE_READ, FILE_SHARE_WRITEモードで開かれる |
ファイルを開く際にFILE_SHARE_READまたはFILE_SHARE_WRITEモードを明示的に指定する必要がある |
左記と同じ |
入力パラメータ |
extern変数は入力パラメータに表示されます |
extern変数とinput変数は入力パラメータに表示されます (スクリプトは#property script_show_inputs指定時) |
extern変数とinput変数の文字列コメントが、入力パラメータに表示されます (スクリプトは#property script_show_inputs指定時)。 |
ファイル構造の変更
古いMT4クライアントターミナル(Build 509以下)では全てのMQL4アプリケーションは、"ターミナルインストールフォルダ\experts"以下のサブディレクトリに格納されていました。
- \experts - EA
- \experts\indicators - カスタムインジケータ
- \experts\scripts - スクリプト
- \include - インクルードファイル
- \libraries - ライブラリファイル
- \files - ファイルサンドボックス
新しいMQL4バージョンでは、"データフォルダ\MQL4"以下に格納されます。
- \Experts - EA
- \Indicators - カスタムインジケータ
- \Scripts - スクリプト
- \Include - インクルードファイル
- \Libraries - ライブラリファイル
- \Images - リソースファイル
- \Files - ファイルサンドボックス
"データフォルダ"はクライアントターミナルのメニュー⇒「ファイル」⇒「データフォルダを開く」、
またはメタエディターのメニュー⇒「ファイル」⇒「データフォルダを開く」で見つける事が出来ます。