Ваши вопросы по языку MQL4

AlexeyVik

Программист mql4 mql5
K[3][20] - 3 показателя за 20 дней, а K[20][3] - за 20 дней 3 показателя!:cool:
Ну да. Как-то мне ни разу не приходило желание почесать левое ухо мизинцем правой ноги.
Не спорю, работать будет, но крайне неудобно.
 

Ugar

Гуру форума
Ведь K[3][20] то есть 3 показателя за 20 дней

А K[20][3] 20 показателей за 3 дня
Ну да, а можно же в голове переставить измерения и тогда получится что K[20][3] за 20 дней 3 показателя.
А смысл в этом появится когда понадобится менять количество дней, ведь только в 0 измерении можно менять размер.
 

star603

Новичок форума
Не получился, а специально так написал. Что бы пояснить зачем дни именно в 0 измерение лучше делать.
я совсем запутался вващих рассуждениях. K[20][3] вобще не представлюю как вы храните показатели 20 дней. Покажите как например то о чем выговорите. Пока для меня K[3][20]
3 это количество индикаторов.
K[0][0-19] один индикатор 0 текущий свеча и текущий показатель. MA c периодом 18
K[1][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 36
K[2][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 72
 

AlexeyVik

Программист mql4 mql5
я совсем запутался вващих рассуждениях. K[20][3] вобще не представлюю как вы храните показатели 20 дней. Покажите как например то о чем выговорите. Пока для меня K[3][20]
3 это количество индикаторов.
K[0][0-19] один индикатор 0 текущий свеча и текущий показатель. MA c периодом 18
K[1][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 36
K[2][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 72
Ну так вот-же я объяснял
Так вот именно в таком случае должно быть 20 в первом измерении.
Первый день, индекс 0 — 3 значения
Второй день, индекс 1 — 3 значения
………………………………
Двадцатый день, индекс 19 — 3 значения.
Первый день
K[0][0] = MA c периодом 18
K[0][1] = MA c периодом 36
K[0][2] = MA c периодом 72
второй день
K[1][0] = MA c периодом 18
K[1][1] = MA c периодом 36
K[1][2] = MA c периодом 72
…………………………………
двадцатый день
K[19][0] = MA c периодом 18
K[19][1] = MA c периодом 36
K[19][2] = MA c периодом 72
 

Ugar

Гуру форума
я совсем запутался вващих рассуждениях. K[20][3] вобще не представлюю как вы храните показатели 20 дней. Покажите как например то о чем выговорите. Пока для меня K[3][20]
3 это количество индикаторов.
K[0][0-19] один индикатор 0 текущий свеча и текущий показатель. MA c периодом 18
K[1][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 36
K[2][0-19] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 72
Я же приводил пример
Код:
Expand Collapse Copy
//--- input parameters
input uint     CalculateBars=20;

double K[][3];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArrayResize(K,CalculateBars);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   for(int i = 0; i < ArrayRange(K, 0);i++)
      {
       K[i][0]= iMACD(NULL,PERIOD_CURRENT,36,18,9,PRICE_CLOSE,MODE_MAIN,i);
       K[i][1]= iMACD(NULL,PERIOD_CURRENT,36,18,9,PRICE_CLOSE,MODE_SIGNAL,i);
       K[i][2]=K[i][0]-K[i][1];
      }
  }
Ну или так, просто поменять измерения местами.
K[0-19][0] один индикатор 0 текущий свеча и текущий показатель. MA c периодом 18
K[0-19][1] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 36
K[0-19] [2] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 72
 
Последнее редактирование:

star603

Новичок форума
Я же приводил пример
Код:
Expand Collapse Copy
//--- input parameters
input uint     CalculateBars=20;

double K[][3];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArrayResize(K,CalculateBars);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   for(int i = 0; i < ArrayRange(K, 0);i++)
      {
       K[i][0]= iMACD(NULL,PERIOD_CURRENT,36,18,9,PRICE_CLOSE,MODE_MAIN,i);
       K[i][1]= iMACD(NULL,PERIOD_CURRENT,36,18,9,PRICE_CLOSE,MODE_SIGNAL,i);
       K[i][2]=K[i][0]-K[i][1];
      }
  }
Ну или так, просто поменять измерения местами.
K[0-19][0] один индикатор 0 текущий свеча и текущий показатель. MA c периодом 18
K[0-19][1] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 36
K[0-19] [2] один индикатор 0 текущий свечай и текущий показатель. MA c периодом 72
Но мне больше подходит вариант где показатели местами поменяны вот такой - K[3[0-19]. Я соглашаюсь с вашим мнением, но мой вариант просто удобен мне для восприятия.

вашем варианте мне не понятны две веши K[][3] - какая логика этой записи опираясь на наш массив и ArrayRange(K, 0); Если не известен количество элементов первой размерности значит данный массив динамический и тогда когда цикл прекратит действовать? И еще эта запись не понята мне ArrayResize(K,CalculateBars);?
 

star603

Новичок форума
Код:
Expand Collapse Copy
enum stopi
  {
   ba,//Фиксированные стопы
   bc,//Торговля без стопов
   bd,//Задаваемые стопы
   bf,//Стопы по МА
   bs,//Стопы по Сар
   bg,//Стопы по теням свечей
   bz,//Стопы по лоу свечам
   br,//Стопы по определенным пунктам
   bt//Торговля в безубыток
  };
//************************************************************
sinput stopi Loss =1;//Выбрать уровень стопов
double svecha[11][31];//Информация о свечах
//********************************************************
void OnTick()
  {
////////////////////////////////////////////////////////////////////////////
    uo(svecha);
    STOPI();
  
////////////////////////////////////////////////////////////////////////////
  }
//********************************************************
double STOPI()//Пользовательская функция
  {
   switch(Loss)
     {
      case 0:
         SL=0*Point;
         break;
      case 1:
         SL= svecha[1][1];
         break;       
     };
   return(SL);
  };
 //-----------------------------------------------------
 void uo(double &gh[11][31])
  {
   for(int i = 0; i < ArrayRange(gh, 1); i++)
     {
      gh[0][i] = Open[i];
      gh[1][i] = Close[i];
      gh[2][i] = High[i];
      gh[3][i] = Low[i];
      gh[4][i] = Open[i]-Close[i];
      gh[5][i] = High[i]-Low[i];
      gh[6][i] = High[i]-Open[i];
      gh[7][i] = High[i]-Close[i];
      gh[8][i] = Open[i]-Low[i];
      gh[9][i] = Close[i]-Low[i];
      gh[10][i]= High[i]-Low[i];
     }
  };

Скажите пожалуйста прокатит или нет чтобы потом был стоплос равен закрытию прошлой свечи. Идею пока не проверял. Заранее спасибо.
 
Последнее редактирование:

star603

Новичок форума
Код:
Expand Collapse Copy
enum stopi
  {
   ba,//Фиксированные стопы
   bc,//Торговля без стопов
   bd,//Задаваемые стопы
   bf,//Стопы по МА
   bs,//Стопы по Сар
   bg,//Стопы по теням свечей
   bz,//Стопы по лоу свечам
   br,//Стопы по определенным пунктам
   bt//Торговля в безубыток
  };
//************************************************************
sinput stopi Loss =1;//Выбрать уровень стопов
double svecha[11][31];//Информация о свечах
//********************************************************
void OnTick()
  {
////////////////////////////////////////////////////////////////////////////
    uo(svecha);
    STOPI();
 
////////////////////////////////////////////////////////////////////////////
  }
//********************************************************
double STOPI()//Пользовательская функция
  {
   switch(Loss)
     {
      case 0:
         SL=0*Point;
         break;
      case 1:
         SL= svecha[1][1];
         break;      
     };
   return(SL);
  };
 //-----------------------------------------------------
 void uo(double &gh[11][31])
  {
   for(int i = 0; i < ArrayRange(gh, 1); i++)
     {
      gh[0][i] = Open[i];
      gh[1][i] = Close[i];
      gh[2][i] = High[i];
      gh[3][i] = Low[i];
      gh[4][i] = Open[i]-Close[i];
      gh[5][i] = High[i]-Low[i];
      gh[6][i] = High[i]-Open[i];
      gh[7][i] = High[i]-Close[i];
      gh[8][i] = Open[i]-Low[i];
      gh[9][i] = Close[i]-Low[i];
      gh[10][i]= High[i]-Low[i];
     }
  };

Скажите пожалуйста прокатит или нет чтобы потом был стоплос равен закрытию прошлой свечи. Идею пока не проверял. Заранее спасибо.
Проверил работает
 

Ugar

Гуру форума
Но мне больше подходит вариант где показатели местами поменяны вот такой - K[3[0-19]. Я соглашаюсь с вашим мнением, но мой вариант просто удобен мне для восприятия.

вашем варианте мне не понятны две веши K[][3] - какая логика этой записи опираясь на наш массив и ArrayRange(K, 0); Если не известен количество элементов первой размерности значит данный массив динамический и тогда когда цикл прекратит действовать? И еще эта запись не понята мне ArrayResize(K,CalculateBars);?
CalculateBars - внешняя переменная в которой можно задать количество баров индикатора и размер массива соответственно. По умолчанию задано 20.
Справочник обычно помогает.
ArrayResize - Устанавливает новый размер в первом измерении массива
ArrayResize(K,CalculateBars); по сути задаёт размер K[CalculateBars][3]. То есть динамический массив становится по умолчанию K[20][3]. Соответственно ArrayRange(K, 0) вернёт 20.
Если же размер массива менять не надо, то измерения можно юзать как нравится. Размер массива можно менять только в 0 измерении, во всём остальном измерения равнозначны.
 
Последнее редактирование:

star603

Новичок форума
CalculateBars - внешняя переменная в которой можно задать количество баров индикатора и размер массива соответственно. По умолчанию задано 20.
Справочник обычно помогает.
ArrayResize - Устанавливает новый размер в первом измерении массива
ArrayResize(K,CalculateBars); по сути задаёт размер K[CalculateBars][3]. То есть динамический массив становится по умолчанию K[20][3]. Соответственно ArrayRange(K, 0) вернёт 20.
Если же размер массива менять не надо, то измерения можно юзать как нравится. Размер массива можно менять только в 0 измерении, во всём остальном измерения равнозначны.
Не спорю что справочник помогает. Просто вы обычные пользователи можете простым языком объяснить. Плюс справочник я тоже почитываю.
 

AlexeNP

Гуру форума
Код:
Expand Collapse Copy
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
double MA[10];


void OnTick()
  {
////////////////////////////////////////////////////////////////////////////
 mk();
 Comment("MA[1]=",MA[1],"\n",
         "MA[2]=",MA[2]);
////////////////////////////////////////////////////////////////////////////
  }
 
 double mk()//Пользовательская функция
{
 for(int i = 0; i < ArrayRange(MA, 0);i++)
  MA[i] = iMA(NULL,PERIOD_CURRENT,18,0,MODE_EMA,PRICE_CLOSE,i);
 return(MA[i]);
};

Получилось с одномерным массивом. На очереди с двумерным придумать как.
Снимок экрана20220403232734.png
 

vladradon

Программист
Тогда скажи почему это сработало и комментарии отразились с правильными значениями?
Массив инициализирован на глобальном уровне и его можно использовать в любых функциях без всяких ссылок. Поэтому после запуска функции mk() в нем появились данные и Comment их без проблем выдал. Return в функции никак не работает в этом случае.
 

AlexeNP

Гуру форума
Это я потом посмотрел по внимательнее. Тогда скажи почему это сработало и комментарии отразились с правильными значениями?
потому, что массив у тебя - глобальная переменная, и в него можно вносить изменения в любом месте программы... поэтому и присваивание функции типа double явно избыточно. можно ее сделать void без всякого return
 

star603

Новичок форума
Код:
Expand Collapse Copy
enum stopi
  {
   ba,//Фиксированные стопы
  };

sinput stopi Loss =0;//Выбрать уровень стопов
extern int StopLoss = 20;//убытки

double STOPI()
  {
   switch(Loss)//Выпадающий список
     {
      case 0: Sl = StopLoss*Point;       
     };
   return(SL);
  };

Подскажите как лучше быть в таком случае. Самому дописывать в код открытие ордера?
Пока мне видеться так :
Код:
Expand Collapse Copy
Ask+SL и Bid-SL
А чтобы наверняка сработало:
Код:
Expand Collapse Copy
double minst = MarketInfo(Symbol(),MODE_STOPLEVEL)*Point;
Ask+SL+minst и Bid-SL-minst
 

vladradon

Программист
А чтобы наверняка сработало
Стоплосс при ненулевом стопуровне должен быть минимум на 1 больше стопуровня.
C#:
Expand Collapse Copy
double STOPI()
  {
    int minst = MarketInfo(Symbol(),MODE_STOPLEVEL);
    switch(Loss)//Выпадающий список
      {
       case 0: Sl = (StopLoss>minst) ? StopLoss*_Point : (minst+1)*_Point;
      };
   return(SL);
  };
 
Верх