input int MagicNumber=1234567;
//--- CTrade 取引クラスを有効にしてクラス変数を宣言する
#include <Trade\Trade.mqh>
CTrade trade;
//--- 未決注文インストールと削除のフラグ
bool pending_done=false;
bool pending_deleted=false;
//--- 未決注文チケットはここに保存される
ulong order_ticket;
//+------------------------------------------------------------------+
//| エキスパート初期化に使用される関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- MagicNumber を設定して全ての注文をマークする
trade.SetExpertMagicNumber(MagicNumber);
//--- 取引リクエストは OrderSendAsync() 関数を使用して非同期モードで送信される
trade.SetAsyncMode(true);
//--- 変数をゼロで初期化する
order_ticket=0;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| エキスパートティック関数 |
//+------------------------------------------------------------------+
void OnTick()
{
//---未決注文のインストール
if(!pending_done)
{
double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
//--- BuyStop() 関数が成功
if(res)
{
pending_done=true;
//--- ctrade から送信リクエストした結果の取得
MqlTradeResult trade_result;
trade.Result(trade_result);
//--- 送信されたリクエストの request_id を取得
uint request_id=trade_result.request_id;
Print("Request has been sent to set a pending order. Request_ID=",request_id);
//--- 注文チケットを保存する(CTrade への送信に非同期モードを使用する場合はゼロ)
order_ticket=trade_result.order;
//--- 完成。 OnTick() ハンドラ—を早期終了する。
return;
}
}
//--- 未決注文の削除
if(!pending_deleted)
//--- 追加のチェック
if(pending_done && (order_ticket!=0))
{
//--- 未決注文の削除を試みる
bool res=trade.OrderDelete(order_ticket);
Print("OrderDelete=",res);
//--- 削除リクエスト送信に成功
if(res)
{
pending_deleted=true;
//--- リクエストの実行結果を取得
MqlTradeResult trade_result;
trade.Result(trade_result);
//--- 結果から request ID と取得
uint request_id=trade_result.request_id;
//--- 操作ログに表示
Print("The request has been sent to delete a pending order #",order_ticket,
". Request_ID=",request_id,
"\r\n");
//--- リクエスト結果から注文チケットを修正
order_ticket=trade_result.order;
}
}
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction 関数 |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- トランザクション型を列挙値として取得する
ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- トランザクションが結果処理のリクエストの場合は、名称のみを表示する
if(type==TRADE_TRANSACTION_REQUEST)
{
Print(EnumToString(type));
//--- 取り扱つかわれたリクエストの文字列名を表示する
Print("------------RequestDescription\r\n",RequestDescription(request));
//--- リクエスト結果の記述を表示する
Print("------------ResultDescription\r\n",TradeResultDescription(result));
//--- OnTick() の次のハンドルで削除されるよう、チケットを保存する
if(result.order!=0)
{
//--- 次の OnTick() の呼び出しでこの注文をチケットによって削除する
order_ticket=result.order;
Print(" Pending order ticket ",order_ticket,"\r\n");
}
}
else // 別の種類のトランザクションの完全記述を表示する
//--- 受け取ったトランザクションの記述を操作ログに表示する
Print("------------TransactionDescription\r\n",TransactionDescription(trans));
//---
}
//+------------------------------------------------------------------+
//| トランザクションのテキスト形式の記述を返す |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
{
//---
string desc=EnumToString(trans.type)+"\r\n";
desc+="Symbol: "+trans.symbol+"\r\n";
desc+="Deal ticket: "+(string)trans.deal+"\r\n";
desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
desc+="Order ticket: "+(string)trans.order+"\r\n";
desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
//--- 取得した文字列を返す
return desc;
}
//+------------------------------------------------------------------+
//| 取引リクエストのテキスト形式の記述を返す |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
{
//---
string desc=EnumToString(request.action)+"\r\n";
desc+="Symbol: "+request.symbol+"\r\n";
desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
desc+="Order ticket: "+(string)request.order+"\r\n";
desc+="Order type: "+EnumToString(request.type)+"\r\n";
desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
desc+="Comment: "+request.comment+"\r\n";
//--- 取得した文字列を返す
return desc;
}
//+------------------------------------------------------------------+
//| リクエスト処理結果の記述ををテキスト形式で返す |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
{
//---
string desc="Retcode "+(string)result.retcode+"\r\n";
desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
desc+="Order ticket: "+(string)result.order+"\r\n";
desc+="Deal ticket: "+(string)result.deal+"\r\n";
desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
desc+="Comment: "+result.comment+"\r\n";
//--- 取得した文字列を返す
return desc;
}
|