模仿EA/指示器的刻度线 - 页 3

 
Meat:

是的,不清楚哪里出了问题......那就试试这个。在导入部分#import "user32.dll" 添加一个函数。

CallWindowProcA(int lpPrevWndFunc[], int hWnd, int Msg, int wParam, int lParam);

并在SetMyTimer函数的末尾添加一行:CallWindowProcA(code,0,0,0,0)。

并用一些平行运行的指标检查此刻是否产生了一个刻度。

好吧,似乎有些变化,现在的日志是这样的。
10:42:52 测试 EURUSD,H1:加载成功
10:42:54 test EURUSD,H1: 函数'CallWindowProcA'从dll 'user32.dll'调用,在02C310A8处出现关键错误 c0000005。
10:42:54 测试 EURUSD,H1:初始化

哪里有虱子?;)

 
Meat:

Zhunko,好吧,如果所有的东西都是非标准的(你自己的日志,你自己的指标实现等),那么你为什么要开始这整个谈话? 我们实际上是在讨论专门与MT4的工作,而不是与我们自己的发展。

在我的第一篇文章中,我特别指出,如果任务是在没有外部链接的 情况下进行,即实现一个只使用系统库的自给自足的专家顾问/指标,那么我的代码将是有用的。 而如果你使用自己的开发,那么它对你就不适用。

总的来说,我不明白为什么我必须 "在工作后手动清理日志",如果不把它弄得乱七八糟会更容易。毕竟,据我所知,你在DLL中实现了你的发展。那么是什么阻止了你在那里设置同样的定时器,正如我在这里建议的那样。但由于某些原因,你更喜欢用手鼓跳各种舞蹈和清理日志。 我的代码让你烦恼,而你却懒得每天清理日志 :)

我的日志是在我提高了我的历史记录之后才填满的。发生在星期三和星期六。因为它的自动清洗,所以忘记了它是什么。

图表的自主更新已经进行了很长时间。它是在这里 实施的。你在任何程序中运行一次该函数,不需要做其他任何事情。即使卸载了所有的MQL4程序,更新仍在继续,图表的打开和关闭也受到监控。

你的代码的替代方案不是我建议的那个。这是一个简单的解决方案,基于你的任务,解决这个问题。一行代码要比你的代码简单得多。你不需要每天都清理日志。只在周末。其余时间,你不需要这个代码。这很合理。无论如何,你必须清理日志。所以,这不是原因。

======================

我已经运行了你的代码。它在Window 7上不起作用。

我们可以去掉AddBytes()函数吗?像这样初始化数组。

  int code[7] = {0x558BEC6A, 0x16A0268, 0, 0, 0, 0, 0x33C05DC3};
  code[2] = MT4InternalMsg;
  code[3] = 0x68000000 + (hWnd >> 8);
  code[4] = (hWnd << 24) + 0x00B80000 + (PostMsgAddr >> 16);
  code[5] = (PostMsgAddr << 16) + 0x0000FFD0;
它更短。尽管如此,这仍然是一个一次性的工作。
 
Zhunko:

我只在历史记录被调换后才得到一个日志。它发生在每周三和周六。因为它的自动清洗,所以忘记了它是什么。

图表的自主更新是在很久以前完成的。它是在这里 实施的。你在任何程序中运行一次该函数,不需要做其他任何事情。即使卸载了所有的MQL4程序,更新仍在继续,图表的打开和关闭也受到监控。

你的代码的替代方案不是我建议的那个。这是一个简单的解决方案,基于你的任务,解决这个问题。一行代码要比你的代码简单得多。你不需要每天都清理日志。只在周末。其余时间,你不需要这个代码。这很合理。无论如何,你必须清理日志。所以,这不是原因。

======================

我已经运行了你的代码。它在Window 7上不起作用。

我们可以去掉AddBytes()函数吗?像这样初始化数组。

会比较短。尽管如此,这仍然是一个一次性的工作。

是的,当然,我发布的代码只是一个理解意义的源代码,而以打包的形式使用更方便 ...但事实证明,现在编译它还为时过早,因为由于某些原因,它不能工作 :) 虽然它在XP和7中对我来说都很好,没有什么崩溃,尽管我运行了大约一个小时。这是一个有点神秘的问题...

一行代码比你的代码容易得多。你不需要每天都清理日志。只在周末。其余时间,你不需要这个代码。这很合理。

如果你有自己的 "日志清洁工 "同时工作,即你在那里有自己的厨房,这对你个人来说可能并不重要,但我们说的是一般情况。想象一下,如果一个普通用户不做这些事情,那么他将需要 "日志清理器",以便在你的指标上良好地工作。 即而且你必须承认,它比我的代码的大小要大得多;)所以我认为你对理性和简洁的看法是错误的,特别是如果你像你建议的那样,把我的代码以打包的形式拿出来。当然,它不是一条线,但它不需要任何其他附加组件,也就是说,它是一个完整的产品。

无论如何都必须对日志进行清理。

如果我没有堵塞,我为什么要清洗它?

 

阿列克谢,清洁剂不一定是自动的。例如,右键点击一个文件夹,选择"清除文件夹"。在周末做完实验后做这个。

一年下来,365个文件在EA和日志中累积。这就是730个文件。它不应该被清洗?听到这个消息很奇怪。你不会因为你什么都不做而被堵塞。当你每天工作时,原木的体积会增长很多。

 
Zhunko:

阿列克谢,清洁剂不一定是自动的。例如,右键点击一个文件夹,选择 "清除文件夹"。在周末做完实验后做这个。

一年下来,365个文件在EA和日志中累积。这就是730个文件。它不应该被清洗?听到这个消息很奇怪。你不会因为你什么都不做而被堵塞。当你每天工作时,日志的大小会增长很多。

嗯,原则上是的,我同意在实验后通常要进行清洗。但是,我们不仅仅是在谈论实验。 一个指标的创建是为了工作,而不是为了实验,所以如果一个经过调试的指标在工作时仍然会堵塞日志文件,那么它就不正确了。

说到删除旧的日志,这是一个个人喜好的问题,例如,我不得不在一年前的日志中寻找一些信息。所以我不删除它们。我指的是与交易直接相关的日志,而不是一些实验。

 
Meat:

嗯,原则上是的,我同意他们在实验后通常需要进行清洗。但我们不只是在谈论实验。毕竟,创建指标是为了工作,而不是为了做实验。因此,如果一个被调试的指标在工作过程中会继续堵塞日志,那么它就已经错了。

所以,我的意思是,只有在周末才需要这样的噱头。其余时间你不需要它。
 

一般来说,在工作日也需要产生蜱。你似乎认为专家顾问/指标只使用其符号的报价。当然,你可以简单地在一些流动性符号上运行它,例如欧元兑美元,那里的刻度线经常出现。但这并不是万能的,而且可能不是很方便。

 

在任何情况下,当人们想在打钩到达之前看到结果时。

也就是说,--出于研究目的。

 

我知道问题出在哪里了,数组应该在全局范围内声明,而不是在本地。

我在此张贴更正后的版本。我同时也缩短了代码。Zhunko提出的变体,尽管比这个变体短了3行,但过于复杂,不便于理解算法)。所以,我认为你不应该为了减少代码而走极端。

#property indicator_chart_window

#import "user32.dll"
  int   RegisterWindowMessageA(string lpString);
  int   SetTimer(int hWnd,int nIDEvent,int uElapse,int& lpTimerFunc[]);
  bool  KillTimer(int hWnd,int uIDEvent);
#import "kernel32.dll"
  int   GetModuleHandleA(string lpModuleName);
  int   GetProcAddress(int hModule,string lpProcName);
  
int TimerId=666;
int TimerCode[7];

//----------------------------------------------------------------------

int init()
{
  SetMyTimer(1000);  // интервал в миллисекундах
}
//----------------------------------------------------------------------

int deinit()
{
  KillMyTimer();
  Comment("");
}  

//+------------------------------------------------------------------+
//| program start function                                           |
//+------------------------------------------------------------------+
int start()
{
  static int n=0;
  n++; 
  Comment("tick:  ",n);
  PlaySound("tick.wav");
}
//-------------------------------------------------------------------

int SetMyTimer(int interval)
{    
  int MT4InternMsg= RegisterWindowMessageA("MetaTrader4_Internal_Message");
  int hWnd= WindowHandle(Symbol(),Period());
  int PostMsgAddr= GetProcAddress(GetModuleHandleA("user32.dll"),"PostMessageA");
  if (PostMsgAddr==0) return(0);
  // push ebp; move ebp,esp; push 01; push 02; push MT4InternMsg; push hWnd; mov eax,PostMsgAddr; call eax; pop ebp; ret;    
  int value[]={ 0x55, 0x8B,0xEC, 0x6A,01, 0x6A,02, 0x68,0000, 0x68,0000, 0xB8,0000, 0xFF,0xD0, 0x5D, 0xC3 };
  int len[]=  { 1,    1,   1,    1,   1,  1,   1,  1,   4,    1,   4,    1,   4,    1,   1,    1,    1    };
  value[8]=MT4InternMsg;  value[10]=hWnd;  value[12]=PostMsgAddr; 
  int byte=0;
  for (int i=0; i<ArraySize(value); i++)
    for (int j=0;  j<len[i];  j++, byte++)
      TimerCode[byte/4] += (value[i]>>(8*j)&0xFF) <<(byte%4*8);
  
  return ( SetTimer(hWnd, TimerId, interval, TimerCode) );
}

//---------------------------------------------------

bool KillMyTimer()
{
  return( KillTimer(WindowHandle(Symbol(),Period()), TimerId) );
}
 
Meat:

一般来说,在工作日也需要产生蜱虫。你似乎认为专家顾问/指标只使用其符号的报价。当然,你可以简单地在一些流动性符号上运行它,例如欧元兑美元,那里的刻度线经常出现。但它不是万能的,也可能不是很方便。

只是一个例子?

只要我一直在写作和使用它,除了周末,我从来没有需要它。

专家顾问+指标。它是通过 "冻结 "专家顾问来解决的。其结果与你相同。为了及时接收数据,对服务器的时间 变化做出反应就可以了。你不需要WinAPI来做这个。

唯一需要的情况,是在周末启动专家顾问。即使是这样,也可以用我上面给出的那句话来实现。只适用于专家顾问。