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

 
Andrey Khatimlianskii:

この1秒が経過した後はどうなるのか?同期がない場合、その動作は継続するのでしょうか?

はい、アラートを出すことで継続します。しかし、1秒が十分でないとは考えにくい。同期はミリ秒単位で続く。

もしそうなったら、ここで報告することをお勧めします。

これは戦闘ロボットに書き込む必要が あるものですか?

いいえ。この行を書かずに上のスクリプトを実行すると、ほとんどの場合、統計は一度も同期が乱れたことがないことを示すだろう。この行は、問題の検出を促す追加要素として必要だったのだ。ほぼ初期状態で、ライブラリーはすべての取引要求を 同期状態に持っていこうとします。タスクを複雑にし、非同期を識別する独立したメカニズムをテストするために、この行を意図的に無効にしました。

 
Andrey Khatimlianskii:

それとも、取引操作の 前にMT4ORDERS::ByPass.Is()をチェックするだけで十分ですか(非同期がないことを確認するため)?

OrdersTotal、OrdersHistoryTotal、および OrderSelect が呼び出されるたびに、ByPass.Is()==true が保留されます。そのため、これらの関数の結果は、呼び出された直後に関連します。時間の経過とともに変化する可能性があるので、間が空いた場合は再度呼び出すのが正しい。これが上記の質問の 答えである。MT5だけでなく、MT4でも同様です。


そのため、取引環境を読み込んだ直後であれば、その環境が残っているため、すぐに取引操作を行うことができます。そのため、一般的なライブラリ利用者からは仕組みを隠すことができたのです。

 
// 変更リスト:
// 13.05.2021
// 修正:OrderOpenReason() のエラーを 修正しました。
 
amrali:

バグ発見:

OrderOpenReason()関数が、利益確定で決済された注文に対して(ENUM_DEAL_REASON)DEAL_REASON_TPを返します。

ありがとうございます!修正 しました。

 

fxsaber:

そう、アラートを出すことによってね。しかし、1秒では十分とは思えない。
もしそうなったら、ここで報告することをお勧めします。

それでも1秒以内に環境が同期したという事実に依存しないのであれば、同期がない場合にEAを正しく中断(新規注文を許可しない)するにはどうすればよいでしょうか?

if ( MT4ORDERS::ByPass.Is() == false ) // 環境が同期していない場合は、取引しないこと。
        return;

OrderSend(...);

?

 
Andrey Khatimlianskii:

同期がない場合、どのようにEAを正しく中断(新規注文を許可しない)することができますか?

ここはあなたの裁量次第です。あなたが書いたようにすることもできます。あるいは別の待機を作る。あるいは休止時間を増やす。私なら、少なくとも1回はこのような長い非同期を待つようにする。

 
fxsaber:

君の裁量次第だ。あなたが書いたようにしてもいい。あるいは別のWaitingにしてもいい。あるいは間を長くする。私なら、少なくとも1回はこのような長い非同期を待つようにする。

ありがとう!

アラートかバックオフを待つようにします、他のチェックは削除します。

 
// 変更リスト:
// 14.05.2021
// 修正: BYPASSメカニズムがOrderSelect(INT_MAX, SELECT_BY_POS)とOrderSelect(INT_MIN, SELECT_BY_POS)に影響しなくなりました。

スナップショットやその他の非常に特殊な取引テクニックを使う人にとっては重要だ。

 

マージンによるサプライズには うんざりだ。コンバットエキスパートアドバイザーを使用する前に、このようなテストスクリプトを実行することをお勧めします。

// MT5 のマージン計算が正しいかどうかを確認します。

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

bool EqualDouble( const double Value1, const double Value2, const double Epsilon = 0.01 )
{
  return(Value1 && Value2 && (MathMax(Value1, Value2) / MathMin(Value1, Value2) < 1 + Epsilon));
}

#define  TOSTRING(A) #A + " = " + (string)(A) + " "

bool CheckMargin( const string Symb )
{
  const double RealMargin = AccountInfoDouble(ACCOUNT_MARGIN);
// const double CalcMargin = GetMarginRequired(Symb); //https://www.mql5.com/ru/forum/170952/page9#comment_4134898
  
  double CalcMargin = 0;
  OrderCalcMargin(ORDER_TYPE_BUY, Symb, 1, SymbolInfoDouble(Symb, SYMBOL_ASK), CalcMargin);
  
  const bool Res = EqualDouble(RealMargin, CalcMargin);
  
  const string Str = TOSTRING(Symb) + TOSTRING(RealMargin) + TOSTRING(CalcMargin) + "- " + (string)Res;
  
  if (Res)
    Print(Str);
  else
    Alert(Str);
      
  return(Res);
}

bool CheckCalcMargin( const string Symb )
{
  bool Res = !OrdersTotal();
  
  if (Res)
  {
    const TICKET_TYPE Ticket = OrderSend(Symb, OP_BUY, 1, SymbolInfoDouble(Symb, SYMBOL_ASK), 0, 0, 0);
    
    if (Res = (Ticket != -1))
    {
      Res = CheckMargin(Symb);
      
      if (OrderSelect(Ticket, SELECT_BY_TICKET))
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
    }
  }
  else
  {
    Alert("ERROR: OrdersTotal() != 0");
    
    ExpertRemove();
  }
  
  return(Res);
}

void OnStart()
{
  if (AccountInfoInteger(ACCOUNT_TRADE_MODE) != ACCOUNT_TRADE_MODE_DEMO)
    Alert("Demo account is required!");
  else  
    for (int i = SymbolsTotal(true) - 1; !IsStopped() && (i >= 0); i--)
    {
      const string Symb = SymbolName(i, true);
      
      if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM))
        CheckCalcMargin(Symb);
    }
}

計算されたMT5のマージンの数値と実際の数値の間に完全な不一致が見られます。そのような状況では、おそらく対応するシンボルを避けるしかないでしょう。


ZЫ また、初歩的なことを取り上げて、すぐにそこにバグを見つけるのも面倒ですし、フォーラムではそれについて何も言われません!

 
fxsaber:
フォーラムで唯一、バグ報告に飽きない人に敬意を表する。ほとんどの人は数回無視されただけでやめてしまう。
それに、この記号を使っている人はここにはほとんどいない。