mql5言語の特徴、微妙なニュアンスとテクニック - ページ 184

 
enum EAct{PUSH,POP};

template<typename T>
void TempCondition(T &value,EAct act){
   static T temp=T();
   switch(act){
      case PUSH: temp=value; break;
      case POP: value=temp;
   }
}

#define  sortArray(_lArray,_lField) do {                     \
   for(int i = 0; i < ArraySize(_lArray); i++) {            \
      TempCondition(_lArray[i],PUSH);                       \
      for(int a = 1; a <= i; a++) {                         \
         if(_lArray[i]._lField < _lArray[a - 1]._lField){   \
            for(int b = i; b >= a; b--) {                   \
               _lArray[b] = _lArray[b - 1];                 \
               }                                            \
               TempCondition(_lArray[a - 1],POP);           \
               break;}}}} while(false)


struct STest{
   double a;
   int b;
};

void OnStart()
{
    STest test[700];
    sortArray(test,a);
}

うまくいくはずなんです。でも、そんなやり方はお勧めしません)

 
Koldun Zloy:

実はこれが最適なんです。そして、より複雑なソート条件を設定することができます。

例えば、こんな感じです。

そうですね、とにかく他に解決策がないんです。

パターンのポイントは、普遍的であることです。もし、この例で少なくとも一つのフィールド a,b,c を含まない別の構造体を渡すと、コンパイルできません。つまり、この関数は同時に2つの異なるデータ型を 扱うことはできない。

 
 

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

取引用のコントロールパネル。mql5 のヘルプが必要です。

ウラジミール・カルプトフ, 2020.08.18 09:04

このコードはうまくいきません。パテと 四角を 比較することはできないのです。

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong OrderTicket=OrderGetTicket(i);
      if(OrderTicket>0 && PositionSelectByTicket(OrderTicket))
        {
         // Stop long позиции------------------------------------------
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            int cur_tr; //трейлинг
            double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
            double newSl = ask - cur_tr*_Point;
            double positionSl = PositionGetDouble(POSITION_SL);
            double positionTP = PositionGetDouble(POSITION_TP);
            if(newSl > positionSl || positionSl == 0)
              {
               CTrade trade;
               trade.PositionModify(OrderTicket,newSl,positionTP);
              }
           }
        }
     }

この条件は、保留中の注文が部分的に約定し、ポジションを発生させた場合に機能します。その場合、同じチケットのオーダーとポジションが同時に存在することになります。

このため、次のような構成が意味を持つ場面もある。

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
選択したポジションや オーダーのMQLデータをゼロにしたい場合。
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

ライブラリ:MT4Orders

fxsaber, 2020.08.20 15:44

非同期トランザクションを扱う方にとって、アカウント内の未処理非同期トランザクションの最大可能数に関する設定を知っておくと便利です。

これを調べるのは難しいことではありません。

Alert: 60 - Too many trade requests


制限にぶつかることがあるので、注意してください。

 
fxsaber:

レナートは昔、制限に引っかかるだけでなく、DCでブロックされることもあると言っていました

 
fxsaber:

この条件は、保留中の注文が部分的に約定し、ポジションが発生した場合に発動されます。そうすると、同じティッカーを持つオーダーとポジションが同時に存在することになります。

RannForex-Serverの デモ口座で以下のコードでこのEAを実行すると、すぐにこの状況を再現することができます。

// Воспроизведение ситуации наличия позиции и отложенного ордера с одинаковыми тикетами.

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

MqlTradeResult Result = {0};
MqlTradeRequest Request = {0};

int OnInit()
{

        Request.action = TRADE_ACTION_PENDING;
        Request.symbol = _Symbol;
        Request.volume = 100;
        Request.price = Ask;
        Request.type = ORDER_TYPE_BUY_LIMIT;
        
        return(!OrderSend(Request, Result)); // Выставили лимитник по текущей цене.
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, _Digits)

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult& )
{
  if (OrderSelect(Result.order) && (OrderGetInteger(ORDER_STATE) == ORDER_STATE_PARTIAL)) // Если наш лимитник исполнился частично
  {
    if (Ask - OrderGetDouble(ORDER_PRICE_OPEN) < 100 * _Point)                            // и находится близко от текущей цены
    {
        Request.action = TRADE_ACTION_MODIFY;
        Request.order = Result.order;
        Request.price = Ask - 1000 * _Point;

      // тогда передвигаем его подальше.
      if (OrderSend(Request, Result)) // Если синхронный OrderSend выполнился успешно, то торговое окружение должно соответствовать.
      {
        // Проверка соответствия торгового окружения.
        if (OrderSelect(Request.order) &&                                                                // Если получилось взять данные нашего ордера
            NormalizeDouble(OrderGetDouble(ORDER_PRICE_OPEN) - Request.price, _Digits))                  // и цена ордера не равна цене успешного OrderSend
          Alert("Bug:" + TOSTRING(OrderGetDouble(ORDER_PRICE_OPEN)) + " != " + TOSTRING(Request.price)); // сообщаем о баге MT5.
      }
    }
    else
      ExpertRemove();
  }     
}


結果


ところで、このスクリプトでは、synchronous OrderSendの実行にバグがあることが(初めてとは限らない)判明しました。

Alert: Bug:OrderGetDouble(ORDER_PRICE_OPEN) = 0.89837 != Request.price = 0.88837

OrderSendが数十/数百ミリ秒実行された後、注文価格はOrderSendが成功したものでなく、古いものになります。


同じチケットの話に戻ると、いくつかの結論が導き出されます。

  1. 部分指値注文がぶら下がっている場合、「注文と取引」タブには、生成された取引は表示されません。
  2. ヘッジでは、1つの注文で異なる価格の複数のIN取引を発生させることができる。その結果、ポジションの始値は端数(pipsに相対する)となります。
  3. 生成されたポジションは、Partial Putを削除することなく決済することができます。しかし、その後、保留中の注文がトリガーされた場合、前に決済されたポジションのチケットと同じチケットでトレードが開始されます。つまり、あるチケットでポジションをクローズする場面があるかもしれません。そして、同じティッカーでポジションが再表示されます。
  4. ブローカーのソフトウェアにより、部分執行の実装が異なる場合があります。上記はMT5の標準的な実装です。

もし、他の取引サーバーで再現できた方がいらっしゃいましたら、その名前を教えてください。

検索文字列:Oshibka 010.

 
fxsaber:


  1. Partial Put を削除することなく、生成されたポジションをクローズすることができます。しかし、その後、保留中の注文がトリガーされた場合、先に決済したポジションのチケットと同じチケットで取引を開始することになります。つまり、あるチケットでポジションをクローズする場面があるかもしれません。そして、同じチケットで再びポジションが出現する。

ユニークなチケットではない?どうしてでしょう?

オーダーもトレードもチケットは一枚ずつですか?

 
Andrey Khatimlianskii:

ユニークなチケットではない?どうしてそうなるのでしょうか?

オープニングオーダーがある限り、常にポジションが存在するという説明です。ただ、常に目に見えるわけではなく、ボリュームはゼロです。そして、このポジションには、ユニークなチケットがあります。さて、このような理由によるヘッジでは、対応するインとアウトの取引の後、同じポジションでイントリガーが発生する可能性が十分にあります。

注文や取引は、独自のチケットまであるのでしょうか?

彼らはユニークです。しかし、もちろんORDER_TICKETはDEAL_TICKETと同じにすることができます。

理由: