Auto-apprentissage du langage MQL5 à partir de zéro - page 84

 
Georgiy Merts #:

C'est ce que je dis !

Et vous dites "personne n'a vu". Personne n'est intéressé - donc personne ne l'a vu (les clowns ne sont pas intéressés - ils ne l'ont pas vu). Ceux qui sont intéressés - ils ont vu.

J'ai envoyé une plainte aux modérateurs contre le clown, et je le ferai jusqu'à ce que vous soyez banni.
 
Vladimir Baskakov #:
J'ai envoyé une plainte aux modérateurs à propos de ce clown, et je le ferai jusqu'à ce que vous soyez banni.

Oh, il a effrayé le hérisson avec son cul nu...

 
Georgiy Merts #:

Oh, il a effrayé le hérisson avec son cul nu...

Je ne suis pas pressé.
 
Georgiy Merts #:

Je ne vois pas le problème.

Bien. Un tableau rempli est déclaré, et ensuite - il est rempli à nouveau, avec d'autres données. À mon avis, c'est une erreur tout à fait acceptable pour un débutant.

Et est-ce une erreur ?

Lorsque je déclare des variables et des tableaux, je DOIS les remplir IMMÉDIATEMENT. Si, au moment de la déclaration, la valeur exacte est inconnue, je la remplis avec une valeur sciemment non valable. Si une variable est déclarée sans initialisation et ensuite utilisée, elle peut contenir des valeurs aléatoires, qui seront utilisées pendant le travail, et le résultat de ce travail sera incorrect et il sera très difficile de trouver le problème (je l'ai trouvé plus d'une fois).

Mais si une variable est initialisée avec une valeur invalide dès sa création, en cas d'utilisation d'une variable non initialisée, on s'apercevra immédiatement qu'elle contient des déchets, il sera facile de trouver d'où ils viennent et de voir que la variable a été utilisée sans initialisation.

Donc personnellement, je pense que déclarer un tableau déjà peuplé est une bonne pratique. Mais nous devrions prendre des valeurs WRONG_VALUE à cet endroit.

Je ne suis pas du tout contre l'initialisation des variables et même des tableaux. Par exemple, comme ceci

int ExtHandle[21] = {};

sera également un tableau initialisé. Mais même cela, dans ce cas, n'est pas nécessaire car le tableau entier est rempli dans OnInit(). Je n'en vois donc pas l'utilité. Et même Pinocchio avec ses pommes ne fonctionne pas ici, car avant d'utiliser (lire) les valeurs, elles seront déjà initialisées.

 
Alexey Viktorov #:

L'initialisation des variables ou même des tableaux ne me dérange pas du tout. Par exemple, comme ceci

sera également un tableau initialisé. Mais même cela, dans ce cas particulier, n'est pas nécessaire, car dans OnInit() le tableau entier est rempli. Je n'en vois donc pas l'utilité. Et même Pinocchio avec ses pommes ne fonctionnera pas ici, car avant d'utiliser (de lire) les valeurs, elles seront déjà initialisées.

Eh... Et où sera-t-il "initialisé" ? Par code, un tel tableau sera rempli de déchets.

À mon avis, c'est une bonne pratique d'initialiser avec des valeurs non invalides à la création, comme je l'ai déjà dit :

int ExtHandle[3] = {WRONG_VALUE;WRONG_VALUE;WRONG_VALUE};

Bien sûr, si le tableau est grand - il est déraisonnable de le remplir par cette méthode, dans ce cas j'utilise la version DEBUG, dans laquelle je remplis même un grand tableau avec des valeurs non invalides, alors que dans la version RELEASE il n'y a pas de remplissage.

Cette pratique m'a évité à plusieurs reprises d'utiliser des variables non initialisées.

 
SanAlex #:

Votre nom dans le code - le code que vous avez mis en place, je l'ai créé sous votre nom pour le savoir. Mais ça n'a pas marché.


Eh bien, qui est à blâmer pour vos mauvaises mains ?

Sur l'image vous pouvez voir que la valeur calculée est 9.08253 et après conversion 9.08 et ne me parlez pas de 1 sur 16 décimales.

Et aussi, si vous obtenez une valeur inférieure au volume minimum

J'ai dû entrer une autre variable pour montrer...

 
Georgiy Merts #:

Erm... Et où serait-il "initialisé" ? Par code, un tel tableau serait plein de déchets.

A mon avis, c'est une bonne pratique d'initialiser avec des valeurs invalides à la création, comme je l'ai déjà dit :

Bien sûr, si le tableau est grand - il est déraisonnable de le remplir par cette méthode, dans ce cas j'utilise la version DEBUG, dans laquelle je remplis même un grand tableau avec des valeurs non invalides, alors que dans la version RELEASE il n'y a pas de remplissage.

Cette pratique m'a évité à plusieurs reprises d'utiliser des variables non initialisées.

Juste ici, dans la boucle lumineuse. Et notez le fait que je ne parlais que d'un seul tableau.

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

Auto-apprentissage de MQL5 à partir de zéro

SanAlex, 2021.11.29 07:17

je ne comprends pas de quoi vous parlez. je l'ai fait de mes propres mains. que voulez-vous dire ? le code provient du terminal, mais la manière elle-même, comment mettre en œuvre l'ouverture de quelques paires dans le testeur, j'ai personnellement obtenu le résultat.

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

Montre-moi où je t'ai pris le code.

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

//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\Trade.mqh>
//---
CTrade ExtTrade;
//+------------------------------------------------------------------+
input double MaximumRisk        = 0.02; // Maximum Risk in percentage
//---
int    ExtHandle[]= {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
double LotsRisk[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
string symb_name[]= {"EURUSD","GBPUSD","USDCHF","USDJPY","USDCAD","AUDUSD","AUDNZD",
                     "AUDCAD","AUDCHF","AUDJPY","CHFJPY","EURGBP","EURAUD","EURCHF",
                     "EURJPY","EURNZD","EURCAD","GBPCHF","GBPJPY","CADCHF","GBPAUD"
                    };

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ExtTrade.SetExpertMagicNumber(0);
   ExtTrade.SetMarginMode();
//---
   for(int i=0; i<20; i++)
     {
      ExtTrade.SetTypeFillingBySymbol(symb_name[i]);
      //--- Moving Average indicator
      ExtHandle[i]=iMA(symb_name[i],_Period,12,6,MODE_SMA,PRICE_CLOSE);
      if(ExtHandle[i]==INVALID_HANDLE)
        {
         printf("Error creating MA indicator");
         return(INIT_FAILED);
        }
     }
//---
   return(INIT_SUCCEEDED);
  }


J'ai retiré du code tout ce qui ne concerne pas notre dialogue. Eh bien, presque tout...

 
Alexey Viktorov #:

Juste là, dans la boucle mise en évidence. Et notez le fait que je ne parlais que d'un seul tableau.

Oui, c'est vrai. A mon avis, c'est une pratique normale.

 
SanAlex #:

Celui-ci est presque prêt - je dois juste supprimer les fonctions non fonctionnelles inutiles. Ce conseiller expert multidevises est issu de ce "MACD Sample.mq5".

Il semble que j'ai supprimé toutes les choses inutiles pour que cela fonctionne. Je dois le polir pour le mettre au goût du jour et ensuite je le posterai ici.

Capture d'écran 2021-11-29 155519

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

Voici ce que j'ai obtenu jusqu'à présent - peut-être que quelqu'un le fera mieux

Dossiers :
00001_Mult.mq5  15 kb
 
Alexey Viktorov #:

J'espère vraiment que tu n'as pas écrit ça...

Voici une fonction qui fonctionne

Tout ce que vous avez à faire est d'entrer la taille du risque à ne pas compter de la pleine marge libre ...

Bonne journée et bonne humeur à tous !

Il m'a fallu beaucoup de temps pour comprendre et examiner les tableaux, mais j'ai déjà le résultat, car j'ai écrit le code de la fonction qui calcule le risque pour 12 paires de devises par moi-même.

Salutations, Vladimir.

//+------------------------------------------------------------------+
//| Входные параметры советника                                      |
//+------------------------------------------------------------------+

input double   Risk0=1.0;           //Риск для валютной пары EURUSD (% от баланса)
.
.
.
.
input double   Risk11=1.0;           //Риск для валютной пары EURJPY (% от баланса)

//+------------------------------------------------------------------+
//| Функция Money_Management рассчитывает размер лота в зависимости  |
//| от риска, заданного во входных параметрах советника.             |
//+------------------------------------------------------------------+
double Money_Management()
  {
//--- объявляем динамический массив
   double risk[];
//--- устанавливаем размер массива
   ArrayResize(risk,12);
//--- заполняем массив значениями риска
   ArrayFill(risk,0,1,Risk0);
   ArrayFill(risk,1,1,Risk1);
   ArrayFill(risk,2,1,Risk2);
   ArrayFill(risk,3,1,Risk3);
   ArrayFill(risk,4,1,Risk4);
   ArrayFill(risk,5,1,Risk5);
   ArrayFill(risk,6,1,Risk6);
   ArrayFill(risk,7,1,Risk7);
   ArrayFill(risk,8,1,Risk8);
   ArrayFill(risk,9,1,Risk9);
   ArrayFill(risk,10,1,Risk10);
   ArrayFill(risk,11,1,Risk11);
//---
   double price=0.0;
   double margin=0.0;
   double MaximumRisk=risk[11]/100;
//---
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);
//---
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
//---
   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//---
   if(lot<min_volume)
      lot=min_volume;
   if(lot>max_volume)
      lot=max_volume;
   return(lot);
  }
//+------------------------------------------------------------------+
Raison: