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

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

#6301
9 часов назад, Just Trader сказал:

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

торговле или нет?

extern   int   CloseHour   = 10;
extern   int   CloseMinute = 00;
extern   int   Magic       = 111;

MqlDateTime dt;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   TimeCurrent(dt);
   
   if(OrdersTotal()>0 && dt.hour>=CloseHour && dt.min>=CloseMinute)
   {
      for(int i=0;i<OrdersTotal();i++)
      {
         if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
         if(OrderSymbol()!=_Symbol || OrderMagicNumber() != Magic) continue; // Убрать фильтр по инструменту и/или магику по надобности
         if(OrderType()==OP_BUY)       OrderClose(OrderTicket(),OrderLots(),Bid,0);
         else if(OrderType()==OP_SELL) OrderClose(OrderTicket(),OrderLots(),Ask,0);
      }
   }
}

Схематично так...

Изменено 7 мая, 2021 пользователем usver73

#6302

Здраствуйте! Как мне взять в панель управления

 if(FullAuto&&!CloseLock){if(AccountBalance()+GrossProfit()<AccountBalance()*0.75){CloseLock=true;}else{CloseLock=false;}}

 if(IsTesting()||IsOptimization()){if(TestInfo){return(0.1);}}

Эти части? Не получается

LockMod.mq45 скач.

#6303
В 29.04.2021 в 20:33, mishastar сказал:

Доброго времени суток! 

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

1) по всем валютным парам. 

2) только по заданным валютным парам

3) только по открытым в текущий момент в терминале парам.

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

А если советник установить,  то он будет торговать по заданным парам с одного окна.

Перелапатил уже достаточно материала на эту тему, но ничего не нашел. 

Может у кого  есть индикатор который мониторит насколько валютных пар с одного окна, дайте посмотреть код.

Буду рад любой информации на эту тему. 

 

сначала отработай работу на одном таймрфейме и одной паре используя стандартные Symblol()|Ask|Bid и тп. чтобы понять как и что работает.

 

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

 

схематично переделка кода выглядит приблизительно так:

1. создаешь массив, в которых загоняются валютные пары

2. загоняшеь всю исполняемую часть в цикл пробегая по вышеуказанному массиву и переписываешь все обращения с "текущим" графиком через маркетинфо с ссылкой на текущий элемент массива.

 

Я когда был молодым и зеленым переделывал Илан на мультивалюту.

вот исходник, в нем можешь многое почерпнуть. Обработчик валютных пар не идеален конечно, там можно поплясать и префиксами и постфиксами и тд. и т.п. и на солнце есть пятна.  Код я выложил как пример, писал я его лет 5 назад и уже ничего по нему не помню.

 

ЗЫ: ах да, если хочешь чтобы код у тебя исполнялся вне зависимости от поступающих тиков по определенной паре(ведь советник работает на графике какой-либо валютной пары), то осваивай OnTimer(). скинутый мной код как раз сделан по такому образу и подобию. там же если покопаешься увидишь как я обыгрываю тестер, чтобы можно было "игнорить" таймер и "торговать" по-дедовски через OnTick()

Ilanus_v2.5multiTF.mq415 скач.

Изменено 20 мая, 2021 пользователем dermitay

#6304

У кого были ошибки zero divide при тестировании, и как с этим бороться? Где может быть ошибка в коде?

#6305
2 часа назад, Lexa000 сказал:

У кого были ошибки zero divide при тестировании, и как с этим бороться? Где может быть ошибка в коде?

В сообщении указывается номер строки и позиция в строке, где произошла ошибка 

#6306
35 минут назад, usver73 сказал:

В сообщении указывается номер строки и позиция в строке, где произошла ошибка 

Да есть,  zero divide in 'Locomotive v1.01 (21).mq4' (713,69), вот такое

if(OrderType()==0) price+=OrderOpenPrice()*(OrderLots()/slot); else price-=OrderOpenPrice()*(OrderLots()/slot);

в этой строчке

#6307
8 минут назад, Lexa000 сказал:

Да есть,  zero divide in 'Locomotive v1.01 (21).mq4' (713,69), вот такое

if(OrderType()==0) price+=OrderOpenPrice()*(OrderLots()/slot); else price-=OrderOpenPrice()*(OrderLots()/slot);

в этой строчке

ошибка деления на ноль. проверяй значение slot

#6308
13 минут назад, dermitay сказал:

ошибка деления на ноль. проверяй значение slot

 for(i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symb && OrderMagicNumber()==magic) {
            if(OrderType()==0) slot+=OrderLots(); else slot-=OrderLots();
            }
         }
      slot =slot-del_slot;
      for(i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symb && OrderMagicNumber()==magic) {
            if(OrderType()==0) price+=OrderOpenPrice()*(OrderLots()/slot); else price-=OrderOpenPrice()*(OrderLots()/slot);
            }
         }
      price = price - del_price;
      price=NormalizeDouble(price+take_profit*Pp,Digits);
      for(i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symb && OrderMagicNumber()==magic) {
            if(OrderType()==0) ModifyOrder(OrderTicket(),-1,1,price);
                          else ModifyOrder(OrderTicket(),-1,price+(Ask-Bid),1);

Так полностью

#6309

Я так понимаю где магик, нужно было дописать

magic&&slot>0

#6310

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

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

- зачем это делается?

- как это должно работать?

- как это работает сейчас?

 

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

 

можешь принтами выводить в логи значения переменных - это уровень чайника. тогда ты увидишь что чему равно в определенный момент исполнения кода. например перед открытиыем ордеров таки вывести print(DoubleToString(slots)) или типа того.

 

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

ну как бы если ты учишься - то учись сразу по правильному пути. все вышеозвученное гуглится - изучай. траст ми гугл и мкл докс станут твоими друзьями:d

Изменено 15 мая, 2021 пользователем dermitay

#6311

Ну да, я мог бы и гуглить, спасибо за ответ

#6312

I ' m interested in their recovery funtion and want to learn form it .   in case of you have many order in recovery mode.

for Example .  1order buy \sell   2nd order sell \ buy    3rd order buy\sell     .  all order no sl , only tp  

when  it hit tp no matter what side  , close all orders ,   

 

please advise , Thank you 

#6313
6 часов назад, Olaft_T сказал:

I ' m interested in their recovery funtion and want to learn form it

I can't understand you and I think no one can here )
Maybe you are talking about this: /laboratoriya-profitfx/24/open-source-sovetnik-to_piranhafx-x2-price-zone/16042/?do=findComment&comment=350086

If so, in that thread you can find open source mq4.

#6314

Здравствуйте! Можете помочь изменить стратегию торговли кода

#6315

***********************************************/

void OnTick()

  {

   double

   BuyPriceMax=0,BuyPriceMin=0,BuyPriceMaxLot=0,BuyPriceMinLot=0,

   SelPriceMin=0,SelPriceMax=0,SelPriceMinLot=0,SelPriceMaxLot=0;

 

   int

   BuyPriceMaxTic=0,BuyPriceMinTic=0,SelPriceMaxTic=0,SelPriceMinTic=0;

 

   double

   op=0,lt=0,tp=0;

 

   int

   tk=0,b=0,s=0;

 

   for(int i=OrdersTotal()-1;i>=0;i--)

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

         if(OrderMagicNumber()==iMagicNumber)

            if(OrderSymbol()==Symbol())

              {

               op=NormalizeDouble(OrderOpenPrice(),Digits());

               lt=NormalizeDouble(OrderLots(),2);

               tk=OrderTicket();

               if(OrderType()==OP_BUY)

                 {

                  b++;

                  if(op>BuyPriceMax || BuyPriceMax==0)

                    {

                     BuyPriceMax    = op;

                     BuyPriceMaxLot = lt;

                     BuyPriceMaxTic = tk;

                    }

                  if(op<BuyPriceMin || BuyPriceMin==0)

                    {

                     BuyPriceMin    = op;

                     BuyPriceMinLot = lt;

                     BuyPriceMinTic = tk;

                    }

                 }

               // ===

               if(OrderType()==OP_SELL)

                 {

                  s++;

                  if(op>SelPriceMax || SelPriceMax==0)

                    {

                     SelPriceMax    = op;

                     SelPriceMaxLot = lt;

                     SelPriceMaxTic = tk;

                    }

                  if(op<SelPriceMin || SelPriceMin==0)

                    {

                     SelPriceMin    = op;

                     SelPriceMinLot = lt;

                     SelPriceMinTic = tk;

                    }

                 }

              }

//*************************************************************//

   double   AwerageBuyPrice=0,AwerageSelPrice=0;

   if(b>=2) AwerageBuyPrice=NormalizeDouble((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*BuyPriceMinLot)/(BuyPriceMaxLot+BuyPriceMinLot)+iMinimalProfit*Point(),Digits());

   if(s>=2) AwerageSelPrice=NormalizeDouble((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)/(SelPriceMaxLot+SelPriceMinLot)-iMinimalProfit*Point(),Digits());

//*************************************************************//

   double BuyLot=0,SelLot=0;

 

   if(BuyPriceMinLot==0)

      BuyLot=iStartLots;

   else

      BuyLot=BuyPriceMinLot*iLotmultiplier;

 

   if(SelPriceMaxLot==0)

      SelLot=iStartLots;

   else

      SelLot=SelPriceMaxLot*iLotmultiplier;

 

   if(BuyLot>iMaximalLots)      BuyLot=iMaximalLots;

   if(SelLot>iMaximalLots)      SelLot=iMaximalLots;

//*************************************************************//

//*********************** One Step ****************************//

//*************************************************************//

   if(b==0 && (Close[1]>Open[1]))

      if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(iStartLots,2),NormalizeDouble(Ask,Digits()),iSlippage,0,0,iMagicNumber,0,clrGreen)<0)

         Print("OrderSend error #",GetLastError());

   if(s==0 && (Close[1]<Open[1]))

      if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(iStartLots,2),NormalizeDouble(Bid,Digits()),iSlippage,0,0,iMagicNumber,0,clrGreen)<0)

         Print("OrderSend error #",GetLastError());

 

//*************************************************************//

//*********************   Profit  *****************************//

//*************************************************************//

   if(b>0 && iPointOrderStepProfit>0 && (Ask-BuyPriceMax)>iPointOrderStepProfit*Point())

      if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(iStartLots,2),NormalizeDouble(Ask,Digits()),iSlippage,0,0,iMagicNumber,0,clrGreen)<0)

         Print("OrderSend error #",GetLastError());

 

   if(s>0 && iPointOrderStepProfit>0 && (SelPriceMin-Bid)>iPointOrderStepProfit*Point())
Здесь нужно чтобы в направлении профита лот увеличивался на единицу, как это сделать?

#6316
6 часов назад, Lexa000 сказал:

Здесь нужно чтобы в направлении профита лот увеличивался на единицу, как это сделать?

Попробуйте переформулировать вопрос.
Примерно в формате: "имеем то-то и то-то, хотим это и это"
п.с. чтобы код читался, нужно его загонять в тэги "код"image.png.1e30fc32ef5b95062b45d37d11889c82.png
 

#6317
54 минуты назад, usver73 сказал:

Попробуйте переформулировать вопрос.
Примерно в формате: "имеем то-то и то-то, хотим это и это"
п.с. чтобы код читался, нужно его загонять в тэги "код"image.png.1e30fc32ef5b95062b45d37d11889c82.png
 

Снова неправильно вопрос задал. Это советник без головы: тп,сл, трал, шаг, лот, минпрофит, мультимножитель мартина, проскальзывание и магик. Сам в тексте и виден, полностью рабочий

#6318

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

#6319

Например: открываются сделки 0.01,0.02,0.03,0.4,0.05 в сел, а в бай 0.01 профит, 0.01 профит. Нужно чтобы в бай 0.01 открывался не 0.01, а 0.02 в бай против 0.05 сел. Как это сделать?

#6320
29 минут назад, Lexa000 сказал:

Как это сделать?

Все равно плохо объясняете.

29 минут назад, Lexa000 сказал:

Нужно чтобы в бай 0.01 открывался не 0.01, а 0.02 в бай против 0.05 сел.

У Вас два ордера в БАЙ. Нужно чтобы второй ордер был 0,02 или оба?
И что значит "против 0,05 СЕЛЛ"? на одном уровне?
Чтобы понять проблему пришлось таки вчитываться в код.
В этом месте 

if(b>0 && iPointOrderStepProfit>0 && (Ask-BuyPriceMax)>iPointOrderStepProfit*Point())
      if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(iStartLots,2),NormalizeDouble(Ask,Digits()),iSlippage,0,0,iMagicNumber,0,clrGreen)<0)
         Print("OrderSend error #",GetLastError());

судя по всему Вы хотите открыть ордер с лотностью на шаг больше, чем лотность самого старшего(по лотности) БАЙ-ордера.
Но открываете почему-то с лотностью iStartLots, хотя выше по коду находите лотность BuyLot...
 
Немного общих замечаний:

lt=NormalizeDouble(OrderLots(),2); нормализовать не нужно.

NormalizeDouble(Ask,Digits()) Нормализовать не нужно.

NormalizeDouble(iStartLots,2) нормализовать не нужно (если не пришло в голову задать в настройках значение 0,0145874).

А вот BuyLot=BuyPriceMinLot*iLotmultiplier;  как раз нужно нормализовать, т.к. не факт, что после операции у Вас будет 2 знака после запятой.

Кусок кода "One Step" проверяет условие на вход по закрытой свече, поэтому имеет смысл завернуть в проверку типа IsNewBar()

#6321
1 час назад, usver73 сказал:

Все равно плохо объясняете.

У Вас два ордера в БАЙ. Нужно чтобы второй ордер был 0,02 или оба?
И что значит "против 0,05 СЕЛЛ"? на одном уровне?
Чтобы понять проблему пришлось таки вчитываться в код.
В этом месте 


if(b>0 && iPointOrderStepProfit>0 && (Ask-BuyPriceMax)>iPointOrderStepProfit*Point())
      if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(iStartLots,2),NormalizeDouble(Ask,Digits()),iSlippage,0,0,iMagicNumber,0,clrGreen)<0)
         Print("OrderSend error #",GetLastError());

судя по всему Вы хотите открыть ордер с лотностью на шаг больше, чем лотность самого старшего(по лотности) БАЙ-ордера.
Но открываете почему-то с лотностью iStartLots, хотя выше по коду находите лотность BuyLot...
 
Немного общих замечаний:

lt=NormalizeDouble(OrderLots(),2); нормализовать не нужно.

NormalizeDouble(Ask,Digits()) Нормализовать не нужно.

NormalizeDouble(iStartLots,2) нормализовать не нужно (если не пришло в голову задать в настройках значение 0,0145874).

А вот BuyLot=BuyPriceMinLot*iLotmultiplier;  как раз нужно нормализовать, т.к. не факт, что после операции у Вас будет 2 знака после запятой.

Кусок кода "One Step" проверяет условие на вход по закрытой свече, поэтому имеет смысл завернуть в проверку типа IsNewBar()

У Вас два ордера в БАЙ. Нужно чтобы второй ордер был 0,02 или оба?
И что значит "против 0,05 СЕЛЛ"? на одном уровне?
Нет, когда открыта сетка ордеров в просадку от 0.01 до 0.05 в целом это лот 0.15 с противоположной стороны нужно чтобы открывалось с 0.02 также сеткой как есть

#6322

Убрал NormalizeDouble, стала появляться ошибка зеро

#6323
47 минут назад, Lexa000 сказал:

Убрал NormalizeDouble, стала появляться ошибка зеро

Причина не в этом. 

Недавно обсуждали,  как искать ошибку 

#6324

по мне так там многое зависит от того что вбивается во входные переменные. 

 

учитывая оба процитированных блока ощущение что iStartLots = 0 изначально. ну и не понятно зачем играть лотностью ордеров чтобы потом открывать их по iStartLots. 

 

я так и не увидел где ордера открываются по BuyLot/SellLot.

где-то есть еще блоки на открытие, в них и ошибка, имхо.

 

ЗЫ: NormalizeDouble'ом кашу не испортишь. Порой мт4 выдавал такую дичь в котировках что лично я его юзаю теперь везде где ни попади. Чтобы было, чтобы стопудово эти ошибки не вываливались. Ошибка зеро по логике не должна появляться/исчезать из-за нормалайза.

смысл этой функции "обрезать" лишнее(имеется ввиду округление). так как например мт4 ругается на лотности, если в них указываются тысячные доли и далее по убывающей порядка(десятитысячная доли, стотясячная доля и тп). аналогично и с котировками и т.д. и т.п. если пятизнак и внезапно выдалась котировка 1.234567890 внутри какой-либо функции на открытие/закрытие/модификации ордера будет ошибка так как 7890 - уже лишняя дробная часть.

 

а ваще, есть вот такая вот штука. настольная библия для новичка.

https://docs.mql4.com/ru/

 

вот пример описания нормалайза

https://docs.mql4.com/ru/convert/normalizedouble

Изменено 27 мая, 2021 пользователем dermitay

#6325

Вот такой Советник

iSmart.mq48 скач.

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

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