실시간 틱 - 페이지 19

 
Yuriy Zaytsev :

옵션으로 Symbol()이 시간을 잡아먹는다는 두려움을 없애기 위해 두 핸들러가 같은 방식으로 "먹게" 합니다.

Symbol() 함수를 미리 정의된 변수 _Symbol로 바꿀 수 있습니다.

 

Symbol() 은 그것과 아무 관련이 없습니다. 로그에 정확한 시간이 표시됩니다.

이벤트 대기열 또는 SymbolInfo 함수의 지연.

내가 무슨 말을 했는지.


따라서 유리가 필요하면 OnBook에서 작업합니다. 필요하지 않은 경우 OnTick에서 작업합니다(대기열 및 추가 호출 없이).

두 방법 모두에 대한 최신 틱 기록을 얻는 가장 빠른 방법을 찾는 것이 남아 있습니다.

마지막 틱만 필요하다면 SymbolInfo가 더 낫다고 생각합니다. 공백 없는 기록이 필요한 경우 CopyTicks만 있으면 됩니다.

 
Andrey Khatimlianskii :

Symbol()은 그것과 아무 관련이 없습니다. 로그에 정확한 시간이 표시됩니다.

이벤트 대기열 또는 SymbolInfo 함수의 지연 .

내가 무슨 말을 했는지.

나는 Simbol이 많이 먹을 수 없다는 데 동의하지만 그는 약간의 기여를 할 수 있으며 테스트의 순수성을 위해 모든 도전 에 앞서 시간을 가져야 합니다.

대기열에 관해서는 - 나는 그런 순간에 관심이 있습니다 - 이상적인 조건에서 OnBuk이 동일한 OnTik보다 얼마나 뒤처질 수 있는지. 저것들. 구독이 이 기호에만 있는 경우 터미널에는 다른 항목 등이 로드되지 않고 원인이 무엇인지 알 수 있습니다.

지금까지는 문제가 대기열에만 있다는 데 동의할 수 없습니다. 핸들러가 아무 작업도 하지 않으면 5-6개의 OnBook 대기열이 문자 확인 작업보다 더 많이 소비하지 않아야 합니다.

모든 체크를 제거하는 동시에 동일한 틱에 대해 OnTick과 OnBuk 사이 에 무엇이 있는지 살펴봐야 합니다.

 void OnBookEvent ( const string &symbol)
{
ul=GetMicrosecondCount();  
   Print ( __FUNCTION__ , "; Time: " , ul, " mcs" );
}
void OnTick ()
{
ul=GetMicrosecondCount();  
   Print ( __FUNCTION__ , "; Time: " , ul, " mcs" );
}
//+--

up: 탐욕스러운 Print가 깨끗한 검사를 허용하지 않는다는 것이 분명해졌습니다. 왜냐하면. 인쇄 때문에 대기열이 길어집니다)

인쇄 없이 oolong 배열에 시간을 몰고 5분마다 한 번씩 모든 것을 인쇄, 나중에 코드로 출력하는 것이 필요합니다.

 

시작하는 코드를 확인하고 싶었습니다.

 //---
bool is_book;
enum ENUM_BOOK_OR_TICK
{
        USE_BOOK,       // Use OnBookEvent
        USE_TICK         // Use OnTick
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
input int    SecForPrint =   120 ;
ulong TimeArrayBook[ 65536 ];
ulong TimeArrayTick[ 65536 ];
ushort curBook,curTick;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
{
   curBook= 0 ;
   curTick= 0 ; 
   ArrayInitialize (TimeArrayBook, INT_MAX );
   ArrayInitialize (TimeArrayTick, INT_MAX );
   if (Mode == USE_BOOK) is_book = MarketBookAdd ( Symbol ());
   if ( EventSetTimer (SecForPrint)) 
   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 ());
  }  
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent ( const string &symbol)
{
  TimeArrayBook[curBook++]= GetMicrosecondCount ();
}
void OnTick ()
{
  TimeArrayTick[curTick++]= GetMicrosecondCount ();
}
//+------------------------------------------------------------------+
void OnTimer ()
  {  
   int total= MathMax (curBook,curTick);
   int i= 0 ,k= 0 ;
   while (i<total)
     {
       while (i<total && TimeArrayBook[i]<TimeArrayTick[k])
        {
           Print ( "Book " ,TimeArrayBook[i++]);
        }    
       if (k<curTick- 1 )
        {
         Print ( "Tick " ,TimeArrayTick[k++]);
        }       
        i++;
     }
     if (curTick> 0 ) Print ( "Tick " ,TimeArrayTick[curTick- 1 ], " last" );
     curBook= 0 ;
     curTick= 0 ;
  }
//---

그러나 어떤 이유로 나는 오프너의 데모 계정을 열 수 없습니다. 아마도 휴무 시간이거나 여전히 문제가 있습니까?



그런 다음 이벤트의 한 틱에서 정확히 비교하는 코드를 완료합니다.

 
Aleksey Mavrin :

시작하는 코드를 확인하고 싶었습니다.

그러나 어떤 이유로 나는 오프너의 데모 계정을 열 수 없습니다. 아마도 휴무 시간이거나 여전히 문제가 있습니까?



그런 다음 이벤트의 한 틱에서 정확히 비교하는 코드를 완료합니다.

그들의 웹사이트에서 열어야 합니다. 그런 다음 메일로 코드를 보냅니다.

 
Andrey Khatimlianskii :


마지막 틱만 필요하다면 SymbolInfo가 더 낫다고 생각합니다. 공백 없는 기록 이 필요한 경우 CopyTicks만 있으면 됩니다.

사실 선도시장(FORTS)은 "고유동성" 상품에서도 매우 약합니다.

, 적절한 가격 으로 매우 제한된 수 의 계약을 구매할 수 있으므로 가격뿐만 아니라

그러나 이 가격의 계약 수량은 매우 중요 합니다.


그리고 SymbolInfo는 이 가격의 볼륨을 제공하지 않습니다.

이와 관련하여 전체 주문서의 가격과 수량을 모두 제공하는 MarketBookGet ()을 사용해야 합니다.

그리고 MarketBookGet() 은 주문서 변경을 가져오기 위해 MarketBookAdd와 함께만 사용할 수 있습니다.

OnBookEvent에서. 물론 유리(MarketBookAdd)를 추가하고 OnTck() 에서 MarketBookGet()을 사용할 수 있습니다.

그러나 다른 DOM 변경 사항은 건너뜁니다( 대기 중인 주문 은 최상의 가격이 아닙니다).

사실, 당신은 "취해서" 들어오는 진드기의 유리를 만들 수 있지만 그것이 필요 합니까?

추가됨

그리고 OnTck()가 실행될 때 기록에서 틱을 얻을 수 있다는 데 동의하지 않습니다.

마지막 틱 시간을 기억하면 OnTck()가 실행될 때 틱을 얻을 수 있습니다.

새로운 틱이 실시간으로 왔습니다. OnTck()가 작동하면 즉시 계산했습니다. 즉, 이것은 기록이 아닙니다 .

 
Andrey Khatimlianskii :

두 방법 모두에 대한 최신 틱 기록을 얻는 가장 빠른 방법을 찾는 것이 남아 있습니다.


OnTick()을 사용하면 OnBook과 같거나 조금 더 빠릅니다(OnBook에는 엄청난 지연이 있지만)

여기에서 함수 실행 속도( 마이크로초 )를 테스트했습니다.

 2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       SymbolInfoTick : time = 2 mcs 2020.02 . 04 13 : 09 : 10.720 Bid= 1573.1 
2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       SymbolInfoDouble : time = 28 mcs ask = 1573.3
2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       SymbolInfoDouble : time = 33 mcs bid = 1573.1
2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       SymbolInfoDouble : time = 36 mcs last = 1573.4
2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       OnTick : time = 41 mcs 2020.02 . 04 13 : 09 : 10.720 Bid= 1573.1 
2020.02 . 04 13 : 09 : 13.101 Ticks_test (GOLD- 3.20 ,M1)       OnTick : time = 41 mcs 2020.02 . 04 13 : 09 : 00.328 Ask= 1573.3 
OnTick - имеется ввиду CopyTicks из OnTick

가장 빠른 SymbolInfoTick 이지만 이 함수에서는 틱에 볼륨을 넣지 않습니다!

참조

tick

[out]  Ссылка на структуру типа MqlTick , в которую будут помещены текущие цены и время последнего обновления цен.

즉, 시간과 가격 만 있고 볼륨은 없습니다.

 

거래소 악기(특히 FORTS의 경우)의 경우 가격이 중요할 뿐만 아니라,

하지만 여전히 이 가격 에 계약 수량 !

 

OnTick() 으로 유리 를 가져오려고 했습니다. "눈으로" 큰 지연이 명확하게 보입니다 !

 //+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link        "https://www.mql5.com"
#property version    "1.00"
//---
bool is_book;
MqlBookInfo BookInfo[];
int book_cnt;
struct MARKET_DATA
{
   double ask;
   long    ask_vol;
   double bid;
   long    bid_vol;
   double prev_ask;
   long    prev_ask_vol;
   double next_bid;
   long    next_bid_vol; 
};
MARKET_DATA m_data;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
{
  is_book = MarketBookAdd ( Symbol ());
   if (is_book == false )
  {
     Alert ( "No add book!" );
     return ( INIT_FAILED );
  }
   return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
{
   if (is_book == true ) MarketBookRelease ( Symbol ());
}
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
bool GetBook( const string a_symb, int &cnt)
{
  cnt = 0 ;
   if ( MarketBookGet (a_symb, BookInfo) == true ) //getBook )
  {
    m_data.ask = 0 ;
    m_data.ask_vol = 0 ;
    m_data.prev_ask = 0 ;
    m_data.prev_ask_vol = 0 ;
    m_data.bid = 0 ;
    m_data.bid_vol = 0 ;
    m_data.next_bid = 0 ;
    m_data.next_bid_vol = 0 ;
    cnt = ArraySize (BookInfo);
     if (cnt > 0 )
    {
       for ( int i = 0 ; i < cnt; i++)
      {
         if (BookInfo[i].type == BOOK_TYPE_BUY ) //Стакан агрегирован, т.е от наибольшего Sell к наименьшему Buy
        {
           if ((i + 1 ) <= (cnt- 1 ))
          {
            m_data.ask = BookInfo[i- 1 ].price;
            m_data.ask_vol = BookInfo[i- 1 ].volume;
            m_data.prev_ask = BookInfo[i- 2 ].price;
            m_data.prev_ask_vol = BookInfo[i- 2 ].volume;
            m_data.bid = BookInfo[i].price;
            m_data.bid_vol = BookInfo[i].volume;
            m_data.next_bid = BookInfo[i+ 1 ].price;
            m_data.next_bid_vol = BookInfo[i+ 1 ].volume;
             break ;
          } else break ;
        }
      }
       return ( true );
    }
  }
   return ( false );
}  
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
void OnTick ()
{
   if (GetBook( Symbol (), book_cnt) == true )
  {
     if (book_cnt >= 4 )
    {
       Print ( "Prev Sell: ask = " , m_data.prev_ask, " volume = " ,m_data.prev_ask_vol); 
       Print ( "Sell: ask = " , m_data.ask, " volume = " ,m_data.ask_vol);
       Print ( "Buy: bid = " , m_data.bid, " volume = " ,m_data.bid_vol);
       Print ( "Next Buy: bid = " , m_data.next_bid, " volume = " ,m_data.next_bid_vol);
    }  
  }
}
//+------------------------------------------------------------------+
 

무슨 일이야?

나는 이전에 trades와 level2가 각각 다른 데이터 구독이라고 썼습니다. 이들은 서로 다른 이벤트 핸들러입니다.
따라서 OnTick에서 거래를 호출하고 OnBook에서 볼륨이 있는 갱을 호출해야 합니다 .
그리고 OnBook 이벤트에서 거래를 호출하고 OnTick에서 갱을 호출하려고 합니다. 동시에 OnBuk이 거래에 더 빠를 것이라고 생각합니다.
그것은 더 빠르지 않을 것입니다. 이것은 각각 자체 데이터 스트림을 위해 설계된 두 개의 이벤트 핸들러를 비교하는 것입니다.
나는 이것이 모두 실험이라는 것을 이해하지만 두 개의 데이터 스트림(거래 및 레벨 2)이 오는 논리를 이해하지 못하면 이러한 OnTik 및 OnBuk 프로세서에서 끝없이 혼란에 빠질 것입니다.