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

От xbms, 13 апреля, 2013 в Уголок Программиста

#6701
В 10.03.2023 в 19:52, BotPro сказал:

Подскажите, как в коде mql4 прописать запрет торговли конкретными парами? Ну или просто выдать разрешение советнику торговать только конкретными парами?

Без вывода этого в настройки.

 

О, ученики великого комбинатора отпочковались и решили сами уйти в продаванство )

Очевидно же, что не свой советник кто-то пытается править :d

#6702

Подскажите, пожалуйста, можно ли в mql4 сделать так, чтобы при создании объекта "FiboChannel" (канал Фибоначчи) по давней истории графика, его наклонные линии были видны только в диапазоне одного какого-то выбранного дня, а не пересекали почти всю историю графика.  

 

 

 

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

Изменено 17 марта, 2023 пользователем Pavel888

#6703
В 11.03.2023 в 20:15, BotPro сказал:

Вопрос про суффикс и ТФ.

 

1) Достаточно ли кода ниже, чтобы советник автоматом определял наличие/отсутствие суффикса/префикса и нормально работал на парах с суфф./преф.?

input string Preffix="Auto";
input string Suffix="Auto";

Инфа отсюда https://www.mql5.com/ru/articles/2564 как-то может помочь? Если да, то как?

 

2) Возможно ли как-то через "условие" запрета торговли на определенных парах также прописать запрет торгов на определенных ТФ?

Если да, то как?

 

Спасибо за дельные ответы

 

 

 

на mql идти лень.
Я в OnInit() проверял текущий инструмент очищенный от префиксов/суффиксов.
Логика примерно такая:
через  SymbolInfoString() получаем базовую валюту и валюту профита. Слияние этих результатов дает имя пары без суффиксов.
Код можно посмотреть в древнем советнике Spring /torgovye-sistemy/2/w1-torgovaja-strategija-spring/14617/?do=findComment&comment=440781
Если не ошибаюсь. МТ4 нет на компе...

Запрет торговли на конкретном ТФ делается так же в OnInit():
if(PeriodCurrent() > PERIOD_H1) ExpertRemove()// Если текущий период графика больше 1 часа, то вываливаемся.

#6704

Кто подскажет по терминалу МТ4? Что то можно изменить в каталогах или еще где полазить? Проблема в том  что на Н4 пары USDJPY отображается не все свечи, пропускает. До определенного времени было все норма- потом с пропусканием. Встречались ли вы с такой проблемой?

#6705
В 06.04.2023 в 15:08, sasa777 сказал:

Кто подскажет по терминалу МТ4? Что то можно изменить в каталогах или еще где полазить? Проблема в том  что на Н4 пары USDJPY отображается не все свечи, пропускает. До определенного времени было все норма- потом с пропусканием. Встречались ли вы с такой проблемой?

History Center - загрузить котировки для М1, прокликать все таймфреймы, перезапустить терминал

 

#6706
3 часа назад, Rigal сказал:

History Center - загрузить котировки для М1, прокликать все таймфреймы, перезапустить терминал

 

Спасибо, помогло. Но последняя свеча Н1 пятницы отличается от моего терминала. Далее будут ли совпадать? и еще вопрос: можно ли было загрузить котировки только для Н4 а не М1?  

#6707
4 минуты назад, sasa777 сказал:

Спасибо, помогло. Но последняя свеча Н1 пятницы отличается от моего терминала. Далее будут ли совпадать? и еще вопрос: можно ли было загрузить котировки только для Н4 а не М1?  

грузить нужно всегда М1, все остальные таймфреймы обсчитываются из этих свечек.

 

Чтобы было понятно: вы загрузили данные от MetaQuotes, не от вашего брокера.

Свечки от брокера строятся в непрерывно запущенном терминале и свечки из прошлого могут не прогружаться - зависит от брокера.

Если ваш терминал не запущен круглосуточно, есть несколько способов попросить котировки программно, но ни один из них не гарантирует результата.

Вручную обычно помогает выключить автоперемотку чарта и поскроллить его в прошлое, на нескольких таймфреймах.

Тем не менее, если котировки в хранилище терминала побились, это может не помогать с "дырами": терминал может полагать, что у него все загружено и все хорошо. Нужно протирать папочку истории брокера и начинать с начала.

#6708
27 минут назад, Rigal сказал:

Вручную обычно помогает выключить автоперемотку чарта и поскроллить его в прошлое, на нескольких таймфреймах.

Можно и без выключения автопрокрутки. Мне всегда помогало на M1 зажать кнопку "home" на секунд 5-10 и всё прогружалось.

#6709

Приветствую всех! У меня вопрос. Можно сделать чтобы ордер считал отложенный ордер своим, и как это сделать. Например: я открыл ордер через советник и отложенный, нужно чтобы следующий отложенный увеличился за счёт двух ордеров, открытого и отложенного. Как это сделать?

#6711

Пытаюсь переписать индикатор https://www.tradingview.com/script/CnB3fSph-Smart-Money-Concepts-LuxAlgo/ под мт5

 

Может есть идеи как эту функцию переписать под MQL5?

 

[top, btm] = swings(length)
 
[itop, ibtm] = swings(5)

 

//Swings detection/measurements
swings(len)=>
    var os = 0
   
    upper = ta.highest(len)
    lower = ta.lowest(len)
 
    os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1]
 
    top = os == 0 and os[1] != 0 ? high[len] : 0
    btm = os == 1 and os[1] != 1 ? low[len] : 0
 
    [top, btm]
 
 
#6712

Приветствую.

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

#6713

Всем привет!!! Может кто видел функцию нахождения цены предыдущего ордера в сетке ордеров. Очень нужна. Или помогите ее создать - самому не получается.

#6714
3 часа назад, mishastar сказал:

Всем привет!!! Может кто видел функцию нахождения цены предыдущего ордера в сетке ордеров. Очень нужна. Или помогите ее создать - самому не получается.

Может не предыдущего а последнего? Тогда, например, так:
 

//---- Ищет последний ордера и возвращает его цену открытия----//
double Last_OrderOpPr(int type, int mn, string sym)
{
   datetime open_time = 0;
   int ticket;
   for(int i= OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(open_time < OrderOpenTime() && OrderMagicNumber() == mn && type == OrderType() && sym==OrderSymbol())
      {
         open_time = OrderOpenTime();
         ticket = OrderTicket() ;
      }
   }
   if(open_time==0) return(-1);
   if( OrderTicket() != ticket ) OrderSelect( ticket , SELECT_BY_TICKET);
   
   return(OrderOpenPrice());
}

 

взято отсюда: https://www.mql5.com/ru/forum/126457
в принципе рекомендую туда с поиском ходить почаще. Многие (если не все) ситуации обмусолены..

#6715
5 часов назад, usver73 сказал:

Может не предыдущего а последнего? Тогда, например, так:
 

//---- Ищет последний ордера и возвращает его цену открытия----//
double Last_OrderOpPr(int type, int mn, string sym)
{
   datetime open_time = 0;
   int ticket;
   for(int i= OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(open_time < OrderOpenTime() && OrderMagicNumber() == mn && type == OrderType() && sym==OrderSymbol())
      {
         open_time = OrderOpenTime();
         ticket = OrderTicket() ;
      }
   }
   if(open_time==0) return(-1);
   if( OrderTicket() != ticket ) OrderSelect( ticket , SELECT_BY_TICKET);
   
   return(OrderOpenPrice());
}

 

взято отсюда: https://www.mql5.com/ru/forum/126457
в принципе рекомендую туда с поиском ходить почаще. Многие (если не все) ситуации обмусолены..

Функция для последнего ордера есть на просторах -это  не проблема..  А вот для предыдущего нет.. именно нужно узнать цену предпоследнего ордера в сетке ордеров.

 

#6716
В 26.06.2023 в 19:35, mishastar сказал:

Функция для последнего ордера есть на просторах -это  не проблема..  А вот для предыдущего нет.. именно нужно узнать цену предпоследнего ордера в сетке ордеров.

 

//---- Ищет ПРЕДпоследний ордер и возвращает его цену открытия----//
double Last_OrderOpPr(int type, int mn, string sym)
{
   datetime last = 0;
   datetime next_to_last = 0;
   int ticket_last = -1;
   int ticket_next_to_last = -1;

   for(int i = OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber() == mn && type == OrderType() && sym==OrderSymbol()) {
         if(last < OrderOpenTime()) {
           if(last > next_to_last) {
             next_to_last = last;
             ticket_next_to_last = ticket_last;
           }
           last = OrderOpenTime();
           ticket_last = OrderTicket() ;
        } else if(next_to_last < OrderOpenTime()) {
        	next_to_last = OrderOpenTime();
            ticket_next_to_last = OrderTicket();
        }
      }
    }
   if(ticket_next_to_last < 0) return(-1);
   OrderSelect(ticket_next_to_last, SELECT_BY_TICKET);
   
   return(OrderOpenPrice());
}

Я добавил пару строк.

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

#6717

Всех приветствую! Не пойму одну вещь, помогите разобраться. Значит изучаю просадку в советнике, допустим ставлю какую-то просадку, по эквити или по минусовому профиту, не важно, суть в том что если имеется просадка, возьмём к примеру в 30% по эквити, то мой советник при такой просадке продолжает торговать и я тут хочу ему заложить логику закрытия просадочных ордеров за счет закрытия ордеров профитных, которые по времени открытия были открыты позже просадочных. Это работает, если профитные ордера перекрывают ордера которые находятся в минусе, но мне нужно чтоб закрывались ордера в просадке не по профиту, а по лотности. И тут приходит в голову простая логика, возьму такой пример: просадка       - 64 при лотности 0,8 общих просадочных ордеров, при этом ордера открывшиеся позже просадочных и закрывшиеся составляют по профиту 28 - из этих данных я пишу формулу какую лотность мне нужно закрыть у просадочных: (28*0.8)/64 = 0,35 значит я должен закрыть 0,35 лота у просадочных, для этого пишу функцию по закрытию:

Спойлер

void SumOfOrders()
  {
   double profluser=0; // остальные ордера в просадке по профиту
   double prblocksorders=0; // блокирующие ордера набравшие определенный профит
   double PartLotsClose=0;//частичного закрытия лота просадочного ордера
   double profluser_lots=0; //сумма просадочных лотов
   double PartClose=0; //значение закрытие по лотности просадочных ордеров
  // double closep = 0, lotclose = 0.01;
  // int j=0;

   for(int y=OrdersHistoryTotal()-1; y>=0; y--)
     {
      if(OrderSelect(y,SELECT_BY_POS,MODE_HISTORY) && (OrderType()==OP_BUY || OrderType()==OP_SELL) && OrderSymbol()==Symbol() && (OrderMagicNumber()==magic_b || OrderMagicNumber()==magic_s)) // magic_b, magic_s - это ордера с определенным мейджиком которые открылись после просадочных
        {
         prblocksorders += OrderProfit()+OrderCommission()+OrderSwap();
        }
     }
   for(int h = 0; h < OrdersTotal(); h++) // закрытие с первых открывшихся ордеров по истории
     {
      if(OrderSelect(h,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
           {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
              {
               profluser += OrderProfit()+OrderSwap()+OrderCommission();
               profluser_lots += OrderLots();

               if(MathAbs(profluser) <= prblocksorders || prblocksorders < MathAbs(profluser)) // само условие закрытия
                 {
                  PartLotsClose = (profluser_lots * prblocksorders) / profluser;
                  PartClose = NormalizeDouble(PartLotsClose,2);
                 }
              }
           }
        }
     }

   if(PartClose>0)
     {
      do
        {
         for(int h = 0; h < OrdersTotal(); h++)
           {
            if(OrderSelect(h,SELECT_BY_POS,MODE_TRADES))
              {
               if(OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
                 {
                  if(OrderType() == OP_BUY)
                     bool close_profit_buy = OrderClose(OrderTicket(), lotclose, Bid, Slippage);
                  if(OrderType() == OP_SELL)
                     bool close_profit_sell = OrderClose(OrderTicket(), lotclose, Ask, Slippage);
                 }
              }
           }
         closep = closep + 0.01;
         j++;
        }
      while((j-j) + closep <= PartClose);
     }          
   }

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

Что-то пошло не так. Эта функция должна запускаться при условии просадки, но открылся в итоге только один ордер и тут же остановка.

Прикрепляю журнал с ошибками

20230818.log

#6718

Доброй ночи.
Подскажите, что быстрее работает, класс или функция? Чтобы при оптимизации меньше времени терять.
И возможно ли реализовать нейросети на MQL4 без сторонних приложений? 

#6719
9 часов назад, makssub сказал:

Доброй ночи.
Подскажите, что быстрее работает, класс или функция? Чтобы при оптимизации меньше времени терять.
И возможно ли реализовать нейросети на MQL4 без сторонних приложений? 

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

2. Нейросети-это обычный пиарход построенный на якобы самообучении программы. По идеи нейросеть должна сама для себя писать алгоритм реализации, а затем его реализовывать. По факту получаем обычным хорошо проработанный алгоритм, зависящий от разработчика. Для примера взять электронные шахматы. Могут ли они переиграть чемпиона мира по шахматам? Влёгкую. Но это всего лишь продуманный алгоритм обычным человеком.

#6720

Всем доброго времени суток.
Подскажите, пожалуйста, как рассчитать цену(не %!) символа, при которой стоп аут произойдет?
Предположим, нам известен процент стоп-аута, допустим 40%. Как узнать и вывести на график цену этого уровня? Видел индикаторы, где это реализовано, но ex4. Может кто-то в курсе как будет выглядеть код расчета цены уровня стоп-аута?


P.S. Процент вычисляется: AccountStopoutLevel(). А вот уровень цены - я без понятия....

Изменено 17 сентября, 2023 пользователем FEEX

#6721

Всем привет, вопрос, как из типа double сделать тип int ? Везде посмотрел но точного ответа не нашел.

Пример double tot = 0,2365

преобразую double znach = (NormalizeDouble(tot,2)), должно получится 0,23

теперь присваиваю к переменной int perem = znach*100, должно получиться 23

в итоге пишет неправильный тип данных int perem и потеря данных

Как сделать?

 

#6722
В 20.09.2023 в 16:15, diodio сказал:

Всем привет, вопрос, как из типа double сделать тип int ? Везде посмотрел но точного ответа не нашел.

Так делать не допустимо. Если тип double преобразовать в тип int, то в общем случае возможна потеря данных.

В 20.09.2023 в 16:15, diodio сказал:

Пример double tot = 0,2365

преобразую double znach = (NormalizeDouble(tot,2)), должно получится 0,23

наверное должно быть 0,24

В 20.09.2023 в 16:15, diodio сказал:

теперь присваиваю к переменной int perem = znach*100, должно получиться 23

в итоге пишет неправильный тип данных int perem и потеря данных

Как сделать?

в вашем случае попробуйте так

double tot = 0.2365;

int perem = (int)MathRound(tot*100);

но еще раз повторю, в общем случае так делать нельзя.

#6723

Пока приглядываюсь к советнику Piramiding.

Было бы очень хорошо, сделать ТР невидимым для брокера, а еще лучше возможность включать или выключать эту невидимость.

#6724

не знаете куда делись видео разделы о программировании ?

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

Перейти к списку тем
Форум · 2.0.20260627.0025