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를 포함하지 않는 다른 구조가 전달되면 컴파일되지 않습니다. 즉, 함수는 두 가지 다른 데이터 유형 과 동시에 작동할 수 없습니다.

 
이 주제와 관련이 없는 댓글은 " MQL4 및 MQL5에 대한 모든 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 "으로 이동되었습니다.
 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

거래용 제어판. 도움이 필요한 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 :

Renat는 오래 전에 한계에 도달 할 수있을뿐만 아니라 DC에서 블록을 잡을 수 있다고 말했습니다.

 
fxsaber :

이 조건은 보류 중인 주문이 부분적으로 채워지고 위치가 생성된 경우 작동합니다. 그러면 같은 티켓을 가진 주문과 포지션이 동시에 존재하게 됩니다.

RannForex-Server 데모 계정에 다음 코드가 있으면 이 Expert Advisor를 실행하면 이 상황을 즉시 재현할 수 있습니다.

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

#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 ();
  }     
}


결과.


그 과정에서 스크립트는 동기 OrderSend 실행의 버그를 보여줍니다(항상 처음은 아님).

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

수십/수백 밀리초 동안 OrderSend를 실행한 후 주문 가격은 OrderSend가 성공적으로 배치한 가격이 아니라 이전 가격입니다.


동일한 티켓의 주제로 돌아가서 몇 가지 결론을 도출할 수 있습니다.

  1. 부분 제한이 설정된 경우 생성된 거래는 "주문 및 거래" 탭에 표시되지 않습니다.
  2. 헤지에서 하나의 주문은 다른 가격으로 여러 IN 거래를 생성할 수 있습니다. 결과는 포지션을 여는 데 대한 분수(포인트 기준) 가격이 됩니다.
  3. Partial-deferred를 삭제하지 않고 형성된 포지션을 닫을 수 있습니다. 그러나 그 후에 연기가 작동하면 이전에 닫은 위치의 티켓과 동일한 티켓으로 거래가 열립니다. 저것들. 특정 티켓으로 포지션을 청산하는 상황이 있을 수 있습니다. 그런 다음 동일한 티켓으로 위치가 다시 나타납니다.
  4. 부분 실행은 브로커 소프트웨어에 따라 다양한 방식으로 구현될 수 있습니다. 위에서 표준 MT5 구현에 대해 설명했습니다.

추신 누군가 다른 거래 서버에서 재생산했다면 이름을 공유하십시오.

검색 문자열 : Osibka 010.

 
fxsaber :


  1. Partial-deferred를 삭제하지 않고 형성된 포지션을 닫을 수 있습니다. 그러나 그 후에 연기가 작동하면 이전에 닫은 위치의 티켓과 동일한 티켓으로 거래가 열립니다. 저것들. 특정 티켓으로 포지션을 청산하는 상황이 있을 수 있습니다. 그런 다음 동일한 티켓으로 위치가 다시 나타납니다.

고유 티켓이 아닌가요? 어떻게 이럴 수있어?

티켓은 주문 및 거래에 대해 고유합니까?

 
Andrey Khatimlianskii :

고유 티켓이 아닌가요? 어떻게 이럴 수있어?

당신 자신을 위해, 당신은 시작 순서가 있는 한 항상 위치가 있다는 설명을 찾을 수 있습니다. 항상 볼 수 있는 것은 아닙니다. 볼륨이 0입니다. 그리고 이 직책에는 고유한 티켓이 있습니다. 음, 헤지에서는 이러한 이유로 해당 인 및 아웃 거래 후에 동일한 위치의 인트레이드를 가질 수 있습니다.

티켓은 주문 및 거래에 대해 고유합니까?

독특합니다. 그러나 물론 ORDER_TICKET은 DEAL_TICKET과 같을 수 있습니다.

사유: