Самообучение языку MQL5 с полного нуля - страница 84

 
Georgiy Merts #:

Дык и я про то! 

А ты говоришь "никто не видел". Никому ж неинтересно - вот никто и не видел (клоунам неинтересно - они не видели). Тем, кому интересно - те видели. 

Отправил жалобу модераторам на клоуна, и буду делать это до тех пор, пока тебя не забанят
 
Vladimir Baskakov #:
Отправил жалобу модераторам на клоуна, и буду делать это до тех пор, пока тебя не забанят

Ох, испугал ежа голой задницей... 

 
Georgiy Merts #:

Ох, испугал ежа голой задницей... 

Я не тороплюсь
 
Georgiy Merts #:

А я не вижу проблемы.

Ну верно. Объявляется заполненный массив, а потом - он заполняется опять, другими данными. На мой взгляд, вполне допустимая ошибка начинающего. 

Да и ошибка ли? 

Я вот при объявлении переменных и массивов ОБЯЗАТЕЛЬНО их СРАЗУ ЖЕ заполняю. Если на момент объявления точное значение неизвестно, заполняю заведомо невалидным значением. Для того, чтобы максимально эффективно выявить ошибку использования неинициализированной переменной.  Если переменную объявить без инициализации, а потом ее использовать - то в ней могут быть случайные значения, которые будут использоваться при работе, и результат этой работы будет неверным, найти проблему будет очень непросто (не раз на это натыкался). 

А вот если переменная сразу при создании инициализируется невалидным значением, то в случае использования неинициализированной переменной сразу же выяснится, что в ней какой-то мусор, легко найти, откуда он взялся, и увидеть, что переменная использовалась без инициализации. 

Так что лично я считаю, что объявление массива уже заполненным - это правильная практика. Вот только значения там надо брать WRONG_VALUE. 

Я нисколько не против инициализации переменных и даже массивов. Например так 

int ExtHandle[21] = {};

тоже будет инициализированный массив. Но даже это в данном конкретном случае не обязательно, ведь в OnInit() весь массив заполняется. Так-что никакой необходимости не вижу. И даже Буратино со своими яблоками тут не катит, потому, что перед использованием(чтением) значений они уже будут инициализированы.

 
Alexey Viktorov #:

Я нисколько не против инициализации переменных и даже массивов. Например так 

тоже будет инициализированный массив. Но даже это в данном конкретном случае не обязательно, ведь в OnInit() весь массив заполняется. Так-что никакой необходимости не вижу. И даже Буратино со своими яблоками тут не катит, потому, что перед использованием(чтением) значений они уже будут инициализированы.

Ээээ... И где ж он будет "инициализированный"? По коду - такой массив будет заполнен мусором. 

На мой взгляд, хорошая практика - инициализировать при создании невалидными значениями, как я уже сказал:

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

Конечно, если массив велик - заполнять его таким методом неразумно, в этом случае я использую DEBUG-версию, в которой-таки заполняю даже большой массив невалидными значениями, а в RELEASE-версии заполнения нет. 

Меня такая практика неоднократно спасала от использования неинициализированных переменных. 

 
SanAlex #:

Ваше имя в коде - код который вы выставляли я создал под вашем именем что бы знать. Но он оказался не рабочий 


Ну кто-же виноват в твоих кривых руках?

На снимке видно, что расчётное значение 9.08253 а после преобразования 9.08 и не говори мне о единичке в 16ом знаке после запятой.

И вот ещё, если получилось значение меньше минимального объёма

Чтобы показать пришлось ввести ещё одну переменную…

 
Georgiy Merts #:

Ээээ... И где ж он будет "инициализированный"? По коду - такой массив будет заполнен мусором. 

На мой взгляд, хорошая практика - инициализировать при создании невалидными значениями, как я уже сказал:

Конечно, если массив велик - заполнять его таким методом неразумно, в этом случае я использую DEBUG-версию, в которой-таки заполняю даже большой массив невалидными значениями, а в RELEASE-версии заполнения нет. 

Меня такая практика неоднократно спасала от использования неинициализированных переменных. 

Вот здесь, в выделенном цикле. И обратите внимание, на тот факт, что я говорил только об одном массиве.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Самообучение языку MQL5 с полного нуля

SanAlex, 2021.11.29 07:17

не пойму о чём Вы ? лично своими руками я это сделал вы о чём? код из терминала но сам способ, как реализовать открытия в тестере несколько пар, я сам лично добился результата. 

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

покажите в каком месте я взял у вас код?

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

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


Всё не касающееся нашего диалога я из кода удалил. Ну, почти всё…

 
Alexey Viktorov #:

Вот здесь, в выделенном цикле. И обратите внимание, на тот факт, что я говорил только об одном массиве.

Да, все верно. На мой взгляд, нормальная практика.

 
SanAlex #:

Вот этот почти готов - надо только лишние нерабочие функции удалить. Этого мультивалютного эксперта перелопатил с этого "MACD Sample.mq5"

 

вроде мне удалось всё лишнее по удалять, что бы он заработал. Ещё нужно довести до ума и тогда выложу сюда.

Снимок экрана 2021-11-29 155519  

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

Вот что пока получилось - может кто лучше себе доделает 

Файлы:
00001_Mult.mq5  15 kb
 
Alexey Viktorov #:

Очень надеюсь, что это писали не вы…

Вот рабочая функция

Достаточно только вписать размер риска, чтобы считать не от полной свободной маржи…

Всем доброго дня и хорошего настроения!

Очень долго разбирался и изучал массивы, но результат уже есть, т.к. самостоятельно написал код функции, которая рассчитывает риск по 12 валютным парам.

С уважением, Владимир.

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

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);
  }
//+------------------------------------------------------------------+
Причина обращения: