Emulation of ticks from an EA/indicator - page 3

 
Meat:

Yeah, it's not clear what's wrong... Try this then: in the import section #import "user32.dll" add a function:

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

And at the end of SetMyTimer function add a line: CallWindowProcA(code,0,0,0,0);

And with some parallel running indicator check if a tick is generated at this moment.

Well, something seems to have changed, the log is now like this:
10:42:52 test EURUSD,H1: loaded successfully
10:42:54 test EURUSD,H1: function 'CallWindowProcA' call from dll 'user32.dll' critical error c0000005 at 02C310A8.
10:42:54 test EURUSD,H1: initialize

Where's a tick? ;)

 
Meat:

Zhunko, well, if everything is non-standard (your own log, your own implementation of indicators, etc.), then why are you starting this whole conversation? We are actually discussing the work specifically with MT4, not with our own developments.

In my first post I specifically pointed out that my code will be useful if the task is to do without external links, ie, to implement a self-sufficient Expert Advisor/indicator that uses only system libraries. And if you are using your own developments, then it's not applicable to you.

And in general, I do not understand why I have to "manually clean the log after work", if it's easier not to clutter it up. After all, as far as I understood, you implement your developments in DLL. Then what prevents you from setting the same timer there, as I suggested here. But for some reason you prefer all sorts of dances with tambourine and cleaning up the log. My code bothers you, while you are too lazy to clean up the log every day :)

My log's only filled up after I pumped up my history. Happens on Wednesdays and Saturdays. Forgot what it is because of its automatic cleaning.

Autonomous update of the charts has been done for a long time. It is implemented here. You run the function once from any program and don't need to do anything else. Even with all MQL4 programs unloaded the update continues, the chart opening and closing is monitored.

The alternative to your code is not the one I suggested. It is a simple solution to this problem, based on your task. One line of code is much simpler than your code. You don't have to clean the logs every day. Only on weekends. The rest of the time you don't need this code. It's rational. You have to clean the log anyway. So, this is not the reason.

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

I've run your code. It doesn't work on Window 7.

May we get rid of AddBytes() function? Initialise the array like this:

  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;
It's shorter. Still, it's a one-off job.
 
Zhunko:

I only get a log after the history has been swapped. It happens on Wednesdays and Saturdays. Forgot what it is because of its automatic cleaning.

The autonomous update of the charts was done a long time ago. It is implemented here. You run the function once from any program and don't need to do anything else. Even with all MQL4 programs unloaded the update continues, the chart opening and closing is monitored.

The alternative to your code is not the one I suggested. It is a simple solution to this problem, based on your task. One line of code is much simpler than your code. You don't have to clean the logs every day. Only on weekends. The rest of the time you don't need this code. It's rational. You have to clean the log anyway. So, this is not the reason.

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

I've run your code. It doesn't work on Window 7.

May we get rid of AddBytes() function? Initialise the array like this:

It'll be shorter. Still, it's a one-off job.

Yes, of course, my posted code is just a source code to understand the meaning, while it's more convenient to use it in a packed form ...But as it turns out, it's too early to compile it, because for some reason it doesn't work :) Although it works fine for me both in XP and in 7, nothing crashes, even though I ran it for about an hour. It's a bit of a mystery...

One line of code is much easier than your code. You don't have to clean the logs every day. Only on weekends. The rest of the time you don't need this code. It's rational.

It may not be crucial for you personally if you have your own "logging cleaner" working at the same time, i.e. you have your own kitchen there, but we are talking about a general case. Imagine a normal user that doesn't do all this stuff. Then he will need the "log cleaner" for good work with your indicator. I.e. And you must admit that it's much larger than the size of my code ;) So I think you're wrong about rationality and brevity, especially if you take my code in a packed form, like you suggest. Of course, it's not a single line, but it doesn't require any other add-ons, i.e. it's a complete product.

The log must be cleaned anyway.

Why should I? If I don't clog it, why should I clean it?

 

Alexei, the cleaner may not necessarily be automatic. For example, right-click on a folder and select"clear folder". Do this after experimenting on weekends.

Over a year, 365 files accumulate in EAs and logs. That is 730 files. It should not be cleaned? It is strange to hear that. You don't get clogged because you do nothing. Logs grow a lot in size when you work every day.

 
Zhunko:

Alexei, the cleaner may not necessarily be automatic. For example, right-click on a folder and select "clear folder". Do this after experimenting on weekends.

Over a year, 365 files accumulate in EAs and logs. That is 730 files. It should not be cleaned? It is strange to hear such a thing. You don't get clogged because you do nothing. The logs grow a lot in size if you work every day.

Well, in principle yes, I agree that after experiments they usually have to be cleaned. But we are not just talking about experimentation. An indicator is being created to work, not for experimentation, so if a debugged indicator will still clog up the log files while working, it won't be correct.

Speaking of deleting the old logs, it is a question of personal preferences, for example, I had to look for some information in the logs from a year ago. So I don't delete them. I mean logs directly related to trading, not to different experiments.

 
Meat:

Well, in principle, yes, I agree that they usually need to be cleaned after experiments. But we're not just talking about experiments. After all, an indicator is created to work, not for experimentation. So, if a debugged indicator will continue to clog logs in the process of its work, it's already wrong.

So, I mean that such a gimmick is needed only at weekends. The rest of the time you don't need it.
 

Generally speaking, the generation of ticks is also necessary on weekdays. You seem to consider an Expert Advisor/indicator that uses only quotes of its symbol. Of course you can simply run it on some liquid symbols, for example EURUSD, where ticks are coming often... But it is not a cure-all, and it may not be very convenient.

 

In any case, when one wants to see the result before the tick has arrived.

That is, - for research purposes.

 

I figured out what the problem was. The array should be declared globally, not locally.

I am posting the corrected version. I shortened the code at the same time. The variant proposed by Zhunko, even though it was 3 lines shorter than this one, was too complicated and inconvenient for understanding the algorithm.) So, I don't think you should go to extremes for the sake of code reduction.

#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:

Generally speaking, the generation of ticks is also necessary on weekdays. You seem to consider an Expert Advisor/indicator that uses only quotes of its symbol. Of course you can simply run it on some liquid symbol, for example EURUSD, where ticks are coming often... But it is not a panacea, and it may not be very convenient.

Do you have just one example?

As long as I've been writing and using it, I have never needed it, except for weekends.

Expert Advisor + indicator. It is solved by "freezing" the Expert Advisor. The result is the same as for you. To receive data in time, it is sufficient to react to server time changes. You do not need WinAPI for that.

The only case, when it is needed, is to start the Expert Advisor at the weekend. Even that can be implemented with the line I gave above. Only for the Expert Advisor.