mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 70

 

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

교체 일정을 결정하는 방법은 무엇입니까?

fxsaber , 2018.02.08 12:39

 void OnTick ()
{  
   const long Chart = ChartID ();
   string PrevSymbol = _Symbol ;
   ENUM_TIMEFRAMES PrevTF = _Period ;
    
   while (! IsStopped ())
  {
     if ((PrevSymbol != ChartSymbol (Chart)) || (PrevTF != ChartPeriod (Chart))) // ноль указывать НЕЛЬЗЯ!
    {      
      PrevSymbol = ChartSymbol (Chart);
      PrevTF = ChartPeriod (Chart);
      
       Alert (PrevSymbol + " " + EnumToString (PrevTF));      
    }
    
     Sleep ( 0 );
  }
}

일부 함수의 null ChartID 입력 매개변수로 인해 값이 다시 계산되지 않습니다. 현재 차트에 대한 최신 데이터가 필요한 경우 본격적인 ID를 사용해야 합니다.

 

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

POSITION_TICKET != POSITION_IDENTIFIER

fxsaber , 2018.02.12 20:14

결과

이것이 브로커 해킹의 특성이 아니라 MT5의 일반적인 동작이라고 생각하면

  • ORDER_STATE_PARTIAL에는 과거 주문이 없습니다.
  • 채워진 주문의 상태는 항상 ORDER_STATE_FILLED입니다.
  • 부분 실행의 경우 해당하는 새로운 시장 주문이 거래 서버에 의해 생성됩니다(ORDER_REASON_CLIENT - 원래 주문이 자동으로 이루어진 경우에도(EXPERT)).
  • 이전 라이브 주문(티켓은 변경되지 않음)은 감소된 볼륨(ORDER_VOLUME_CURRENT)으로 계속 중단됩니다.
  • 동시에 이전 라이브 주문은 ORDER_STATE_PARTIAL 상태를 받습니다. 사실 이 플래그는 ORDER_VOLUME_CURRENT와 ORDER_VOLUME_INITIAL을 비교한 결과이다.
  • 열린 모든 위치는 ID == OrderTicket을 받습니다. Where OrderTicket - 거래 서버에서 생성한 티켓입니다.
  • 무역 거래에는 항상 정확히 하나의 역사적 주문이 있으며 그 상태는 ORDER_STATE_FILLED입니다.
  • 실행된 각 역사적 주문에는 정확히 하나의 거래가 있습니다.
  • 실행된 모든 주문의 경우 ORDER_VOLUME_INITIAL은 실행된 볼륨과 같습니다. 저것들. 전체 실행 후 원래 찢어진 주문의 ORDER_VOLUME_INITAL은 생성된 거래의 양과 같습니다.
  • (부분적으로 실행된) 원래 주문의 시간은 변경되지 않으며 거래 시간과 동일하지 않습니다.
  • 기록 테이블은 거래가 아닌 주문 시간(ORDER_TIME_SETUP)별로 정렬됩니다. 따라서 DEAL_TIME에서 HistorySelect를 수행하면 해당 주문을 기록 테이블에 가져오지 못할 수 있습니다.
  • HistorySelectByPosition은 항상 필요한 거래/주문 세트를 반환합니다.
  • 모든 거래 거래에 대해 슬리피지 금액을 계산할 수 있습니다.

단점

  • ORDER_REASON_PARTIAL, DEAL_REASON_PARTIAL 및 POSITION_REASON_PARTIAL이(가) 누락되었습니다. 동시에 해당 열거에서 이러한 플래그는 REASON_EXPERT 바로 뒤에 배치되어야 합니다.
  • 지정가 주문의 부분 실행에서 해당 시장가 주문은 본질적으로 음의 슬리피지를 가질 수 있습니다. 이는 오더 유형의 오류일 뿐이며 실제로 시장 오더가 없는 것 같습니다. MT5 내부에서만 생성되고 외부로 나가지 않습니다.

ZY 완전히 확인된 가설

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

POSITION_TICKET != POSITION_IDENTIFIER

파벨 콜친 , 2018.02.12 13:31

(잘 모르겠어, 포지션 부분 청산에 비유해서 확인이 어렵다)

모두 다음과 같이 작동합니다.

1) 보류 중인 주문이 부분적으로 트리거됨 - Position_ID = Order_Ticket1로 포지션이 열렸습니다.

2) 나머지 주문은 새로운 Order_Ticket2 주문으로 구성되고 실행을 기다리고 있습니다. new Order_Ticket2 != Order_Ticket1, 동일한 Order_Ticket을 가진 2개의 주문이 기록에 있을 수 없기 때문입니다.

3) 나머지 주문이 채워졌습니다 - Position_ID = Order_Ticket2로 포지션이 열렸습니다.

기록에 두 개의 주문이 있고 터미널에 두 개의 위치가 있으며 모든 것이 일치합니다.

 

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

"상인을 위한 LifeHack: 정의(#define)에 ForEach 반죽" 기사에 대한 토론

fxsaber , 2018.02.14 10:54

성능 측정

 #define BENCH(A)                                                              \
{                                                                             \
   const ulong StartTime = GetMicrosecondCount ();                              \
  A;                                                                          \
   Print ( "Time[" + #A + "] = " + ( string )( GetMicrosecondCount () - StartTime)); \
}

double GetAsk()
{
   static MqlTick tick = { 0 };
  
   return ( SymbolInfoTick ( Symbol (),tick) ? tick.ask : 0 );
}

#define AMOUNT 1 e6

void OnStart ()
{
   double Sum = 0 ;
  
  BENCH( for ( int i = 0 ; i < AMOUNT; i++) Sum += GetAsk())
  BENCH( for ( int i = 0 ; i < AMOUNT; i++) Sum += SymbolInfoDouble ( _Symbol , SYMBOL_ASK ))
  
   Print (Sum);
}


결과

 Time [ for (inti= 0 ;i<AMOUNT;i++)Sum+=GetAsk()] = 78952
Time [ for (inti= 0 ;i<AMOUNT;i++)Sum+= SymbolInfoDouble ( _Symbol , SYMBOL_ASK )] = 162606

내가 완전히 틀렸어! SymbolInfoDouble은 SymbolInfoTick보다 2배 느립니다.

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

"상인을 위한 LifeHack: 정의(#define)에 ForEach 반죽" 기사에 대한 토론

fxsaber , 2018.02.14 11:58

무능한. 테스터의 결과

 2017.09 . 01 00 : 00 : 10    Time [ for (inti= 0 ;i<AMOUNT;i++)Sum+=GetAsk()] = 87424
2017.09 . 01 00 : 00 : 10    Time [ for (inti= 0 ;i<AMOUNT;i++)Sum+= SymbolInfoDouble ( _Symbol , SYMBOL_ASK )] = 83410

성능이 필요한 경우(Optimizer) SymbolInfoDouble 을 사용 하는 것이 좋습니다. 실제로는 중요하지 않습니다.


ЗЫ 기능의 속도 측정은 성능이 중요한 환경 - 테스터에서 측정해야 합니다.

 

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

오류, 버그, 질문

fxsaber , 2018.02.12 23:10

두 거래 데모 서버에서 손으로 BUY 포지션을 엽니다.


RoboForex-MetaTrader 5

2018.02.13 00:02:08.424 '8520459': market buy 1.00 GBPUSD
2018.02.13 00:02:10.101 '8520459': accepted market buy 1.00 GBPUSD
2018.02.13 00:02:10.101 '8520459': deal #90389019 buy 1.00 GBPUSD at 1.38387 done (based on order #107426544)
2018.02.13 00:02:10.101 '8520459': order #107426544 buy 1.00 / 1.00 GBPUSD at 1.38387 done in 1683.949 ms


FXOpen-MT5

2018.02.13 00:00:25.780 '18000903': market buy 1.00 GBPUSD
2018.02.13 00:00:25.912 '18000903': accepted market buy 1.00 GBPUSD
2018.02.13 00:00:25.922 '18000903': market buy 1.00 GBPUSD placed for execution
2018.02.13 00:00:25.942 '18000903': order #896454 buy 1.00 / 1.00 GBPUSD at market done in 154.252 ms
2018.02.13 00:00:25.942 '18000903': deal #80559 buy 1.00 GBPUSD at 1.38387 done (based on order #896454)

같은 색의 행은 같은 것을 의미합니다. 그러나 그들이 다른 순서로 가고 있음을 분명히 알 수 있습니다. Robo의 경우 주문 실행에 대한 메시지는 트랜잭션 실행 후에 옵니다. 그리고 오픈을 위해 - BEFORE! 이러한 이유로 OrderSend는 행운을 반환하지만 아직 거래는 없습니다. 저것들. OrderSend가 기록과 동기화되지 않습니다.

FXOpen-MT5용 코드

 #define PRINT(A) Print ( #A + " = " + ( string )(A))

void OnStart ()
{
   MqlTradeRequest Request = { 0 };
  
  Request.action = TRADE_ACTION_DEAL ;
  Request.symbol = _Symbol ;
  Request.volume = 1 ;
  Request.type_filling = ORDER_FILLING_IOC ;
  
   MqlTradeResult Result;
  
  PRINT( OrderSend (Request, Result));
  PRINT(Result.deal);
}


결과

 OrderSend (Request,Result) = true
Result.deal = 0


이 상황에는 다음과 같은 설명이 있습니다.

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

오류, 버그, 질문

라시드 우마로프 , 2018.02.15 06:25

주문이 외부 거래 시스템으로 전송되면 MetaTrader 5 거래 서버는 응답을 기다리지 않고 즉시 요청 결과를 "주문 완료"로 반환합니다. 이러한 이유로 아직 완료된 거래에 대한 정보가 없기 때문에 OrderSend는 항상 거래=0을 반환합니다. OnTrade 또는 OnTradeTransaction에서 잡으십시오.

무역 이벤트 리스너의 예 는 MOEX 모스크바 거래소 - TradeTransactionListener.mq5를 위한 거래 로봇을 생성할 때 시작 위치 문서에 나와 있습니다.

OrderSend - 시장 거래를 하기 위해 주문을 보냈습니다. 주문이 완료되었습니다. 이를 위해서는 Result.order에 익숙해져야 합니다. 그러나 아무도 거래를 기다리고 있지 않습니다. 많은 거래가 있을 수 있으며 일반적으로 실행에 소요되는 총 시간은 정의되지 않습니다.

브로커 측의 특정 출력 구현에 따라 다릅니다. 일반적으로 정의되지 않습니다.

따라서 FXOpen-MT5의 데모 계정을 코드 테스트로 사용하는 것이 좋습니다. 다른 데모와 상당히 다릅니다.


예를 들어, 이러한 거래 논리를 사용하여 MQL5에서 스크립트를 작성하는 것이 좋습니다(MQL4 스타일은 의미를 빠르게 보여주기 위한 것입니다).

 void OnStart ()
{
   OrderCloseBy ( OrderSend ( _Symbol , OP_BUY , 1 , Ask , 0 , 0 , 0 ), OrderSend ( _Symbol , OP_SELL , 1 , Bid , 0 , 0 , 0 ));
}

전혀 쉽지 않습니다. 또한 부분 실행을 수행하기 위해 언급된 데모 서버를 권장합니다.

 
fxsaber :
MT5에서 가장 흔한 실수 중 하나에 대한 설명이 제공된 게시물을 제거했습니다.
그는 삭제된 사람 중에 없습니다. 기이한. 다시 게시 할 수 있습니까?
 
fxsaber :

게시물은 훌륭했습니다. 제거될 것이라고 예상하지 못했습니다. 철거 사유를 듣고 싶습니다. 제거에 다시 실행하는 것은 마조히즘이기 때문입니다.

나는 - 원격 사람들 사이가 아니라고 말합니다. 결함이 있었을까요?
 

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

주문 열거 주기의 구성

fxsaber , 2018.02.16 09:40

MT5에서는 모든 것이 전혀 순서가 아닙니다. 문제를 보여주는 예

 // Пример неправильного считывания торгового окружения на каждом тике
// Скрипт эмулирует два тика ТС, которая должна открыть одну позицию, если ее нет.

#include <Trade/Trade.mqh>

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
   int Res = 0 ;
  
   // Этот MQL5-код с ошибкой
   for ( int i = PositionsTotal () - 1 ; i >= 0 ; i--)
     if ( PositionGetSymbol (i) == Symb)
      Res++;

/*
   // В MT4 такой код выполняется без ошибки
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/       
   return (Res);
}

// Пример OnTick
void ExampleOnTick()
{
   static CTrade Trade;
  
   // Если нет позиции, открываем
   if (!GetAmountPositions( _Symbol ))
    Trade.Buy( 1 );    
}

// Эмуляция прихода двух Tick-событий
void OnStart ()
{
  ExampleOnTick(); 
  
   Sleep ( 10 ); // Между двумя тиками ~10 мс.
  
  ExampleOnTick();
}

위치가 없는 기호에 이 스크립트를 실행하면 결과가 어떻게 될까요?

정답: 하나 또는 두 개의 포지션 이 열릴 것입니다.

이런 일이 일어나는 이유. 첫 번째 OrderSend 후에 시장가 주문이 나타나고 실행 전에 새 틱이 도착하면 아직 포지션이 없고 두 번째 OrderSend가 배치됩니다.

이와 관련하여 겉보기에는 정상적인 MT5 템플릿 이 제대로 작동하지 않으며 결과적 으로 코드베이스에 있는 대부분의 MT5 Expert Advisors가 작동하지 않습니다 . 동시에 거의 동일한 MT4 템플릿 이 문제 없이 계속 갈 것입니다.

언뜻 보기에 좋은 아이디어인 PositionsTotal은 MT5가 시장 주문에 대해 OrdersTotal도 분석해야 할 필요성에 의해 다소 가려졌습니다.

조심하세요!

 
fxsaber :

이와 관련하여 겉보기에는 정상적인 MT5 템플릿 이 제대로 작동하지 않으며 결과적 으로 코드베이스에 있는 대부분의 MT5 Expert Advisors가 작동하지 않습니다 .

이 진술의 증거로 MT5 코드 기반에서 거의 모든 Expert Advisor를 사용할 수 있습니다. 무언가를 찾지 말고 현재 최신 Expert Advisor를 즉시 사용하십시오 . KB에서 MT5 퍼블리싱 경험이 풍부한 작가님이 쓰셨다니 좋네요.

소스 코드에는 그런 줄이 있습니다(내 주석을 강조 표시했습니다).

 //+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ()
  {
//....
   int total= 0 ; // для расчета количества открытых советником позиций
//....
//--- main cycle
   for ( int i= PositionsTotal ()- 1 ;i>= 0 ;i--)
       if (m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if (m_position. Symbol ()==m_symbol.Name() && m_position.Magic()==m_magic)
           {
            total++; // расчет количества открытых позиций
//....
   if (total== 0 ) // Если нет открытых советником позиций
     {
       if (! RefreshRates ())
        {
         PrevBars= iTime ( 1 );
         return ;
        }
       //--- open BUY 
       if (MACD_MAIN_2>MACD_SIGNAL_2 && MACD_MAIN_4<MACD_SIGNAL_4) // Сигнал на покупку
        {
         double sl=(InpStopLoss!= 0 )?m_symbol. Ask ()-ExtStopLoss: 0.0 ;
         double tp=(InpTakeProfit!= 0 )?m_symbol. Ask ()+ExtTakeProfit: 0.0 ;
         OpenBuy(sl,tp); // Отправка маркет-ордера на покупку
         return ;
        }
       //--- open SELL
       if (MACD_MAIN_2<MACD_SIGNAL_2 && MACD_MAIN_4>MACD_SIGNAL_4) // Сигнал на продажу
        {
         double sl=(InpStopLoss!= 0 )?m_symbol. Bid ()+ExtStopLoss: 0.0 ;
         double tp=(InpTakeProfit!= 0 )?m_symbol. Bid ()-ExtTakeProfit: 0.0 ;
         OpenSell(sl,tp); // Отправка маркет-ордера на продажу
        }
     }
   return ;
  }

우리는 설명 된 동일한 상황을 얻습니다.

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

mql5 언어의 특징, 미묘함 및 작업 방법

fxsaber , 2018.02.16 19:52

첫 번째 OrderSend 후에 시장가 주문이 나타나고 실행 전에 새 틱이 도착하면 아직 포지션이 없고 두 번째 OrderSend가 배치됩니다.

언뜻 보기에 좋은 아이디어인 PositionsTotal은 MT5가 시장 주문에 대해 OrdersTotal도 분석해야 할 필요성에 의해 다소 가려졌습니다.

이것은 일반적인 경우 고문이 하나가 아닌 두 개, 세 개 등의 위치를 열 것임을 의미합니다. 틱이 오는 빈도와 시장 주문이 실행되는 기간에 따라 다릅니다.


코드 기반의 거의 모든 MT5 Expert Advisors는 MT5 템플릿 과 동일한 논리에 따라 작성되기 때문에 포함된 것과 동일한 오류가 있습니다. 불행히도 이것은 KB의 거의 모든 MT5 Expert Advisors에 적용됩니다.

MACD EA
MACD EA
  • 투표: 4
  • 2018.02.15
  • Vladimir Karputov
  • www.mql5.com
При поступлении сигнала противоположная позиция закрывается. Также советник может закрывать половину позиции (параметр Profit for closing half of the position), может переводить позицию в безубыток (параметр Breakeven). Размер открываемой позиции может задавать вручную (параметр Lots) или в процентах риска от свободной маржи (параметр Risk in...
 

네팅에서는 동시에 동일한 기호에 대해 열린 포지션과 여러 방향의 시장 주문이 있을 수 있습니다. 예를 들어, BUY 포지션과 BUY 주문. 사실, 규칙이 비동기식으로 어디에나 적용되기 때문에 그러한 데모 계정을 찾을 수 없었습니다.

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

오류, 버그, 질문

fxsaber , 2018.02.14 08:58

OnTradeTransaction 이벤트의 전체 시리즈는 OrderSend가 완료된 후에 발생합니다.

조언자

 void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &, const MqlTradeResult & )
{ 
   static bool FirstRun = true ;  
   static ulong StartTime;
  
   if (FirstRun)
  {
    StartTime = GetMicrosecondCount ();
    
    FirstRun = false ;
  }

   Print ( EnumToString (Trans.type));
   Print (( GetMicrosecondCount () - StartTime) / 1000 );    
}

손은 무역 주문을 보냅니다.

통나무

2018.02.14 09:41:46.671 '8854170': instant sell 1.00 EURUSD at 1.23673
2018.02.14 09:41:46.853 '8854170': accepted instant sell 1.00 EURUSD at 1.23673
2018.02.14 09:41:46.853 '8854170': deal #192088422 sell 1.00 EURUSD at 1.23673 done (based on order #208541700)
2018.02.14 09:41:46.853 '8854170': order #208541700 sell 1.00 / 1.00 EURUSD at 1.23673 done in 190.608 ms


전문가 고문 결과

 2018.02 . 14 09 : 41 : 46.853 TRADE_TRANSACTION_ORDER_ADD
2018.02 . 14 09 : 41 : 46.853 0
2018.02 . 14 09 : 41 : 46.853 TRADE_TRANSACTION_DEAL_ADD
2018.02 . 14 09 : 41 : 46.853 1
2018.02 . 14 09 : 41 : 46.853 TRADE_TRANSACTION_ORDER_DELETE
2018.02 . 14 09 : 41 : 46.853 1
2018.02 . 14 09 : 41 : 46.853 TRADE_TRANSACTION_HISTORY_ADD
2018.02 . 14 09 : 41 : 46.853 2
2018.02 . 14 09 : 41 : 46.853 TRADE_TRANSACTION_REQUEST
2018.02 . 14 09 : 41 : 46.853 2


시간 열과 EA의 수치 지표 에서 거래 주문 실행 기간이 OnTradeTransaction 이벤트의 순서에 어떤 식으로든 영향을 미치지 않는다는 것을 분명히 알 수 있습니다 . 모든 비동기는 지옥에 간다! 그들은 그것을 망쳐 놓았습니다. 빌드 1755.

예를 들어, 터미널에서 OrderSendAsync 시장가 주문을 할 때, 시장가 주문은 잠시도 나타나지 않습니다. 아마도 개발자들은 가속을 위해 이것을 하기로 결정했을 것입니다.

 

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

"MetaTrader 5에서 거래 전략 최적화 시각화" 기사 토론

fxsaber , 2018.02.22 08:39

프레임 모드에서 OnInit, OnDeinit, OnTick, OnTrade, OnTradeTransaction 및 OnTimer는 무시됩니다. OnChartEvent만 쟁기질합니다.

물론 OnChartEvent 예외로 인해 프레임 모드 플래그가 있는지 필수 확인해야 합니다.