Autoaprendizaje del lenguaje MQL5 desde cero - página 84

 
Georgiy Merts #:

¡Eso es lo que estoy diciendo!

Y dices que "nadie ha visto". A nadie le interesa, por lo que nadie lo ha visto (a los payasos no les interesa, no lo han visto). Los que están interesados - han visto.

Envié una queja a los moderadores contra el payaso, y lo haré hasta que te baneen
 
Vladimir Baskakov #:
Envié una queja a los moderadores sobre el payaso, y lo haré hasta que te baneen

Oh, asustó al erizo con su trasero desnudo...

 
Georgiy Merts #:

Oh, asustó al erizo con su trasero desnudo...

No tengo prisa.
 
Georgiy Merts #:

No veo el problema.

Sí. Se declara un array lleno, y luego - se llena de nuevo, con otros datos. En mi opinión, es un error bastante aceptable para un principiante.

¿Y es un error?

Cuando estoy declarando variables y arrays, DEBO LLENARLOS INMEDIATAMENTE. Si en el momento de la declaración se desconoce el valor exacto, lo relleno con un valor no válido a sabiendas. Si se declara una variable sin inicializar y luego se utiliza, puede contener valores aleatorios, que se utilizarán durante el trabajo, y el resultado de este trabajo será incorrecto y será muy difícil encontrar el problema (lo he encontrado más de una vez).

Pero si una variable se inicializa con un valor no válido justo en el momento de su creación, en caso de utilizar una variable no inicializada se descubrirá inmediatamente que contiene alguna basura, será fácil encontrar de dónde viene y ver que la variable se utilizó sin inicializar.

Así que, personalmente, creo que declarar un array ya poblado es una buena práctica. Pero debemos tomar valores WRONG_VALUE allí.

No estoy en contra de la inicialización de variables e incluso de arrays en absoluto. Por ejemplo, así

int ExtHandle[21] = {};

también será un array inicializado. Pero incluso esto en este caso no es necesario porque todo el array se llena en OnInit(). Así que no veo ninguna necesidad en ello. Y ni siquiera Pinocho con sus manzanas funciona aquí, porque antes de usar (leer) los valores, ya estarán inicializados.

 
Alexey Viktorov #:

No me importa inicializar variables o incluso arrays en absoluto. Por ejemplo, así

también será un array inicializado. Pero incluso esto en este caso particular no es necesario, porque en OnInit() se llena todo el array. Así que no veo ninguna necesidad en ello. E incluso Pinocho con sus manzanas no funcionará aquí, porque antes de usar (leer) los valores, ya estarán inicializados.

Eh... ¿Y dónde se va a "inicializar"? Por código, tal matriz se llenará de basura.

En mi opinión, es una buena práctica inicializar con valores no inválidos en la creación, como ya he dicho:

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

Por supuesto, si el array es grande - no es razonable llenarlo con este método, en este caso utilizo la versión DEBUG, en la que relleno incluso el array grande con valores no inválidos, mientras que en la versión RELEASE no hay relleno.

Esta práctica me ha salvado repetidamente de utilizar variables no inicializadas.

 
SanAlex #:

Tu nombre en el código - el código que has creado bajo tu nombre para saberlo. Pero no funcionó.


Bueno, ¿quién tiene la culpa de sus malas manos?

En la imagen se puede ver que el valor calculado es 9,08253 y después de la conversión 9,08 y no me digan el 1 en 16 decimales.

Y además, si se obtiene un valor inferior al volumen mínimo

Tuve que introducir otra variable para mostrar...

 
Georgiy Merts #:

Erm... ¿Y dónde se "inicializaría"? Por código, una matriz así estaría llena de basura.

En mi opinión, es una buena práctica inicializar en la creación con valores no válidos, como ya he dicho:

Por supuesto, si el array es grande - no es razonable llenarlo con este método, en este caso utilizo la versión DEBUG, en la que relleno incluso el array grande con valores no inválidos, mientras que en la versión RELEASE no hay relleno.

Esta práctica me ha salvado repetidamente de utilizar variables no inicializadas.

Justo aquí, en el bucle resaltado. Y nótese el hecho de que sólo estaba hablando de una matriz.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Autoaprendizaje en MQL5 desde cero

SanAlex, 2021.11.29 07:17

no puedo entender de que hablas. lo hice con mis propias manos. ¿a que te refieres? el codigo es del terminal, pero la forma en si, como implementar la apertura de unos pares en el tester, yo personalmente logre el resultado.

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

Muéstrame dónde te he quitado el código.

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

//|                        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);
  }


He eliminado del código todo lo que no tiene que ver con nuestro diálogo. Bueno, casi todo...

 
Alexey Viktorov #:

Justo ahí, en el bucle resaltado. Y nótese el hecho de que sólo estaba hablando de una matriz.

Sí, así es. En mi opinión, es una práctica normal.

 
SanAlex #:

Este está casi listo - sólo necesito eliminar las funciones innecesarias no funcionales. Este Asesor Experto multidivisa es de este "MACD Sample.mq5"

Parece que he eliminado todas las cosas innecesarias para que funcione. Tengo que pulirlo al gusto y luego lo publicaré aquí.

Captura de pantalla 2021-11-29 155519

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

Esto es lo que he conseguido hasta ahora - quizás alguien lo haga mejor

Archivos adjuntos:
00001_Mult.mq5  15 kb
 
Alexey Viktorov #:

Realmente espero que no hayas escrito esto...

Esta es una función que funciona

Todo lo que tienes que hacer es introducir el tamaño del riesgo para que no cuente desde el margen libre completo...

¡Buen día y buen humor a todos!

Me llevó mucho tiempo entender y examinar las matrices, pero ya tengo el resultado, porque escribí el código de la función que calcula el riesgo para 12 pares de divisas por mí mismo.

Saludos, 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);
  }
//+------------------------------------------------------------------+
Razón de la queja: