Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1739

 
Artyom Trishkin #:

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

Благодарю за информацию!

Если будет время, прошу вас ответить, как исправить:

На истории N свечей назад ставятся две разнонаправленные цели: Close[N]+50*Point и Close[N]-50*Point. 
Затем условие, что цена должна дойти до одной из целей(if (High[i]> Close[N]+50*Point) или  (if (Low[i]< Close[N]-50*Point)
При выполнении условия расстояние от Close[N] до High[i] заносится в массив x[high]=High[i].
Затем рандомно кидается на любой из графиков в любое время. 

И при проверке через Print(x[high]), 1-2 из десяти значений показывают меньше 50! У одного 12, у другого 49. Хотя, строго указано +50*Point. 8-9 правильно показывают (больше 50-ти), а 1-2 аномальные. Это не через тестер, а на реальный график накидываю советник (без торговых функций), а только с вышеуказанными, он работает с историей и такое пишет. 

Чем больше берется значение, тем меньше таких ошибок. Думал, может, спред мешает, но... в МТ4 вроде нет спреда на истории

 
Artis98 #:

Здравсвуйте уважаемые форумчане и опытные программёры! Нужна помощь в доделывании советника)) Подскажите, плиз, как добавить в код советника 2 вещи:

1. Ситуация следующая - открываю ордер (1-ыЙ) с TP и SL и определённым лотом (пусть будет 0,01). Если данный ордер закрывается по тейк-профиту - круто, ничего не меняется. Но, если данный (1-ый) ордер закрывается по SL, то тогда следующий ордер сразу после этого (2-ой) открывается с увелечинным лотом в 2 раза (0,01*2=0,02). Если этот 2-ой ордер закрывается по тейк-профиту - тогда следующий ордер (3-ий) открывается с обычным лотом, т.е. увеличенный лот в 2 раза нужен только на следующий ордер (2-ой) после того как на прошлом (1-ый) было закрытие по SL. Если же на 3-ем ордере во второй раз подряд будет закрытие по SL - тогда лот остаётся увелеченным в 2 раза до тех пор, пока не будет закрытие по TP. Надеюсь, описал подробно логику что нужно добавить;


2. И второе что нужно добавить - это передвижение SL, сейчас объясню на конкретном примере: допустим есть ордер с базовыми парамметрами T.P. + 300, S.L. — 500. Цена идёт в нужную сторону и проходит +100 пиппсов от цены открытия ордера. Как только цена добралась до +100 от цены открытия ордера,  SL должен передвинуться с базовых —500 на + 90 . Т.е. при достижении цены + 100 пиппсов от цены открытия ордеоа, переводим ордер в безубыток выставляя S,L. на + 90 пиппсов. После этого, если цена дальше идёт в нужную сторону, и проходит ещё + 50 пиппсов - S.L. передвигается на 50 пиппсов => теперь он должен быть на отметке в + 140 пиппсов от цены открытия ордера. Т.е. S.L. в первый раз передвигается с базового положения на + 90 пиппсов от цены открытия ордера, а затем передвигается если проходит по + 50 пиппсов ( — 500 => + 90 => + 140 => + 190 и т.д.). И так всё идёт либо до того как цена достигнет T.P. , либо когда движение тренда развернётся и выбьет по S.L.


Надеюсь, что всё подробно описал, и очень надеюсь на вашу помощь, т.к. добавив эти недостоющие элементы, советник будет готов)) Если есть вопросы - спрашивайте))) Ниже выкладываю часть кода советника:

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

По второму: В этой ветке я давно уже выкладывал образец для создания трейлингстопа. Поищите. Лучше в моём профиле в сообщениях пользователя - там быстрее найдёте, чем листать 100+ страниц здесь. Потом уже на основе найденного примера, попробуете создать свой трал.

 
Artyom Trishkin #:

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

А можно программно получить количество подгруженных баров?

Сам просто смотрю дату в архиве котировок для каждого ТФ и стараюсь за них не вылезать в расчетах. 

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

 
Artyom Trishkin #:

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

По-моему я это и изменил уже в коде:

//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
 double Lots()  // Расчет объема лота
  {
   int n=0;
   double Lotscount;
   double OL=Lot;
   
   
   if(Lot>0) return(LOT());          // "если во внешней переменной "Lot" стоит число больше 0 => будет фиксированный лот без авт. расчёта" 
   Lotscount=AccountFreeMargin()/10000;  // раcчёт лота - свободная маржа/9000 => 100/9000=0.01 лота 
   Lotscount=MathMin(15,MathMax(0.01,Lotscount));
    if(Lotscount<0.1) Lotscount=NormalizeDouble(Lotscount,2);
    else 
     {
       if(Lotscount<1) Lotscount=NormalizeDouble(Lotscount,1);
      else       Lotscount=NormalizeDouble(Lotscount,0);
     }
     
     for (int j = OrdersHistoryTotal()-1; j >= 0; j--)
   {
      if (OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
      {
          if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if (OrderProfit()<0) 
             {
               if (n==0) OL=NormalizeDouble(OrderLots()*K_Martin,DigitsLot);
               n++; 
               if (OrderProfit()>0) return(Lotscount);
            }
            else
            {
               if (n==0) {Comment("2");return(Lotscount);}
               else {Comment("3");return(OL);}
            }
         }
      }
   }
      return(Lotscount);
 }
//------------------------------------------------------------------
double LOT()
{
   int n=0;
   double OL=Lot;
   for (int j = OrdersHistoryTotal()-1; j >= 0; j--)
   {
      if (OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if (OrderProfit()<0) 
            {
               if (n==0) OL=NormalizeDouble(OrderLots()*K_Martin,DigitsLot);
               n++; 
               if (OrderProfit()>0) return(Lot);}
            }
            else
            {
               if (n==0) {Comment("2");return(Lot);}
               else {Comment("3");return(OL);}
            }
         }
      }
   }
   return(OL);
}

Или это не то? К тому же, я не знаю как  изменить две вещи связанные с лотом. Первое, это сделать так, что-бы ордер с удвоенным лотом открывался только один раз и только на одном ордере (следующем ордере после того, на котором был S.L.). И второе, что не знаю как добавить, это сделать так, что-бы в случае двух S.L. подряд (два ордера закрылись по S.L. подряд), третий ордер не открывался с лотом увеличенным ещё на 2 (2*2*2) , а только один раз (2*2) как и второй ордер. 

 
Artis98 #:

По-моему я это и изменил уже в коде:

Или это не то? К тому же, я не знаю как  изменить две вещи связанные с лотом. Первое, это сделать так, что-бы ордер с удвоенным лотом открывался только один раз и только на одном ордере (следующем ордере после того, на котором был S.L.). И второе, что не знаю как добавить, это сделать так, что-бы в случае двух S.L. подряд (два ордера закрылись по S.L. подряд), третий ордер не открывался с лотом увеличенным ещё на 2 (2*2*2) , а только один раз (2*2) как и второй ордер. 

у вас есть ДВА типа ордеров - №1 - ордер с обычным лотом, и №2 - ордер с увеличенным лотом. Лоты увеличиваются только по SL типа №1

Сохраните тип ордера в "comment" например. А лучше запомните у себя, вообще хорошая привычка - запоминать самому всё про свои ордера. 

 
Maxim Kuznetsov #:

у вас есть ДВА типа ордеров - №1 - ордер с обычным лотом, и №2 - ордер с увеличенным лотом. Лоты увеличиваются только по SL типа №1

Сохраните тип ордера в "comment" например. А лучше запомните у себя, вообще хорошая привычка - запоминать самому всё про свои ордера. 

Не нужно ему ничего запоминать (тем более, что запоминание требует последующего восстановления). Ему достаточно знать как закрылась прошлая позиция. Всё. Не нужно знать ни две, ни три, ни сто подряд или не подряд закрытых по стоплосс, а лишь прошлая. Если она закрыта по стоплосс, то следующая должна быть с удвоенным лотом. Но лот нужно удваивать не от лота прошлой позиции, а от заданного в программе обычного лота. Тогда - если позиция закрыта не по стоплосс, то открывать обычным лотом следующую. Если позиция закрыта по стоплосс, то открывать следующую удвоенным. Всё. Больше ничего знать не нужно.

 
Artyom Trishkin #:

Не нужно ему ничего запоминать (тем более, что запоминание требует последующего восстановления). Ему достаточно знать как закрылась прошлая позиция. Всё. Не нужно знать ни две, ни три, ни сто подряд или не подряд закрытых по стоплосс, а лишь прошлая. Если она закрыта по стоплосс, то следующая должна быть с удвоенным лотом. Но лот нужно удваивать не от лота прошлой позиции, а от заданного в программе обычного лота. Тогда - если позиция закрыта не по стоплосс, то открывать обычным лотом следующую. Если позиция закрыта по стоплосс, то открывать следующую удвоенным. Всё. Больше ничего знать не нужно.

не учи людей плохому.

свои данные надо помнить и по ним работать

 
Artyom Trishkin #:

 Ему достаточно знать как закрылась прошлая позиция. Всё. Не нужно знать ни две, ни три, ни сто подряд или не подряд закрытых по стоплосс, а лишь прошлая. Если она закрыта по стоплосс, то следующая должна быть с удвоенным лотом.  Если позиция закрыта по стоплосс, то открывать следующую удвоенным. 

Это мне и нужно, вот собственно в этом и вопрос - как это прописать в коде? 

 

Здравствуйте!
Может кто знает, как компилятору принудительно указать, чтобы компилировал для МТ4, а не MT5?

Если файл с расширением *.mq4 то все нормально, если  *.mqh, то компилятор начинает его воспринимать как *.mq5 и сыпятся ошибки.

 
Sergey Zhukov #:

Здравствуйте!
Может кто знает, как компилятору принудительно указать, чтобы компилировал для МТ4, а не MT5?

Если файл с расширением *.mq4 то все нормально, если  *.mqh, то компилятор начинает его воспринимать как *.mq5 и сыпятся ошибки.

Давай сюда файл. Это что-то новенькое, такого еще не слышал.