Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

Обучение языку MQL4 под MetaTrader 4 Опубликовано
11 часов назад, 0ll сказал:

1. Надеюсь запускаете по закрытию бара, а не на каждом тике.

2. Зачем пересчитывать уже закрытые бары в цикле многократно? они уже цвет не поменяют!

Я не большой профи в программировании, к сожалению))). Прошу, если возможно, более подробно расписать, что Вы имели в виду. Я пишу сюда т.к. полагаю, что здесь могут помочь в плане обучения mql4. Если не сложно прямо в коде внесите корректировке, если возможно... Спасибо!!

Ссылка на сообщение
Поделиться на другие сайты

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

Речь идет о том, что не будет значимых нововведений. А только баги периодически будут править. А вот все новое мол - в МТ5. Когда они вживую сказали то же самое на конференции в Москве, я уточнил: "То

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано
48 минут назад, Владимир Стариков сказал:

Если не сложно прямо в коде внесите корректировке, если возможно... Спасибо!!

Пробуйте:

Спойлер

double PercentsBearBars(int Q_bar_,ENUM_TIMEFRAMES tf,bar_color_style bar_color_)
  {
   static datetime dtb;
   static int kf;
   if  ( dtb == iTime(NULL, tf, 1)) return( (kf / Q_bar_)*100 );   // если бар не закрыт - выход
         dtb  = iTime(NULL, tf, 1);
         
   kf=0;
   for(int i=1; i< Q_bar_+1; i++)
     {
      if(bar_color_==full)
        {
         if(iClose(NULL,tf,i)<iOpen(NULL,tf,i)&&
            (ha(tf,3,i)<ha(tf,2,i)))
            kf++;    break;
        }
      if(bar_color_==Jap)
        {
         if(Close <Open)
            kf++;    break;
        }
      if(bar_color_==Ha)
        {
         if(ha(tf,3,i)<ha(tf,2,i))//белая
            kf++;    break;
        }
      if(bar_color_==Elder)
        {
         if(MA(i)<MA(i+1)&&(BB_lines(MODE_MAIN,i)<BB_lines(MODE_MAIN,i+1)))
            kf++;    break;
        }
      if(bar_color_==superfull)
        {
         if(iClose(NULL,tf,i)<iOpen(NULL,tf,i)&&ha(tf,3,i)<ha(tf,2,i)&&
            MA(i)<MA(i+1)&&(BB_lines(MODE_MAIN,i)<BB_lines(MODE_MAIN,i+1)))
            kf++;    break;
        }
     }
   return( (kf / Q_bar_)*100 );
  }

 

 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

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

 

Спойлер

#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

double buffer1[];
double buffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  SetIndexBuffer(0, buffer1);
  SetIndexStyle(0, DRAW_ARROW);
  SetIndexArrow(0, 242);
  SetIndexBuffer(1, buffer2);
  SetIndexStyle(1, DRAW_ARROW);
  SetIndexArrow(1, 241);

  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
void start()
{
  int limit = Bars - IndicatorCounted() + 1;

  for(int i = 0; i < limit - 1; i++)
    {
 //   buffer = 0.5 * (Close[ i ] + Close[i + 1]);
    if(i > 1)
      {
      if((Low [ i ]< Low[+ 1])        // если цена меньше предыдущего бара (i+1)
        && (Low[ i ] < Low[i - 1])   // если цена меньше последующего бара (i-1)
        && (Low[ i ] < Low[+ 2])  // если цена меньше и последующего бара (i+2)
        && (Low[ i ] < Low[- 2]))  // если цена меньше и последующего бара (i-2)
        buffer2 [ i ]= Low[ i ] - 0.00005; // установка символа на мин ценой с отступом (0.00005) пипса
      }
    }
  for(int i = 0; i < limit - 1; i++)
    {
    if(i > 1)
      {
      if((High[ i ] > High[+ 1])        // если цена больше предыдущего бара (i+1)
        && (High[ i ] > High[i - 1])   // если цена больше последующего бара (i-1)
        && (High[ i ] > High[i + 2])  // если цена больше и последующего бара (i+2)
        && (High[ i ] > High[i - 2]))  // если цена больше и последующего бара (i-2)
        buffer1[ i ] = High[ i ] + 0.00005; // установка символа на мах ценой с отступом (0.00005) пипса
      }
    }
    
}

 

Буду очень признателен!!!

Изменено пользователем vikneo
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@vikneo Приветствую! Буду откровенен! Ты вот эту ерунду пытался от компилировать? Под словом ерунда подразумеваю ошибки, а не твою идею.

Изменено пользователем MikR0ReR
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

в выражениях при прописывании в буферах Low  и High  не копируется [ i ],  простите нашел почему без пробелов не рисует.

Исправлено.

 

Изменено пользователем vikneo
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
9 минут назад, vikneo сказал:

компелятор ошибок не выявляет

 

Провокация!

Спойлер

1024041595_.thumb.jpg.88ec09abf3b9ba8463ff44cda2ec0a05.jpg

 

 

3 минуты назад, vikneo сказал:

в выражениях при прописывании в буферах Low  и High  не копируется  ""пытался отредактировать не пишет

 

Не понял!

Изменено пользователем MikR0ReR
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
3 часа назад, MikR0ReR сказал:

Не понял!

Форумный движок воспринимает [ i ] (без пробелов) как тэг перехода текста на курсив и сам тэг исчезает из текста, рекомендую для вставки кода использовать специальное поле в меню обозначено знаком "</>"

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Доброго времени суток, уважаемые форумчане!

В процессе написания советника возникла небольшая заминка. Подскажите как ее лучше разрешить.

Суть вопроса: некоторые сделки серии могут зависнуть на несколько дней, соответственно могут начисляться отрицательные свопы. Вот я и подумал, что неплохо было бы циклом перебрать все открытые ордера, отобрать те у которых OrderSwap < 0 и модифицировать OrderTakeProfit этих ордеров, добавив к ним OrderSwap*(-1). Заминка в том, что OrderTakeProfit это конкретная цена котировки, а OrderSwap это сумма в usd например. Соответственно их нужно привести к единообразию.

Реализовать я думаю следующим образом (схематично):

Если OrderTakeProfit(цена) - OrderOpenPrice(цена) < TP(пункты)

то ModifyOrders: TP(пункты) = (OrderTakeProfit(цена) + OS(цена)-OrderOpenPrice(цена))*Point(цена пункта)

где OS=OrderSwap(usd)*(-1)/Point(цена пункта)

 

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

Изменено пользователем Oleg Petrov
корректировка формулы
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@Oleg Petrov тут есть тонкости:

MarketInfo( _Symbol, MODE_TICKVALUE ) - Размер минимального изменения цены инструмента в валюте депозита

Point - Возвращает размер пункта текущего инструмента в валюте котировки

OrderSwap (в валюте депозита) / цену пункта (в валюте депозита) = количество пп для модификации (dTP)

Потом TP(новая цена) = OrderTakeProfit(цена) +- dTP ( не перепутать направление!)

Изменено пользователем 0ll
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
55 минут назад, 0ll сказал:

@Oleg Petrov тут есть тонкости:

MarketInfo( _Symbol, MODE_TICKVALUE ) - Размер минимального изменения цены инструмента в валюте депозита

Point - Возвращает размер пункта текущего инструмента в валюте котировки

OrderSwap (в валюте депозита) / цену пункта (в валюте депозита) = количество пп для модификации (dTP)

Потом TP(новая цена) = OrderTakeProfit(цена) +- dTP ( не перепутать направление!)

Спасибо за уточнение.

Насколько я понял, моя вышеуказанная логика должна быть скорректирована следующим образом (для покупок):

Если OrderTakeProfit(цена) - OrderOpenPrice(цена) < TP(пункты) и OrderSwap<0

то ModifyOrders: TP(цена) = OrderTakeProfit(цена) + OS(пункты)*Point(цена пункта) //здесь получаем итоговую котировку для ТР

где OS(пункты)=OrderSwap(usd)*(-1)/MarketInfo( _Symbol, MODE_TICKVALUE )  //здесь получаем количество пунктов для корректировки ТР

 

Утром на свежую голову напишу код.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Получился вот такой код. Компиляция ошибок не выдала.

Спойлер

 


void ModifyOrders1(int otype)
{
   double osp, otp=0;
   double os = 0;
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
           if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
           {
               otp = OrderTakeProfit();
               os = OrderSwap();
           }
       }
   }
   osp = NormalizeDouble(os*(-1) / MarketInfo(Symbol(),MODE_TICKVALUE), Digits);
   
   if (otype == OP_BUY) tp = NormalizeDouble(otp + NormalizeDouble(osp*Point, Digits), Digits); 
   if (otype == OP_SELL) tp = NormalizeDouble(otp - NormalizeDouble(osp*Point, Digits), Digits); 
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
          if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
          {
             if (OrderModify(OrderTicket(), OrderOpenPrice(), 0, tp, 0))
               Print ("Ордера успешно модифицированы");
             else Print ("Ошибка модификации ордеров");  
          }
      }
   }

} 

 

Изменено пользователем 0ll
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@Oleg Petrov Если несколько ордеров, то нужно делать 1 цикл, 2 цикла работать не будет! т.е. сразу снимаете данные ордера и сразу модифицируете ТП.

osp - тип int! все эти заморочки с NormalizeDouble не нужны с пунктами

Это:

if (otype == OP_BUY) tp = NormalizeDouble(otp + NormalizeDouble(osp*Point, Digits), Digits); 
if (otype == OP_SELL) tp = NormalizeDouble(otp - NormalizeDouble(osp*Point, Digits), Digits);

можно заменить (по-желанию) на это:

tp = NormalizeDouble( otp + MathPow(-1,otype)*osp*_Point, Digits ); 

Изменено пользователем 0ll
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
5 часов назад, 0ll сказал:

@Oleg Petrov Если несколько ордеров, то нужно делать 1 цикл, 2 цикла работать не будет! т.е. сразу снимаете данные ордера и сразу модифицируете ТП.

@0ll спасибо за комментарии. Правильно ли я понимаю, что для того чтобы использовать 2 цикла нужно применить 2 магика? Или есть еще какой-то вариант.

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

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@Oleg Petrov Не пойму зачем Вам 2 цикла перебора ордеров? Задача по пересчёту ТП и его модификации прекрасно делается в 1 цикле, и наоборот в 2 циклах сделать невозможно.

Как Вы собираетесь первые несколько ордеров сетки в цикле отсортировывать? - мне тоже интересно.

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

У Вас ситуация сложнее - только разные магики вводить.

В общем цикл по отдельным ордерам может выглядеть так:

