매직넘버 생성

 
/**
* create a positive integer for the use as a magic number.
*
* The function takes a string as argument and calculates
* an 31 bit hash value from it. The hash does certainly not 
* have the strength of a real cryptographic hash function 
* but it should be more than sufficient for generating a
* unique ID from a string and collissions should not occur.
*
* use it in your init() function like this: 
*    magic = makeMagicNumber(WindowExpertName() + Symbol() + Period());
*
* where name would be the name of your EA. Your EA will then
* get a unique magic number for each instrument and timeframe
* and this number will always be the same, whenever you put
* the same EA onto the same chart.
*
* Numbers generated during testing mode will differ from those
* numbers generated on a live chart.
*/
int makeMagicNumber(string key){
   int i, k;
   int h = 0;
   
   if (IsTesting()){
      key = "_" + key;
   }
   
   for (i=0; i<StringLen(key); i++){
      k = StringGetChar(key, i);
      h = h + k;
      h = bitRotate(h, 5); // rotate 5 bits
   }
   
   for (i=0; i<StringLen(key); i++){
      k = StringGetChar(key, i);
      h = h + k;
      // rotate depending on character value
      h = bitRotate(h, k & 0x0000000F);
   }
   
   // now we go backwards in our string
   for (i=StringLen(key); i>0; i--){   
      k = StringGetChar(key, i - 1);
      h = h + k;
      // rotate depending on the last 4 bits of h
      h = bitRotate(h, h & 0x0000000F); 
   }
   
   return(h & 0x7fffffff);
}

/**
* Rotate a 32 bit integer value bit-wise 
* the specified number of bits to the right.
* This function is needed for calculations
* in the hash function makeMacicNumber()
*/
int bitRotate(int value, int count){
   int i, tmp, mask;
   mask = (0x00000001 << count) - 1;
   tmp = value & mask;
   value = value >> count;
   value = value | (tmp << (32 - count));
   return(value);
}
 
7bit :
[ ... 해시 함수 ... ]

기록을 위해 fbj는 잘 알려진 djb2 해시 기능을 사용하여 유사한 작업을 한 번 수행했습니다. https://www.mql5.com/en/forum/120034/page2

 
나는 처음에 이 http://www.cs.hmc.edu/~geoff/classes/hmc.cs070.200101/homework10/hashfuncs.html에서 영감을 얻었습니다. 특히 CRC 변형(djb2와 매우 유사)으로 레이블이 지정된 것 . 이 해시만으로는 충돌을 쉽게 생성할 수 없었지만 충분한 확신을 갖지 못했고 때로는 두 개의 유사한 문자열의 해시 간에 약간의 비트만 차이가 났습니다. 그래서 나는 h의 다양한 회전으로 그것의 3가지 변형을 만들고 3개의 모든 하위 해시를 함께 추가했습니다. 그들 중 하나가 충돌하면 완전히 다른 방식으로 계산된 다른 두 가지가 있습니다. 이제 입력 문자열에서 변경된 모든 비트는 해시의 모든 비트 중 절반 이상을 변경하고 모든 비트는 완전히 무작위로 보입니다.


위의 링크에서 언급한 djb2는 수백 줄의 라인 없이 다음과 같이 간단하게 작성할 수 있습니다.
 int djb2( string key){
   int i, h, k;
   for (i= 0 ; i< StringLen (key); i++){
      k = StringGetChar(key, i);
      h = (h << 5 ) + h + k;
   }
   return (h);
}
 
7bit :
위의 링크에서 언급한 djb2는 수백 줄의 줄 없이 다음과 같이 간단하게 작성할 수 있습니다. [...]

저는 특히 djb2는 고사하고 해시 알고리즘의 전문가는 아니지만 해시 값(귀하의 버전에서 h 변수)을 5381로 초기화하는 것이 중요한 것으로 간주된다는 것을 기억하는 것 같습니다. 하지만 아무도 그 이유를 정확히 모릅니다.

 
*    magic = makeMagicNumber(name+ Symbol() + Period());
대충 짚고 넘어가려는 것은 아니지만 다음과 같은 방법도 사용할 수 있어야 합니다.
*    magic = makeMagicNumber(WindowExpertName() + Symbol() + Period());
코드(및 해시 문서!)를 게시해 주셔서 감사합니다.

질문 - 같은 차트, 같은 알고리즘 등에서 여러 주문을 열고 닫는 방법을 연구하고 있습니다.

2단계로 접근하고 있습니다.

1) 기본 MN(위 코드가 수행하는 것처럼 보임)을 정수로 생성합니다. 기본은 항상 각 차트/기호/기간에 대해 동일합니다.
2) 접미사가 사용되지 않으면 다시 사용할 수 있게 하는 각 특정 주문 전송에 대해 소수점으로 표시된 특정 접미사 생성

따라서 MN은 XXXXXX.YYY가 됩니다. 여기서 X는 기본이고 Y는 특정 접미사입니다. 접미사는 .001에서 시작하여 각각의 새 전송에 대해 .001씩 증가합니다. 각 주문 전송에서 현재 사용되지 않는 가장 낮은 접미사를 할당합니다. 이렇게 하면 기본 MN을 재생성하고 접미사를 순환하여 나중에 MN을 검색할 수 있습니다.

조금 지나치게 복잡해 보입니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

완성되면 제가 가지고 있는 것을 포스팅합니다.
 
NuB로서 왜 '암호화된' MagicNumber를 원하거나 필요로 하는지 잘 모르겠습니다.
저는 EA # 버전에 처음 5개의 숫자를 사용하고 거래되는 시간(분)에 마지막 4개의 숫자를 사용합니다.
 
FourX :
NuB로서 왜 '암호화된' MagicNumber를 원하거나 필요로 하는지 잘 모르겠습니다.
저는 EA # 버전에 처음 5개의 숫자를 사용하고 거래되는 시간(분)에 마지막 4개를 사용합니다.

귀하의 예에서 Symbol()은 어떻게 MN의 일부가 될까요? EA 번호와 Timeframe 번호가 있지만 기호는 어떻습니까?

나는 MN으로만 내 주문을 식별하고 주문 목록에 대한 내 루프는 OrderMagicNumber()만 비교하므로 귀하의 주문은 기호 이름도 확인해야 합니다. 주문 목록과 관련된 작업을 수행하는 몇 가지 다른 독립 스크립트가 있습니다. 예를 들어 EA의 주식 플롯을 그리거나 거래를 다른 플랫폼으로 복사하는 경우 모두 특정 쌍에서 특정 EA의 거래를 식별하기 위해 매직 넘버만 있으면 됩니다. 특정 기간.

나는 다른 EA에 일련 번호를 전혀 사용하지 않고 모든 EA에 4-5자의 짧은 이름을 사용합니다. 예를 들어 snowball.mq4라는 EA는 "snow"라는 이름을 갖게 됩니다. 이것은 코드에 고정되어 있으며 절대 변경되지 않습니다. 주문 댓글 에도 이 짧은 이름을 사용합니다.

그래서 저는 3가지가 있습니다: 짧은 이름, 기호 및 기간. 이것을 MN으로 변환하는 가장 편리한 방법은 해시입니다. 이름 대신 EA에 숫자를 지정할 수는 있지만 기호 이름을 숫자로 변환하는 쉬운 방법은 여전히 없습니다. 해시는 이러한 모든 문제를 한 번에 해결합니다.

 
FourX :
NuB로서 왜 '암호화된' MagicNumber를 원하거나 필요로 하는지 잘 모르겠습니다.
저는 EA # 버전에 처음 5개의 숫자를 사용하고 거래되는 시간(분)에 마지막 4개의 숫자를 사용합니다.

이것도 봐야 합니다 -> https://www.mql5.com/en/forum/120034


이 전체 접근 방식에 대한 문제는 때때로 동일한 계정에서 동일한 전문가/기호/기간을 실행한다는 것입니다. 그래서 결국에는 여전히 수동으로 무언가를 변경해야 하므로 마법 자체를 수동으로 설정하는 것을 선호합니다.

 
gordon :
이 전체 접근 방식에 대한 문제는 때때로 동일한 계정에서 동일한 전문가/기호/기간을 실행한다는 것입니다. 그래서 결국에는 여전히 수동으로 무언가를 변경해야 하므로 마법 자체를 수동으로 설정하는 것을 선호합니다.

초를 사용하는 것은 어떻습니까? TimeCurrent()는 항상 고유한 숫자를 반환합니다. 글쎄요, 적어도 해당 초 범위를 벗어나면..

- 전문가에게 GlobalVariable ID 번호를 할당하십시오. WindowExpertName()을 사용하여 반환합니다.

- 해당 ID를 증분 카운터(동일한 전문가를 첨부해야 함) 및 TimeCurrent()와 연결

- TimeCurrent()에 의해 반환된 숫자가 허용된 크기를 초과하는 경우. 그런 다음 일, 시간, 분 및 초의 계수를 얻을 때까지 년 및 월의 양을 버리십시오.

 
cameofx :

초를 사용하는 것은 어떻습니까? TimeCurrent()는 항상 고유한 숫자를 반환합니다. 글쎄요, 적어도 해당 초 범위를 벗어나면..

- 전문가의 ID 번호를 할당합니다. WindowExpertName()을 사용하여 반환합니다.

- 해당 ID를 증분 카운터 및 TimeCurrent()와 연결

- TimeCurrent()에 의해 반환된 숫자가 허용된 크기를 초과하는 경우. 그런 다음 일, 시간, 분 및 초의 계수를 얻을 때까지 년 및 월의 양을 버리십시오.

그 마법에 대한 지속성 수준을 유지해야하기 때문입니다. 터미널이 다시 시작되면 어떻게 됩니까? 마법이 달라졌을텐데...

 
gordon :

그 마법에 대한 지속성 수준을 유지해야하기 때문입니다. 터미널이 다시 시작되면 어떻게 됩니까? 마법은 다를텐데...

맙소사, 당신은 내 편집 속도를 능가했습니다 :)). 나는 그것을 편집했다. 그것은 GlobalVariable이라는 것을 언급하는 것을 잊었습니다.