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

hoz

Активный участник
Зачем ты мене даёшь ссылку на документацию? Это у тебя индикатор?
Ну ты сам рассуди. Если ты считаешь от количества баров на графике, а смотришь, наверняка, на последние... Какое совпадение ты можешь увидеть...


Алексей, чё та меня занесло не туда.. Но ведь Bars и есть последний бар. Тока вот я индекс получал не тот, который хотел получить.. :( Мля. Я понял в чём косяк.

Дословный перевод с аглицкого твоей переменной тоже ни о чём не говорит. Это всего-лишь набор символов, а что в ней должно быть это только тебе известно. Но я не вижу чтобы этой переменной присваивалось какое-либо значение перед выводом её из функции.


Так это ж дефайн. Согласно значения основных слов и создал. Вот ответ на Ваш вопрос:

PHP:
#define REQUIRED_SEQUENTIAL_MISS             -1              // Признак отсуствия заданного значения свечей одного типа вподряд
#define REQUIRED_SEQUENTIAL_BULL_CANDLE       0              // Признак наличия заданного значения бычьих свечей вподряд
#define REQUIRED_SEQUENTIAL_BEAR_CANDLE       1              // Признак наличия заданного значения медвежьих свечей вподряд
 
Последнее редактирование модератором:

hoz

Активный участник
Нет, это количество баров. Последний бар, это Bars-1

Думал так, а в я спехе сказал не верно.


Тут такая ситуация. Я переписал функцию. Вот что есть:


PHP:
int LastCandlesType()
{
   int cnt;                            // Счётчик идущих друг за другом бычьих свечей
   
   for (int i=i_AnyBarsToHistory; i>=1; i--)
   {
      if ((Close[i] - Open[i]) <= i_sizeOfCurrBar * Point)    // Пропускаем все бары, размера меньше заданного внешним параметром
          continue;
     
      if (Close[i] > Open[i])                               // Если условие соблюдается, значит текущий бар направлен вверх
          cnt++;
      if (Close[i] < Open[i])
          cnt = 0;
      Print("i = ", i, "; cnt = ", cnt);
   }
   if (cnt == 5)                                            // Если 5 баров вподряд бычьи..
    return (REQUIRED_SEQUENTIAL_BEAR_CANDLE);           //..Выходим из функции
}


Вот принт:


PHP:
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 1; up = 0; cnt = 14
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 3; up = 0; cnt = 13
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 12; up = 0; cnt = 12
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 13; up = 0; cnt = 11
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 14; up = 0; cnt = 10
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 16; up = 0; cnt = 9
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 19; up = 0; cnt = 8
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 22; up = 0; cnt = 7
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 23; up = 0; cnt = 6
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 24; up = 0; cnt = 5
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 26; up = 0; cnt = 4
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 27; up = 0; cnt = 3
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 29; up = 0; cnt = 2
2013.04.24 18:51:45	2012.04.20 00:02  Scalper_M1 EURUSD,M1: i = 30; up = 0; cnt = 1


Там цикл по барам от индекса i_AnyBarsToHistory до последнего закрытого.Если появляется не бычий бар, счётчик должен обнулится, но что-то по принту видно, что он не обнуляется. Прибавляется и всё.В чём причина?
 
Последнее редактирование модератором:

qqmber

Почетный гражданин
Если появляется не бычий бар, счётчик должен обнулится, но что-то по принту видно, что он не обнуляется. Прибавляется и всё.В чём причина?

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

hoz

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


Как это не может? Допустим считаем от последнего закрытого бара. Есть бар бычий, дальше бычий, а потом медвежий.. значит счётчик обнулится должен. Ведь в таком случает условие соблюдается только то, где обнуление. (на том баре)
Вот переписал:


PHP:
int LastCandlesType()
{
   int cnt;                            // Счётчик идущих друг за другом бычьих свечей
   
   for (int i=1; i<=i_AnyBarsToHistory; i++)
   {
      if (MathAbs(Close[i] - Open[i]) <= 5 * i_sizeOfCurrBar * Point)    // Пропускаем все бары, размера меньше заданного внешним параметром
          continue;
     
      if (Close[i] > Open[i])                               // Если бар бычий,..
          cnt++;                                            // Счётчику добавим 1
      if (Close[i] < Open[i])                               // Если бар медвежий..
          cnt = 0;                                          // Счётчик обнуляем
      if (i == 1)
         Print("i = ", i,"; cnt = ", cnt);
   }
 //  Print("cnt = ", cnt);
   if (cnt == 5)                                            // Если 5 баров вподряд бычьи..
    return (REQUIRED_SEQUENTIAL_BEAR_CANDLE);           //..Выходим из функции
}


Меня одно интересует. Вот скрин, где видно, что бары идут периодически друг за другом:


0_94a3a_3cbdc33_orig.jpg


Я запринтовал канкретно последний закрытый бар. Вот что выводит:


PHP:
2013.04.24 20:14:54	2012.04.20 00:17  Scalper_M1 EURUSD,M1: i = 1; cnt = 1
2013.04.24 20:14:48	2012.04.20 00:16  Scalper_M1 EURUSD,M1: i = 1; cnt = 1
2013.04.24 20:14:45	2012.04.20 00:15  Scalper_M1 EURUSD,M1: i = 1; cnt = 1
2013.04.24 20:14:44	2012.04.20 00:14  Scalper_M1 EURUSD,M1: i = 1; cnt = 1
2013.04.24 20:14:36	2012.04.20 00:11  Scalper_M1 EURUSD,M1: i = 1; cnt = 0
2013.04.24 20:14:13	2012.04.20 00:04  Scalper_M1 EURUSD,M1: i = 1; cnt = 1
2013.04.24 20:13:56	2012.04.20 00:01  Scalper_M1 EURUSD,M1: i = 1; cnt = 0


Тут типа максимально 1 бар был последовательный. А по факту видно, что вон последние 4 бычьих, например. Почему не так показывает счётчик cnt ?
 
Последнее редактирование модератором:

hoz

Активный участник
Логику я чутка понял. Нужно смотреть если циклю с последнего закрытого, на бар с индексом не 1, а дальше.. Тока вот как тут лучше поступить?
 

AlexeyVik

Программист mql4 mql5
Удали условие где комментарий //Пропускаем все бары, размера меньше заданного
И поставь такое условие
if(Close - Open >= 5) cnt++;
Это будет точно бар бычий и больше заданного.
и if(Open - Close >= 5) cnt = 0;
А если попадается медвежий больше заданного, то счётчик обнуляем.
 
Последнее редактирование:
  • Like
Реакции: hoz

hoz

Активный участник
Удали условие где комментарий //Пропускаем все бары, размера меньше заданного
И поставь такое условие
if(Close - Open >= 5) cnt++;
Это будет точно бар бычий и больше заданного.
и if(Open - Close >= 5) cnt = 0;
А если попадается медвежий больше заданного, то счётчик обнуляем.



Я думал над этим. В плане оптимизации кода, это верно..
 

hoz

Активный участник
Вообще-то да. Но, на сколько я знаю, обычно полный рефакторинг кода делается в процессе или даже уже когда код написан. Хотя смотря, конечно, какой. Тут в принципе очевидно, значит лучше сразу.
 

hoz

Активный участник
Вот такой подход и приводит к таким вопросам.


В принципе да. Но это от недостатка опыта. И не стандартных ситуаций.
Вот смотрите. Щяс я решил придать данной функции универсальный вид. Пока что не совсем всё додумал, но те признаки, которые есть, хочу чтоб работали в 2 режимах.

1. В режиме, когда основной тренд вниз.
2. В режиме, когда основной тренд вверх.

Вот что я написал:

PHP:
int LastCandlesType(int trand)
{
   int cnt,                            // Счётчик идущих друг за другом свечей с требуемыми признаками
   
   if (trand == up)
       li_cmd = -1;
   if (trand == down)
       li_cmd = 1;

   for (int i=i_AnyBarsToHistory; i>=1; i--)
   {
      if (li_cmd * (Close[i] - Open[i]) >= i_sizeOfSequentialCorrectionBar * pt)              // Если бар соответствует требуемым признакам..
          cnt++;                                                                     // .. прибавим 1 к счётчику

      if (Close[i] < Open[i])                                                        // Если бар, не соответствует основному признаку..
          cnt = 0;                                                                   // .. счётчик обнуляем
      
/*      if (i == 1)
      Print("i = ", i,"; cnt = ", cnt);*/
   }

   if (cnt == 3)                                                                     // Если 5 баров вподряд бычьи..
    return (REQUIRED_SEQUENTIAL_CANDLE_GOT);                                         //..Выходим из функции
}

Переменная li_cmd нужна для того, чтоб если другой режим, т.е. тренд основной в другую сторону, то есс-но если вычитая из цены закрытия цену открытия всё-равно было значение положительное.
Я так понимаю, что нужно как-то назначить переменные для close и open ? Хотя это уже таймсерия, а значит - массив..
В общем, как тут сразу думать и сразу писать оптимально код, дабы не расписывать тоже самое для второго и, возможно, третьего режима для меня вопрос.
На данный момент код работает только для режима trand == down

Как можно сделать так, чтоб это функция была универсальной?
 
Последнее редактирование модератором:

AlexeyVik

Программист mql4 mql5
Как-же ты любишь создавать себе препятствия и их преодолевать...
Задачка ведь самая простая.

Весь код писать не буду, только условия

if(Close - Open >= 5) // если свеча бычья и тело больше заданного
{
cnt_Up++; // счётчик бычьих баров увеличиваем на 1
cnt_Dn = 0; // и обнуляем счётчик медвежьих баров
// Здесь можно добавить if(cnt_Up == 5) return(cnt_Up);
}
// Можно добавить else
if(Open - Close >= 5) // если свеча медвежья и тело больше заданного
{
cnt_Up = 0; // обнуляем счётчик бычьих баров
cnt_Dn++; // а счётчик медвежьих баров увеличиваем на 1
// Здесь можно добавить if(cnt_Dn == 5) return(cnt_Dn);
}

Всё!!!
А ты вставляешь какие-то флаги, пропуск баров меньше заданного и всякую другую несусветицу...
Я надеюсь ты сам вместо цифры 5 вставишь свои значения или переменные.
 

hoz

Активный участник
Как-же ты любишь создавать себе препятствия и их преодолевать...
Задачка ведь самая простая.

Весь код писать не буду, только условия

if(Close - Open >= 5) // если свеча бычья и тело больше заданного
{
cnt_Up++; // счётчик бычьих баров увеличиваем на 1
cnt_Dn = 0; // и обнуляем счётчик медвежьих баров
// Здесь можно добавить if(cnt_Up == 5) return(cnt_Up);
}
// Можно добавить else
if(Open - Close >= 5) // если свеча медвежья и тело больше заданного
{
cnt_Up = 0; // обнуляем счётчик бычьих баров
cnt_Dn++; // а счётчик медвежьих баров увеличиваем на 1
// Здесь можно добавить if(cnt_Dn == 5) return(cnt_Dn);
}

Всё!!!
А ты вставляешь какие-то флаги, пропуск баров меньше заданного и всякую другую несусветицу...
Я надеюсь ты сам вместо цифры 5 вставишь свои значения или переменные.


Ну так у Вас то что я и говорил. Это тоже самое расписать для каждого if..
Это не есть универсальность.
Неужели это единственный вариант?
 

smartmans

Активный участник
Приветствую.
Есть индикатор X, обновляется только при смене таймфрейма или при перезапуске терминала.
Подскажите, что нужно вставить, чтобы обновлялся (перестраивался) в необходимое время терминала, скажем 00:00?
То есть не каждый бар/тик, а только в назначенное время.
#include <WinUser32.mqh> в шапку индикатора

Попробуйте такую функцию пропишите после функции работы по времени.
PHP:
  int hwnd =WindowHandle(Symbol(),Period());
     if(hwnd != 0 && (time==0 || TimeCurrent()-time>10)) 
       { 
         PostMessageA(hwnd, WM_COMMAND, 33324, 0); 
         time=TimeCurrent();
       }
Увы не сработало по наступлению 00:00. только перезапуск.

А как попробовать?,чтобы по типу:
PHP:
extern int hour= 00;
extern int minutes = 00;
...
    if(Таймкуррент  >= hour+minutes>=рефреш (обновление/перестроение) )||
 

AlexeyVik

Программист mql4 mql5
Ну так у Вас то что я и говорил. Это тоже самое расписать для каждого if..
Это не есть универсальность.
Неужели это единственный вариант?
Это совсем не то, что написал ты.
Сначала было условие, что бары меньше заданного игнорируются не зависимо от направления. Потом ты ставишь условие

if (Close[i] < Open[i]) // Если бар, не соответствует основному признаку.. (не зависимо от величины тела свечи)
cnt = 0; // .. счётчик обнуляем

и какие могут быть ещё условия? Какую универсальность ты хочешь придумать?

 

hoz

Активный участник
и какие могут быть ещё условия? Какую универсальность ты хочешь придумать?


Например, вот моя функция перевода в безубыток:
PHP:
//+-------------------------------------------------------------------------------------+
//| Перенос стопа в б.у.                                                                |
//+-------------------------------------------------------------------------------------+
void MovingStopLossToBU()
{ // функция учёта ордеров для модификации
  double priceBU;
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    {
       if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;
//------------------------------------------------------------------------------------------------------------------------------- 
       if (OrderSymbol() != Symbol()) continue;
       if (i_myMagic != -1) if (OrderMagicNumber() != i_myMagic) continue;
       if (OrderType() > 1) continue;
       
       RefreshRates();
        
       if (OrderType() == OP_BUY)
       {
         double Price = Bid; int li_cmd = 1;
       }
       else
       {
         li_cmd = -1; Price = Ask;
       }
       // функция модификации ордера в безубыток
       if (li_cmd * (Price - OrderOpenPrice()) >= i_triggerForBU*pt)
       {
           priceBU = NormalizeDouble(OrderOpenPrice() + li_cmd * (i_PreservedProfit*pt), Digits);
           if (NormalizeDouble(OrderStopLoss() - priceBU, Digits) != 0.0)
           {
               if (!OrderModify (OrderTicket(), OrderOpenPrice(), priceBU, OrderTakeProfit(), 0, CLR_NONE))
               {
                   Print ("Ошибка модификации ордера ", OrderType(), " - ", GetLastError());
               }
               
               Comment ("Ордер успешно переведён в безубыток");
               Print ("Ордер успешно переведён в безубыток");
           }
       }
    }
}

Видите, как тут универсально всё реализовано? Нет повторений тех же действий. Думал, что и тут можно что-то ещё придумать. Даже интересно..
Просто тут в цикле массив, потому и задумался я. А если б там не было цикла, то было бы просто всё..
 
Последнее редактирование модератором:

AlexeyVik

Программист mql4 mql5
Например, вот моя функция перевода в безубыток:
PHP:
//+-------------------------------------------------------------------------------------+
//| Перенос стопа в б.у.                                                                |
//+-------------------------------------------------------------------------------------+

       if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;
//------------------------------------------------------------------------------------------------------------------------------- 
       if (OrderSymbol() != Symbol()) continue;
       if (i_myMagic != -1) if (OrderMagicNumber() != i_myMagic) continue;
       if (OrderType() > 1) continue;
Видите, как тут универсально всё реализовано?
Это ты называешь универсально???
Всё что я оставил из твоего кода можно заменить одной строкой
if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() < 2)
{
}
Это будет эффективней и быстрей выполняться.
 
Последнее редактирование модератором:

qqmber

Почетный гражданин
Например, вот моя функция перевода в безубыток:
Видите, как тут универсально всё реализовано? Нет повторений тех же действий.
Вижу. Проходил этот этап.
На следующем витке познаний вы обнаружите, что сопровождение коротких и длинных позиций может сильно отличаться. И работа в бычьем и медвежьем тренде может использовать разные алгоритмы. Тогда придется универсальность ликвидировать.
 
  • Like
Реакции: hoz

hoz

Активный участник
В общем-то я пришёл к выводу, что так будет само адекватно.

PHP:
int LastCandlesType(int DirectionMA)
{
   int cnt;                                                                            // Счётчик идущих друг за другом свечей с..
                                                                                       // .. требуемыми признаками
   for (int i=i_AnyBarsToHistory; i>=1; i--)
   {
      if (DirectionMA == CROSS_UP)
      {
         if ((Open[i] - Close[i]) >= i_sizeOfSequentialCorrectionBar * pt)              // Если бар соответствует требуемым признакам..
             cnt++;                                                                     // .. прибавим 1 к счётчику

         if ((Close[i] - Open[i]) >= i_sizeOfTrandBar * pt)                             // Если бар, не соответствует основному признаку..
             cnt = 0;                                                                   // .. счётчик обнуляем
      
         if (i == 1)
            Print(" DirectionMA ", DirectionMA, "; i = ", i, "; Open[i] - Close[i] = ", Open[i] - Close[i], "; cnt = ", cnt);

         if (cnt == i_sequentBarscСount)                                                   // Если 5 баров вподряд бычьи..
             return (REQUIRED_SEQUENTIAL_CANDLE_GOT);                                         // .. Выходим из функции
      }

      if (DirectionMA == CROSS_DN)
      {
         if ((Close[i] - Open[i]) >= i_sizeOfSequentialCorrectionBar * pt)              // Если бар соответствует требуемым признакам..
             cnt++;                                                                     // .. прибавим 1 к счётчику

         if ((Open[i] - Close[i]) >= i_sizeOfTrandBar * pt)                             // Если бар, не соответствует основному признаку..
             cnt = 0;                                                                   // .. счётчик обнуляем
     
         if (i == 1)
            Print(" DirectionMA ", DirectionMA, "; i = ", i, "; Close[i] - Open[i] = ", Close[i] - Open[i], "; cnt = ", cnt);

         if (cnt == i_sequentBarscСount)                                                   // Если 5 баров вподряд бычьи..
             return (REQUIRED_SEQUENTIAL_CANDLE_GOT);                                         // .. Выходим из функции
      }
   }
}
 
Верх