어떤 디자인이 맞습니까? - 페이지 8

 
valenok2003 :

감사합니다. 오류를 처리하는 중입니다. 메시지가 나타납니다. 가격이 잘못되었지만 무엇이 잘못되었는지 알 수 없습니다.

그런 다음 줄을 추가하십시오

 int err = GetLastError ();

함수 시작 부분으로 - 오류 버퍼 지우기: 때때로 "다른 사람의" 오류를 읽을 수 있습니다. 그렇지 않으면 함수가 시작될 때 오류 버퍼가 지워집니다.

이것은 필수는 아니지만 프로그램이 실제 생활을 위한 것이라면 모든 것을 가능한 한 올바르게 수행하는 것이 매우 바람직합니다.

행운을 빕니다.

 
VladislavVG :

그런 다음 줄을 추가하십시오

함수 시작 부분으로 - 오류 버퍼 지우기: 때때로 "다른 사람의" 오류를 읽을 수 있습니다. 그렇지 않으면 함수가 시작될 때 오류 버퍼가 지워집니다.

이것은 필수는 아니지만 프로그램이 실제 생활을 위한 것이라면 모든 것을 가능한 한 올바르게 수행하는 것이 매우 바람직합니다.

행운을 빕니다.


예, 감사합니다. 실제 프로그램에서는 그렇게 합니다.
 
좋은 사람들이여, 미결 주문이 없는데도 함수가 0을 반환하는 이유를 알려주세요. 오류가 발생해야 합니까?
 //+------------------------------------------------------------------+
//| функция закрытия ордеров по символу
//+------------------------------------------------------------------+
int Close_This_Symbol_All( string _Symbol_Name, string _Type_Order, int _Slippage, bool _Alert_ON)
{
  bool _Result;
  ERROR = 0 ;
//----
  if ( OrdersTotal () == 0 ) return (- 1 );
  for ( int _Cnt = OrdersTotal ()- 1 ; _Cnt >= 0 ; _Cnt--) 
  {
    if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) break ;
    if (OrderSymbol() == _Symbol_Name)
    { 
      while (!IsTradeAllowed()) Sleep ( 1000 );
      RefreshRates();
      if (OrderType() == OP_BUY   && _Type_Order == "BUY" ) 
      {
        _Result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_BID), _Slippage, CLR_NONE );
        ERROR = GetLastError ();
      }
      if (OrderType() == OP_SELL && _Type_Order == "SELL" ) 
      {
        _Result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_ASK), _Slippage, CLR_NONE );
        ERROR = GetLastError ();
      }
      if (_Result == true) PlaySound (Name_Sound_Close);
      else 
      {
        Error(Name_Expert, " Close " +_Type_Order+ ": " ,ERROR,_Alert_ON);
        break ;
      }
    }  
  }
//----
  return (ERROR);
}
//+------------------------------------------------------------------+
 
다시 한번 뼈를 분해해볼까요?
 
valenok2003 :
좋은 사람들이여, 미결 주문이 없는데도 함수가 0을 반환하는 이유를 알려주세요. 오류가 발생해야 합니까?
정수 주문 합계 ( )

미결 및 보류 중인 주문 의 총 수를 반환합니다.

아직도 주문해서 쓰시나요?

 

-- 밑줄과 이중 밑줄로 시작하는 이름을 사용하는 것은 잘못된 형식입니다. 끝 부분에 밑줄을 긋는 것이 좋습니다.


-- _Type_Order가 문자열인 이유는 무엇입니까? IMHO, 비현실적으로 불편합니다. 그런 다음 가져와야합니다. 왜냐하면 "판매" 또는 "판매"라고 쓰면 아무것도 쟁기질하지 않습니다.


-- 실수를 원하면 실수를 하라:

ERROR = -1 ;

그리고 이대로가 더 좋다

#define ERROR_NOTHING_TO_CLOSE -1
...

...
ERROR = ERROR_NOTHING_TO_CLOSE;


--

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) break ;

왜 휴식? 밀리초 전에 주문이 TP에 의해 마감되었다고 가정해 보겠습니다. 이 때문에 나머지는 마감할 필요가 없습니까? 더 나은 방법:

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;

--

 while (!IsTradeAllowed()) Sleep ( 1000 );

끈은 쓸모없는 것보다 더 나쁩니다. 그것은 해롭습니다. 아마도 이것은 의미가 있었습니까?

 while (IsTradeContextBusy()) Sleep ( 1000 );


--

 else 
      {
        Error(Name_Expert, " Close " +_Type_Order+ ": " ,ERROR,_Alert_ON);
         break ;
      }

저것들. 갑자기 명령을 닫을 수 없으면 "운전대에서 손을 떼고 눈을 감고 소리를 지르십시오."

나머지는 닫아야 하나요? 다시 시도해야 하지 않겠습니까?


여기에서 오류를 반환하는 이유는 무엇입니까? 예를 들어 모든 것이 성공적으로 닫히면 true를 반환하고 그렇지 않으면 false를 반환하는 것이 훨씬 더 적절합니다.


지금 모든 것처럼.

 
TheXpert :

-- 밑줄과 이중 밑줄로 시작하는 이름을 사용하는 것은 잘못된 형식입니다. 끝부분에 밑줄을 긋는 것이 좋습니다.


함수 내에서 밑줄로 시작하는 이름을 사용하여 변수를 재정의할 위험을 제거했습니다. 저것. start()에서 동일한 이름을 안전하게 사용할 수 있지만 밑줄은 없습니다. 코드의 투명도를 높입니다.

- _Type_Order가 문자열인 이유는 무엇입니까? IMHO, 비현실적으로 불편합니다. 그런 다음 가져와야합니다. 왜냐하면 "판매" 또는 "판매"라고 쓰면 아무것도 쟁기질하지 않습니다.

물론 당신이 맞습니다. 하지만 문자열을 사용하면 코드의 투명도가 높아지며 현재 가지고 있는 코드의 양이 많아 캐스트가 필요하지 않습니다. 이 문제가 실제로 발생하면 그렇게 할 것이지만 지금은 그럴 필요가 없습니다. 저는 그냥 SELL 또는 BUY라고 씁니다.


왜 휴식? 밀리초 전에 주문이 TP에 의해 마감되었다고 가정해 보겠습니다. 이 때문에 나머지는 마감할 필요가 없습니까? 더 나은 방법:

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;

당신이 확실히 옳았습니다. 감사합니다.


끈은 쓸모없는 것보다 더 나쁩니다. 그것은 해롭습니다. 아마도 이것은 의미가 있었습니까?

IsTradeContextBusy() 함수는 스레드의 바쁘다는 것만 알려주고 IsTradeAllowed()는 다소 넓습니다.


저것들. 갑자기 명령을 닫을 수 없으면 "운전대에서 손을 떼고 눈을 감고 소리를 지르세요"


예, 정확히 이와 같은 디버깅 기간 동안

여기에 오류가 반환되는 이유는 무엇입니까? 예를 들어 모든 것이 성공적으로 닫히면 true를 반환하고 그렇지 않으면 false를 반환하는 것이 훨씬 더 적절합니다.


감사합니다. 무엇이 잘못되었는지 알아낸 것 같습니다. 이제 확인하고 다시 작성하겠습니다.
 

오류는 다음과 같습니다.

bool _Result 변수는 초기화되지 않았습니다. 즉, 거기에서 false가 됩니다. 따라서 어떤 조건도 충족되지 않았기 때문에 _Result 변수를 변경하지 않았고 이미 false가 포함되어 있습니다. 그리고 함수는 실제로 존재하지 않는 오류 처리 로 진행합니다.

기능을 수정하여 여기에 게시했는데 누군가에게 유용할 수 있을 것 같습니다.

 //+------------------------------------------------------------------+
//| функция закрытия ордеров по символу
//+------------------------------------------------------------------+
int Close_This_Symbol_All( string _Symbol_Name, string _Type_Order, int _Slippage, bool _Alert_ON)
{
int _Cnt_Close_Orders = 0 ;
//----
  if ( OrdersTotal () == 0 ) return (_Cnt_Close_Orders);
  for ( int _Cnt = OrdersTotal ()- 1 ; _Cnt >= 0 ; _Cnt--) 
  {
    if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;
    if (OrderSymbol() == _Symbol_Name)
    { 
      while (!IsTradeAllowed()) Sleep ( 1000 );
      RefreshRates();
      if (OrderType() == OP_BUY   && _Type_Order == "BUY" ) 
      {
        if (OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_BID), _Slippage, CLR_NONE ))
        {
          _Cnt_Close_Orders++;
          PlaySound (Name_Sound_Close);        
        } 
        else 
        {
          Error(Name_Expert, " Close " +_Type_Order+ ": " , GetLastError (),_Alert_ON);
          continue ;
        }
      }
      if (OrderType() == OP_SELL && _Type_Order == "SELL" ) 
      {
        if (OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_ASK), _Slippage, CLR_NONE ))
        {
          _Cnt_Close_Orders++;
          PlaySound (Name_Sound_Close);        
        } 
        else 
        {
          Error(Name_Expert, " Close " +_Type_Order+ ": " , GetLastError (),_Alert_ON);
          continue ;
        }
      }
    }  
  }
//----
  return (_Cnt_Close_Orders);
}
//+------------------------------------------------------------------+

PS 중재자 . 그러한 분기는 우연히 밝혀졌습니다 - 올바른 주문 마감에 대한 기성품 자습서. 예를 들어 파싱 예제를 사용하여 주문을 올바르게 마감하는 방법과 같이 이름을 바꾸는 것이 좋습니다.

PPS 참여해주신 모든 분들께 진심으로 감사드립니다 . 아마도 더 많은 질문이 있을 것입니다.

 
valenok2003 :

오류는 다음과 같습니다.

bool _Result 변수는 초기화되지 않았습니다. 즉, 거기에서 false가 됩니다. 따라서 어떤 조건도 충족되지 않았기 때문에 _Result 변수를 변경하지 않았고 이미 false가 포함되어 있습니다. 그리고 함수는 실제로 존재하지 않는 오류를 처리합니다.

기능을 수정하여 여기에 게시했는데 누군가에게 유용할 수 있을 것 같습니다.

PS 중재자 . 그러한 분기는 우연히 밝혀졌습니다 - 올바른 주문 마감에 대한 기성품 자습서. 예를 들어 파싱 예제를 사용하여 주문을 올바르게 마감하는 방법과 같이 이름을 바꾸는 것이 좋습니다.

PPS 참여해주신 모든 분들께 진심으로 감사드립니다 . 아마도 더 많은 질문이 있을 것입니다.


CodeBase를 살펴보고 포럼을 주의 깊게 읽으면 주문의 올바른 마감에 대한 100개 이상의 예가 있지만 이것이 모든 분기의 이름을 즉시 바꿔야 한다는 의미는 아닙니다. 영웅은 충분합니다.
 
valenok2003 :

오류는 다음과 같습니다.

bool _Result 변수는 초기화되지 않았습니다. 즉, 거기에서 false가 됩니다. 따라서 어떤 조건도 충족되지 않았기 때문에 _Result 변수를 변경하지 않았고 이미 false가 포함되어 있습니다. 그리고 함수는 실제로 존재하지 않는 오류를 처리합니다.

기능을 수정하여 여기에 게시했는데 누군가에게 유용할 수 있을 것 같습니다.

PS 중재자 . 그러한 분기는 우연히 밝혀졌습니다 - 올바른 주문 마감에 대한 기성품 자습서. 예를 들어 파싱 예제를 사용하여 주문을 올바르게 마감하는 방법과 같이 이름을 바꿀 가치가 있습니까?

PPS 참여해주신 모든 분들께 진심으로 감사드립니다 . 아마도 더 많은 질문이 있을 것입니다.

IMHO: 그 기능은 바로 논리상 이해할 수 없는 것으로 판명되었습니다. 테스터의 경우 불필요한 것이 많으며 실제라면 오류를 처리할 가치가 있습니다. 반환된 값은 전혀 의미가 없습니다. 호출이 오류로 종료되었다는 외부 수준(호출 수준)에 보고하고 오류 자체는 손실되고 로그에 기록되었습니다. 전문가는 어떻게 생각합니까?

어떻게 더 정확할까요? (다시 IMHO)

1. 에러 번호를 읽고 저장합니다.

2. 오류를 복구 가능한 오류와 복구 불가능한 오류로 나눕니다. 이렇게 하려면 핸들러를 만드십시오. 주문을 여전히 닫을 수 있는 오류(바쁜 스레드, 연결 끊김 등)는 그 자리에서 바로 처리됩니다. 나는 이것을했습니다 (먼저 복구 할 수없는 다음 "고칠"수있는 것).

 #define MAXCYKLESCNT 20

int ErrReaction( int err)
{
     switch (err)
    {
         case ERR_TRADE_NOT_ALLOWED    :
                 Print ( "TRADE NOT ALLOWED ! SWITCH ON option \' Allow live trading\' (Необходимо включить опцию \'Разрешить советнику торговать\')" );
         case ERR_INVALID_FUNCTION_PARAMSCNT :    
         case ERR_INVALID_FUNCTION_PARAMVALUE :    
         case ERR_INVALID_STOPS        : 
         case ERR_INVALID_TRADE_VOLUME : 
         case ERR_MARKET_CLOSED        : 
         case ERR_TRADE_DISABLED       : 
         case ERR_NOT_ENOUGH_MONEY     : 
                 return (-err);
         case ERR_NO_CONNECTION        :
                 ReScanServers();
         case ERR_BROKER_BUSY          : 
         case ERR_TRADE_CONTEXT_BUSY   : 
        case ERR_ORDER_LOCKED         :
                 int n= 0 ;
                 while ((!IsTradeAllowed())&&(n< 20 )){ Sleep ( 500 );n++;}
         case ERR_PRICE_CHANGED : 
         case ERR_OFF_QUOTES    : 
         case ERR_REQUOTE       : 
                 RefreshRates();
                 break ;
         default : break ;
    } //switch(err)
     return ( 0 );
} //int ErrReaction(int err)

3. 치명적 에러의 경우, 에러 플래그가 아닌 그 번호를 반환하여 외부 모듈에서 이러한 상황을 처리할 수 있도록 한다. 작업 결과를 분석할 때:

 bool res    = false;
int   ncykls =     0 ;

     while ((!res)&&(ncykls<MAXCYKLESCNT))
    {
        res = ...............
         if (!res)
        { 
            ncykls++;
            err= GetLastError ();
             Print (ncykls, " Err(" ,err, ") : " ,ErrorDescription(err)); 
            err_res = ErrReaction(err); 
            if (err_res< 0 ) return (err_res);
        } 
    } //while((!res)&&(ncykls<MAXCYKLESCNT))

행운을 빕니다.

PS 중단/계속 관련

 if ( ! OrderSelect (i,SELECT_BY_POS,MODE_TRADES) ) break ;     // No more Orders
질문은 무의미합니다. 아직 주문이 있는 경우 테이크/스톱이 트리거되면 주문 번호가 변경됩니다. 즉, 주문은 계속 선택됩니다. 티켓이 아닌 일련 번호로 선택합니다. 주문이 선택되지 않은 경우 주문이 없음을 의미합니다. 매번 주문 수를 확인하지 않기 때문에 몇 번이나 유휴 사이클을 실행하십시오.