Спойлер

   for (int i=OrdersTotal()-1; i>=0; i--)
   {
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
           if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
           {
               otp = OrderTakeProfit();
               os = OrderSwap();
               osp = -os / MarketInfo(_Symbol, MODE_TICKVALUE);
               tp = NormalizeDouble( otp + MathPow(-1,otype)*osp*_Point, Digits );
               if (OrderModify(OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                    Print ("Ордера успешно модифицированы");
               else Print ("Ошибка модификации ордеров"); 
           }
       }
   }

 

 

  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@0ll , 2 цикла именно потому что не предполагается одного общего ТР для всех сделок: у первой группы ордеров он общий, а у второй группы ТР индивидуальный для каждого ордера. Соответственно логика модификации для двух групп ордеров отличается.

Реализовать это на мой взгляд можно с помощью счетчиков ордеров Count. Сначала считаются count1 для группы ордеров с общим ТР, потом после достижения count1 максимального ограничения количества ордеров (из настроек советника конечно) начинают считаться count2 с индивидуальными ТР. Ну и магики естественно тоже разные для двух групп.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
3 часа назад, Oleg Petrov сказал:

2 цикла именно потому что не предполагается одного общего ТР для всех сделок

Я именно для этого случая и пишу: только в 1 цикле. Но Ваше право попробовать по своему.

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

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@0ll , извините если туплю, но у меня сейчас вопрос возник по модификации. Смущает вот что. Допустим запустили мы этот цикл корректировки ТР на своп. Код без ошибок, компиляция прошла успешно. Но после его корректного исполнения (увеличения ТР на величину своп) цикл будет бесконечно повторяться так как первичное условие (OrderSwap < 0) не изменилось. И получается что ТР будет постоянно расти, даже при том условии что минусовое значение свопа не увеличивается. Подскажите как сделать чтобы ТР изменялся только при изменении своп в сторону большего минуса? Или я что-то не так понял?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 20.01.2020 в 15:32, Oleg Petrov сказал:

Подскажите как сделать чтобы ТР изменялся только при изменении своп в сторону большего минуса?

Запускать модификацию нужно только после ролловера, 1 раз в сутки. 

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

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@0ll , это ограничение лучше сделать через жесткую фиксацию разрешенного времени для модификации?

Например: if (TimeHour(TimeCurrent())==1 && TimeMinute(TimeCurrent())==1)  // вроде за минуту должны успеть все ордера модифицироваться

Или есть како-то более надежный способ? (смущает что даже за минуту может произойти несколько модификаций одного ордера)

Хотя если следуя Вашей рекомендации считать модификацию не от последнего ТР а от стартового OpenPrice то возможно зацикливание модификации и не так уж критично. 

Спойлер

   for (int i=OrdersTotal()-1; i>=0; i--)
   {
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
           if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
           {                                                                                                       
               oop = OrderOpenPrice();                                                                                                    
               os = OrderSwap();
               osp = -os / MarketInfo(_Symbol, MODE_TICKVALUE);
               tp = NormalizeDouble( oop+ TakeProfit*Point + MathPow(-1,otype)*osp*_Point, Digits );
               if (OrderModify(OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                    Print ("Ордера успешно модифицированы");
               else Print ("Ошибка модификации ордеров"); 
           }
       }
   }

 

 

Изменено пользователем 0ll
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
3 часа назад, Oleg Petrov сказал:

Или есть како-то более надежный способ?

да, есть, например:

datetime dtLast = 0; // на глобальном уровне - дата последней модификации

if ( Hour() = 1 && TimeCurrent() - dtLast >= 23*3600 ) // если текущий час = 1 и время от последней модификации >= 23 часов

3 часа назад, Oleg Petrov сказал:

возможно зацикливание модификации

Чтоб не "мучить" брокера пустыми запросами, нужно сделать проверку:

if ( MathAbs( tp - OrderTakeProfit() ) < 3 ) continue;  // если дистанция от нового ТП до старого меньше 3 пипс - следующий ордер (т.е. пропустить модификацию)

if (OrderModify(OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                {    Print ("Ордера успешно модифицированы");

                     dtLast = TimeCurrent();  // здесь можно сохранить текущее - последнее время модификации

                }

Изменено пользователем 0ll
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@0ll Получился вот такой код. Компиляция ошибок не выдала. Но есть предупреждение "possible loss of data due to type conversion " (несоответствие типов) в строке расчета osp. NormalizeDouble с округлением до нуля не помогает. Подскажите плиз как его исправить.

Спойлер

 if (CountTrades()>=1) 
 {
 if (BuyCount()>=1 && SellCount()==0 && Hour()==1 && (TimeCurrent()-dtLast)>=23*3600)
 {
  ModifyOrders(OP_BUY); 
 }
 if (SellCount()>=1 && BuyCount()==0 && Hour()==1 && (TimeCurrent()-dtLast)>=23*3600)
 {
  ModifyOrders(OP_SELL); 
 }
//+------------------------------------------------------------------+
void ModifyOrders(int otype)
{
   int osp;
   double otp = 0;
   double oop = 0;
   double os = 0;   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
           if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
           {
               oop = OrderOpenPrice();
               otp = OrderTakeProfit();
               os = OrderSwap();               
           }
       }
   }
   osp = -os/MarketInfo(Symbol(),MODE_TICKVALUE);   
   if (otype == OP_BUY) tp = NormalizeDouble(oop+(TakeProfit*Point)+(osp*Point), Digits); 
   if (otype == OP_SELL) tp = NormalizeDouble(oop-(TakeProfit*Point)-(osp*Point), Digits); 
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
          if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype && OrderSwap() < 0)
          {
             if (MathAbs(tp-otp<3)) continue;
             if (OrderModify(OrderTicket(), OrderOpenPrice(), 0, tp, 0))               
               Print ("Ордера успешно модифицированы");
             else Print ("Ошибка модификации ордеров");
               dtLast = TimeCurrent();                            
          }
      }
   }
}   

 

 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
15 часов назад, Oleg Petrov сказал:

расчета osp. NormalizeDouble с округлением до нуля не помогает. Подскажите плиз как его исправить.

Так: osp = (int) -os/MarketInfo(Symbol(),MODE_TICKVALUE); 

Объясню в последний раз алгоритм Вашей реализации с двумя циклами:

1. Первый цикл перебирает все ордера и заканчивается, при этом в переменных oop, otp, os - останутся данные последнего ордера!

2. Вычисляете ТП для последнего ордера

3. Модифицируете ТП всех ордеров по расчётному ТП для последнего ордера.

Если так и задумано, то - ОК.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...