Autoapprendimento del linguaggio MQL5 da zero - pagina 84

 
Georgiy Merts #:

Questo è quello che sto dicendo!

E tu dici 'nessuno ha visto'. Nessuno è interessato - quindi nessuno l'ha visto (i clown non sono interessati - non l'hanno visto). Quelli che sono interessati - hanno visto.

Ha inviato un reclamo ai moderatori contro il pagliaccio, e lo farà fino a quando non verrà bannato
 
Vladimir Baskakov #:
Ha inviato un reclamo ai moderatori riguardo al pagliaccio, e lo farà fino a quando non verrà bannato

Oh, ha spaventato il riccio con il suo culo nudo...

 
Georgiy Merts #:

Oh, ha spaventato il riccio con il suo culo nudo...

Non ho fretta.
 
Georgiy Merts #:

Non vedo il problema.

Giusto. Viene dichiarata una matrice riempita, e poi - viene riempita di nuovo, con altri dati. Secondo me, è un errore abbastanza accettabile per un principiante.

Ed è un errore?

Quando dichiaro variabili e array, DEVO riempirli IMMEDIATAMENTE. Se al momento della dichiarazione il valore esatto è sconosciuto, lo riempio con un valore consapevolmente non valido. Se una variabile viene dichiarata senza inizializzazione e poi utilizzata, può contenere valori casuali, che verranno utilizzati durante il lavoro, e il risultato di questo lavoro sarà sbagliato e sarà molto difficile trovare il problema (l'ho trovato più di una volta).

Ma se una variabile è inizializzata con un valore non valido proprio alla creazione, nel caso in cui si usi una variabile non inizializzata si scoprirà immediatamente che contiene della spazzatura, sarà facile trovare da dove viene e vedere che la variabile è stata usata senza inizializzazione.

Quindi, personalmente, penso che dichiarare un array già popolato sia una buona pratica. Ma lì dovremmo prendere valori WRONG_VALUE.

Non sono affatto contrario all'inizializzazione delle variabili e persino degli array. Per esempio, così

int ExtHandle[21] = {};

sarà anche un array inizializzato. Ma anche questo in questo caso non è necessario perché l'intero array è riempito in OnInit(). Quindi non ne vedo la necessità. E anche Pinocchio con le sue mele non funziona qui, perché prima di usare (leggere) i valori, questi saranno già inizializzati.

 
Alexey Viktorov #:

Non mi dispiace affatto inizializzare le variabili o anche gli array. Per esempio, così

sarà anche un array inizializzato. Ma anche questo in questo caso particolare non è necessario, perché in OnInit() l'intero array viene riempito. Quindi non ne vedo la necessità. E anche Pinocchio con le sue mele non funzionerà qui, perché prima di usare (leggere) i valori, questi saranno già inizializzati.

Eh... E dove sarà "inizializzato"? Per codice, un tale array sarà riempito di spazzatura.

Secondo me, è buona pratica inizializzare con valori non validi alla creazione, come ho già detto:

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

Naturalmente, se l'array è grande - è irragionevole riempirlo con tale metodo, in questo caso uso la versione DEBUG, in cui riempio anche array grandi con valori non validi, mentre nella versione RELEASE non c'è riempimento.

Questa pratica mi ha salvato più volte dall'uso di variabili non inizializzate.

 
SanAlex #:

Il tuo nome nel codice - il codice che hai impostato l'ho creato sotto il tuo nome per saperlo. Ma non ha funzionato.


Beh, di chi è la colpa per le tue brutte mani?

Sull'immagine potete vedere che il valore calcolato è 9.08253 e dopo la conversione 9.08 e non mi dite di 1 in 16 cifre decimali.

E inoltre, se si ottiene un valore inferiore al volume minimo

Ho dovuto inserire un'altra variabile per mostrare...

 
Georgiy Merts #:

Ehm... E dove sarebbe "inizializzato"? In base al codice, un tale array sarebbe pieno di spazzatura.

Secondo me, è buona pratica inizializzare con valori non validi alla creazione, come ho già detto:

Naturalmente, se l'array è grande - è irragionevole riempirlo con tale metodo, in questo caso uso la versione DEBUG, in cui riempio anche array grandi con valori non validi, mentre nella versione RELEASE non c'è riempimento.

Questa pratica mi ha salvato più volte dall'uso di variabili non inizializzate.

Proprio qui, nel ciclo evidenziato. E notate il fatto che stavo parlando solo di un array.

Forum sul trading, sistemi di trading automatico e test di strategia

Autoapprendimento in MQL5 da zero

SanAlex, 2021.11.29 07:17

Non riesco a capire di cosa stai parlando. l'ho fatto con le mie mani. cosa vuoi dire? il codice è dal terminale, ma il modo stesso, come implementare l'apertura di alcune coppie nel tester, ho raggiunto personalmente il risultato.

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

Mostrami dove ho preso il codice da te.

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

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


Ho rimosso dal codice tutto ciò che non riguarda il nostro dialogo. Beh, quasi tutto...

 
Alexey Viktorov #:

Proprio lì, nel ciclo evidenziato. E notate il fatto che stavo parlando solo di un array.

Sì, proprio così. A mio parere, una pratica normale.

 
SanAlex #:

Questo è quasi pronto - ho solo bisogno di rimuovere le funzioni non funzionali non necessarie. Questo Expert Advisor multivaluta proviene da questo "MACD Sample.mq5".

Mi sembra di aver rimosso tutte le cose inutili per farlo funzionare. Devo lucidarlo al gusto e poi lo posterò qui.

Schermata 2021-11-29 155519

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

Questo è quello che ho ottenuto finora - forse qualcuno lo farà meglio

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

Spero davvero che tu non abbia scritto questo...

Ecco una funzione funzionante

Tutto quello che devi fare è inserire la dimensione del rischio per non contare dal margine libero completo...

Buona giornata e buon umore a tutti!

Mi ci è voluto molto tempo per capire ed esaminare gli array, ma ho già il risultato, perché ho scritto da solo il codice della funzione che calcola il rischio per 12 coppie di valute.

Saluti, 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);
  }
//+------------------------------------------------------------------+
Motivazione: