MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 1950

 
Valeriy Yastremskiy # :

구조에 저장하거나 필요한 가격을 티켓과 함께 배열하고 예를 들어 시간과 같이 필요한 기타 사항을 배열하고 가격별로 추가한 후 즉시 정렬합니다. 자료에 따르면 자주 검색하면 같거나 조금 더 비싸고 자주 검색하면 기억하는 것이 좋습니다. 글쎄요, 물론 100500개의 주문이 있는 경우가 아니라면요) 그러면 가격도 비쌀 수 있습니다. 일반적으로 구조나 다차원 배열에서 정렬을 하면 불행히도 첫 번째 인덱스에 대해서만 문제가 해결됩니다.

때로는 인덱스, 티켓, 시간, 가격이 동일한 여러 1차원 배열을 사용합니다. 그리고 필요한 속성의 인덱스에서 검색하십시오. 예를 들어 더 짧은 시간 또는 더 높은 가격의 인덱스를 얻고 필요한 주문의 티켓을 얻습니다. 물론 목발이지만 분명히 작동합니다.

p.s 나도 한번 봐야겠다...
 
Valeriy Yastremskiy # :

구조에 저장하거나 필요한 가격을 티켓과 함께 배열하고 예를 들어 시간과 같이 필요한 기타 사항을 배열하고 가격별로 추가한 후 즉시 정렬합니다. 자료에 따르면 자주 검색하면 같거나 조금 더 비싸고 자주 검색하면 기억하는 것이 좋습니다. 글쎄요, 물론 100500개의 주문이 있는 경우가 아니라면요) 그러면 가격도 비쌀 수 있습니다. 일반적으로 구조나 다차원 배열에서 정렬을 하면 불행히도 첫 번째 인덱스에 대해서만 문제가 해결됩니다.

때로는 인덱스, 티켓, 시간, 가격이 동일한 여러 1차원 배열을 사용합니다. 그리고 필요한 속성의 인덱스에서 검색하십시오. 예를 들어 더 짧은 시간 또는 더 높은 가격의 인덱스를 얻고 필요한 주문의 티켓을 얻습니다. 물론 목발이지만 분명히 작동합니다.

나는 이것을 이렇게 했다:

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[]; // С начала массива - ордера на покупку, по убыванию цены,
                       // С конца - на продажу, по возрастанию

배열은 항상 정렬되어 원하는 지점에 새 주문이 삽입되고 다른 주문의 이동과 함께 주문이 삭제되면 이동이 발생합니다.

하지만 MT5에서

 
JRandomTrader # :

나는 이것을 이렇게 했다:

배열은 항상 정렬되어 원하는 지점에 새 주문이 삽입되고 다른 주문의 이동과 함께 주문이 삭제되면 이동이 발생합니다.

하지만 MT5에서

작성, 삭제 및 정렬 시 시프트 코드가 있으면 좋을 것입니다. 필드별로 구조 배열을 정렬하는 것은 쉬운 일이 아닙니다. 네, 그리고 교대합니다.)

 
Valeriy Yastremskiy # :

작성, 삭제 및 정렬 시 시프트 코드가 있으면 좋을 것입니다. 필드별로 구조 배열을 정렬하는 것은 쉬운 일이 아닙니다. 네, 그리고 교대도 합니다.)

 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 ;
}

그리고 아마도 가장 흥미로운 것:

 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 # :

고맙습니다.

나쁘지 않다. 나는 배열을 좋아하지 않는다)))), 그리고 배열에서 디버깅하지 않고 생각한 것이 처음으로 밝혀진 적은 한 번도 없다. ))) 특히 교대, 복사, 정렬이 규칙적이지 않음)))
 
Valeriy Yastremskiy # :

고맙습니다.

나쁘지 않다. 나는 배열을 좋아하지 않는다)))), 그리고 배열에서 디버깅하지 않고 생각한 것이 처음 밝혀진 적은 없다. ))) 특히 교대, 복사, 정렬이 표준이 아님)))

각 도구는 그 자체로 좋습니다.

단, 한 번의 오류로 교활한 오프 체크 및 재확인))

 

이것이 바로 이전 코드를 새롭게 보는 것이 의미하는 바입니다!

나는 이전 버전의 기초인 두 개의 동일한 잼을 봅니다.

하나의 명백한 불일치.

그리고 하나의 구식 디자인.

 
안녕하세요. 내가 주소에 없으면 어디에 쓸지 알려주세요. 고맙습니다.

설정에 지정된 손익에 도달하면 모든 포지션 을 청산하고 설정에 지정된 방향으로 즉시 새 포지션을 여는 무료 MT5 고문을 찾고 있습니다. 누군가 스레드에 대한 링크를 제공할 수 있습니까?
또는 열려 있는 포지션이 없다고 판단하고 청산하지 않는 경우 시장에서 1개의 포지션을 개설하는 Expert Advisor가 있을 수도 있습니다.
 

MT4 1353

로그에 어떤 오류가 표시됩니까?

코드가 올바르게 작동합니다


 
Vitaly Muzichenko # :

MT4 1353

로그에 어떤 오류가 표시됩니까?

코드가 올바르게 작동합니다


"new"를 통해 생성된 일부 개체는 종료 시 소멸되지 않는 것 같습니다.

사유: