거래 환경에서 작업할 때 일반적인 실수와 이를 제거하는 방법 - 페이지 3

 
fxsaber :

간단한 예에 대한 올바른 옵션

포지션에 아직 주문이 반영되지 않은 경우가 더 정확하다고 생각하는데, 반영될 때까지 기다리시면 됩니다.
 
Комбинатор :
포지션에 아직 주문이 반영되지 않은 경우가 더 정확하다고 생각하는데, 반영될 때까지 기다리시면 됩니다.

아이디어를 얻지 못했습니다.

 
일반 OrderSend의 조건부 구현 방식(시간 초과 없음)
 static MqlTradeResult LastResult = { 0 };

void OnTradeTransaction ( const MqlTradeTransaction &, const MqlTradeRequest &, const MqlTradeResult &Result )
{ 
  LastResult = Result;
}

// Условный алгоритм реализации штатной OrderSend
bool OrderSend ( const MqlTradeRequest &Request, MqlTradeResult &Result )
{  
   bool Res = OrderSendAsync (Request, Result);
  
   if (Res)
  {
     while (LastResult.request_id != Result.request_id)
       OnTradeTransaction (); // условно-схематичный вызов
          
    Result = LastResult;    
    Res = (Result.retcode == TRADE_RETCODE_PLACED ) ||
          (Result.retcode == TRADE_RETCODE_DONE ) ||
          (Result.retcode == TRADE_RETCODE_DONE_PARTIAL );

    LastResult.request_id = 0 ;
  }
    
   return (Res);
}


이 다이어그램은 동일한 MetaQuotes-Demo에서 OrderSendAsync 를 통해 시장 주문을 할 때 주문이 실행되거나 거부되는 순간까지 해당 주문을 하는 이벤트를 포착하는 것이 불가능하다는 것을 분명히 보여줍니다. 저것들. MT5에는 OrderSendAsync의 중간 결과를 평가하기 위한 간단한 메커니즘이 없습니다.

 

화제가 된 것 같다

이 코드는 다음과 같습니다.

 if ( ! OrderSend (request,result) ) PrintFormat (" OrderSend error %d", GetLastError ());
else Print (result.price);

DEMO(결과=요청)에서 완벽하게 작동합니다.

그러나 REAL에서는 결과를 얻는 것이 불가능합니다(result=0.0). ... 몇 초만 기다리지 않는 한.

 
Ivan Ivanov :

화제가 된 것 같다

이 코드는 다음과 같습니다.

DEMO(결과=요청)에서 완벽하게 작동합니다.

그러나 REAL에서는 결과를 얻는 것이 불가능합니다(result=0.0). ... 몇 초만 기다리지 않는 한.

누락된 데이터 - 로그, OrderSend 뒤의 구조 필드 값, 거래 서버 이름.

 
fxsaber :

간단히 말해서 의미는 다음과 같습니다. 시장 주문이 있는 경우 이를 "포지션"으로 간주합니다. 래핑 위치이기 때문에 따옴표로 묶습니다. 강조 표시된 코드는 원칙적으로 어디에도 나타나지 않습니다. 그러나 그것은 당신이 포지션을 다시 여는 것을 피할 수 있게 해줍니다. 여기서 가장 흥미로운 부분은 빨간색으로 강조 표시되어 있습니다. 이 칩의 필요성은 즉시 실현되지 않습니다.

 for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
     if ( OrderGetTicket (i) && ( OrderGetInteger ( ORDER_TYPE ) <= ORDER_TYPE_SELL ) &&
        ! OrderGetInteger ( ORDER_POSITION_ID ) && ( OrderGetString ( ORDER_SYMBOL ) == Symb))
      Res++;   // если мы сюда попадаем при проверке состояния, не запускать стратегию вообще, т.к. это промежуточное состояние.
 
Комбинатор :

다음 틱에는 거래 신호가 없을 수 있습니다. 본인도 MT4 스타일을 사용하기 때문에 그런 "포지션"을 볼 수 밖에 없고 문제는 없습니다.

 
fxsaber :

누락된 데이터 - 로그, OrderSend 이후의 구조 필드 값, 거래 서버 이름.

 //+------------------------------------------------------------------+
//|                                                      TestBUY.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{ //--- объявление и инициализация запроса и результата
   MqlTradeRequest request={ 0 };
   MqlTradeResult result={ 0 };
//--- параметры запроса
  request.action = TRADE_ACTION_DEAL ;
  request.symbol= _Symbol ; 
  request.volume= 0.01 ;
  request.type= ORDER_TYPE_BUY ;
  request.price= SymbolInfoDouble ( _Symbol , SYMBOL_ASK );
  request.deviation= 5 ;
  request.magic= 1234 ;
  request.tp= 0.0 ;
  request.comment= DoubleToString (request.price, _Digits );
//--- отправка запроса
   if ( ! OrderSend (request,result) )
     PrintFormat ( "OrderSend error %d" , GetLastError ()); // если отправить запрос не удалось, вывести
//--- информация об операции
   PrintFormat ( "retcode=%u deal=%I64u order=%I64u" ,result.retcode,result.deal,result.order, " NewOrder" );
}


2018.02.20 15:20:35.845 주문 거래 #66745055 시장에서 0.01 / 0.01 EURUSDeur 매수 완료 610.625ms

2018.02.20 15:20:35.935 거래 거래 #5461453 1.23403에서 0.01 EURUSDeur 구매 완료(주문 #66745055 기준)

2018.02.20 15:20:35.845 TestBUY (EURUSDeur,M15) retcode=10009 거래=0 주문=66745055

요청이 완료된 경우(10009) 거래=0인 이유

 
Ivan Ivanov :

요청이 완료된 경우(10009) 거래=0인 이유

여기 에서 토론이 시작되었습니다 . 자세한 내용은 링크를 참조하세요.

OrderSend가 완벽하게 작동하는 솔루션이 있지만 이것은 광고가 될 것입니다.

 
fxsaber :

간단한 예에 대한 올바른 옵션

간단히 말해서 의미는 다음과 같습니다. 시장 주문이 있는 경우 이를 "포지션"으로 간주합니다. 래퍼 위치이기 때문에 따옴표로 묶습니다. 강조 표시된 코드는 원칙적으로 어디에도 나타나지 않습니다. 그러나 그것은 당신이 포지션을 다시 여는 것을 피할 수 있게 해줍니다. 여기서 가장 흥미로운 것은 빨간색으로 강조 표시되어 있습니다. 이 칩의 필요성은 즉시 실현되지 않습니다.

사실은 소위 마감 시장 주문이 있다는 것입니다. 동일한 SL/TP. 그러한 시장 주문은 "포지션"으로 간주되지 않을 것이 분명합니다. 예, 그리고 그 자신이 폐쇄를 위해 내놓은 명령도 비슷합니다. 여기서 강조 표시된 조건은 해당 필터입니다.

 for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
     if ( OrderGetTicket (i) && ( OrderGetInteger ( ORDER_TYPE ) <= ORDER_TYPE_SELL ) &&
         ! OrderGetInteger ( ORDER_POSITION_ID ) && ( OrderGetString ( ORDER_SYMBOL ) == Symb))
      Res++;   

PS 여기 에 이 코드를 붙여넣고 데모 서버 에서 결과를 확인하십시오.

관심 있는 모든 사람을 이 문제에 대해 논의하도록 초대합니다. 이에 대한 제 의견은 이렇습니다.


  1. 서버에 주문 보내기
  2. 결국 취소될 수 있는 시장 주문이 나타나지만 이미 포지션으로 계산했습니까?
 for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
     if ( OrderGetTicket (i) && ( OrderGetInteger ( ORDER_TYPE ) <= ORDER_TYPE_SELL ) &&
         ! OrderGetInteger ( ORDER_POSITION_ID ) && ( OrderGetString ( ORDER_SYMBOL ) == Symb))
      Res++;   

이 루프는 위치 ID(ID 0)가 없는 주문이 발견되면 하나의 위치를 추가합니다.

우리는 한 위치를 더 반환했습니다.

서버에서 주문을 취소하면 어떻게 되나요?

...

시장 주문을 고려할 때 예를 들어 WRONG_VALUE와 같이 반환하는 것이 필요한 경우 - 위치는 0보다 작을 수 없습니다. 이것은 설명되지 않은 시장 주문이 있다는 신호입니다. 그러나 위치 수를 추가하지 마십시오.