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

 
mt4コードのシームレスな変換には本当に驚かされます。本当にありがとう。
 

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

ライブラリ: MT4Orders

fxsaber, 2023.07.07 13:12

パフォーマンス

b3815とb2958のパフォーマンス表(ミリ秒単位の実行時間)。

MT5ビルド LastCloseTimeMQL4 LastCloseTimeMQL5 LastCloseTimeMQL4_2 LastCloseTimeMQL4+VIRTUAL::スナップショット LastCloseTimeMQL4+VirtualTester
b3815 2875 113 708 732 45
b2958 2718 107 675 715 50

20.07.2022の MT4Ordersが随所で使用された。

同じ方法で、b4040 とb4057 という 2 つの MT5 ビルドの比較表を作成した。

MT5ビルド LastCloseTimeMQL4 LastCloseTimeMQL5 LastCloseTimeMQL4_2 LastCloseTimeMQL4+VIRTUAL::スナップショット LastCloseTimeMQL4+VirtualTester
b4040 3663 117 881 928 27
b4057 246 122 171 213 27

b4057+ では、履歴を扱う際の MT4Orders のパフォーマンスは、ネイティブの MQL5 よりも劣っていません。


従って、先に述べた推奨はもはや意味をなさない(MT5 b4057+の場合)

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

ライブラリ: MT4Orders

fxsaber, 2023.07.07 13:12

  • 過去の注文のOrderSelectコールを減らす必要があります。これは、表の右側の3つの列に示されている方法で実現できます。
 

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

ライブラリ: MT4Orders

fxsaber, 2017.06.14 11:30 AM.

// 変更リスト:
// 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を返す。

理解する必要がある場合は、端末が取引注文またはサーバーに拒否を行いました。

// 拒否された場合は、その理由を見る。  
if (!OrderDelete(OrderTicket(), INT_MIN)) //https://www.mql5.com/ru/forum/93352/page12#comment_5290455
  Print(ToString(MT4ORDERS::LastTradeRequest) + //https://www.mql5.com/en/forum/203931#comment_5287237
        ToString(MT4ORDERS::LastTradeResult) +
        ToString(MT4ORDERS::LastTradeCheckResult));
 

リアル。私はMT4Orders、バーチャルを経由した仮想環境を使用しており、バーチャルとリアルを同期させています。この目的のために、各ティックで、リアルで開いた注文を数回確認します。このため、最初のパスで関心のある注文のリストを作成し、他のパスではこのリストを使って作業します。

以前はこのようなコードを持っていた:

long OrderTickets[];
for(int i=OrdersTotal()-1;i>=0;--i)
{
  if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    continue;
  AddToArray(OrderTickets,OrderTicket());
}
...
for(int i=ArraySize(OrderTickets)-1;i>=0;--i)
{
  if(!OrderSelect(OrderTickets[i],SELECT_BY_TICKET,MODE_TRADES))
    continue;
  do_something();
}

練習の結果、これは良い方法ではないことがわかりました。リミッターの一部が埋まっていると、同じチケットで2つの注文が生成され、2回目のパスでは不幸になる。

そこで、次のコードに変更した。

int Orders[];
for(int i=OrdersTotal()-1;i>=0;--i)
{
  if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    continue;
  AddToArray(Orders,i);
}
...
for(int i=0;i!=ArraySize(Orders);++i)
{
  if(!OrderSelect(Orders[i],SELECT_BY_POS,MODE_TRADES))
    continue;
  do_something();
}

さらに、作業前にスナップショットを作成します。これは正しく機能するのでしょうか、それとも何か他の問題が出てくるのでしょうか?

 
traveller00 各ティックで、リアルで開いた注文を数回確認します。このため、最初のパスで関心のある注文のリストを作成し、他のパスではこのリストを使って作業します。

以前はこのようなコードだった:

練習の結果、これは良い方法ではないことがわかりました。リミッターの一部が埋まっていると、同じチケットで2つの注文が生成され、2回目のパスではそれが不幸になる。

このようにすれば、悲しいことはありません。

AddToArray(OrderTickets, (OrderType() <= OP_SELL) ? OrderTicket() : - OrderTicket());

これはMT4Ordersの機能です。しかし、SELECT_BY_TICKETはMT4/5や仮想化では高速なメカニズムではありません。その理由の一つは、ライブの中から見つからなければ、履歴に移動してしまうからだ(MODE_TRADES-フラグは、最初にどこを見るかの優先順位表示でしかない)。


現在、私はこのコードに切り替えている。

さらに、作業前にスナップショットを作成している。これは正しく機能するのでしょうか、それとも何か別の問題が出てくるのでしょうか?

ここではすでにVirtual.mqhのアドオンの話をしている。もちろん、たくさんのキャラクターや魔法が取引されている場合、スナップショットはとてもクールなスピードアップになります。

スナップショットはExpert Advisorの外部環境(取引API)での作業を最小限に抑えます。つまり、最も処理速度の遅い関数は最初の読み込みのために一度だけ呼び出され、その後は同じMT4スタイルであるため、プログラマーが気づかないうちに取引環境に関するすべての作業がEA内部で行われます。


これらのスナップショット・バリアントのいずれかを使用することは理にかなっています。

#define  VIRTUAL_SNAPSHOT_REFRESHTIME 1000 // 更新のためのスナップショットの有効期間。MT5では、MT4Orders.mqhに接続する必要があります。
#define  VIRTUAL_SNAPSHOT_WITHOUT_HISTORY // パフォーマンス向上のため、履歴スナップショットを破棄する
#include <fxsaber\Virtual\Virtual.mqh>

VIRTUAL::Snapshot(); // 1: один (_Symbol) символ, все мэджики.
VIRTUAL::Snapshot(VIRTUAL_SNAPSHOT_REFRESHTIME, MyMagic); // 2: один (_Symbol), один мэджик.
VIRTUAL::Snapshot(VIRTUAL_SNAPSHOT_REFRESHTIME, -1, false, ""); // 3: все символы и мэджики.


  1. 私はそれを使っています。1つのEAに複数のサブOTC(それぞれが独自のmajicを持つ)を持つことができます。また、1つのシンボルに複数のExpert Advisorがある場合でも、このオプションを使用するのは合理的だと思います。つまり、一度スナップショットを行い、その結果ですべてのサブOTCを動作させます。
  2. モノカレンシーのExpert Advisorが1つのメジャーだけで動作する場合、それは最速のオプション です。
  3. 多通貨Expert Advisorでは、majicまたはすべてのmajicを設定することができます。


VIRTUAL::Snapshot()を連続して1000回呼び出すことができますが、VIRTUAL_SNAPSHOT_REFRESHTIMEで設定した回数(例では1ミリ秒です-それで十分です)以上、外部取引APIと対話することはありません。そのため、何も記憶する必要はなく、コードは大体このようになる。

VIRTUAL::Snapshot();

for (uint i = OrdersTotal(); (bool)i--;)
{
  VIRTUAL::Snapshot();
  
  do_something();
}


これが仮想環境を使った私の同期コード(サブTSごとに呼び出される)だ。

  // 現在の(選択された)VirtualPointerTo-environmentとVirtualPointerOut(閉じる位置)に基づいて同期する。
  static bool SyncChannel( const string &Symb, const MAGIC_TYPE Magic, const double Lots,
                           const VIRTUAL_POINTER &VirtualPointerTo, const VIRTUAL_POINTER &VirtualPointerOut, const int FlagChange = false )
  {      
    // IsNullメカニズムに必要。
    if (!VirtualPointerTo.GetHandle() || !VIRTUAL::GetHandle())
      _B2(VIRTUAL::Snapshot());    
    
    const bool IsNull = !OrdersTotal() && !_VP(VirtualPointerTo, OrdersTotal());
    bool Res = IsNull || !FlagChange || _B(SYNCCHANNEL::IsNotChange(true), 500);
  
    if (!IsNull)
    {
      Res &= SYNCCHANNEL::IsCloseBy(/*Symb*/.) && MACRO_ISCHANGE(SYNCCHANNEL::SyncCloseBy(Symb, Magic, VirtualPointerTo/*, (inMinLotCorrection <= 0)*/));
      
      Res &= MACRO_ISCHANGE(SYNCCHANNEL::SyncExistOrders(Symb, Magic, VirtualPointerTo, VirtualPointerOut));

      if (Lots && (inMinLotCorrection > Lots))
        ::Alert("inMinLotCorrection(" + (string)inMinLotCorrection + ") > Lots(" + (string)Lots + ")");
      
      Res &= MACRO_ISCHANGE(SYNCCHANNEL::SetNewLimit(Symb, Magic, Lots, OP_BUYLIMIT, VirtualPointerTo, inMinLotCorrection));
      Res &= MACRO_ISCHANGE(SYNCCHANNEL::SetNewLimit(Symb, Magic, Lots, OP_SELLLIMIT, VirtualPointerTo, inMinLotCorrection));
    }    

    return(Res);    
  }

ハイライトされた部分から、スナップショットの作成がわかります。これはブレーキ関数の後に呼び出される必要がある。例えばOrderSend。もし余分に呼び出したとしても、上のコードのように大した問題ではありません。

しかし、このソースコードが与えられているのは別の理由がある。同期中に新しいティック(SymbolInfoTickまたはCopyTicks)が到着した場合、同期を完全に停止するマクロの中に潜在的に低速な関数をすべて入れました。すべて、取引コピー機や外部の暗号取引所で動作するはずのものとまったく同じです。

 
Caught OrderBug22 何が問題なのでしょうか?RP 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) Line = 1537 NF 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) Before MT4ORDERS::HistoryDealSelect(Result): DP 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) MT4ORDERS::OrderSendBug = 22 CL 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) Result.deal = 0
 
Sviatoslav Tyshchyk :HistoryDealSelect(Result) の前:DP 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) MT4ORDERS::OrderSendBug = 22 CL 0 19:00:01.733 Pip Funnels 1.0 (AUDJPY,H2) Result.deal = 0

問題ありません。

 
このテクニックを使えば、取引履歴から未決注文を削除することができます。
int HistoryOrdersTotalTmp( void ) { return(-1); }

#define HistoryOrdersTotal HistoryOrdersTotalTmp
  #include <MT4Orders.mqh> //https://www.mql5.com/ja/code/16006
#undef HistoryOrdersTotal
 
Line = 1773
Before ::HistoryOrderSelect(Result.order):
MT4ORDERS::OrderSendBug = 96
Result.deal = 0
Line = 1796
Before MT4ORDERS::HistoryDealSelect(Result):
MT4ORDERS::OrderSendBug = 96
Result.deal = 0
Alert: OrderSend(1505369998) - BUG!
Alert: Please send the logs to the coauthor - https://www.mql5.com/en/users/fxsaber
Alert: C:\Program Files\MetaTrader 5 5\MQL5\Logs\20240402.log

バグ

 
leonerd #:

バグ

普通のことだ。