실시간 틱 - 페이지 22

 
Andrey Khatimlianskii :

로그 시간을 보십시오. 이 모든 일이 1ms 안에 일어났고 다음(같은 ms에서) 많은 OnBooks가 발생했습니다.

모든 이벤트를 카운터로 계산할 수 있지만 시각적으로도 더 많은 OnBook이 있다는 것이 분명합니다.

Andrey, OnFunctions가 트리거될 때 숫자가 고정된 마이크로초이고 모든 것이 어레이에서 함께 인쇄됩니다. OnBuks는 결국 더 많을 수 있습니다. 계산해 보겠습니다. 하지만 OnTiki가 대기열에서 계속 진행되도록 허용한 이유는 분명하지 않습니다. 아니면 각 OnTik이 OnBuk에 해당하지 않습니까?
 
prostotrader :


비동기 주문을 사용하고 있다고 썼습니까?
흥미로워졌습니다. 트랜잭션 실행을 제어하는 알고리즘은 무엇입니까?

 
Aleksey Mavrin :
Andrey, OnFunctions가 트리거될 때 숫자가 고정된 마이크로초이고 모든 것이 어레이에서 함께 인쇄됩니다. OnBuks는 결국 더 많을 수 있습니다. 계산해 보겠습니다. 하지만 OnTiki가 대기열에서 계속 진행되도록 허용한 이유는 분명하지 않습니다. 아니면 각 OnTik이 OnBuk에 해당하지 않습니까?

네트워킹의 세계에 오신 것을 환영합니다

관리자로 실행하는 가장 쉬운 방법: Netstat - a -b

당신은 포트와 소프트웨어를 볼 수 있습니다, 나는 주위를 찌르고 싶지 않지만 MT5 서버는 터미널이 이미 필요한 "선반"에 넣은 다른 정보로 패킷을 비동기적으로 구동한다고 생각합니다.

추신: 한 번에 많은 양을 출력할 경우 Print() 및 인쇄 누락에 대해? - 파일에 정보를 기록하십시오 - 모든 것을 순서대로 저장하되 닫기 전에 파일을 닫는 것을 잊지 마십시오. 이론상으로는 파일의 로그에 있는 Print()가 완료되어야 하는데 확인을 해보지 않았고 일반적으로 많은 데이터가 표시되면 신뢰가 가지 않습니다. https://www.mql5.com/ru/forum/329730 여기에서 논의 , 매우 자주 "누락 된 지문"이 논의됩니다))) - 검색

 
Aleksey Mavrin :
Andrey, OnFunctions가 트리거될 때 숫자가 고정된 마이크로초이고 모든 것이 어레이에서 함께 인쇄됩니다. OnBuks는 결국 더 많을 수 있습니다. 계산해 보겠습니다. 하지만 OnTiki가 대기열에서 계속 진행되도록 허용한 이유는 분명하지 않습니다. 아니면 각 OnTik이 OnBuk에 해당하지 않습니까?

이해했다.

음, 여전히 근처에 OnBook이 많이 있습니다. 이러한 로그로는 어떤 결론도 내리기가 어렵습니다.

 
Roman :

비동기 주문을 사용하고 있다고 썼습니까?
흥미로워졌습니다. 트랜잭션 실행을 제어하는 알고리즘은 무엇입니까?

OnTradeTransaction() + 함수에서 오랫동안 서버 응답이 없으면 확인합니다.

일반적으로 마법에.

각 심볼마다 어드바이저 설치 시 65535 매직을 예약하고,

주문을 보낼 때 고유한 마법을 할당합니다.

다른 악기와 겹치지 않습니다.

이것이 내가 심볼에 초기 마법을 할당하는 방법입니다.

 //+------------------------------------------------------------------+
//|                                                    AutoMagic.mqh |
//|                                 Copyright 2017-2018 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//version   "1.01
ulong symb_magic;
//-------------------------------------------------------------------+
// Split string function                                             |
//+------------------------------------------------------------------+
string SplitString( const string a_str, ulong &a_month, ulong &a_year)
  {
   int str_size= StringLen (a_str);
   int str_tire= StringFind (a_str, "-" );
   int str_tochka= StringFind (a_str, "." , str_tire);
   if ((str_tire> 0 ) && (str_tochka> 0 ) &&(str_size > 0 ))
     {
      a_month= ulong ( StringToInteger ( StringSubstr (a_str,str_tire+ 1 ,str_tochka-str_tire- 1 )));
      a_year = ulong ( StringToInteger ( StringSubstr (a_str,str_tochka+ 1 ,str_size-str_tochka- 1 )));
       if ((a_month > 0 ) && (a_year > 0 )) return ( StringSubstr (a_str, 0 , str_tire));
     }
   return ( "" );
  }
//-------------------------------------------------------------------+
// Get Magic function                                                |
//+------------------------------------------------------------------+
ulong GetMagic( const string a_symbol)
{
  symb_magic = 0 ;
   if ( SymbolSelect ( Symbol (), true ) == false )
  {
     Print ( __FUNCTION__ , ": Нет такого символа!" );
     return ( 0 );
  }
   ulong month = 0 ;
   ulong year = 0 ;
   string new_str = SplitString(a_symbol,month,year);
   if ( StringLen (new_str)> 0 )
  {
     uchar char_array[];
     int result= StringToCharArray (new_str,char_array, 0 , WHOLE_ARRAY , CP_ACP );
     if (result> 0 )
   {
     ulong value;
     for ( int i = 0 ; i < result - 1 ; i++)
     {
       value= ulong (char_array[i]);
       value<<=( 56 -(i* 8 ));
       symb_magic += value;
     }
     month<<= 24 ;
     symb_magic += month;
     year<<= 16 ;
     symb_magic += year;
     return (symb_magic);
   }
 }
   return ( 0 ); 
}
//-------------------------------------------------------------------+
// Is my magic function                                              |
//+------------------------------------------------------------------+
bool IsMyMagic( const ulong m_magic)
{
   if (m_magic > 0 )
  {
     ulong stored_magic=symb_magic;
    stored_magic>>= 16 ;
     ulong in_magic = m_magic;
    in_magic>>= 16 ;
     if (in_magic == stored_magic) return ( true );
  }  
   return ( false );
}
//-------------------------------------------------------------------+
// Get stored magic function                                         |
//+------------------------------------------------------------------+
ulong GetStoredMagic()
{
   if (symb_magic > 0 ) return (symb_magic);
   return ( 0 );  
}
//+------------------------------------------------------------------+

매직 - ulong(8바이트) N-p

GAZR-3.12

바이트[7](상위 바이트) - "G"

바이트[6] - "A"

바이트[5] - "Z"

바이트[4] - "R"

바이트[3] - "3"

바이트[2] - "12"

Byte[1] 및 Byte[0] - 마술사를 위한 예약(65535)

주문을 보낼 때 마법을 정렬하는 방법은 다음과 같습니다.

  mem_magic = magic_storage + 1 ;
   if (magic_storage >= (magic_number + 65530 )) mem_magic = magic_number;

그러나 이것은 심볼 이름이 표준화 되어 있기 때문에 FORTS에서만 작동합니다!

추가됨

주문이 성공적으로 전송되면

시간을 기억

   if ( OrderSendAsync (request, result) == true )
  {
     if ((result.retcode == TRADE_RETCODE_PLACED ) || (result.retcode == TRADE_RETCODE_DONE )) 
    {
      req_id = result.request_id;
      magic_storage = mem_magic;
      state = ORD_DO_SET;
      mem_time = GetMicrosecondCount ();
      mem_start_time = TimeCurrent ();
      SetTransCount();
    }
     else
    {
      mem_magic = 0 ;
      mem_time = 0 ;
      mem_start_time = 0 ;
      CheckError(result.retcode, "Place: Ордер не установлен! Причина: " , order_status, ticket);
    }
  }
mem_time = GetMicrosecondCount (); - для проверки времени задержки OnTradeTransaction
mem_start_time = TimeCurrent ();   - для сужения рамок поиска в истории

그런 다음(OnTradeTransaction에 응답이 없는 경우)

ticket = FindOrderBuyMagic(mem_magic, start_time);

글쎄, FindOrderBuyMagic 함수 자체

 #define TIME_DELAY     180
 //+------------------------------------------------------------------+
// Expert Find order Buy Magic function                              |
//+------------------------------------------------------------------+
ulong FindOrderBuyMagic( const ulong a_magic, const datetime set_time)
{
   if (a_magic > 0 )
  {
     if (IsMyMagic(a_magic) == true )
    {
       ulong cur_ticket = 0 ;
       for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
      {
        cur_ticket = OrderGetTicket (i);
         if ( OrderSelect (cur_ticket))
        {
           if ( ulong ( OrderGetInteger ( ORDER_MAGIC )) == a_magic) return (cur_ticket);
        }  
     }
      cur_ticket = 0 ;
       datetime start_time = datetime ( ulong (set_time) - TIME_DELAY);
       datetime end_time = datetime ( ulong ( TimeCurrent ()) + TIME_DELAY);    
       if ( HistorySelect (start_time, end_time))
      {
         for ( int i = HistoryOrdersTotal () - 1 ; i >= 0 ; i--)
        {
          cur_ticket = HistoryOrderGetTicket (i);
           if ( ulong ( HistoryOrderGetInteger (cur_ticket, ORDER_MAGIC )) == a_magic) return (cur_ticket);
        }
      }
    }
  }
   return ( 0 );
}

추가됨

Automagic의 "For good"에서는 첫 번째 바이트에 어드바이저 식별자 (0-255)를 추가해야 합니다.

하지만 저는 아직 필요없어서 하지 않았어요 :)

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
prostotrader :

OnTradeTransaction() + 함수에서 오랫동안 서버 응답이 없으면 확인합니다.

팁 고마워.

 
prostotrader :

1. 2차 이후부터는 브로커에서 단말기가 지급되며, 주식(주식포트폴리오 )만 매매하는 전략은 없습니다.

2. 누적된 GetMicrosecondCount ()를 표시하려는 경우

OnDeinit()에서 타이머 없이 수행하면 EA가 종료될 때 모든 것이 인쇄됩니다.

plz는 개인 계정에서 할 수 있는 브로커에 대한 링크를 던집니다.

흥미로운 스레드... :-)

 
Igor Makanu :

네트워킹의 세계에 오신 것을 환영합니다

관리자로 실행하는 가장 쉬운 방법: Netstat - a -b

당신은 포트와 소프트웨어를 볼 수 있습니다, 나는 주위를 찌르고 싶지 않지만 MT5 서버는 터미널이 이미 필요한 "선반"에 넣은 다른 정보로 패킷을 비동기적으로 구동한다고 생각합니다.

추신: 한 번에 많은 양을 출력할 경우 Print() 및 인쇄 누락에 대해? - 파일에 정보를 기록하십시오 - 모든 것을 순서대로 저장하되 닫기 전에 파일을 닫는 것을 잊지 마십시오. 이론상으로는 파일의 로그에 있는 Print()가 완료되어야 하는데 확인을 해보지 않았고 일반적으로 많은 데이터가 표시되면 신뢰가 가지 않습니다. https://www.mql5.com/ru/forum/329730 여기에서 논의 , 매우 자주 "누락 된 지문"이 논의됩니다))) - 검색

Igor, 로그 파일을 여는 것을 생각하지 않은 사람들 사이에서 인쇄물의 손실이 논의됩니다. Rinat Fatkullin 자신은 로그 파일에서 손실되는 것이 없다고 백 번 썼습니다. 그러나 귀하의 게시물이 헛되지 않도록 :) 출력을 별도의 파일에 추가했습니다. 또한 두 번째 파일도 만들어 약간 다르게 출력했습니다(CArrayObj에 모든 이벤트 누적). 두 개의 어레이를 주문하는 내 디자인의 예. 두 개의 배열에서 모든 것을 CArrayObj로 밀어 넣은 다음 마이크로초로 정렬하고 Tick 또는 Book 이벤트의 종류를 메모와 함께 출력합니다.

그리고 예, 여기에 포트가 있습니다. 무엇을 줄 것입니까? Expert Advisor의 이벤트 대기열을 테스트 중입니다. 틱이 도착하면 OnTick과 해당 OnBook의 두 가지 이벤트가 생성되어야 하며 OnTick은 항상 대기열에 있으며 OnTick은 대기열에 이미 OnTick이 있는 경우 ( 매뉴얼에서와 같이) 사라질 수 있습니다. OnTicks가 OnBooks 없이 차례로 진행되는 상황은 1. OnTics가 "순차를 벗어남" 2. OnBuk의 시스템 지연이 있는 경우에만 가능합니다. 동료에 의해 식별됩니다. 하루에 2배 이상의 OnBook이 있지만 왜 뒤처져 있습니까? 이 지연이 패킷의 비동기화 및 정렬로 인한 것이라면 가능하지만 지금까지는 Expert Advisor로서 수입 사실만 확인하고 있습니다. 나머지 뉘앙스를 고려하여 항의하는 방법, 나는 아직 그것에 대해 생각하지 않았습니다.

