Auto-aprendizagem da linguagem MQL5 a partir do zero - página 84

 
Georgiy Merts #:

Isso é o que estou dizendo!

E você diz: "ninguém viu". Ninguém está interessado - portanto ninguém viu (os palhaços não estão interessados - não viram). Aqueles que estão interessados - eles já viram.

Enviou uma reclamação aos moderadores contra o palhaço, e o fará até ser banido
 
Vladimir Baskakov #:
Enviou uma reclamação aos moderadores sobre o palhaço, e o fará até ser banido

Oh, assustou o ouriço com o rabo nu.

 
Georgiy Merts #:

Oh, assustou o ouriço com o rabo nu.

Eu não tenho pressa.
 
Georgiy Merts #:

Eu não vejo o problema.

Certo. Uma matriz preenchida é declarada, e então - ela é preenchida novamente, com outros dados. Na minha opinião, é um erro bastante aceitável para um iniciante.

E isso é um erro?

Quando estou declarando variáveis e matrizes, devo preenchê-las IMEDIATAMENTE. Se no momento da declaração o valor exato é desconhecido, eu o preencho com um valor intencionalmente inválido. Se uma variável é declarada sem inicialização e depois utilizada, ela pode conter valores aleatórios, que serão utilizados durante o trabalho, e o resultado deste trabalho será incorreto e será muito difícil encontrar o problema (eu a encontrei mais de uma vez).

Mas se uma variável for inicializada com valor inválido logo no momento da criação, no caso de usar uma variável não inicializada será imediatamente descoberto que ela contém algum lixo, será fácil encontrar de onde ela veio e ver que a variável foi usada sem inicialização.

Portanto, pessoalmente, acho que declarar uma série já povoada é uma boa prática. Mas devemos levar para lá os valores WRONG_VALUE.

Não sou contra a inicialização de variáveis e até mesmo de arrays. Por exemplo, como este

int ExtHandle[21] = {};

também será uma matriz inicializada. Mas mesmo isto, neste caso, não é necessário porque todo o conjunto é preenchido no OnInit(). Portanto, não vejo nenhuma necessidade nisso. E mesmo Pinóquio com suas maçãs não funciona aqui, porque antes de usar (ler) os valores, elas já serão inicializadas.

 
Alexey Viktorov #:

Não sou de modo algum contra a inicialização de variáveis e até mesmo de arrays. Por exemplo, como este

também será uma matriz inicializada. Mas mesmo isto neste caso particular não é necessário, porque no OnInit() todo o conjunto é preenchido. Portanto, não vejo nenhuma necessidade nisso. E mesmo Pinóquio com suas maçãs não funcionará aqui, porque antes de usar (ler) os valores, elas já serão inicializadas.

Eh... E onde será "inicializada"? Por código, tal conjunto será preenchido com lixo.

Na minha opinião, é uma boa prática inicializar com valores não invalidos na criação, como já disse:

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

É claro, se a matriz é grande - não é razoável preenchê-la por tal método, neste caso eu uso a versão DEBUG, na qual eu preencho mesmo uma matriz grande com valores não-invalidos, enquanto que na versão RELEASE não há preenchimento.

Esta prática tem me poupado repetidamente do uso de variáveis não inicializadas.

 
SanAlex #:

Seu nome no código - o código que você criou sob seu nome para saber. Mas não funcionou.


Bem, quem é o culpado por suas mãos ruins?

Na imagem você pode ver que o valor calculado é 9,08253 e após a conversão 9,08 e não me diga cerca de 1 em 16 casas decimais.

E também, se você receber um valor menor que o volume mínimo

Tive que entrar outra variável para mostrar...

 
Georgiy Merts #:

Erm... E onde seria "inicializada"? Por código, tal conjunto estaria cheio de lixo.

Em minha opinião, é uma boa prática inicializar na criação com valores inválidos, como eu já disse:

É claro, se a matriz é grande - não é razoável preenchê-la por tal método, neste caso eu uso a versão DEBUG, na qual eu preencho mesmo uma matriz grande com valores não-invalidos, enquanto que na versão RELEASE não há preenchimento.

Esta prática tem me poupado repetidamente do uso de variáveis não inicializadas.

Aqui mesmo, no laço destacado. E note o fato de que eu estava falando apenas de uma matriz.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Auto-estudo em MQL5 a partir do zero

SanAlex, 2021.11.29 07:17

não consigo entender do que você está falando. eu o fiz com minhas próprias mãos. o que você quer dizer? o código é do terminal, mas a maneira em si, como implementar a abertura de alguns pares no testador, eu pessoalmente alcancei o resultado.

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

Mostre-me onde eu tirei o código de você.

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

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


Retirei tudo do código que não diz respeito ao nosso diálogo. Bem, quase tudo...

 
Alexey Viktorov #:

Bem ali, no laço destacado. E note o fato de que eu estava falando apenas de uma matriz.

Sim, é isso mesmo. Na minha opinião, a prática normal.

 
SanAlex #:

Este está quase pronto - só preciso remover funções não-funcionais desnecessárias. Este Expert Advisor Multimoedas é deste "MACD Sample.mq5".

Pareço ter removido todas as coisas desnecessárias para que funcionasse. Tenho que poli-lo ao gosto e depois o afixarei aqui.

Captura de tela 2021-11-29 155519

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

Isto é o que eu tenho até agora - talvez alguém o faça melhor

Arquivos anexados:
00001_Mult.mq5  15 kb
 
Alexey Viktorov #:

Espero realmente que não tenha escrito isto...

Aqui está uma função de trabalho

Tudo o que você tem que fazer é inserir o tamanho do risco para não contar a partir da margem livre total...

Bom dia e bom humor para todos!

Demorei muito tempo para entender e examinar matrizes, mas já tenho o resultado, pois escrevi o código de função que calcula o risco para 12 pares de moedas por mim mesmo.

Cumprimentos, 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ão: