Mt4 Fin de l'assistance. - page 27

 
Реter Konow:
Linéaire, non-linéaire... Vous parlez encore de l'opéra en programmation ?

pas du tout.

 
Реter Konow:

OK. Votre solution ne fonctionne que sur les tiques. Le mien est sur minuterie. Pensez-vous que ma méthode de chronométrage des apparitions dans les bars présente un inconvénient ? Ok. Que ce soit comme ça. Je vais ajouter une vérification de l'arrivée d'un devis avant d'établir un nouveau drapeau de barre. Je vais ajouter un autre paramètre à la fonction - un symbole. L'utilisateur choisira le symbole par lequel il veut recevoir le nouvel événement de barre et l'envoyer à la fonction. La fonction vérifiera l'heure de la dernière citation de ce symbole. Ensuite, nous comparerons l'heure de l'apparition formelle du bar et l'heure de la cotation et nous mettrons le drapeau d'événement.

Je viens de commencer à étudier ce sujet, mais je ne vois pas de difficultés.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Mt4 Fin de l'assistance.

Artyom Trishkin, 2017.09.10 22:27

Je sais comment obtenir des devis :)

Dans un programme multi-devises - dans un timer dans une boucle sur les bons symboles. Et l'ouverture d'une nouvelle barre (physique et non virtuelle - erronée - comme chez vous) est contrôlée par l'heure de la dernière cotation et la comparaison de cette heure avec l'heure du symbole de la barre zéro.

Vous, par contre, vous faites du hasard - un bar virtuel qui n'existe peut-être pas. Vous ne les avez pas le week-end, mais vous êtes censé les avoir - c'est la chose la plus simple à donner en exemple.

Et, tu vois, tu es le seul qui ne le ferait pas de cette façon. Le reste d'entre nous le fait de manière correcte et fiable. Mais cela, bien sûr, ne regarde que vous.

Je voulais vous dire comment le faire correctement et montrer la grande différence entre la simplicité de l'écriture en POO et les tournures compliquées en style procédural pour résoudre la même tâche.

Mais vous en savez probablement plus et n'en avez pas besoin. Je n'ose pas avoir l'air d'en savoir plus. Désolé.


 
Galina Bobro:

Pas de problème. Couverture pour sauver la comparaison des opérations sur les chaînes de caractères, enfin, si le client est un maniaque et qu'il négocie sur tous les caractères simultanément.

Mais il semble qu'il n'y ait pas d'autre endroit pour sauvegarder les opérations et la mémoire - tout est minimal.

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

//+------------------------------------------------------------------+

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

//+------------------------------------------------------------------+

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


Il a une vérification pour un nouveau symbole et un tf, ne vérifie pas tout, mais seulement ce dont vous avez besoin, pas d'opérations inutiles, ce qui signifie qu'il devrait fonctionner assez rapidement.

meilleures salutations.

P.S. La seule petite chose qui pourrait être ajoutée ici est de combiner les tableaux st_time et st_id dans une structure, car ils sont liés, cela réduirait le nombre d'opérations d'incrémentation de tableau dans le code.

 
Artyom Trishkin:

J'avais pour objectif que son code de style procédural finisse par fonctionner en boucle comme ceci :

 ENUM_TIMEFRAMES array_timeframes[]=
      {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
      };
   int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
   for(int i=0; i<total; i++){
      string symbol_name=SymbolName(i,true);
      for(int j=0; j<total_tf; j++){
         if(IsNewBar(symbol_name,array_timeframes[j])){
            Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
            }
         }
      }


quelque chose comme ça (code pour MQL5) :

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }

void OnTick()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="") 
  {
   static const ENUM_TIMEFRAMES TF[22]=
     {
      PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym=0;
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      while(TF[curtf]!=tf) curtf++;
      return (newbar[n_cur*22+curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
   for(int j=0,j1=0; j<total; j++,j1+=22)
      for(int i=0;i<22;i++)
        {
         long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
         if(acb[j1+i]<CurBars) // пришел новый бар
           {
            //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]=true;
           }
         else
           {
            newbar[j1+i]=false;
            if(i==1) for(;i<22;i++) newbar[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }

Mais je le répète - je suis un partisan de la POO.
C'est juste un exemple vraiment malheureux pour montrer ce qui ne peut pas être fait en programmation procédurale.

 
Andrey Kisselyov:
Il ne s'agit pas d'appeler une fonction dans une EA, mais d'écrire des interfaces universelles (handlers).

vous avez des milliers de tâches pour écrire des robots; en fait, chacune d'entre elles consiste à
1 fonction d'obtention d'un signal d'ouverture
2. fonction d'ouverture de l'ordre
3 fonction de suivi des commandes
4) La fonction de réception d'un signal pour fermer un ordre.
et ainsi de suite.
Ces fonctions sont différentes pour chaque robot, mais elles sont répétées dans 1000 projets. Par conséquent, vous pouvez combiner les fonctions dans des modules universels et, selon la tâche, appeler le bon module.

Eh bien, si vous avez ces fonctions, vous n'avez pas besoin de faire autre chose. Les paramètres d'entrée de la fonction sont l'interface. Chaque complexité supplémentaire augmente le nombre d'erreurs possibles et accroît le temps de travail du programmeur.

 
Nikolai Semko:

quelque chose comme ça (code pour MQL5) :

Mais je le répète - je suis un partisan de la POO.
C'est juste un exemple malheureux pour montrer ce qui ne peut pas être fait en programmation procédurale.

Un tel exemple existe-t-il en principe ? Même si ce n'est pas le vôtre ? J'ai de profonds doutes. Au début des années 2000, j'ai cessé de compter le nombre de lignes de code débogué et fonctionnel que j'avais écrites, car il dépassait le million - cela devenait inintéressant. Et je n'ai jamais rencontré la nécessité de créer ma propre classe, bien que la variété et l'ampleur de mes tâches aient été très diverses. J'ai dû utiliser des variables de type procédure lorsqu'il était nécessaire de paralléliser le travail de plusieurs personnes mais pas plus. Pourquoi ?

Au fait, pourquoi parlez-vous de programmation procédurale comme d'une alternative à la POO ? Il existe des langages sans POO, non procéduraux en principe (SQL), il y a même une direction de développement des langages - la programmation fonctionnelle https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5 :"Certains concepts et paradigmes sont spécifiques à la programmation fonctionnelle et sont pour la plupart étrangers à la programmation impérative (y compris la programmation orientée objet)", "Un autre avantage des programmes fonctionnels est qu'ils offrent de vastes possibilités d'automatisation ". Il s'avère que la POO empêche la mise en parallèle automatique des calculs. Ceci devrait maintenant être considéré comme un inconvénient très sérieux, la perspective n'est pas pour OOP.

 
Vladimir:

Existe-t-il, en principe, un exemple de cela? Même si ce n'est pas le vôtre ? J'ai de profonds doutes.


Je pense qu'il est tout à fait possible qu'un tel exemple ne se trouve pas. Personnellement, je pense que les principaux avantages de la POO sont une programmation plus pratique des grands projets et un mécanisme pratique pour utiliser vos développements à l'avenir. Cela a déjà été dit à juste titre ici à de nombreuses reprises.

 
Andrei:

Il a déjà été discuté qu'une interface unique n'est pas applicable à la programmation de toutes les tâches de calcul... Mettre de belles choses sous forme d'interfaces est un procédé purement cosmétique, qui n'est applicable qu'à un code déjà prêt et qui empêche également le support et le raffinement ultérieurs du code...

Non. Ce n'est pas "pas du tout applicable" mais "il n'y a aucun intérêt à les utiliser".

Les interfaces ne sont pas "une procédure purement cosmétique applicable au code prêt à l'emploi".

Bien au contraire, les interfaces sont au cœur de l'architecture du système. C'est là que la conception commence. Les interfaces ne font pas "obstacle au soutien et au remaniement", mais les aident plutôt en délimitant clairement les limites de ce qui est permis. S'il n'y a pas d'interfaces, il est facile de franchir ces limites et d'apporter des modifications là où elles n'étaient pas prévues, ce qui entraîne des erreurs difficiles à calculer.

Tout système complexe (et pas seulement en programmation) commence par l'élaboration des principes de base de l'interaction entre ses parties. Mais en programmation, parce que la tâche initiale est généralement très petite, ils vont dans la direction opposée. Les parties sont d'abord écrites puis combinées en un tout, se heurtant souvent au fait que les parties ne sont pas compatibles entre elles - ce qui explique d'ailleurs le désir "d'avoir accès à toutes les variables disponibles".

 

Tout va bien, à l'exception du fait que la fonction isNewBar() ne devrait pas exister du tout. C'est drôle qu'il y ait autant de danse autour d'une chose aussi triviale.

Il s'agit d'une variable, qui est simplement comparée au temps de la barre ; si tous les cas sont réussis, la variable se voit attribuer le temps de la nouvelle barre à la fin. Sinon, une seule tentative est attribuée à tous les cas.

 
Dmitry Fedoseev:

Tout va bien, à l'exception du fait que la fonction isNewBar() ne devrait pas exister du tout. C'est drôle qu'il y ait autant de danse autour d'une chose aussi triviale.

C'est juste une variable, et elle est simplement comparée au temps de la barre ; si tous les cas réussissent, alors la variable se voit attribuer le temps de la nouvelle barre à la fin. Sinon, une seule tentative est attribuée à tous les cas.


+1