루프 및 주문 마감 또는 삭제 - 페이지 5

 
Eleni Anna Branou :

</> 버튼을 사용하여 코드를 삽입하십시오.


죄송합니다... 적절한 형식으로 되어 있습니다.

OrdersTotal()이 올바르지 않습니다...

나는 OrdersTotal()을 사용 하여 올바른 결과를 제공하지 않는 루프 코드 시퀀스에 놀랐습니다(두 개의 다른 브로커에서 관찰됨).

WINE 3.0을 실행하는 Linux Ubuntu-MATE 16.04 데스크탑에서 MT4 버전 1090을 사용하고 있습니다.

여기 내가 사용한 것이 있습니다 ...

여기있어:

 for ( int cc = 0 ; cc < OrdersTotal (); cc++)
{
       if (! OrderSelect (cc, SELECT_BY_POS , MODE_TRADES ) ) continue ;
       if ( OrderSymbol () != Symbol () ) continue ;
       if ( OrderType () > 1 ) continue ;     //--ignore pending trades

      OpenTradecnt++;     //--counts up for every live position of that symbol that exists
       Print ( "count of the open trades of this symbol is: " , OpenTradecnt);

나는 두 개의 다른 브로커에서 OrdersTotal() 값이 MT4 브로커의 'Trade' 탭에 표시된 값과 항상 일치하지 않는다는 것을 알게 되었습니다. 처음에는 OrdersTotal()이 제대로 작동하지 않는 원인이 브로커라고 생각했습니다. 두 번째 브로커에서 눈치채고 MT4에 내부 '문제'가 있는지, 아니면 내 코드가 잘못된 것인지 아니면 MT4가 서버와 제대로 동기화하는 데 문제가 있는 것인지 궁금해지기 시작했습니다....?

이 포럼 스레드를 읽은 후 for..loop를 다음과 같이 변경하여 더 나은 결과를 얻을 수 있는지 궁금합니다.

 for ( int cc = OrdersTotal () - 1 ; cc >= 0 ; cc--)
{
      if (! OrderSelect (cc, SELECT_BY_POS , MODE_TRADES ) ) continue ;
       if ( OrderSymbol () != Symbol () ) continue ;
       if ( OrderType () > 1 ) continue ;     //--ignore pending trades

      OpenTradecnt++;     //--counts up for every live position of that symbol that exists
       Print ( "count of the open trades of this symbol is: " , OpenTradecnt);
또는 OnTick() 이벤트 중에 OrdersTotal()이 제대로 동기화되도록 하는 플래그 또는 코드 줄이 있습니까?

이에 대한 설명은 매우 도움이 될 것이며 대단히 감사하겠습니다!

 
Simon Gniadkowski :

이것은 내가 보는 가장 일반적인 오류 중 하나입니다. 아마도 부분적으로 Expert Advisor Builder와 같은 쓰레기 같은 것들 때문일 것입니다. 그래서 나중에 참조할 수 있도록 해당 주제에 대한 전용 스레드를 만들 때라고 생각했습니다.

문제

간단한 예를 들어 보겠습니다. 우리는 EA에 대한 모든 미결 주문을 마감하는 기능을 원합니다. 많은 예가 있지만 처음부터 하나 만들어 보겠습니다.

특정 EA에 대한 모든 주문을 닫고 싶기 때문에 루프가 필요합니다. 이 루프 내에 는 주문을 선택하는 코드, 올바른 기호 및 매직 번호인지 확인하는 코드, 마지막으로 주문을 종료하는 코드가 있습니다.

이 코드는 좋지 않습니다. . . 그것을 사용하지 마십시오 . . . 그 이유는 다음 섹션에서 설명하겠습니다. . .

설명

위의 코드를 통해 작업해 보겠습니다. . . 라인별, 주문별 주문 . . .

닫고자 하는 다음 주문이 있다고 가정해 보겠습니다. 모두 EA와 동일한 매직 번호와 기호를 갖고 있으므로 코드에서 모두 닫기를 원합니다.

위치 티켓 번호
0 111
1 222
2 333
444
4 555

루프를 통해 첫 번째 실행:

PositionIndex의 초기 값은 0이므로 위치 0의 주문이 선택되고 티켓 번호 111, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다.

위치 티켓 번호
0 222
1 333
2 444
555

루프를 통해 두 번째 실행:

이제 PositionIndex의 값이 1이므로 위치 1의 주문이 선택되고 티켓 번호 333, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다 .

위치 티켓 번호
0 222
1 444
2 555

루프를 통해 세 번째 실행:

이제 PositionIndex의 값이 2이므로 위치 2의 주문이 선택되고 티켓 번호 555, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다 .

위치 티켓 번호
0 222
1 444

루프를 통해 4번째 실행:

이제 PositionIndex의 값 은 3입니다. OrderSelect()는 위치 3에서 Order를 선택하려고 시도하고 실패 하고, continue는 루프의 다음 값으로 코드를 실행합니다. .


다섯 번째이자 마지막 루프 실행:

이제 PositionIndex의 값은 4입니다. OrderSelect()는 위치 4에서 Order를 선택하려고 시도하고 실패 하면 계속은 루프의 다음 값으로 코드를 실행합니다. . . 루프가 완료되었습니다.


이제 2개의 주문, 티켓 222번과 444번이 남았습니다. 티켓은 닫았어야 했지만 닫히지 않았습니다. . . 다음으로 이 문제를 해결하는 방법입니다.

해결책

다음 코드는 미결 주문을 닫거나 보류 주문을 삭제할 때 올바른 접근 방식입니다. . .

주요 차이점은 루프가 ( TotalNumberOfOrders - 1 ) 에서 0 으로 감소 한다는 것입니다.

다시 한 번 위의 코드를 통해 작업해 보겠습니다. . . 라인별, 주문별 주문 . . .

이전과 동일한 주문이 있습니다.

위치 티켓 번호
0 111
1 222
2 333
444
4 555

루프를 통해 첫 번째 실행:

PositionIndex의 초기 값은 TotalNumberOfOrders - 1이고 5 - 1 = 4 이므로 위치 4의 주문이 선택되고 티켓 번호 555, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다.

위치 티켓 번호
0 111
1 222
2 333
444

루프를 통해 두 번째 실행:

이제 PositionIndex의 값은 3이므로 위치 3의 주문이 선택되고 티켓 번호 444, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다 .

위치 티켓 번호
0 111
1 222
2 333

루프를 통해 세 번째 실행:

이제 PositionIndex의 값이 2이므로 위치 2의 주문이 선택되고 티켓 번호 333, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다 .

위치 티켓 번호
0 111
1 222

루프를 통해 4번째 실행:

이제 PositionIndex의 값 이 1 이므로 위치 1의 주문이 선택되고 티켓 번호 222, 이 주문은 성공적으로 삭제되고 나머지 주문은 다음과 같이 위치가 변경됩니다 .

위치 티켓 번호
0 111

다섯 번째이자 마지막 루프 실행:

이제 PositionIndex의 값은 0입니다 . 따라서 위치 0의 주문이 선택되고 티켓 번호 111, 이 주문이 성공적으로 삭제되었습니다. 값 0은 루프에 대한 마지막 유효한 값입니다 . . . 루프가 완료되었습니다.

일치하는 모든 주문을 성공적으로 삭제했습니다. . .

이 스레드에 대한 링크: 루프 및 주문 마감 또는 삭제

매우 감사합니다! 아주 명쾌한 설명이다
 
안녕하세요 코더 여러분,
나는 이 스레드를 통해 주문 선택에 대해 읽었습니다. 실제로, 나는 일을 제대로 했다고 생각하는 코드가 있지만 선택한 주문 의 OpenPrice를 읽을 수 없기 때문에 선택이 작동하지 않습니다 . 제공된 코드의 해당 부분만 제외하고 다른 모든 것은 잘 작동합니다. 이유를 모르겠습니다.
전체 코드에는 해당 주문이 전송된 직후 OrderOpenPrice를 호출해야 하는 4개의 섹션이 있습니다. OrderSend는 잘 작동하지만 OrderSelect는 내가 원하는 결과를 얻지 못합니다. 도움이 될 수 있으면 코드의 1개 섹션을 참조하세요.
고맙습니다.
 if (Protection_Step_One== 1 )
        {
         while (Protective_Order< 0 )
          {
           RefreshRates ();
          Protective_Order= OrderSend ( Symbol (), OP_SELL ,Protective_Lots, NormalizeDouble ( MarketInfo ( Symbol (), MODE_BID ), MarketInfo ( Symbol (), MODE_DIGITS )), 3 , 0 , 0 , "Intermediary" ,MN_Sell_Intermediary_Protection, 0 ,Cyan);
          }
   //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Addition for Clamp       
           for ( int i= OrdersTotal ()- 1 ; i>= 0 ; i--)
            { if ( OrderSelect (i, SELECT_BY_POS , MODE_TRADES )== true )
               { if ( OrderMagicNumber ()==MN_Sell_Intermediary_Protection)
                  { RefreshRates ();
                  Intermediary_OpenPrice_Sell= OrderOpenPrice ();
                  }
                }
             }   
               //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..
         if (Protective_Order!=- 1 )
          { 
          Protection_Step_One= 0 ;
          RealTime_Drawing= 2 ;
          Protective_Mode_Activated= 1 ;
          Protective_Order=- 2 ;
          Defcon= 2 ;

 

친애하는 Simon Gniadkowski 에게 감사드립니다.

귀하의 게시물은 내 시간을 정말 절약했습니다.

 
Gelson Kasonia :
 void OnStart ()
{
     int Protective_Order= OrderSend ( _Symbol , ORDER_TYPE_BUY , 0.01 ,Ask, 3 , 0 , 0 , "Intermediary" );
     if (Protective_Order< 0 )
           return ;
     if (! OrderSelect (Protective_Order,SELECT_BY_TICKET, MODE_TRADES))
           return ;
     Print (Protective_Order, " OrderOpenPrice: " , OrderOpenPrice());
}
 

이것은 시장 주문을 마감할 때 제안하는 코드입니다.

 int MagicNo= 1234 ;
int Slippage= 10 ;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersBackward()
  {
   for ( int i= OrdersTotal ()- 1 ; i>= 0 && !IsStopped() ; i--)
     {
       if (! OrderSelect (i,SELECT_BY_POS,MODE_TRADES))
        {
         Print ( "Order Select failed, order index: " ,i, " Error: " , GetLastError ());
         continue ;
        }

       if (OrderSymbol()== Symbol () && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if (!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))

             Print ( "Order Close failed, order ticket: " ,OrderTicket(), " Error: " , GetLastError ());
        }
     }
  }

그리고 저는 정방향 for 루프가 사용되는 경우 이것이 올바른 방법이라고 제안합니다(미국 중개인의 FIFO 규칙을 준수하기 위해)

 int MagicNo= 1234 ;
int Slippage= 10 ;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersForward()
  {
   for ( int i= 0 ; i< OrdersTotal () && !IsStopped(); i++)
     {
       if (! OrderSelect (i,SELECT_BY_POS,MODE_TRADES))
        {
         Print ( "Order Select failed, order index: " ,i, " Error: " , GetLastError ());
         continue ;
        }

       if (OrderSymbol()== Symbol () && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if (OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
           {
             i--;
           }
         else
           {
             Print ( "Order Close failed, order ticket: " ,OrderTicket(), " Error: " , GetLastError ());
           }
        }
     }
  }

순방향 루프에서,

  1. OrderTotal() 함수는 for 루프 내에서 인덱스가 배열 범위 를 벗어나는 것을 방지하기 위해 각 루프 반복에서 열린 주문의 나머지 수를 업데이트하는 데 사용됩니다.
  2. 인덱스 i는 일부 주문을 건너뛰는 것을 피하기 위해 각 주문이 마감될 때 감소합니다.
 
amrali : 일부 주문을 건너뛰는 것을 방지하기 위해 각 주문이 마감될 때 인덱스 i가 감소 합니다.
여러 주문(하나의 EA 여러 차트, 여러 EA, 수동 거래)이 있는 경우 현재 작업(닫기, 삭제, 수정)이 완료되기를 기다리는 동안 다른 주문에 대한 여러 다른 작업이 동시에 발생할 수 있으며 위치 인덱싱을 변경했습니다.
  1. FIFO가 아닌(미국 중개인) (또는 EA는 기호당 하나의 주문만 엽니다) 위치 루프에서 간단히 카운트다운 있으며 주문을 놓치지 않을 것입니다. 항상 카운트 다운하는 습관을 들이십시오.
    루프 및 주문 마감 또는 삭제 - MQL4 프로그래밍 포럼
    FIFO(미국 중개인) 경우 기호당 여러 주문을 (잠재적으로) 처리하려면 가장 이른 주문 찾아 마감하고 성공적인 작업에서 나머지 모든 위치를 다시 처리해야 합니다.
    FIFO 규칙에 의한 CloseOrders - 전략 테스터 - MQL4 프로그래밍 포럼 - 페이지 2 #16

  2. 이전 위치가 삭제된 경우 OrderSelect 확인하십시오.
    함수 반환 값이란 무엇입니까? 어떻게 사용합니까? - MQL4 프로그래밍 포럼
    MQL4 프로그램의 일반적인 오류 및 이를 방지하는 방법 - MQL4 기사
  3. (잠재적으로) 여러 주문 처리하는 경우 다음 주문/서버 호출에서미리 정의된 변수 ( Bid/Ask ) 또는 (방향 독립적이고 사용) OrderClosePrice ( ) .
 

이것이 얼마나 도움이 되었는지 알게 될 것입니다. 내가 작업하고 있던 코드뿐만 아니라 완전히 이해했습니다. 그것은 지금 완벽하게 작동하고 나는 그것을 다른 방식으로 구현할 이해가 있습니다.

이 정보에 정말 감사드립니다.

사유: