#define EMPTYSTRING ""
#define EAIDMIN 1
#define EAIDMAX 21473
//+------------------------------------------------------------------+
//
int iMakeHash (string s1, string s2=EMPTYSTRING, string s3=EMPTYSTRING, string s4=EMPTYSTRING, string s5=EMPTYSTRING
,string s6=EMPTYSTRING, string s7=EMPTYSTRING, string s8=EMPTYSTRING, string s9=EMPTYSTRING, string s10=EMPTYSTRING)
{
/*
Produce 32bit string hash code from a string composed of up to TEN concatenated input strings.
WebRef: http://www.cse.yorku.ca/~oz/hash.html
KeyWrd: "djb2"
FirstParaOnPage:
" Hash Functions
A comprehensive collection of hash functions, a hash visualiser and some test results [see Mckenzie
et al. Selecting a Hashing Algorithm, SP&E 20(2):209-224, Feb 1990] will be available someday. If
you just want to have a good hash function, and cannot wait, djb2 is one of the best string hash
functions i know. it has excellent distribution and speed on many different sets of keys and table
sizes. you are not likely to do better with one of the "well known" functions such as PJW, K&R[1],
etc. Also see tpop pp. 126 for graphing hash functions.
"
NOTES:
0. WARNING - mql4 strings maxlen=255 so... unless code changed to deal with up to 10 string parameters
the total length of contactenated string must be <=255
1. C source uses "unsigned [char|long]", not in MQL4 syntax
//
Downside?
original code uses UNSIGNED - MQL4 not support this, presume could use type double and then cast back to type int.
*/
string s = StringConcatenate(s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);
int iHash = 5381;
int iLast = StringLen(s)-1;
int iPos=0;
while( iPos <= iLast ) //while (c = *str++) [ consume str bytes until EOS hit {isn't C concise!} ]
{
//original C code: hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
iHash = ((iHash << 5) + iHash) + StringGetChar(s,iPos); //StringGetChar() returns int
iPos++;
}
return(MathAbs(iHash));
}//iMakeHash()
//+------------------------------------------------------------------+
//
int iMakeExpertId ()
{
int i1a,i2a,i1b,i2b;
int iExpertId = EAIDMAX+1;
while(iExpertId<EAIDMIN || iExpertId>EAIDMAX)
{
i1a=TimeLocal(); i2a=GetTickCount();
Sleep(500);
i1b=TimeLocal(); i2b=GetTickCount();
MathSrand(iMakeHash(Symbol()
,DoubleToStr(Period(),Digits)
,DoubleToStr(i2a*WindowBarsPerChart()/Period(),Digits-1)
,DoubleToStr(WindowTimeOnDropped()/i2b,Digits+1)
,StringConcatenate(i2a/Period()
,Symbol()
,Period()
,i1a
,i2b*WindowBarsPerChart()/Period()
,i1b/WindowBarsPerChart()
,WindowTimeOnDropped()
)
)
);
iExpertId = MathRand(); //here, on 2nd rand call, is even btr (tests seem to say this...)
}
return(iExpertId);
}//iMakeExpertId()
daaaaamn... these results are when had diff EAIDMAX! Anyway, just can't get the staff these days 0 lol
/*test extract:
12:06:22 "EXPERT ID = "19736
12:06:21 "EXPERT ID = "16236
12:06:20 "EXPERT ID = "4633
12:06:19 "EXPERT ID = "26753
12:06:18 "EXPERT ID = "28286
12:06:16 "EXPERT ID = "23335
12:06:15 "EXPERT ID = "4036
12:06:14 "EXPERT ID = "12879
12:06:13 "EXPERT ID = "8095
12:06:08 "EXPERT ID = "7940
12:06:07 "EXPERT ID = "10700
12:06:06 "EXPERT ID = "24889
12:06:05 "EXPERT ID = "16055
12:06:04 "EXPERT ID = "12774
12:06:03 "EXPERT ID = "10058
12:06:02 "EXPERT ID = "29346
12:06:01 "EXPERT ID = "14624
12:06:00 "EXPERT ID = "18432
*/
int MagicNumber;int init(){// Unique sting id. string id =WindowExpertName()+Symbol()+Period();// If there isn't already a Global Variable with the id in wich search for the MagicNumber create it if(!GlobalVariableCheck( id)){
MagicNumber =WindowHandle(Symbol(),0);GlobalVariableSet( id, MagicNumber);}else// Just get the MagicNumber for the unique id{
MagicNumber =GlobalVariableGet( id);}}
我在这里错过了一些东西。如果我打开两个图表,例如USDJPY H1,并为每个图表添加一个EA实例,那么两个图表都使用神奇的数字9999033。
是的,这个选项不是内置的,因为我从来没有使用过它。区分两个独立图表的唯一可能性(我看到的)是在窗口手柄中加入哈希值......
但这样一来,你就失去了重新启动和关闭图表 的持久性,因此,可能会或将会因此而产生孤儿订单。
那么,MT终端应用程序是一个 "容器"--用一个hWnd表示<整个事情>吗?
是的,它是一个相当典型的MDI应用程序。有一个顶层窗口,它包含像工具栏、窗格和MDI客户端区域。后者包含每个图表,而每个图表实际上由两个窗口组成:一个容器,里面是绘图区。这些东西中的每一个都有自己的hWnd句柄。WindowHandle()函数 返回绘图区的句柄,因此使用GetParent()API调用三次,就可以得到顶级MT4窗口的hWnd。
我在下面使用,从来没有出现过重复的情况。同样的EA在多达10个[任何类型]的图表上。
我对交给哈希函数 的大量过剩的垃圾实际数据没有答案。我只是把包括厨房水槽在内的所有东西都塞了进去。也就是说,我不是数学专家......,只是敲敲打打,直到从未出现过重复的情况--即使在终端启动时有10个图表资料都是同一个EA......。
显然,我很想有一个更好的、更可描述的/ 有逻辑的方法......所以开始把它撕成碎片 :O)
我在下面使用,从来没有出现过重复的情况。同样的EA在多达10个[任何类型]的图表上。
我对交给哈希函数的大量过剩的垃圾实际数据没有答案。我只是把包括厨房水槽在内的所有东西都塞了进去。也就是说,我不是数学专家......,只是敲敲打打,直到从未出现过重复的情况--即使在终端启动时有10个图表资料都是同一个EA......。
显然,我很想有一个更好的、更可描述的/ 有逻辑的方法......所以开始把它撕成碎片 :O)
我喜欢它。特别是好的老的djb2哈希。
非常令人印象深刻的东西,伙计们 :)
MDI容器让我想起了<sigh>。
我还是要说,IMHO,魔法数字太重要 了,不能随意应用
我相信CB会确认,在重启时可预测的恢复是一个强大系统中极其重要的元素。
顺便说一句
-BB-
有了这段代码,如果平台关闭,EA就能识别自己的订单。它使用了全局变量,所以如果你想让EA对PC关机 "免疫",可以改写成使用文件 而不是全局变量。我也附上了一个例子,它在初始时间开仓,并在下一栏关闭,你可以在1M时间框架内加载专家,关闭metatrader,然后再次打开,只需等待下一栏,看看EA如何关闭订单。这还没有用多个图形来证明,也没有用多个订单来欺骗,但你怎么看?
我喜欢它。特别是好的老的djb2哈希。
谢谢 - 但我确实对makeexpertid中这样一个不知所云的编码感到羞愧......
现在还为时过早,但也许有人会发现其中的缺陷......如果它们存在的话
非常令人印象深刻的东西,伙计们 :)
MDI容器让我想起了<sigh>。
我还是要说,IMHO,魔法数字太重要了,不能随意应用
我相信CB会确认,在重启时可预测的恢复是一个强大系统中极其重要的元素。
顺便说一句
-BB-
我仍然说,IMHO,神奇的数字是太重要了,不能随意应用!
当然,BB,vip datums。我花了太多的时间试图发现一个独特的 基准,一个EA的多个实例可以使用。这个基准点必须是可重复的,这样所有打开的文件在恢复/重启时都可以映射。我想让任何数量的相同的ccy+每张图表的EA实例有可能 "以某种方式 "打开一个独特的文件名,并在重启时神奇地 重新打开......
窗口处理数据可能是那个 "X因素"?
当然是BB,vip数据。我花了太多的时间试图发现一个独特的 基准点,一个EA的多个实例可以使用。这个基准点必须是可重复的,这样所有打开的文件在恢复/重启时都可以映射。我想让任何数量的相同cy+每张图表的EA实例 "以某种方式 "打开一个独特的文件名,并在重启时神奇地 重新打开。
如果MT4或用户不给每个EA分配一个ID,我看不出这有什么可能。或者,更准确地说,我看不到任何不涉及非常讨厌的东西,如生成一个独特的ID,然后修改EA的.chr文件,将ID作为EA的外部参数 的一部分来存储。
而且,为了一般的娱乐,下面这个方法并没有真正推动讨论,但它用一个保证唯一的值取代了djb2散列的输入(代价是需要调用DLL)。我不知道djb2在GUIDs这样的东西上有多好,但我刚试着生成了100万个ID,没有任何碰撞。但还是不能解决重启的问题。
窗口处理数据可能是那个 "X因素"?
如果你没有部分关闭任何 订单,你可以使用订单注释来存储起始对/时间框架的信息。
因此,EA在重新启动时,可以找出它是否有任何先前的订单,以及它应该使用什么神奇的数字?
NB
将评论保持在<25,并检查LEFT(OrderComments(), 24),否则[sl]或[tp]的东西可能会影响事情。
假设<所有历史>在账户历史选项卡中是可用的!
顺便说一句
-BB-