다음은 새 코드입니다. 열 때 작업의 정확성을 테스트하고 하루 동안 실행할 것입니다.

추신 그 이유는 다음과 같을 수 있습니다. Tick이 오더북을 변경하지 않고 동일한 가격으로 전달된 경우 - OnBook이 형성되지 않습니까? 나는 주식 거래 전문가가 아닙니다. 나는 OnTick이 항상 OnBook을 호출한다고 생각했습니다 .

 //+------------------------------------------------------------------+
//|                                                   TestOnBook.mq5 |
//|                                           Copyright 2019, Allex@ |
//|                                                 alex-all@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Allex@"
#property link        "alex-all@mail.ru"
#property version    "1.00"
#include <Allex\Logger.mqh>
#include <Arrays\ArrayObj.mqh>
//---
bool is_book;
enum ENUM_BOOK_OR_TICK
{
        USE_BOOK,       // Use OnBookEvent
        USE_TICK         // Use OnTick
};
class CMcsOn: public CObject
{
public :
ulong mcs;
ENUM_BOOK_OR_TICK Ontype;
CMcsOn( ulong m, ENUM_BOOK_OR_TICK t):mcs(m),Ontype(t){};
int        Compare( const CObject*Object, const int mode= 0 ) const
     {
       const CMcsOn* obj1= dynamic_cast < const CMcsOn*>(Object);
      CMcsOn* obj=(CMcsOn*)(obj1);
       if (!obj) return 0 ;
       return (mcs-obj.mcs);
      }
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
input int    SecForPrint =   3600 ;
//---
ulong TimeArrayBook[ 65536 ];
ulong TimeArrayTick[ 65536 ];
ushort curBook,curTick;
ulong   DelaySum= 0 ,DelayCount= 0 ,CountOnBook= 0 ,CountOnTick= 0 ;
int delay,delayMax= 0 ;
CLogger* Logger,*Logger2;
CArrayObj ArrayObj;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
{
   curBook= 0 ;
   curTick= 0 ; 
   DelaySum= 0 ;DelayCount= 0 ;CountOnBook= 0 ;CountOnTick= 0 ;delayMax= 0 ;
   ArrayInitialize (TimeArrayBook, INT_MAX );
   ArrayInitialize (TimeArrayTick, INT_MAX );
   Logger=CLogger::GetLogger();
   Logger2= new CLogger();
   Logger.SetSetting( __FILE__ + "\\" , Symbol ()+ "_" + EnumToString ( Period ())+ "_" + TimeToString ( TimeCurrent (), TIME_DATE ));  
   Logger2.SetSetting( __FILE__ + "\\" , "Alt_" + Symbol ()+ "_" + EnumToString ( Period ())+ "_" + TimeToString ( TimeCurrent (), TIME_DATE ));  
   if (Mode == USE_BOOK) is_book = MarketBookAdd ( Symbol ());
  ArrayObj.Shutdown();
   if ( EventSetTimer (SecForPrint) &&  Logger.Init() && Logger2.Init()) 
   return ( INIT_SUCCEEDED );
   else return ( INIT_FAILED );
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
{
   if (Mode == USE_BOOK)
  {
     if (is_book == true ) MarketBookRelease ( Symbol ());
  }  
   delete Logger;
   delete Logger2;
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent ( const string &symbol)
{  
  TimeArrayBook[curBook++]= GetMicrosecondCount ();
  CountOnBook++;
   //Print(__FUNCTION__, " ",curBook);
}
void OnTick ()
{
  TimeArrayTick[curTick++]= GetMicrosecondCount ();
  CountOnTick++;
   //Print(__FUNCTION__, " ",curTick);

}
//+------------------------------------------------------------------+
void OnTimer ()
  {
   string out= NULL ;
   int total= MathMax (curBook,curTick);
   int i= 0 ,k= 0 ;
   while (i<total)
     {
       while (i<total && TimeArrayBook[i]<TimeArrayTick[k] )
        {
          MyPrint( "Book " +TimeArrayBook[i++]);
        }    
       if (k<curTick- 1 )
        {
         if (i<total)
          {
           delay=TimeArrayBook[i]-TimeArrayTick[k];
           if (delay>delayMax) 
            delayMax=delay;
           if (delay> 0 )
              {
                 DelaySum+=delay;
                 DelayCount++;
              }
          }
         MyPrint( "Tick " +TimeArrayTick[k++]+ " delay mcs " +delay);
        }       
        i++;
     }
     if (curTick> 0 )
     {
     MyPrint( "Tick " +TimeArrayTick[curTick- 1 ]+ " last" );
     string out= "Count Event Book after Tick " +DelayCount+ ". Delay Average " + DoubleToString (DelaySum/DelayCount, 2 )+ ". Max " +delayMax+ " OnBooks " +CountOnBook+ " OnTicks " +CountOnTick;
     MyPrint (out);
     Comment (out);
     }
     Logger.Logger();
     Alt();
     curBook= 0 ;
     curTick= 0 ;
  }
//---
void MyPrint( string out)  
{
   Print (out);
   Logger.Log( __FUNCTION__ ,out, 2 , false );
}
//---
void Alt()
{
int last=ArrayObj.Total();
for ( int i= 0 ;i<curBook;i++)
  {
   if (!ArrayObj.Add( new CMcsOn(TimeArrayBook[i],USE_BOOK)))
      Logger2.Log( __FUNCTION__ , "Error Book Add" , 0 );   
  }
for ( int i= 0 ;i<curTick;i++)
  {
   if (!ArrayObj.Add( new CMcsOn(TimeArrayTick[i],USE_TICK)))
      Logger2.Log( __FUNCTION__ , "Error Tick Add" , 0 );   
  }
  ArrayObj.Sort();
   int total=ArrayObj.Total();
  total-=last;
  CMcsOn*Obj;
   for ( int i= 0 ;i<total;i++)
    {    
     Obj=ArrayObj.At(i);
     if ( CheckPointer (Obj)== POINTER_INVALID )
      { Logger2.Log( __FUNCTION__ , "Error At Array" , 0 ); continue ;}
       string out = Obj.USE_BOOK ? "Book " : "Tick " ;
      out+= Obj.mcs  ;
      Logger2.Log( __FUNCTION__ ,out, 2 );
    }
   Logger2.Log( "ArrayObj_" , "Last " +last+ " total " +ArrayObj.Total(), 1 );  
   Logger2.Logger();
   //ArrayObj.Shutdown(); 
}
 
prostotrader :
하지만 topikstarter가 그의 질문에 대한 답변에 만족하는지 궁금합니다.

나는 이미 모든 답변을 받았고 스스로 결론을 내렸습니다.
거래 가격, 실현 거래량 등 고정된 기간 동안의 거래 피드를 분석해야 합니다.
또한 전략 테스터 에서 알고리즘의 작동을 시뮬레이션해야 합니다.
OnTick 이벤트는 이것을 완벽하게 처리하는데, 실제 거래 결과와 테스터의 시뮬레이션 결과는 나를 만족시키는 작은 오류로 수렴됩니다.
거래 피드에 대한 더 빠른 분석이 필요한 경우 OnTimer를 사용할 수 있습니다.

그리고 터미널에 오는 모든 틱이 OnBook으로 이동해야 하는 것은 아닙니다. 이것은 시장 주문 실행의 세부 사항입니다.

 
Vladimir Mikhailov :


그리고 터미널에 오는 모든 틱이 OnBook으로 이동해야 하는 것은 아닙니다. 이것은 시장 주문 실행의 세부 사항입니다.

반대로 OnTick 핸들러로 오는 각 틱 (이벤트)은 OnBook과 동기화되어야 합니다.
보세요, OnTick 핸들러에는 세 가지 이벤트, 최고 입찰가 변경, 최고가 변경 및 거래(마지막)가 있습니다.
거래가 없는 매수호가나 매도호가가 바뀌면 이벤트가 되고 이러한 이벤트가 온틱에 옵니다.
또한 OnBuk은 이러한 이벤트, 자체 이벤트, 해당 핸들러만 포착해야 합니다. 그렇지 않으면 핸들러 간에 입찰 요청 가격에 불일치가 발생합니다.

그리고 마지막 이벤트가 OnTick에 오면 거래가 통과된 것입니다.
거래 후 주문장에서 밴드의 가격이나 거래량이 변경되기 때문에 거래는 OnBook에서 이벤트를 생성합니다.
악순환이 됩니다.

OnTick과 OnBook에는 모두 최고 입찰가와 최고 입찰가 이벤트가 있습니다.
이러한 이벤트는 두 처리기 모두에서 항상 동기식이어야 합니다.
그리고 마지막 이벤트 자체는 거래 후 OnBook에서 이벤트를 생성합니다.
따라서 OnTick 핸들러에 발생하는 모든 이벤트는 OnBook에 동기적으로 반영되어야 합니다.

사유: