일반 클래스 라이브러리 - 버그, 설명, 질문, 사용 기능 및 제안 사항 - 페이지 11

 

오늘 그리고 아마도 이번 주에 대한 마지막 예: 거래 번호와 거래를 시작한 주문 번호 간의 대응:

 //+------------------------------------------------------------------+
//|                                                     OrdersID.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version    "1.00"
#include <Generic\HashMap.mqh>
input ulong FindTicketOrder = 82479995 ;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{
   ulong tiks = GetMicrosecondCount ();
   HistorySelect ( 0 , TimeCurrent ());
   CHashMap< ulong , ulong > deals_orders;
   int total = HistoryDealsTotal ();
   ulong deal_id = 0 ;
   for ( int i = 0 ; i < total; i++)
   {
      deal_id = HistoryDealGetTicket (i);
       ulong order_id = HistoryDealGetInteger (deal_id, DEAL_ORDER );
      deals_orders.Add(deal_id, order_id);
   }
   ulong t2 = GetMicrosecondCount ()-tiks;
   printf ( "Время заполнения коллекции: " + ( string )t2 + " микросекунд" );
   tiks = GetMicrosecondCount ();
   ulong find_order = 0 ;
   if (deals_orders.TryGetValue(deal_id, find_order))
       printf ( "Сделке с номером " + ( string )deal_id + " Соответствует ордер с номером " + ( string )find_order);
   ulong delay = GetMicrosecondCount () - tiks;
   printf ( "Время выполнения запроса: " + ( string )delay + " микросекунд" );
}

제 경우에는 계정에 10,000건 이상의 거래가 있는 경우 결과는 다음과 같습니다.

 2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время заполнения коллекции: 145865 микросекунд
2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Сделке с номером 44455231 Соответствует ордер с номером 83473421
2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
 

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

일반 클래스 라이브러리 - 버그, 설명, 질문, 사용법 및 제안

바실리 소콜로프 , 2017.12.08 13:30

N이 매우 작으면 해시 함수로 얻은 숫자를 정규화하여 항상 N의 한계에 있도록 합니다.

int index = GetHashCode(word) % ArraySize (m_array);

여기까지 읽었습니다. Vasily, 감사합니다. 강조 표시된 부분을 제외하고 모든 것이 명확합니다. 제 생각에는 나머지를 정규화로 취하는 것은 잘못된 것입니다. 그게 더 논리적으로 보입니다.

 int index = GetHashCode(word) * ArraySize (m_array) / HashSize ; // Надо бы и округлять, а не отбрасывать нецелочисленную часть, но не стал усложнять
 
바실리 소콜로프 :

문제는 사전의 크기를 알 수 없는 경우가 많다는 것입니다. 간단한 예를 들어 Expert Advisor가 있다고 가정해 보겠습니다. 완료된 거래를 추적합니다. 거래가 역사에 나타난 후에는 이 거래를 전문가의 마법과 연관시켜야 합니다. 이를 위해 사전을 사용하는 것이 논리적입니다. 거래번호를 키로 사용하고(고유식별자) 전문가의 매직넘버를 값으로 사용하는 경우. 문제는 어드바이저를 시작할 때 100개의 트랜잭션이 있는지, 1000개 또는 전혀 없는지 여부를 미리 결정하는 것이 불가능하다는 것입니다. 미리 할당한 메모리의 양에 관계없이 여전히 너무 적거나 너무 많습니다.

명백하게 나는 나의 두뇌를 완전히 망가뜨리지 않았다. 강조 표시된 부분을 설명할 수 있습니까? 나는 전혀 이해하지 못한다.

 

조롱같다

 //+------------------------------------------------------------------+
//| Returns a hashcode for boolean.                                  |
//+------------------------------------------------------------------+
int GetHashCode( const bool value )
  {
   return ( ( value )? true : false );
  }


포함하지 않은 HashFunction.mqh. 이것은 잘못된 것입니다.


이 기능의 용도는 무엇입니까?

 template < typename T>
int GetHashCode(T value)
  {
//--- try to convert to equality comparable object  
   IEqualityComparable<T>*equtable= dynamic_cast <IEqualityComparable<T>*>(value);
   if (equtable)
     {
       //--- calculate hash by specied method   
       return equtable.HashCode();
     }
   else
     {
       //--- calculate hash from name of object
       return GetHashCode( typename (value));
     }
  }
결국 struct와 union의 경우 컴파일이 쉽지 않을 것입니다.
 
fxsaber :

명백하게 나는 나의 두뇌를 완전히 망가뜨리지 않았다. 강조 표시된 부분을 설명할 수 있습니까? 나는 전혀 이해하지 못한다.

개인적으로 딜을 할 때 어드바이저가 매직넘버를 딜넘버에 따라 사전(배열)에 적어줘야 하는데, 이 경우에는 셀 인덱스라고 이해했습니다.

미래의 거래 수는 미리 알 수 없으며 마법을 기록하려면 이미 배열이 선언 되어 있어야 합니다. 작업은 사전에 어레이에 필요한 메모리 양을 할당하는 것입니다.

정확한 양의 메모리를 미리 할당하는 것은 불가능합니다. 이것은 당신이 문자열에 마법을 쓰고, 마지막에 부분 문자열의 수를 얻고, 배열을 초기화하고, 거기에 모든 부분 문자열(마법)을 쓸 수 있다는 것을 의미합니다.

또한 각 매직에 대한 접근은 거래 건수로 이루어진다.

제가 그리는 방식은 대략 그렇습니다.

 
바실리 소콜로프 :

오늘 그리고 아마도 이번 주에 대한 마지막 예: 거래 번호와 거래를 시작한 주문 번호 간의 대응:

제 경우에는 계정에 10,000건 이상의 거래가 있는 경우 결과는 다음과 같습니다.

그리고 귀하의 경우 클래식 버전은 얼마를 반환합니까?

 ulong GetDealOrder( const ulong Deal )
{
   return ( HistoryDealSelect (Deal) ? HistoryDealGetInteger (Deal, DEAL_ORDER ) : 0 );
}


 2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
이것은 printf 의 런타임입니다.
 
fxsaber :

이 기능의 용도는 무엇입니까?

결국 struct와 union의 경우 컴파일이 쉽지 않을 것입니다.

다른 오버로드 추가됨

 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }


직면했다

 //+------------------------------------------------------------------+
//| Returns a hashcode for string.                                   |
//+------------------------------------------------------------------+
int GetHashCode( const string value )
  {
   int len=StringLen( value );
   int hash= 0 ;
//--- check length of string
   if (len> 0 )
     {
       //--- calculate a hash as a fucntion of each char
       for ( int i= 0 ; i<len; i++)
         hash= 31 *hash+ value [i];
     }
   return (hash);
  }
이 코드에서 논리적으로 뒤따르는 음수를 반환합니다. 이건 괜찮아?
 
fxsaber :

다른 오버로드 추가됨

 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }

저 같은 경우 객체가 특정 인터페이스나 메소드를 구현하지 않으면 조용히 은폐하는 것보다 명시적으로 예외를 던지는 것이 더 낫고, 문제의 원인을 얼마나 찾아봐야 할지 막막합니다.


이 코드에서 논리적으로 뒤따르는 음수를 반환합니다. 이건 괜찮아?

절대적으로 정상입니다.
해시는 당신에게 아무 것도 보장하지 않으며, 이것은 특정 범위 내에서 이것 또는 그 객체를 특징짓는 숫자일 뿐입니다.
정수가 필요한 경우 - 자유롭게 uint를 사용하십시오.

 
세르게이 주블리크 :

저 같은 경우 객체가 특정 인터페이스나 메소드를 구현하지 않으면 조용히 은폐하는 것보다 명시적으로 예외를 던지는 것이 더 낫고, 문제의 원인을 얼마나 찾아봐야 할지 막막합니다.

MqlTick ?

 
fxsaber :

MqlTick ?


T 유형에 대한 GetHashCode 템플릿 함수 전문화를 명시적으로 구현 하지 않은 경우 코드가 수행하는 작업을 이해하고 있습니까?
 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }
답변: 구현 부족 문제가 숨겨져 있기 때문에 더러운 속임수입니다. 동일한 클래스의 모든 객체는 동일한 해시 값을 반환합니다.