ライブラリ: MT4Orders - ページ 12

 
ネット口座でライブラリを使用する場合、Expert Advisorの取引部分がいかに簡潔で信頼できるかの一例です。

MetaTrader 5の取引シグナルをお客様の口座で自動執行します。

LCHI2017

MetaTrader 5
無料

Expert Advisorは株式商品で取引します。

#include <MT4Orders.mqh>     //https://www.mql5.com/ja/code/16006
#include <TypeToBytes.mqh>   //https://www.mql5.com/ja/code/16280
#include <Price_Compare.mqh> //https://www.mql5.com/ja/code/16169

sinput double exLots = 1;

int OrderScan( const int Type0, const int Type1 = -1, const int Type2 = -1, const int Type3 = -1 )
{
  int Res = -1;

  int Types[4];
    
  Types[0] = Type0;
  Types[1] = Type1;
  Types[2] = Type2;
  Types[3] = Type3;
  
  for (int i = 0; (i < 4) && (Types[i] != -1) && (Res == -1); i++)
    for (int j = OrdersTotal() - 1; j >= 0; j--)
      if (OrderSelect(j, SELECT_BY_POS) && (OrderType() == Types[i]) && (OrderSymbol() == _Symbol))
      {
        Res = Types[i];
        
        break;
      }
      
  return(Res);    
}

bool MyOrderModify( const double Price )
{
  return((CP(Price) != OrderOpenPrice()) && OrderModify(OrderTicket(), Price, 0, 0, 0));
}

bool MyOrderSend( const int Type, const double Price )
{
  const double Lots = exLots + OrderLots();      
  
  return((OrderScan(Type) == -1) ? OrderSend(_Symbol, Type, Lots, Price, 0, 0, 0) : MyOrderModify(Price));
}

MqlTick Ticks[];

void OnTick( void )
{  
  static const MqlTick NullTick = {0};
  
  const MqlTick Level = GetLevel(Ticks);
  
  if (_R(Level) != NullTick)
  {
    const int Type = OrderScan(OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT);
    
    if (Type == OP_BUY)
      MyOrderSend(OP_SELLLIMIT, Level.bid);
    else if (Type == OP_SELL)
      MyOrderSend(OP_BUYLIMIT, Level.ask);
    else if (Type != -1)
      MyOrderModify((OrderScan(OP_BUYLIMIT, OP_SELLLIMIT) == OP_BUYLIMIT) ? Level.ask : Level.bid);
    else
      OrderSend(_Symbol, OP_BUYLIMIT, exLots, Level.ask, 0, 0, 0);
  }
  
  return;
}
 
とても役に立った!
 
最新バージョンは常にここにある
 

SELECT_BY_POS+MODE_TRADES モードでのOrderSelect 実装の特異性を示すスクリプト

#include <MT4Orders.mqh>
#include <MQL4_To_MQL5.mqh>

void OnStart()
{
  OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask - 100 * _Point, 0, 0, 0);  // 買い指値を設定する
  OrderSend(_Symbol, OP_SELLLIMIT, 1, Bid + 100 * _Point, 0, 0, 0); // セル・リミットを設定する
  OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);                    // 買いポジションを建てる
  
  bool FirstRun = true;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      OrderPrint();
      
      if (FirstRun)
      {
        OrderSend(_Symbol, OP_SELL, 1, Bid, 100, 0, 0); // 売りポジションを開く
        
        FirstRun = false;
      }
    }    
}

MT4

#196155484 2017.05.04 15:38:07 buy 1.00 EURUSD 1.09229 0.00000 0.00000 1.09221 0.00 0.00 -8.00  0
#196155480 2017.05.04 15:38:06 sell limit 1.00 EURUSD 1.09321 0.00000 0.00000 1.09221 0.00 0.00 0.00  0
#196155479 2017.05.04 15:38:06 buy limit 1.00 EURUSD 1.09129 0.00000 0.00000 1.09229 0.00 0.00 0.00  0

MT5

#147352190 2017.05.04 15:38:06 sell limit 1.00 EURUSD 1.09322 0.00000 0.00000 1.09222 0.00 0.00 0.00 0
#147352193 2017.05.04 15:38:06 sell 1.00 EURUSD 1.09222 0.00000 0.00000 1.09231 0.00 0.00 -9.00 0
#147352191 2017.05.04 15:38:06 buy 1.00 EURUSD 1.09231 0.00000 0.00000 1.09222 0.00 0.00 -9.00 0

スクリプトの取引結果は両プラットフォームで同じであるにもかかわらず、OrderSelectの動作は異なります。したがって、ログも異なります。

このスクリプトは特別に吸い出されたものであり、このようなスタイルの取引ロジックの書き方は、各プラットフォームで目に見えにくい論理エラーをはらんでいるため、お勧めできません。また、このようなコードは実行時に100%同じでなくなる。

そのため、そのような稀なMT4のカーブが、通常のコードで起こるように、MT5で絶対に完璧に実行されるようにライブラリを修正するのは不都合なように思われる。

そのようなMT4取引の構築の曲率や希少性について私が間違っているのであれば、明らかにしてください。

 
どういうわけか、スローダウンがおかしいことさえ判明した。
 
Vitaly Muzichenko:
スローダウンしているのがちょっと面白い。

取引、自動取引システム、取引戦略のテストに関するフォーラム

MT4-テスター VS MT5-テスター

fxsaber, 2017.05.08 01:11 pm.

MT5の速度低下がサードパーティ製ライブラリの使用によるものであるという疑念があるのであれば、希望者はこのEAのシンプルなMT4ロジックをMQL5で自分好みに書き換えて仮説を検証すればよい。
 
fxsaber:

SELECT_BY_POS+MODE_TRADESモードでのOrderSelect実装の特殊性を示すスクリプト。

このスクリプトは特別に吸い出されたもので、このスタイルのトレードロジックの書き方はお勧めできません。

トレードロジックを記述するもう一つの推奨できないスタイルで、OrderSelectの 別の機能に遭遇することがありますが、すでにSELECT_BY_TICKET+MODE_HISTORY モードになっています。

#include <MT4Orders.mqh>

#define Ask (::SymbolInfoDouble(_Symbol, SYMBOL_ASK))

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun && OrderSelect(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0), SELECT_BY_TICKET) &&
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0))  
  {
    Print(OrderTicket()); // 2 - OPENポジションはこのチケットで
    
    Print(OrderSelect(OrderTicket(), SELECT_BY_TICKET, MODE_HISTORY)); // 偽, потому что тикет ЗАКРЫТОЙ позиции равен тикету закрывающей сделки.
    Print(OrderSelect(OrderTicket() + 1, SELECT_BY_TICKET, MODE_HISTORY)); 上記の理由により、 // true。
      
    FirstRun = false;
  }
}

これはテスター用のExpert Advisorです。コメントにこの動作の理由があります。そして、それは以下の理由で正しいです。

  • 未決済ポジションのチケットは(原則として)新規注文のチケットと同じです(取引ではありません)。(MT5の用語)。
  • ポジションが部分的にクローズされた場合、曖昧さを避けるために、クローズされた対応するポジションのチケットは、オープンポジションのチケットと等しくあってはならない(MT5の用語)。

  • つまり、MT5自体が「曲者」に作られているため、MT4Ordersの他の動作を考えるのは難しい。もちろん、最初に履歴でSELECT_BY_POSを行い、すべてのチケットを記録すれば、SELECT_BY_TICKETは問題なく機能する。

    一般的に、MT4の取引ロジックが「悪く」書かれている場合、MT5+MT4Ordersの結果とMT4の結果に、MT4の理解としては異常な齟齬が生じることがあります。MT4の「正しい」書き方に従っていれば、ライブラリに問題は検出されていません。

     
    fxsaber:

    トレードロジックを書く際に、非常に推奨されない別のスタイルを使用すると、OrderSelectの別の機能に遭遇する可能性があります。

    一般的に、MT4の取引ロジックが「悪く」書かれている場合、MT5+MT4OrdersとMT4の結果の間にMT4が理解できない不一致が生じる可能性があります。MT4の "正しい "書き方に忠実であれば、ライブラリに問題はありません。


    ライブラリは素晴らしいです。)ヒストリーの同期を追加した後は、なくてはならないものになりました。hftストラテジーでも高速に動作します。

    MT5の標準機能に追加したい。

     

    更新

    // 変更リスト:
    // 14.06.2017:
    // 追加: クローズポジション(OrderCloseでクローズ)のSL/TP検出の実装を有効にする。
    // 追加:MagicNumberはlong-8バイト型になった(以前はint-4バイト)。
    // 追加: OrderSend、OrderClose、OrderModify において、カラー入力パラメータ(最新のもの)が INT_MAX と等しく設定されている場合、そのパラメータが生成される。
    // 対応する MT5 取引リクエスト(MT4ORDERS::LastTradeRequest)は送信されません。代わりに MT5 がチェックします、
    // その結果はMT4ORDERS::LastTradeCheckResultで確認できます。
    // OrderModifyとOrderCloseが成功すればtrueを返し、そうでなければfalseを返す。
    // OrderSendは成功すれば0を返し、そうでなければ-1を返す。
    //
    // 対応するカラー入力パラメータがINT_MINに設定されている場合、生成されたカラー入力パラメータのMT5チェックが成功した場合のみ、以下のようになります。
    // (INT_MAXの場合と同様に)取引要求が送信される。
    // 追加: MQL4取引関数の非同期アナログを追加:OrderSendAsync、OrderModifyAsync、OrderCloseAsync、OrderDeleteAsync。
    // 成功すれば対応するResult.request_idを返し、そうでなければ0を返す。

    INT_MIN-modeにより、テスターのログの詰まりを完全に取り除くことができます。これは特に最適化中に重要です。誤った取引ロジックにより、大量のメッセージは最適化のパフォーマンスを何倍も低下させ、その結果、時間だけでなくコスト(クラウド)も増加させます。

    また、クローズしたポジションの TP/SLを決定することを可能にします。

    おそらくいつの日か、この機能が MT5 の標準になるでしょう。


    非同期MQL4関数の使用例

    #property script_show_inputs
    
    sinput int Amount = 5; // テスト数 OrderSend(Async)
    
    #include <MT4Orders2.mqh>
    
    #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
    #define  PRINT(A) Print(#A + " = " + (string)(A));
    
    void OnStart()
    {  
    // OrderSendAsync  
      const ulong StartTime1 = GetMicrosecondCount();
      
      for (int i = 0; i < Amount; i++)
        PRINT(OrderSendAsync(NULL, OP_BUY, 0.1, Ask, 100, 0, 0))
        
      PRINT(GetMicrosecondCount() - StartTime1)
    
    // オーダー送信
      const ulong StartTime2 = GetMicrosecondCount();
      
      for (int i = 0; i < Amount; i++)
      {
        PRINT(OrderSend(NULL, OP_BUY, 0.1, Ask, 100, 0, 0))
        Print(MT4ORDERS::LastTradeResult.comment);
      }
        
      PRINT(GetMicrosecondCount() - StartTime2)
      
      PRINT(TerminalInfoInteger(TERMINAL_PING_LAST))
    }


    結果

    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 117
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 118
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 119
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 120
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 121
    GetMicrosecondCount()-StartTime1 = 403
    
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 221.820 + 0.013 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 252.067 + 0.008 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 220.909 + 0.005 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 189.578 + 0.005 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 180.182 + 0.010 ms
    GetMicrosecondCount()-StartTime2 = 1064775
    
    TerminalInfoInteger(TERMINAL_PING_LAST) = 97942