EA利用時の買い注文、売り注文のオーダー関数の例です。
まず、新規注文に関するOrderSend関数のMQL4リファレンスは次となります。
OrderSend - Trade Functions - MQL4 Reference
また、MQL5の場合、文法が違うので、そちらに合わせて設定する必要があります。
MQL5のドキュメンテーション: 取引関数 / OrderSend
一方、僕のこのOpenOrder関数はMQL4のOrderSend関数についての利用だけではなく、より実践的な構成となっています。下記の機能を追加しています。
・注文タイプのチェック
・処理のエラーチェック
・通信エラー発生時のリトライ、カウンターの設定
・処理後のログ出力
・処理結果のメール送信連絡 ※設定方法に関しては別記事
もちろん、必要に応じてアレンジして利用しても良いです。また、指標値を自らのものにするのもおすすめです。ここでは設計観点を提供します。
stopLossAvailable、takeProfitAvailableなどの変数は必要に応じて設定か削除かご調整してください。指値注文しなければ、これら必要ないからです。また、指値注文の場合、openPriceを自らのアルゴリズムに合わせて設定しましょう。
int OpenOrder(const int orderType, const double lots, const color arrowColor) { Print("OpenOrder start : ", orderType, " ", lots); if ((orderType != OP_BUY) && (orderType != OP_SELL)) Print(__ERROR__, __FUNCTION__, ", Order type error, orderType:", orderType, " Line:", __LINE__); double stopLoss = 0; double takeProfit = 0; double openPrice = 0; int ticket = -1; int count = 0; while (count < ORDER_ERROR_RETRY_COUNT) { openPrice = 0; if (orderType == OP_BUY) openPrice = MarketInfo(symbol, MODE_ASK); else openPrice = MarketInfo(symbol, MODE_BID); if (stopLossAvailable) { if (orderType == OP_BUY) stopLoss = openPrice - stopLossPips * pipsPoint; else stopLoss = openPrice + stopLossPips * pipsPoint; } if (takeProfitAvailable) { if (orderType == OP_BUY) takeProfit = openPrice + takeProfitPips * pipsPoint; else takeProfit = openPrice - takeProfitPips * pipsPoint; } if (openPrice > 0) { ticket = OrderSend(symbol, orderType, Common_VerifyLotSize(lots), openPrice, orderSlippage, stopLoss, takeProfit, NULL, magicNumber, 0, arrowColor); if (ticket > 0) break; } else { ResetLastError(); Print(__ERROR__, __FUNCTION__, ", Get open price error.", " Line:", __LINE__); } count++; if (IsTradeContextBusy()) Sleep(1000); // 1000 ms. } if (ticket < 0) { int lastError = GetLastError(); string errorDesc = ErrorDescription(lastError); string errorAlert = StringConcatenate(__ERROR__, __FUNCTION__, ", Open order error:", lastError, " ", errorDesc); string errorLog = StringConcatenate(errorAlert, " order type: ", IntegerToString(orderType), " lot size:", DoubleToStr(lots, Digits), " Line:", __LINE__); Print(errorLog); Alert(errorLog); SendMail("Open order Error.", errorLog); Print(__FUNCTION__, ", Mail send. Line:", __LINE__); ResetLastError(); } else { // Real trade mode. if (!isTesting) { string openMsg = "Open order\n"; openMsg = openMsg + "Loss cut level:" + IntegerToString(Common_GetCurrentLossCutLevel()) + "\n"; openMsg = openMsg + "Equity:" + DoubleToStr(AccountEquity(), 0) + "\n"; openMsg = openMsg + "Symbol:" + StringSubstr(symbol, 0, 6) + "\n"; openMsg = openMsg + "Type:" + getOrderTypeString(orderType) + "\n"; openMsg = openMsg + "Lots:" + DoubleToStr(lots, 2) + "\n"; openMsg = openMsg + "OpenPrice:" + DoubleToStr(NormalizeDouble(openPrice, Digits), Digits) + "\n"; openMsg = openMsg + "StopLoss:" + DoubleToStr(NormalizeDouble(stopLoss, Digits), Digits) + "\n"; openMsg = openMsg + "TakeProfit:" + DoubleToStr(NormalizeDouble(takeProfit, Digits), Digits) + "\n"; openMsg = openMsg + "MagicNumber:" + IntegerToString(magicNumber) + "\n"; openMsg = openMsg + "Time:" + Common_GetTimeString(TimeCurrent()); Print(openMsg); SendMail("Open order OK.", openMsg); Print(__FUNCTION__, ", Mail send. Line:", __LINE__); } } Print("OpenOrder end."); return ticket; }
エラー状態の取得関数GetLastError、エラー内容の出力関数ErrorDescriptionの説明などを別の記事に紹介していきます。
そして上記の関数の呼び出し例は次のもので良いでしょう。
次の例では、注文の前に、注文のタイプと注文のビジー状態、資金状況の確認を行なっています。
int Common_OpenNewPosition(const int orderType, const double lotSize) export { Print("OpenNewPosition start : ", orderType, " ", lotSize); if ((orderType != OP_BUY) && (orderType != OP_SELL)) Print(__ERROR__, __FUNCTION__, ", Order type error, orderType:", orderType, " Line:", __LINE__); while (IsTradeContextBusy()) Sleep(1000); int ticket = EMPTY_DATA; if (orderType == OP_BUY || orderType == OP_SELL) { if ((AccountFreeMarginCheck(symbol, orderType, lotSize) <= 0) || (GetLastError() == 134)) { Print(__ERROR__, __FUNCTION__, ", No enough money to hold a new buy position!"); } else { if (orderType == OP_BUY) ticket = OpenOrder(OP_BUY, lotSize, Green); else ticket = OpenOrder(OP_SELL, lotSize, Magenta); } } Print("OpenNewPosition end.\n"); return ticket; }
コーディングスタイルは本家のMQLそのものではなく、今までの仕事上のC, Javaスタイルそのまま継続します。僕自身はなるべく整ったスタイルを継続しています。
EAファイルの作成の方法、関数の命名規格の設計などを別の記事をご参考ください。
FX
|
|
コメント