Emulation des ticks d'un EA/indicateur - page 3

 
Meat:

Ouais, ce n'est pas clair ce qui ne va pas... Essayez ceci alors : dans la section import #import "user32.dll" ajouter une fonction :

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

Et à la fin de la fonction SetMyTimer, ajoutez une ligne : CallWindowProcA(code,0,0,0,0,0) ;

Et avec un indicateur fonctionnant en parallèle, vérifiez si un tick est généré à ce moment.

Eh bien, quelque chose semble avoir changé, le journal est maintenant comme ceci :
10:42:52 test EURUSD,H1 : chargé avec succès
10:42:54 test EURUSD,H1 : appel de la fonction 'CallWindowProcA' depuis la dll 'user32.dll'erreur critique c0000005 à 02C310A8.
10:42:54 test EURUSD,H1 : initialiser

Où est la tique ? ;)

 
Meat:

Zhunko, eh bien, si tout est non-standard (votre propre journal, votre propre implémentation des indicateurs, etc.), alors pourquoi lancez-vous toute cette conversation ? En fait, nous discutons du travail spécifiquement avec MT4, et non de nos propres développements.

Dans mon premier message, j'ai spécifiquement indiqué que mon code sera utile si la tâche consiste à se passer de liens externes, c'est-à-dire à mettre en œuvre un conseiller expert/indicateur autonome qui n'utilise que des bibliothèques système. Et si vous utilisez vos propres développements, alors il ne vous est pas applicable.

Et en général, je ne comprends pas pourquoi je dois "nettoyer manuellement le journal après le travail", s'il est plus simple de ne pas l'encombrer. Après tout, d'après ce que j'ai compris, vous implémentez vos développements en DLL. Alors, qu'est-ce qui vous empêche d'y installer la même minuterie, comme je l'ai suggéré ici. Mais pour une raison quelconque, vous préférez toutes sortes de danses avec tambourin et le nettoyage du journal. Mon code vous dérange, alors que vous êtes trop paresseux pour nettoyer le journal tous les jours :)

Mon journal ne s'est rempli qu'après avoir gonflé mon historique. Ça se passe les mercredis et les samedis. J'ai oublié ce que c'était grâce à son nettoyage automatique.

La mise à jour autonome des cartes se fait depuis longtemps. Il est mis en œuvre ici. Vous exécutez la fonction une fois à partir de n'importe quel programme et vous n'avez rien d'autre à faire. Même si tous les programmes MQL4 sont déchargés, la mise à jour continue, l'ouverture et la fermeture du graphique sont surveillées.

L'alternative à votre code n'est pas celle que j'ai suggérée. Il s'agit d'une solution simple à ce problème, basée sur votre tâche. Une ligne de code est beaucoup plus simple que votre code. Vous n'avez pas besoin de nettoyer les bûches tous les jours. Seulement les week-ends. Le reste du temps, vous n'avez pas besoin de ce code. C'est rationnel. Vous devez nettoyer le journal de toute façon. Donc, ce n'est pas la raison.

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

J'ai exécuté votre code. Il ne fonctionne pas sur Window 7.

Peut-on se débarrasser de la fonction AddBytes() ? Initialiser le tableau comme ceci :

  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;
C'est plus court. Pourtant, c'est un travail ponctuel.
 
Zhunko:

Je n'obtiens un journal qu'après l'échange de l'historique. Cela se passe les mercredis et les samedis. J'ai oublié ce que c'était grâce à son nettoyage automatique.

La mise à jour autonome des cartes a été faite il y a longtemps. Il est mis en œuvre ici. Vous exécutez la fonction une fois à partir de n'importe quel programme et vous n'avez rien d'autre à faire. Même si tous les programmes MQL4 sont déchargés, la mise à jour continue, l'ouverture et la fermeture du graphique sont surveillées.

L'alternative à votre code n'est pas celle que j'ai suggérée. Il s'agit d'une solution simple à ce problème, basée sur votre tâche. Une ligne de code est beaucoup plus simple que votre code. Vous n'avez pas besoin de nettoyer les bûches tous les jours. Seulement les week-ends. Le reste du temps, vous n'avez pas besoin de ce code. C'est rationnel. Vous devez nettoyer le journal de toute façon. Donc, ce n'est pas la raison.

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

J'ai exécuté votre code. Il ne fonctionne pas sur Window 7.

Peut-on se débarrasser de la fonction AddBytes() ? Initialiser le tableau comme ceci :

Ce sera plus court. Pourtant, c'est un travail ponctuel.

Oui, bien sûr, mon code posté est juste un code source pour comprendre le sens, alors qu'il est plus pratique de l'utiliser sous une forme emballée ...Mais il s'avère qu'il est trop tôt pour le compiler, car pour une raison quelconque, il ne fonctionne pas :) Bien qu'il fonctionne bien pour moi à la fois sous XP et sous 7, rien ne plante, même si je l'ai fait tourner pendant environ une heure. C'est un peu un mystère...

Une ligne de code est bien plus facile que votre code. Vous n'avez pas besoin de nettoyer les bûches tous les jours. Seulement les week-ends. Le reste du temps, vous n'avez pas besoin de ce code. C'est rationnel.

Il se peut que ce ne soit pas crucial pour vous personnellement si vous avez votre propre "nettoyeur de bûches" qui travaille en même temps, c'est-à-dire que vous avez votre propre cuisine sur place, mais nous parlons d'un cas général. Imaginez un utilisateur normal qui ne fait pas toutes ces choses. Il aura alors besoin du "nettoyeur de logs" pour bien travailler avec votre indicateur. C'est à dire Et vous devez admettre qu'elle est bien plus grande que la taille de mon code ;) Je pense donc que vous avez tort au sujet de la rationalité et de la brièveté, surtout si vous prenez mon code sous une forme emballée, comme vous le suggérez. Bien sûr, il ne s'agit pas d'une ligne unique, mais elle ne nécessite pas d'autres modules complémentaires, c'est-à-dire qu'il s'agit d'un produit complet.

La bûche doit être nettoyée de toute façon.

Pourquoi devrais-je le faire ? Si je ne le bouche pas, pourquoi devrais-je le nettoyer ?

 

Alexei, le nettoyeur n'est pas forcément automatique. Par exemple, cliquez avec le bouton droit de la souris sur un dossier et sélectionnez"effacer le dossier". Faites-le après avoir expérimenté pendant les week-ends.

Sur une année, 365 fichiers s'accumulent dans les EA et les journaux. Cela représente 730 fichiers. Il ne doit pas être nettoyé ? C'est étrange d'entendre ça. On ne s'encrasse pas parce qu'on ne fait rien. Les bûches prennent beaucoup d'ampleur quand on travaille tous les jours.

 
Zhunko:

Alexei, le nettoyeur n'est pas forcément automatique. Par exemple, cliquez avec le bouton droit de la souris sur un dossier et sélectionnez "effacer le dossier". Faites-le après avoir expérimenté pendant les week-ends.

Sur une année, 365 fichiers s'accumulent dans les EA et les journaux. Cela représente 730 fichiers. Il ne doit pas être nettoyé ? C'est étrange d'entendre une telle chose. On ne s'encrasse pas parce qu'on ne fait rien. Les bûches prennent beaucoup d'ampleur si vous travaillez tous les jours.

Eh bien, en principe oui, je suis d'accord pour dire qu'après les expériences, ils doivent généralement être nettoyés. Un indicateur est créé pour fonctionner, pas pour l'expérimentation, donc si un indicateur débogué encombre toujours les fichiers journaux tout en fonctionnant, il ne sera pas correct.

En ce qui concerne la suppression des anciens journaux, c'est une question de préférences personnelles. Par exemple, j'ai dû rechercher certaines informations dans les journaux d'il y a un an. Donc je ne les supprime pas. J'entends par là les journaux directement liés au commerce, et non à des expériences différentes.

 
Meat:

Eh bien, en principe, oui, je suis d'accord pour dire qu'ils doivent généralement être nettoyés après les expériences. Mais nous ne parlons pas seulement d'expériences. Après tout, un indicateur est créé pour fonctionner, pas pour expérimenter. Ainsi, si un indicateur débogué continue à encombrer les journaux au cours de son travail, il est déjà faux.

Donc, je veux dire qu'un tel gadget n'est nécessaire que le week-end. Le reste du temps, vous n'en avez pas besoin.
 

D'une manière générale, la génération de tiques est également nécessaire les jours de semaine. Vous semblez considérer un conseiller expert/indicateur qui n'utilise que les citations de son symbole. Bien sûr, vous pouvez simplement l'exécuter sur certains symboles liquides, par exemple EURUSD, où les ticks arrivent souvent... Mais ce n'est pas une panacée, et ce n'est pas forcément très pratique.

 

En tout cas, quand on veut voir le résultat avant que le tic-tac ne soit arrivé.

C'est-à-dire - à des fins de recherche.

 

J'ai trouvé la cause du problème. Le tableau doit être déclaré globalement, et non localement.

J'affiche la version corrigée. J'ai raccourci le code en même temps. La variante proposée par Zhunko, même si elle était plus courte de 3 lignes que celle-ci, était trop compliquée et peu pratique pour comprendre l'algorithme). Je ne pense donc pas qu'il faille aller à l'extrême pour réduire le code.

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

D'une manière générale, la génération de tiques est également nécessaire les jours de semaine. Vous semblez considérer un conseiller expert/indicateur qui n'utilise que les citations de son symbole. Bien sûr, vous pouvez simplement l'exécuter sur certains symboles liquides, par exemple EURUSD, où les ticks arrivent souvent... Mais ce n'est pas une panacée, et ce n'est pas forcément très pratique.

Un seul exemple ?

Depuis que j'écris et que je l'utilise, je n'en ai jamais eu besoin, sauf le week-end.

Conseiller expert + indicateur. Il est résolu en "gelant" le conseiller expert. Le résultat est le même que pour vous. Pour recevoir les données à temps, il suffit de réagir aux changements d'heure du serveur. Vous n'avez pas besoin de WinAPI pour cela.

Le seul cas où cela est nécessaire est de lancer le conseiller expert pendant le week-end. Même cela peut être mis en œuvre avec la ligne que j'ai donnée ci-dessus. Seulement pour le conseiller expert.

Raison: