MQL4をMQL5に移植するので、備忘録としてメモを作成。
MQL4をMQL5に移植する。(その1:レートの受信)の続き。
移植の基本情報は前回の記事を参照。
今回は取引を実行するEAをMQL5に移植する。前回の記事に記載した、アカウント情報とレートをMQL5に移植してコンパイルすると、エラーが多数出たので順に修正する。
##ライブラリの移植
MQL4で利用していた標準ライブラリ、がエラーになっているのでコメントして先に進む。
MQL5で利用できる標準ライブラリは以下。
セクション | ディレクトリ |
---|---|
数学 | Include\Math\ |
OpenCL | Include\OpenCL\ |
基本クラスCObject | Include |
データ収集 | Include\Arrays\ |
ジェネリックデータコレクション | Include\Generic\ |
ファイル | Include\Files\ |
文字列 | Include\Strings\ |
グラフィックオブジェクト | Include\Objects\ |
カスタムグラフィックス | Include\Canvas\ |
価格チャート | Include\Charts\ |
科学的チャート | Include\Graphics\ |
指標 | Include\Indicators\ |
トレードクラス | Include\Trade\ |
ストラテジーモジュール | Include\Expert\ |
パネルとダイアログ | Include\Controls\ |
今回の移植に関係しそうな、基本クラスのCObject、文字列、トレードクラス、ストラテジーモジュールに目を通す。科学的チャートのディレクトリ名が「Graphics」になっているのが気になるが今回はスルー。 |
##エラー処理の移植: ErrorDescription()
ErrorDescription(GetLastError()) がエラーになっていたので調べると、ErrorDescription用のMT5ライブラリが用意されていた。MQL5ドキュメントに提供されている ErrorDescription.mqh を \MetaTrader 5\MQL5\Include フォルダにコピーしたところ、エラーは解消した。参照:ErrorDescription - MetaTrader 5のためのライブラリ
MQL5のドキュメントに掲載されているサンプルより。
#include <ErrorDescription.mqh>
//+------------------------------------------------------------------+
//| Example of use of the ErrorDescription.mqh library |
//+------------------------------------------------------------------+
void OnStart()
{
Print("----- Description of trade server return codes -----");
for(int i=10004;i<=10034;i++)
{
Print("Trade server return code:",i,TradeServerReturnCodeDescription(i));
}
Print("-------- Description of runtime error codes ---------");
for(int i=4001;i<=4014;i++)
{
Print("Runtime error code:",i,ErrorDescription(i));
}
}
//+------------------------------------------------------------------+
参照:ErrorDescription - MetaTrader 5のためのライブラリ
##注文処理の移植: OrderSend()
OrderSend() 関数を、MT5に移植する。MT5ドキュメントの OrderSend()に記載されたサンプルプログラムで、注文は以下のように実行されている。参照:OrderSend
MTL5では、注文に必要な情報を MqlTradeRequest 構造体に設定、OrderSend(request, result) に引数として渡し、注文の結果は、MQLTradeResult 構造体で受け取る仕様となっている。
//--- リクエストを準備する
MqlTradeRequest request={0};
request.action=TRADE_ACTION_PENDING; // 未決注文を設定する
request.magic=magic_number; // ORDER_MAGIC
request.symbol=_Symbol; // シンボル
request.volume=0.1; // 0.1 ロットのボリューム
request.sl=0; // 決済逆指の指定なし
request.tp=0; // 決済指値の指定なし
//--- 注文の種類を形成する
request.type=GetRandomType(); // 注文の種類
//--- 未決注文の価格を形成する
request.price=GetRandomPrice(request.type); // 始値
//--- 取引リクエストを送る
MqlTradeResult result={0};
OrderSend(request,result);
//--- サーバ返答をログに書く
Print(__FUNCTION__,":",result.comment);
if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- 取引サーバの返答のコードを返す
return result.retcode;
今回移植するEAは成行き注文のみ使用しているので、成行き注文に必要なフィールドを以下のように設定し注文する。
//--- リクエストを準備する
MqlTradeRequest request = {0};
request.action = TRADE_ACTION_DEAL; // 成行注文
request.magic = magic_number; // マジックナンバーを指定
request.symbol = _Symbol; // 通貨ペアを指定
request.volume = lot; // 取引数量
request.type=ORDER_TYPE_BUY; // 買い注文の場合
//--- 取引リクエストを送付
MqlTradeResult result = {0};
OrderSend(request,result);
MqlTradeRequest, MQLTradeResult構造体はそれぞれ以下の通り。
struct MqlTradeRequest
{
ENUM_TRADE_REQUEST_ACTIONS action; // 取引の種類
ulong magic; // エキスパートアドバイザー ID(マジックナンバー)
ulong order; // 注文チケット
string symbol; // 取引シンボル
double volume; // 約定のための要求されたボリューム(ロット単位)
double price; // 価格
double stoplimit; // 注文のストップリミットレベル
double sl; // 注文の決済逆指値レベル
double tp; // 注文の決済指値レベル
ulong deviation; // リクエストされた価格からの可能な最大偏差
ENUM_ORDER_TYPE type; // 注文の種類
ENUM_ORDER_TYPE_FILLING type_filling; // 注文実行の種類
ENUM_ORDER_TYPE_TIME type_time; // 注文期限切れの種類
datetime expiration; // 注文期限切れの時刻 (ORDER_TIME_SPECIFIED 型の注文)
string comment; // 注文コメント
ulong position; // Position ticket
ulong position_by; // The ticket of an opposite position
};
参照:取引リクエスト構造体 (MqlTradeRequest)
struct MqlTradeResult
{
uint retcode; // 操作のリターンコード
ulong deal; // 実行された場合の 約定チケット
ulong order; // 注文された場合のチケット
double volume; // ブローカーによって確認された約定ボリューム
double price; // ブローカーによって確認された約定価格
double bid; // 現在の売値
double ask; // 現在の買値
string comment; // 操作に対するブローカーコメント(デフォルトは取引サーバの返したコードの記述)
uint request_id; // ディスパッチの際に、端末によって設定されたリクエストID
uint retcode_external; // 外部取引システムのリターンコード
};
参照:取引リクエスト結果の構造体 (MqlTradeResult)
##注文処理の移植: OrderSelect() => PositionSelectByTicket()
OrderSelect() 関数を、MT5に移植する。MT5では、PositionSelectByTicket() を利用する。
Order(注文)、Position(ポジション)、History(履歴)のそれぞれに対してアクセス用の関数が用意されている。対象データにより異なる関数を利用する必要があるため注意が必要。参照:取引関数
bool PositionSelectByTicket(
ulong ticket // ポジションチケット
);
##注文処理の移植: OrderOpenPrice() => PositionGetDouble()
OrderOpenPrice() 関数を、MT5に移植する。MT5では、PositionGetDouble(POSITION_PRICE_OPEN) を利用する。
double PositionGetDouble(
ENUM_POSITION_PROPERTY_DOUBLE property_id // プロパティ識別子
);
###ENUM_POSITION_PROPERTY_DOUBLE
識別子 | 説明 | Type |
---|---|---|
POSITION_VOLUME | ポジションボリューム | Double |
POSITION_PRICE_OPEN | ポジションの始値 | Double |
POSITION_SL | 未決済ポジションの決済逆指レベル | Double |
POSITION_TP | 未決済ポジションの決済指値 | Double |
POSITION_PRICE_CURRENT | ポジションシンボルの現在価格 | Double |
POSITION_SWAP | 累積スワップ | Double |
POSITION_PROFIT | 現在の利益 | Double |
##注文処理の移植: OrderLots() => PositionGetDouble()
OrderLots() 関数を、MT5に移植する。MT5では、PositionGetDouble(POSITION_VOLUME) を利用する。関数の概要については「注文処理の移植: OrderOpenPrice() => PositionGetDouble()」の説明参照。
ここまでの修正でコンパイラのエラーは解消した。