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

hoz

Активный участник
Имея маловатый опыт, не торопитесь обвинять язык в кривости и баговости.
Вы продолжаете обращаться к несуществующему элементу массива, несмотря на совет Алексея. В массиве длиной i последний элемент имеет индекс i-1.


Так тут так и есть. Ведь в массиве 4 элемента. У нас есть цикл от 0 до 4 (не включительно). А значит переменная i примет значение от 0 до 3.

PHP:
for (int i=0; i<4; i++)
   {
      ArrayResize(crossDir,i);
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;
 

qqmber

Почетный гражданин
Так тут так и есть. Ведь в массиве 4 элемента. У нас есть цикл от 0 до 4 (не включительно). А значит переменная i примет значение от 0 до 3.
Цикл выполнится 4 раза, размер массива будет расти от 0 до 3. В нем ни разу не будет четырех элементов.
 

qqmber

Почетный гражданин
Первый проход цикла. ArrayResize(crossDir,0); Массив получает нулевой размер, т.е. в нем вообще нет элементов. Тем не менее, вы присваиваете значение несуществующему элементу с индексом 0.
Аналогично и на последующих оборотах. Массив становится длиной i, в нем нет элемента с индексом i, присваивание за границу массива.
 

hoz

Активный участник
Первый проход цикла. ArrayResize(crossDir,0); Массив получает нулевой размер, т.е. в нем вообще нет элементов. Тем не менее, вы присваиваете значение несуществующему элементу с индексом 0.
Аналогично и на последующих оборотах. Массив становится длиной i, в нем нет элемента с индексом i, присваивание за границу массива.


Хм. Я так понял, нужно вот так? Объявить размер за пределами цикла.


PHP:
//+-------------------------------------------------------------------------------------+
//| Получение положения машек между собой                                               |
//+-------------------------------------------------------------------------------------+
void GetStateMa(int& crossDir[])
{
   double ema365_1;
   double ema365_0 = GetCurAndPrevMA(365, ema365_1);
   ArrayResize(crossDir,4);

   for (int i=0; i<4; i++)
   {
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;
      
      Print("crossDir[i] = ", i, "___", crossDir[i]);
      Print("crossDir[i] = ", i, "___", crossDir[i]);

      if (ema1 < ema365_1 && ema0 > ema365_0)
      {
         Print("ema1b < 365_1 ___ ", ema1 ," < ", ema365_1, "___",i);
         Print("ema0b > 365_0 ___ ", ema0 ," > ", ema365_0, "___",i);
         crossDir[i] = CROSS_UP;
      }
      if (ema1 > ema365_1 && ema0 < ema365_0)
      {
         Print("ema1s > 365_1 ___", ema1 ," > ", ema365_1, "___",i);
         Print("ema0s < 365_0 ___ ", ema0 ," < ", ema365_0, "___",i);
         crossDir[i] = CROSS_DN;
      }
   }
}
 
Последнее редактирование:

hoz

Активный участник
Да, так вполне разумно.


И, тем не менее, всё-равно нечего не работает.
PHP:
//+-------------------------------------------------------------------------------------+
//| Получение значений МА на двух соседних барах                                        |
//+-------------------------------------------------------------------------------------+
double GetCurAndPrevMA(int maPeriod, double& prevMA)
{
   prevMA = iMA(NULL, i_TF, maPeriod, 0, MODE_EMA, MODE_CLOSE, 1);
   return (iMA(NULL, i_TF, maPeriod, 0, MODE_EMA, MODE_CLOSE, 0));
}
//+-------------------------------------------------------------------------------------+
//| Получение положения машек между собой                                               |
//+-------------------------------------------------------------------------------------+
void GetStateMa(int& crossDir[])
{
   double ema365_1;
   double ema365_0 = GetCurAndPrevMA(365, ema365_1);
//   ArrayResize(crossDir,4);

   for (int i=0; i<4; i++)
   {
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;
      
      Print("ema0_1 = ", i, "___", ema1);
      Print("ema0_0 = ", i, "___", ema0);
      Print("ema365_1 = ", i, "___", ema365_1);
      Print("ema365_0 = ", i, "___", ema365_0);
      
      Print("crossDir[i] = ", i, "___", crossDir[i]);

      if (ema1 < ema365_1 && ema0 > ema365_0)
      {
         Print("ema1b < 365_1 ___ ", ema1 ," < ", ema365_1, "___",i);
         Print("ema0b > 365_0 ___ ", ema0 ," > ", ema365_0, "___",i);
         crossDir[i] = CROSS_UP;
      }
      if (ema1 > ema365_1 && ema0 < ema365_0)
      {
         Print("ema1s > 365_1 ___", ema1 ," > ", ema365_1, "___",i);
         Print("ema0s < 365_0 ___ ", ema0 ," < ", ema365_0, "___",i);
         crossDir[i] = CROSS_DN;
      }
   }
}

В глобальных у нас:

PHP:
extern string ___H0 = " __________ Параметры МА __________ ";
extern int i_TF = 0;
int g_maPeriod[4] = {6, 25, 150, 250},             // Периоды обрабатываемых МА
    g_singMa[4] = {1,2,3,4};                     // признаки машек, добавляемые к основному мэйджику
int crossDir[4];                                                // Положение каждого из набора средних друг относительно друга
bool returnSign[4];                                             // Признак возврата цены к соответствующей средней
int signal[4];                                                  // Массив общего сигналапо каждой из торговых систем
#define CROSS_UP             0                                 // Признак нахождения быстрой средней
                                                               // ..над медленной
#define CROSS_DN             1                                // Признак нахождения медленной..
                                                               // ..средней над быстрой
#define CROSS_NO            -1                                 // Признак равенства двух средних


В журнале:

PHP:
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: crossDir[i] = 3___-1
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_0 = 3___1.3799
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_1 = 3___1.3798
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_0 = 3___1.3915
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_1 = 3___1.3915
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: crossDir[i] = 2___-1
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_0 = 2___1.3799
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_1 = 2___1.3798
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_0 = 2___1.3981
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_1 = 2___1.3982
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: crossDir[i] = 1___-1
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_0 = 1___1.3799
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_1 = 1___1.3798
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_0 = 1___1.3895
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_1 = 1___1.3894
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: crossDir[i] = 0___-1
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_0 = 0___1.3799
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema365_1 = 0___1.3798
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_0 = 0___1.3869
2013.04.12 16:36:04	2009.01.05 00:03  Base150_New EURUSD,H1: ema0_1 = 0___1.3857

Т.е. до выполнения условий не доходит вообще. Почему?
 
Последнее редактирование:

qqmber

Почетный гражданин
А вы что хотели бы увидеть?
На мой взгляд все нормально, ведь нет пересечений на последнем баре.
 

AlexeyVik

Программист mql4 mql5
hoz, ты узнал о возможности сохранять значения переменных таким способом (int& crossDir[]) и теперь пользуешься им абсолютно везде не задумываясь. А это не правильно. Надо думать.
Зачем тебе ArrayResize(crossDir, 4);? Ведь размер массива известен и не меняется. Объяви массив на глобальном уровне crossDir[4] и заполняй его даже не обнуляя перед заполнением. И будут значения массива доступны из любого места программы.
 

hoz

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


Да. Я это понимаю. А как сделать тогда так, чтобы если машки ранее пересеклись в каком-то направлении, и пересечение на текущий момент сохраняется?

hoz, ты узнал о возможности сохранять значения переменных таким способом (int& crossDir[]) и теперь пользуешься им абсолютно везде не задумываясь. А это не правильно. Надо думать.
Зачем тебе ArrayResize(crossDir, 4);? Ведь размер массива известен и не меняется. Объяви массив на глобальном уровне crossDir[4] и заполняй его даже не обнуляя перед заполнением. И будут значения массива доступны из любого места программы.


Я тоже об этом подумал. Уже исправил.
 

qqmber

Почетный гражданин
Да. Я это понимаю. А как сделать тогда так, чтобы если машки ранее пересеклись в каком-то направлении, и пересечение на текущий момент сохраняется?
Убрать crossDir = CROSS_NO;
Глобально
int crossDir[]={-1, -1, -1, -1}; //Инициализатор задает размер массива
Массив будет помнить последнее пересечение.
 

hoz

Активный участник
Убрать crossDir = CROSS_NO;
Глобально
int crossDir[]={-1, -1, -1, -1}; //Инициализатор задает размер массива
Массив будет помнить последнее пересечение.



А условия эти:

PHP:
if (/*ema1 < ema365_1 && */ema0 > ema365_0

Я пока что закомментил. Если раскоментить, должно работать?
 

qqmber

Почетный гражданин
Должно. Я не вижу ошибок в логике определения пересечения.
 

hoz

Активный участник
Должно. Я не вижу ошибок в логике определения пересечения.

При входе в функцию я обнулял значения, т.к. у меня был печальный опыт, когда я несколько дней долбался с этим. Только там был в массиве сигнал. Сигнал сохранялся постоянно, т.к. массив статичен судя из документации.
Но в данном случае, вполне резонно сделать именно так как Вы выше написали.
 

hoz

Активный участник
А отскок от быстрой машки при пересечении медленной я верно получил?

PHP:
//+-------------------------------------------------------------------------------------+
//| Получение значений МА на указанном баре                                             |
//+-------------------------------------------------------------------------------------+
double GetMA(int index, int maPeriod)
{
   return (iMA(NULL, i_TF, maPeriod, 0, MODE_EMA, MODE_CLOSE, index));
}
//+-------------------------------------------------------------------------------------+
//| Имеет ли место отскок?                                                              |
//+-------------------------------------------------------------------------------------+
void IsRebound(int crossDir[], bool& returnSign[])
{
   for (int i = 0; i < 4; i++)
   {
      if (crossDir[i] == CROSS_NO)
         continue;

      returnSign[i] = false;
      double ema = GetMA(1, g_maPeriod[i]);

 //     VrPr (ND(MathAbs(ema - Ask)));
   //   VrPr (i_thresholdFromMa * pt);
      if (crossDir[i] == CROSS_UP)
      {
         if (ND(MathAbs(ema - Ask)) <= i_thresholdFromMa * pt) // ..зазор между ценой покупки и машки, <= i_thresholdFromMa..
         {
         //   VrPr (ND(MathAbs(ema - Ask)) <= i_thresholdFromMa * pt);
            returnSign[i] = true;
     //       VrPr (returnSign[i]);
     Alert("CROSS_UP");
         }
      }
      if (crossDir[i] == CROSS_DN)
      {
         if (ND(MathAbs(ema - Bid)) <= i_thresholdFromMa * pt) // ..зазор между ценой покупки и машки, <= i_thresholdFromMa..
         {
            returnSign[i] = true;
       //     VrPr (returnSign[i]);
       Alert("CROSS_DN");
         }
      }
   }
}

До алерта не доходит.. Почему-то.
 

qqmber

Почетный гражданин
А отскок от быстрой машки при пересечении медленной я верно получил?
До алерта не доходит.. Почему-то.
Алерты будут когда цена окажется рядом с быстрой машкой и если до этого было пересечение.
 

hoz

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

Логично... Как обычно, косяк был в описке.. в сигнальной функции. Чаще ошибки там, где их не ищут...:facepalm:
 

hoz

Активный участник
Как оказалось, есть какие-то неучтённые моменты, всё-таки. Вот что имеется сейчас:

PHP:
//+-------------------------------------------------------------------------------------+
//| Имеет ли место отскок?                                                              |
//+-------------------------------------------------------------------------------------+
void IsRebound(int crossDir[], bool& returnSign[])
{
   for (int i = 0; i < 4; i++)
   {
      if (crossDir[i] == CROSS_NO)
         continue;

      returnSign[i] = false;
      double ema = GetMA(1, g_maPeriod[i]);

      if (crossDir[i] == CROSS_UP)
      {
         if (ND(Ask - ema) <= i_thresholdFromMa * pt) // ..зазор между ценой покупки и машки, <= i_thresholdFromMa..
         {
            returnSign[i] = true;
            VrPr (" returnSign["+0+"]"+" = "+ returnSign[0]);
            VrPr (" returnSign["+1+"]"+" = "+ returnSign[1]);
            VrPr (" returnSign["+2+"]"+" = "+ returnSign[2]);
            VrPr (" returnSign["+3+"]"+" = "+ returnSign[3]);
         }
      }
      if (crossDir[i] == CROSS_DN)
      {
         if (ND(ema - Bid) <= i_thresholdFromMa * pt) // ..зазор между ценой продажи и машки, <= i_thresholdFromMa..
         {
            returnSign[i] = true;
            VrPr (" returnSign["+0+"]"+" = "+ returnSign[0]);
            VrPr (" returnSign["+1+"]"+" = "+ returnSign[1]);
            VrPr (" returnSign["+2+"]"+" = "+ returnSign[2]);
            VrPr (" returnSign["+3+"]"+" = "+ returnSign[3]);
         }
      }
   }
}


Сбоку у меня выводится на экран текущие данные каждого элемента анализируемого массива.


0_942bc_6adef7b6_orig.jpg


Значение массива returnSign почему-то то не принимает ложное значение, то наоборот не становится в истинное.

На графике видно, что цена застопорилась у 2 машек, которые в массиве будут находится в 0 и 1-м индексе. Что может быть не так?
 

gold_traid

Новичок форума
Вопрос

Добрый вечер всем!Господа может кто нибудь знает можно ли в советник встроить автосмену настроек по времени?Примерно так с тра и весь день советник торгует с настройками которые заданы мной а вот в ночное время скажем с 10 часов вечера мняются на другие?и обратно?считаю это необходимым так как сов работает на vps и у меня нет возможности менять ему настройки каждый раз.Кто нибудь может помочь?
 
Последнее редактирование:

hoz

Активный участник
Добрый вечер всем!Господа может кто нибудь знает можно ли в советник встроить автосмену настроек по времени?Примерно так с тра и весь день советник торгует с настройками которые заданы мной а вот в ночное время скажем с 10 часов вечера мняются на другие?и обратно?считаю это необходимым так как сов работает на vps и у меня нет возможности менять ему настройки каждый раз.Кто нибудь может помочь?

В принципе можно, и, довольно-таки несложно. Проверяешь время, если время ночное., то настройки такие-то.., а если другое.. то другие. Что тут сложного-то?
 
Верх