Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 1950

 
Valeriy Yastremskiy #:

um in seiner Struktur oder seinem Array die gewünschten Preise mit Tickets und vielleicht noch etwas anderem, z.B. Zeit, zu speichern und sofort nach dem Hinzufügen nach Preis zu sortieren. Nach Ressourcen, wenn Sie nicht oft schauen, ist es das gleiche oder ein wenig teurer, und wenn Sie oft, ist es besser zu erinnern. Natürlich, wenn Sie nicht 100500 Aufträge haben) Dann kann es zu teuer sein. Im Allgemeinen wird die Sortierung in einer Struktur oder einem mehrdimensionalen Array leider nur für den ersten Index gelöst.

Manchmal verwende ich mehrere eindimensionale Arrays mit den gleichen Indizes, Tickets, Zeit, Preise. Und suchen Sie nach dem Index der gewünschten Eigenschaft. Zum Beispiel erhalten wir den Index einer kleineren Zeit oder eines größeren Preises und erhalten das Ticket der notwendigen Reihenfolge. Natürlich ist es eine Krücke, aber es funktioniert eindeutig.

Danke - ich werde auch einen Blick darauf werfen...
 
Valeriy Yastremskiy #:

in seiner Struktur oder seinem Array die gewünschten Preise mit Tickets und vielleicht noch etwas anderem, wie z.B. der Zeit, zu speichern und sofort nach dem Hinzufügen nach dem Preis zu sortieren. Nach Ressourcen, wenn Sie nicht oft schauen, ist es das gleiche oder ein wenig teurer, und wenn Sie oft, ist es besser zu erinnern. Natürlich, wenn Sie nicht 100500 Aufträge haben) Dann kann es zu teuer sein. Im Allgemeinen wird die Sortierung in einer Struktur oder einem mehrdimensionalen Array leider nur für den ersten Index gelöst.

Manchmal verwende ich mehrere eindimensionale Arrays mit den gleichen Indizes, Tickets, Zeit, Preise. Und suchen Sie nach dem Index der gewünschten Eigenschaft. Wenn wir zum Beispiel den Index einer kleineren Zeit oder eines größeren Preises bekommen, erhalten wir das Ticket der notwendigen Reihenfolge. Natürlich ist es eine Krücke, aber es funktioniert sehr gut.

Ich habe es auf diese Weise gemacht:

enum MT_ORD_STATE
  {
   ORD_NA,  // Not available
   ORD_SENT,
   ORD_ACTIVE,
   ORD_CHANGE_SENT,
   ORD_DEL_SENT
  };

struct MTOrder
  {
   ulong id;
   ulong Ticket;
   datetime Time;
   datetime TimeNotFound;
   double   Price;
   double   Vol;
   double   VolInit;
   uint     request_id;
   ENUM_ORDER_TYPE   Type;
   ENUM_ORDER_STATE State;
   MT_ORD_STATE MTState;
   int      Reserved;
   bool     Idf; // Identified
  };

...

   MTOrder  Orders[]; // С начала массива - ордера на покупку, по убыванию цены,
                      // С конца - на продажу, по возрастанию

Das Array ist immer sortiert, ein neuer Auftrag wird an der gewünschten Stelle eingefügt, wobei andere Aufträge verschoben werden, beim Löschen eines Auftrags findet eine Verschiebung statt.

Aber das ist in MT5

 
JRandomTrader #:

Ich habe es auf diese Weise gemacht:

Das Array ist immer sortiert, der neue Auftrag wird an der richtigen Stelle eingefügt, mit einer Verschiebung anderer Aufträge, wenn ein Auftrag gelöscht wird, gibt es eine Verschiebung.

Aber das ist in MT5.

Es wäre schön, wenn es einen Code für das Verschieben beim Schreiben, Löschen und Sortieren gäbe. Es ist keine leichte Aufgabe für mich, die Array-Struktur nach Feldern zu sortieren. Ja, und auch Verschiebungen).

 
Valeriy Yastremskiy #:

Shift-Code zum Schreiben, Löschen und Sortieren wäre gut. Es ist keine triviale Aufgabe für mich, eine Array-Struktur nach Feldern zu sortieren. Und auch Verschiebungen).

bool Tr2MT::InsertOrder(MTOrder &ord_tmp) // Из AddOrder (2 варианта), единственное место добавления ордеров в массив
{
 int i=0,n=0;
 string str="";
 ord_tmp.id=++st.LastOrdID;

 switch(ord_tmp.Type)
   {
    case ORDER_TYPE_BUY:
    case ORDER_TYPE_BUY_LIMIT:
      for(i=0,n=-1;i<ArraySize(Orders);i++)
        {
         if(Orders[i].id==0)
           {
            n=i; break;
           }
        }
      if(n<0) break;
      for(i=n;i>=0;i--)
        {
         if(i==0 || Orders[i-1].Price>=ord_tmp.Price)
           {
            Orders[i]=ord_tmp;
            SaveState();
            //str=OrdString();
            //Log(str);
            return true; //добавили
           }
         else
           {
            Orders[i]=Orders[i-1];
           }
        }
      break;
    case ORDER_TYPE_SELL:
    case ORDER_TYPE_SELL_LIMIT:
      for(i=ArraySize(Orders)-1,n=-1;i>=0;i--)
        {
         if(Orders[i].id==0)
           {
            n=i;
            break;
           }
        }
      if(n<0) break;
      for(i=n;i<ArraySize(Orders);i++)
        {
         if(i==ArraySize(Orders)-1 || Orders[i+1].Price<=ord_tmp.Price)
           {
            Orders[i]=ord_tmp;
            SaveState();
            //str=OrdString();
            //Log(str);
            return true; //добавили
           }
         else
           {
            Orders[i]=Orders[i+1];
           }
        }
      break;
    default:
      return false;
      break;
   }
 str="Can't add order - out of array!";
 ErrLog(str);
 return false; //не нашли места для ордера
}
bool Tr2MT::DelOrder(int n)
{
 int i;
 MTOrder ord_tmp={};

      switch(Orders[n].Type)
         {
          case ORDER_TYPE_BUY:
          case ORDER_TYPE_BUY_LIMIT:
            for(i=n;i<ArraySize(Orders);i++)
              {
               if(i==ArraySize(Orders)-1 || Orders[i+1].id==0 || Orders[i+1].Price>Orders[i].Price)
                 {
                  Orders[i]=ord_tmp; // Обнуляем
                  break;
                 }
               else
                 {
                  Orders[i]=Orders[i+1];
                 }
              }
            break;
          case ORDER_TYPE_SELL:
          case ORDER_TYPE_SELL_LIMIT:
            for(i=n;i>=0;i--)
              {
               if(i==0 || Orders[i-1].id==0 || Orders[i-1].Price<Orders[i].Price)
                 {
                  Orders[i]=ord_tmp; // Обнуляем
                  break;
                 }
               else
                 {
                  Orders[i]=Orders[i-1];
                 }
              }
            break;
          default:
            return false;
            break;
         }
 return true;
}

Und das ist wahrscheinlich der interessanteste Teil:

bool Tr2MT::UpdOrder(int n) // Только если есть тикет или угадываем
{
 string str;
 int i;
 bool flag=false;
 MTOrder ord_tmp={0};
 ulong ticket=Orders[n].Ticket;

 if(ticket==0)
   {
    if(!GuessOrdTicket(n))return false; // Если угадываем - он будет в Orders[n].Ticket
    else ticket=Orders[n].Ticket;
   }

 switch(FindOrder(ticket,Orders[n].Time+100000))
   {
    case ORD_FOUND: //изменён или просто проверка
      //update (sync) order
      if(Orders[n].Price==OrderGetDouble(ORDER_PRICE_OPEN)) // Цена не изменилась
        {
         if(Orders[n].State==(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE)&&Orders[n].MTState!=ORD_NA)
           {
            if(Orders[n].Vol==OrderGetDouble(ORDER_VOLUME_CURRENT))
               return true; // Не нужно сохранять состояние, можно сразу выйти
            else
               Orders[n].Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         else
           {
            //Orders[n].State=(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE);
            SetOrdState(Orders[n],(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE)); // Обнулит и TimeNotFound
            if(Orders[n].Vol!=OrderGetDouble(ORDER_VOLUME_CURRENT))
               Orders[n].Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
        }
      else // Цена изменилась
        {
         ord_tmp=Orders[n];
         //ord_tmp.State=(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE);
         SetOrdState(ord_tmp,(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE));
         ord_tmp.Price=OrderGetDouble(ORDER_PRICE_OPEN);
         ord_tmp.Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
         switch(Orders[n].Type)
           {
            case ORDER_TYPE_BUY:
            case ORDER_TYPE_BUY_LIMIT:
               if(ord_tmp.Price>Orders[n].Price) // Цена ордера увеличилась, перемещаем вверх (по массиву - вниз)
                 {
                  for(i=n;i>=0;i--)
                    {
                     if(i==0 // Конец массива ордеров
                        || ord_tmp.Price<=Orders[i-1].Price) // Следующий - по большей цене, вставляем перед ним
                       {
                        Orders[i]=ord_tmp;
                        break;
                       }
                     else
                       {
                        Orders[i]=Orders[i-1]; // Сдвигаем следующий элемент
                       }
                    }
                 }
               else // Цена ордера умньшилась, перемещаем вниз (по массиву - вверх)
                 {
                  for(i=n;i<ArraySize(Orders);i++)
                    {
                     if(i==ArraySize(Orders)-1 // Конец массива ордеров
                        || Orders[i+1].Ticket==0 // Следующий элемент пустой
                        || ord_tmp.Price>Orders[i+1].Price // Следующий - по меньшей цене, вставляем перед ним
                        || Orders[i+1].Price>Orders[i].Price) // Следующий - ордер уже на продажу
                       {
                        Orders[i]=ord_tmp;
                        break;
                       }
                     else
                       {
                        Orders[i]=Orders[i+1]; // Сдвигаем следующий элемент
                       }
                    }
                 }
               break;
            case ORDER_TYPE_SELL:
            case ORDER_TYPE_SELL_LIMIT:
               if(ord_tmp.Price>Orders[n].Price) // Цена ордера увеличилась, перемещаем вверх (по массиву - вниз)
                 {
                  for(i=n;i>=0;i--)
                    {
                     if(i==0 // Конец массива ордеров
                        || Orders[i-1].Ticket==0 // Следующий элемент пустой
                        || ord_tmp.Price<Orders[i-1].Price // Следующий - по большей цене, вставляем перед ним
                        || Orders[i-1].Price<Orders[i].Price) // Следующий - ордер уже на покупку
                       {
                        Orders[i]=ord_tmp;
                        break;
                       }
                     else
                       {
                        Orders[i]=Orders[i-1]; // Сдвигаем следующий элемент
                       }
                    }
                 }
               else // Цена ордера умньшилась, перемещаем вниз (по массиву - вверх)
                 {
                  for(i=n;i<ArraySize(Orders);i++)
                    {
                     if(i==ArraySize(Orders)-1 // Конец массива ордеров
                        || ord_tmp.Price>Orders[i+1].Price) // Следующий - по меньшей цене, вставляем перед ним
                       {
                        Orders[i]=ord_tmp;
                        break;
                       }
                     else
                       {
                        Orders[i]=Orders[i+1]; // Сдвигаем следующий элемент
                       }
                    }
                 }
               break;
            default:
               return false;
               break;
           }
        }
      SaveState();
      //str=OrdString();
      //Log(str);
      break;
    case ORD_HIST_FOUND: //исполнен || снят
      //delete order
      if(!DelOrder(n))
         return false;
      SaveState();
      str=OrdHistString(ticket); // Уточнить
      Log(str);
      break;
    case ORD_NOT_FOUND: //отправлен в историю?
      if(Orders[n].MTState!=ORD_NA)
        {
         Orders[n].MTState=ORD_NA;
         Orders[n].TimeNotFound=TimeCurrent();
         SaveState();
         printf(__FUNCTION__, "Order not found, ticket:",IntegerToString(Orders[n].Ticket)," TimeNF:",TimeToString(Orders[n].TimeNotFound,TIME_SECONDS));
        }
      else
        {
         if(TimeCurrent()-Orders[n].TimeNotFound>60) // > 60 секунд не найден
           {
            if(!DelOrder(n))
              return false;
            SaveState();
            str="Order not found >60s "+IntegerToString(ticket)+"\n";
            Log(str);
           }
        }
       break;
    default:
      return false; //не тот ордер
      break;
   }
 return true;
}
 
JRandomTrader #:

Ich danke Ihnen.

Nicht schlecht. Ich mag arrays)))) nicht, und es funktioniert nie beim ersten Mal ohne Debugging in Arrays. ))) Insbesondere Verschiebungen, Kopieren, Sortieren nicht regelmäßig)))
 
Valeriy Yastremskiy #:

Ich danke Ihnen.

Nicht schlecht. Ich mag arrays)))) nicht, und es funktioniert nie beim ersten Mal ohne Debugging in Arrays. ))) Insbesondere Verschiebungen, Kopieren, Sortieren nicht regelmäßig)))

Jedes Werkzeug ist um seiner selbst willen gut.

Aber, heimtückisch aus-einem-Fehler-Check und Recheck ))

 

Das ist es, was ein neuer Blick auf Ihren alten Code bedeutet!

Ich sehe zwei identische Fehler, Überbleibsel der vorherigen Version.

Eine offensichtliche Suboptimalität.

Und ein veraltetes Design.

 
Hallo. Wenn ich an der falschen Stelle bin, bitte ich Sie, mir zu sagen, wo ich schreiben soll, danke.

Ich suche einen kostenlosen MT5 Expert Advisor, der Positionen ALLE schließt, wenn ein in den Einstellungen festgelegter Gewinn oder Verlust erreicht wird, und sofort neue Positionen in der in den Einstellungen festgelegten Richtung eröffnet. Kann mir jemand einen Link zu diesem Thema geben?
Oder vielleicht kennen Sie einen EA, der nur 1 Position auf dem Markt eröffnet, wenn er sieht, dass es keine offenen Positionen gibt und nicht schließt.
 

MT4 1353

Welche Art von Fehler wird im Protokoll angezeigt?

Der Code funktioniert korrekt


 
Vitaly Muzichenko #:

MT4 1353

Welche Art von Fehler wird im Protokoll angezeigt?

Der Code funktioniert korrekt.


Es sieht so aus, als ob einige mit "new" erstellte Objekte beim Beenden nicht zerstört werden.

Grund der Beschwerde: