Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 380

 
Bonjour à tous.
C'est ma première fois sur le forum, si je fais quelque chose de mal sur le forum, veuillez me pardonner par avance.
Je regarde des graphiques avec des indicateurs depuis longtemps. Récemment, j'ai perdu deux dépôts. Avant d'ouvrir un nouveau compte, je veux vérifier la rentabilité de la stratégie sur l'historique. J'utilise un compte de démonstration dans MT4.
Je ne suis pas du tout un programmeur. Je suis seulement capable d'installer l'indicateur sur MT4 et peut-être de changer l'épaisseur de la ligne de l'indicateur dans MetaEditor (je ne pourrai probablement pas changer la couleur dans le code de l'indicateur, seulement dans le terminal).
Avez-vous des informations claires pour quelqu'un avec mes connaissances, où commencer à tester étape par étape (en anglais simple "instructions pour les nègres comment utiliser les toilettes") ? La stratégie dispose de 3 indicateurs : MA (3 simples), Stochastique avec des niveaux standards, et CCI avec 5 niveaux. Ouverture de transactions courtes après le franchissement des niveaux des indicateurs de haut en bas, transactions longues vice versa (je suppose que c'est clair...). Réglage des prises et des pertes.
J'aimerais pouvoir suivre visuellement la stratégie en mode automatique ainsi que sans visualisation pour sélectionner les paramètres des indicateurs et des ordres.
 
ZebStamp:
Bonjour à tous.
C'est ma première fois sur le forum, si je fais quelque chose de mal sur le forum, veuillez me pardonner par avance.
Je regarde des graphiques avec des indicateurs depuis longtemps. Récemment, j'ai perdu deux dépôts. Avant d'ouvrir un nouveau compte, je veux vérifier la rentabilité de la stratégie sur l'historique. J'utilise un compte de démonstration dans MT4.
Je ne suis pas du tout un programmeur. Je suis seulement capable d'installer l'indicateur sur MT4 et peut-être de changer l'épaisseur de la ligne de l'indicateur dans MetaEditor (je ne pourrai probablement pas changer la couleur dans le code de l'indicateur, seulement dans le terminal).
Avez-vous des informations claires pour quelqu'un avec mes connaissances, où commencer à tester étape par étape (en clair "instructions pour les nègres comment utiliser les toilettes") ? La stratégie dispose de 3 indicateurs : MA (3 simples), Stochastique avec des niveaux standards, et CCI avec 5 niveaux. Ouverture de transactions courtes après le franchissement des niveaux des indicateurs de haut en bas, transactions longues vice versa (je suppose que c'est clair...). Réglage des prises et des pertes.
J'aimerais pouvoir suivre visuellement la stratégie en mode automatique, ainsi que sans visualisation pour sélectionner les paramètres des indicateurs et des ordres.

Lorsque vous créez un objet graphique (GO), tel que TrendLine, vous sélectionnez la couleur. Lorsque vous recréez la TrendLine, elle est créée avec la même couleur. Pour Hline - vous choisissez une couleur - et la suivante est comme ceci. Prenez du jaune, du bleu, ...

Si CS crée un Expert Advisor, un indicateur, un script - alors comme vous l'écrivez dans le programme. Parfois, le choix des paramètres

 
STARIJ:

Si vous pensez que quelqu'un qui regarde votre code peut rapidement trouver une erreur, vous vous trompez. Le compilateur recherche les erreurs. Le texte du programme doit être formaté - MetaEditor dispose d'un outil de style pour cela. Si vous aimez un style différent, utilisez, par exemple, le programme AStyle.exe. Après le stylisme, vous verrez rapidement que le programme 1) a une parenthèse fermante supplémentaire. 2) Variable déclarée : datetime date_Buf_1 ; // indicateur de tableau de dates - pour que ce soit un tableau, il doit être [size] ou [] pour un tableau dynamique et ensuite la taille doit être fixée à ArrayResize il semble. Et vous devez le faire avant d'utiliser un tableau - voir les articles ci-dessus à ce sujet. 3) FileOpen(InpDirectoryName+"//"+InpFileName - il semble que les bâtons devraient être inclinés dans l'autre direction. Et il est préférable de se passer de InpDirectoryName+"//" - vous trouverez le fichier dans le dossier Files de toute façon.

sur la ligne : int copied=CopyTime(NULL,0,0,0,date_Buf_1) ; le compilateur se fâche, start=0=0


Merci. J'ai réussi à réparer quelque chose, mais plus par intuition que par compréhension. Mais nous avons toujours 3 erreurs concernant le tableau :

Buf_1' - tableau requis 111.mq4 93 21

date_Buf_1' - tableau requis 111.mq4 94 21

Buf_1' - tableau requis 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


Je ne comprends pas comment mettre en œuvre vos commentaires. Mais j'ai trouvé une agrafe supplémentaire :)
 
YarTrade:

Merci. J'ai réussi à réparer quelque chose, mais plus par intuition que par compréhension. Mais j'ai toujours 3 erreurs concernant le tableau :

Buf_1' - tableau requis 111.mq4 93 21

date_Buf_1' - tableau requis 111.mq4 94 21

Buf_1' - tableau requis 111.mq4 100 16



Je ne comprends pas comment mettre en œuvre vos commentaires. Mais j'ai trouvé un support supplémentaire :)
Ne laissez que les noms des variables du tableau. Supprimez les "[]" dans les lignes de code que le compilateur vous indique.
 
Artyom Trishkin:
Ne laissez que les noms des tableaux de variables. Supprimez les "[]" dans les lignes de code que le compilateur vous indique.

Merci. Je verrai ce qui se passe dans la vraie vie. Je doute fort que quelque chose soit écrit dans le fichier :)

 

Un certain nombre de questions se posent, j'espère beaucoup de votre aide. J'ai constaté une chose très triste, à savoir que les performances de l'EA pendant les tests et en temps réel sont très différentes. Je voudrais donc analyser les erreurs les plus courantes et les plus typiques. Je vais d'abord écrire sur ceux que j'ai rencontrés. J'apprécierais que vous partagiez vos expériences avec le programmeur qui sait ce qu'il doit garder à l'esprit et ce qu'il doit garder dans son code.

1. L'erreur de division par zéro apparaissait dans le mode de trading réel, malgré le fait que la division par zéro n'était pas présente dans le code et qu'elle ne s'était pas produite lors des backtests. Le programmeur a résolu le problème en écrivant chaque diviseur comme NormalizeDouble(x,Digits) ;

2. Le marché n'a pas été ouvert. Vendredi, lorsque j'ai effectué le backtest, la transaction s'est ouverte, mais pas lorsque j'étais en train de négocier. De plus, le journal du conseiller expert n'a montré aucune erreur. Je ne sais pas quel peut être le problème ici, mais j'ai deux ou trois choses à dire. Tout d'abord, j'ai reçu des avertissements comme "la valeur de retour de 'ordersend' doit être vérifiée" mais si je comprends bien, cela ne devrait pas affecter l'exécution du code ? Ou est-ce une question de glissement ? Ma valeur est de 1, ce qui n'est pas trop petit. Et la barre à laquelle je devrais effectuer une entrée s'est ouverte sans gap.

J'ai pris la ligne "if(Volume[0]>1) return ;" de l'exemple standard avec les slips et je l'ai insérée au début du code. C'est-à-dire que mon code n'est exécuté que pendant le premier tick lorsqu'une nouvelle barre apparaît. Se peut-il qu'une barre s'ouvre avec un volume et que mon code ne soit pas exécuté ?

4. Veuillez donner des conseils sur les éléments auxquels il faut faire attention ou sur les erreurs typiques lorsque l'on travaille avec l'EA avec l'historique et le temps réel, s'il vous plaît.


 
LuckySith:

Un certain nombre de questions se posent, j'espère beaucoup de votre aide. J'ai constaté une chose très triste, à savoir que les performances de l'EA pendant les tests et en temps réel sont très différentes. Je voudrais donc analyser les erreurs les plus courantes et les plus typiques. Je vais d'abord écrire sur ceux que j'ai rencontrés. J'apprécierais que vous partagiez vos expériences avec le programmeur qui sait ce qu'il doit garder à l'esprit et ce qu'il doit garder dans son code.

1. L'erreur de division par zéro apparaissait dans le mode de trading réel, malgré le fait que la division par zéro n'était pas présente dans le code et qu'elle ne s'était pas produite lors des backtests. Le programmeur a résolu le problème en écrivant chaque diviseur comme NormalizeDouble(x,Digits) ;

2. Le marché n'a pas été ouvert. Le vendredi, la transaction a été ouverte lorsque le backtest était en cours d'exécution, mais aucune transaction n'a été ouverte pendant le trading réel. De plus, le journal du conseiller expert n'a montré aucune erreur. Je ne sais pas quel peut être le problème ici, mais j'ai deux ou trois choses à dire. Tout d'abord, j'ai reçu des avertissements comme "la valeur de retour de 'ordersend' doit être vérifiée" mais si je comprends bien, cela ne devrait pas affecter l'exécution du code ? Ou est-ce une question de glissement ? Ma valeur est de 1, ce qui n'est pas trop petit. Et la barre à laquelle je devrais effectuer une entrée s'est ouverte sans gap.

J'ai pris la ligne "if(Volume[0]>1) return ;" de l'exemple standard avec les slips et je l'ai insérée au début du code. C'est-à-dire que mon code n'est exécuté que pendant le premier tick lorsqu'une nouvelle barre apparaît. Se peut-il qu'une barre s'ouvre avec un volume et que mon code ne soit pas exécuté ?

4. Veuillez me conseiller sur les points auxquels il faut faire attention ou sur les erreurs typiques lorsque l'on travaille avec l'EA avec l'historique et le temps réel, s'il vous plaît.

Remplacez cette construction sauvage "if(Volume[0]>1) return ;" par une vérification normale de "Nouvelle barre", le forum en est rempli.

Les avertissements du type "la valeur de retour de 'ordersend' devrait être vérifiée" ne sont pas des erreurs à ce jour, mais des erreurs potentielles pour l'avenir. Il ne devrait y avoir aucun avertissement dans le code, et encore moins lorsqu'on travaille en ligne.

"J'ai 1, ce qui n'est pas trop peu" - cela peut être très peu à l'ouverture d'une nouvelle barre, et surtout à l'ouverture d'une demi-heure ou d'une heure, à ce moment-là l'écart se creuse fortement.

Ce dont nous avons besoin : faire une vérification sur la nouvelle barre, et si elle est nouvelle, alors regarder les conditions d'entrée, si elles coïncident - faire un accord. Après cela, nous devons enregistrer que le bar a fonctionné et attendre le nouveau.

Ce que nous avons maintenant : if(Volume[0]>1) return ; = s'il y a une nouvelle barre, nous cherchons des conditions, la condition ne correspond pas == grand écart = sortir à nouveau dans OnTick(), sur le prochain tick if(Volume[0]>1) return ; il ne va pas aller plus loin, donc le trade est déjà manqué, même si l'écart est de 0.0001

 

Bonjour. Pouvez-vous me dire comment décrire ce qui suit avec le code : Il y a un appartement, délimité par des lignes horizontales supérieure et inférieure. Le conseiller expert les détecte et les définit lui-même.

Nous avons besoin que l'EA détecte lorsque le prix quitte la zone plate et y retourne. Et seulement après cela, il ouvre une position.

Pour filtrer le bruit, j'utilise une cible mobile avec le paramètre 2 ou 3

 
Vitaly Muzichenko:

Remplacez ces constructions sauvages "if(Volume[0]>1) return ;" par une vérification normale de "Nouvelle barre", il y en a beaucoup ici sur le forum.

Des avertissements tels que "la valeur de retour de 'ordersend' devrait être vérifiée" - ce n'est pas encore une erreur, c'est une erreur potentielle pour l'avenir. Il ne devrait y avoir aucun avertissement dans le code, et encore moins lorsqu'on travaille en ligne.

"J'ai 1, ce qui n'est pas trop peu" - cela peut être très peu à l'ouverture d'une nouvelle barre, et surtout à l'ouverture d'une demi-heure ou d'une heure, à ce moment-là l'écart se creuse fortement.

Ce dont nous avons besoin : faire une vérification sur la nouvelle barre, et si elle est nouvelle, alors regarder les conditions d'entrée, si elles coïncident - faire un accord. Après cela, nous devons enregistrer que le bar a fonctionné et attendre le nouveau.

Ce que nous avons maintenant : if(Volume[0]>1) return ; = s'il y a une nouvelle barre, alors regardez les conditions, la condition ne correspond pas == grand écart = sortie à nouveau dans OnTick(), sur le prochain tick if(Volume[0]>1) return ; il ne manquera pas plus, donc le trade sera manqué même si l'écart est de 0.0001


A propos de l'ouverture d'un nouveau bar. Est-ce que ce serait bien ? :

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

A propos de l'ouverture d'un nouveau bar. Serait-ce une bonne option ? :

Que ce soit comme ça au début.

Ensuite, nous devons faire une fixation correcte que la barre est travaillée, mais ici nous devons calculer l'approche entière du RPT.

D'après ce que je vois dans votre message, nous devons procéder de cette façon :

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

L'essentiel est le suivant : si l'écart est supérieur à la normale, nous sortons à nouveau deOnTick, et sur un nouveau tick, nous vérifions l'écart, s'il est normal - nous envoyons un ordre et nous nous souvenons qu'il y a eu une transaction sur cette barre.

Il y a aussi une deuxième voie :

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

En général, vous devez définir la logique, quand il doit enregistrer, et ne pas vérifier à nouveau avant la formation d'une "Nouvelle barre".