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

Ugar

Гуру форума
Так же не очень правильно сравнивать цену закрытия с стоп лоссом, даже нормированные. Это в тестере всё гладко, а в реале может иногда и не прокатить.
 

deepdig

Активный участник
Помогите пожалуйста разобраться! Никак не получается добиться от советника октрытия второго цикла отложенных ордеров.


PHP:
Expand Collapse Copy
extern double lot1     = 0;      //рабочий лот
extern double lot2     = 0;      //лот 1-го отложенного ордера
extern double lot3     = 0;      //лот 2-го отложенного ордера
extern double lot4     = 0;      //лот 3-го отложенного ордера
extern double lot5     = 0;      //лот 4-го отложенного ордера
extern int Stop_Loss   = 0;        //стоп лосс
extern int Take_Profit = 0;        //тейк профит
extern int Open_Level  = 0;        //уровень отдаления от цены, на котором ставим отложенный ордер
extern int slippage    = 2;         //уровень допустимого реквота
extern int MagicNumber = 0;      //магическое число ордеров

int tiсket1=0, ticket2=0, ticket3=0, ticket4=0, ticket5=0;
  

  int init()
  {
  Comment("Старт советника ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));
   
  return(0);
  }



  int start()
  {
  
  
   double SLbuy=0, SLsell=0,TPbuy=0,TPsell=0;
   double Spread=Ask-Bid;
   double Pending_By=Ask+Open_Level*Point;
   double Pending_Sell=Bid-Open_Level*Point;
   
if(Stop_Loss>0) {SLbuy=Ask-Stop_Loss*Point-Spread; SLsell=Bid+Stop_Loss*Point+Spread;}
if(Take_Profit>0) {TPbuy=Ask+Take_Profit*Point; TPsell=Bid-Take_Profit*Point;}


  int count=OrdersTotal();                            // объявление переменной колличества ордеров
  
//-------------------------Старт цикла. Открытие 1-го и 2-го отрдеров ------------

   if(count==0) tiсket1=OrderSend (Symbol(), OP_SELL, lot1, Bid, slippage,       
   SLsell, TPsell, "LLL_1_Sell", MagicNumber, 0, Red);
   
   if(count==0) ticket2=OrderSend (Symbol(), OP_BUYSTOP, lot2, Pending_By, slippage, 
   SLbuy+Open_Level*Point, TPbuy+Open_Level*Point, "LLL_1_Bystop", MagicNumber, 0, Blue);
    
//-------------------------удаление несработавших отложенных ордеров----------------------

   for(int i=0; i<count; i++)                         // цикл пересчета открытых ордеров
   {
   bool res=OrderSelect(i, SELECT_BY_POS);            // выбор ордера по позиции
      if (res)
      {
      int ticket=OrderTicket();
         if (count==1) OrderDelete(ticket);          // удаление несработавших отложенных ордеров
      }
   }  
//---------------------------открытие 2-го отложенного ордера------------------------------
    
   bool res1=OrderSelect(ticket2, SELECT_BY_TICKET);           // выбор 1-го отложенного ордера         
      if (res1)
      {
      int type=OrderType();                           // проверка состояния 1-го отложенного ордера
      
         if (type==0&&ticket3==0) ticket3=OrderSend (Symbol(), OP_SELLSTOP, lot3, 
         Pending_Sell+Spread, slippage, SLsell-Open_Level*Point, TPsell-Open_Level*Point, "LLL_1_Selltop", MagicNumber, 0, Yellow);  
                                                      //открытие 2-го отложенного ордера
      }
          
      
//---------------------------открытие 3-го отложенного ордера------------------------------      
      
   bool res2=OrderSelect(ticket3, SELECT_BY_TICKET);           // выбор 2-го отложенного ордера 
      if (res2)
      {
      int type2=OrderType();                          // проверка состояния 2-го отложенного ордера
      
         if(type2==1&&ticket4==0) ticket4=OrderSend (Symbol(), OP_BUYSTOP, lot4, Pending_By-Spread, slippage, 
         SLbuy+Open_Level*Point-Spread, TPbuy+Open_Level*Point-Spread, "LLL_2_Bystop", MagicNumber, 0, Green);
                                                      //открытие 3-го отложенного ордера   
      }
         
//---------------------------открытие 4-го отложенного ордера------------------------------
      
   bool res3=OrderSelect(ticket4, SELECT_BY_TICKET);           // выбор 3-го отложенного ордера 
      if (res3)
      {
      int type3=OrderType();                          // проверка состояния 3-го отложенного ордера
      
         if (type3==0&&ticket5==0) ticket5=OrderSend (Symbol(), OP_SELLSTOP, lot5, 
         Pending_Sell+Spread, slippage, SLsell-Open_Level*Point, TPsell-Open_Level*Point, "LLL_2_Selltop", MagicNumber, 0, White);
                                                      //открытие 4-го отложенного ордера   
      }
   
   return(0);
  }
 
Последнее редактирование модератором:

vetallic

Местный знаток
хелп... как правильно прописать расчет максимума и минимума за определенный период часового времени и открытие при пробое... :question:
 

Ugar

Гуру форума
хелп... как правильно прописать расчет максимума и минимума за определенный период часового времени и открытие при пробое... :question:
Код:
Expand Collapse Copy
int _Hour_=8;
   double Maximum=iHigh(NULL,PERIOD_H1,iHighest(NULL,PERIOD_H1,MODE_HIGH,_Hour_,1));
   double Minimum=iLow(NULL,PERIOD_H1,iLowest(NULL,PERIOD_H1,MODE_LOW,_Hour_,1));
Здесь задаётся в _Hour_ количество часов для поиска максимума и минимума.
В переменных Maximum и Minimum, соответственно максимальная и минимальная цена за этот период.
 

Praktikantrop

Прохожий
Прошу не пинать, только изучаю mql4, возник вопрос:
функция TimeCurrent() и значение массива Time[0] с индексом 0, разве не должны быть близкими по значению??? если эти значения в секундах, то разница между ними у меня составляет почти 16 часов, это нормально???
 

Ugar

Гуру форума
Прошу не пинать, только изучаю mql4, возник вопрос:
функция TimeCurrent() и значение массива Time[0] с индексом 0, разве не должны быть близкими по значению??? если эти значения в секундах, то разница между ними у меня составляет почти 16 часов, это нормально???
TimeCurrent() это время прихода последнего тика.
Time[0] это время открытия текущего бара, текущего тайм фрейма.
Если на графике выбран график D1 то разница между ними может достигать до 24 часов.
 

Praktikantrop

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

Praktikantrop

Прохожий
Хорошо, а подсчет времени одного бара в секундах (TimeCurrent() - Time[Bars-1])/Bars
так корректно?
 

Ugar

Гуру форума
Хорошо, а подсчет времени одного бара в секундах (TimeCurrent() - Time[Bars-1])/Bars
так корректно?
Это что, попытка рассчитать среднее время бара? В любом случае это некорректно. Время идёт всегда, а в выходные баров нет. Да и дыры в истори не учтены.
Время бара в секунда соответствует периоду графика в численном представлении *60. Это конечно примерно, так как в mql4 всё привязано к тикам.
 

Praktikantrop

Прохожий
Спасибо, с этим вроде разобрался. Но все равно МТ4 не работает так как я хочу)))) вот например нужно найти свечку, которая была месяц назад
я делаю так:
i=Bars-1;
while (Time < (TimeCurrent()-60*60*24*30))
{
i--;
}
дальше смотрим что получилось
Alert(Time - TimeCurrent());
и видим число 2032226 на М1, это получается 23 с половиной суток. Такое впечатление, что терминал выдает число с потолка. И плюс ко всему это число еще и разное на разных таймфреймах. Какой то рандом блин....
P.S. историю котировок не забыл подгрузить
 

Ugar

Гуру форума
Спасибо, с этим вроде разобрался. Но все равно МТ4 не работает так как я хочу)))) вот например нужно найти свечку, которая была месяц назад
я делаю так:
i=Bars-1;
while (Time < (TimeCurrent()-60*60*24*30))
{
i--;
}
дальше смотрим что получилось
Alert(Time - TimeCurrent());
и видим число 2032226 на М1, это получается 23 с половиной суток. Такое впечатление, что терминал выдает число с потолка. И плюс ко всему это число еще и разное на разных таймфреймах. Какой то рандом блин....
P.S. историю котировок не забыл подгрузить

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

datetime CTime=TimeCurrent();//Текущее время
datetime Time30=CTime-60*60*24*30;//Время 30 дней назад
int bar=iBarShift(NULL,0,Time30,false); //номер ближайшего бара
Comment("Текущее время ",TimeToStr(CTime,TIME_DATE|TIME_MINUTES),
"\n","30 дней назад ",TimeToStr(Time[bar],TIME_DATE|TIME_MINUTES));

Надеюсь с помощью справочника разберёшься что написал.
 

Dom

Гуру форума
Ugar!Помоги пожалуйста,заклинило,не могу сообразить.Мне нужно выставить лимитный ордер по цене открытия,последней закрытой позиции по профиту.
У меня не получается,ума не хватает.
 

Ugar

Гуру форума
Ugar!Помоги пожалуйста,заклинило,не могу сообразить.Мне нужно выставить лимитный ордер по цене открытия,последней закрытой позиции по профиту.
У меня не получается,ума не хватает.
Ордера в истории находятся в порядке времени закрытия.
Перебирай в цикле исторические ордера от последнего к первому. Проверяй как закрылся ордер, если ордер закрылся не по тейку переходи к следующему по continue. Если по тейку то извлекай цену открытия по OrderOpenPrice и прерывай перебор break.
Далее устанавливай ордер по этой цене, не забудь предварительно её нормировать.
Естественно, перед этим всем надо убедиться что открытый ордер закрылся и что отложенный ордер ещё не установлен. Например переребором не исторических ордеров.

Если есть элементарные знания языка, всё что я здесь нацарапал будет понятно. А если нет то лучше обратиться к программисту.
 

Dom

Гуру форума
Ордера в истории находятся в порядке времени закрытия.
Перебирай в цикле исторические ордера от последнего к первому. Проверяй как закрылся ордер, если ордер закрылся не по тейку переходи к следующему по continue. Если по тейку то извлекай цену открытия по OrderOpenPrice и прерывай перебор break.
Далее устанавливай ордер по этой цене, не забудь предварительно её нормировать.
Естественно, перед этим всем надо убедиться что открытый ордер закрылся и что отложенный ордер ещё не установлен. Например переребором не исторических ордеров.

Если есть элементарные знания языка, всё что я здесь нацарапал будет понятно. А если нет то лучше обратиться к программисту.
Спасибо!Завтра попробую,сегодня уже ступор.Я пробовал прицепить Кимовские функции "Возвращает флаг закрытия последней позиции по тейку" и "Возвращает цену открытия последней закрытой позиций" не получилось.
 

Praktikantrop

Прохожий
Попробуй как скрипт вот такой код.

Все равно лыжи не едут. Точнее поехали но не полностью. Предложенный код работает на всех графиках кроме М1, тоесть кроме того графика, где подгружена история котировок. Выдает дату, далекую от нужной. хотя при жестком указании номера свечки, их можно прочитать (получается все свечки доступны). По идее должно работать:fa:
 

Ugar

Гуру форума
Все равно лыжи не едут. Точнее поехали но не полностью. Предложенный код работает на всех графиках кроме М1, тоесть кроме того графика, где подгружена история котировок. Выдает дату, далекую от нужной. хотя при жестком указании номера свечки, их можно прочитать (получается все свечки доступны). По идее должно работать:fa:
Может лыжи не едут потому что на асфальте?
Значит подгружена кривая или дырявая история.
Вот что у меня показывает на M1
12.JPG

Как видно отрабатывает точно 30 дней назад.

int bar=iBarShift(NULL,0,Time30,false); //номер ближайшего бара
Эта строчка находит бар которому принадлежит указанное время. Если такого бара нет то указывает ближайший. Если в конце строки вместо false указать true, то в случае не существующего бара не будет выискиваться ближайший, будет возвращено -1, то есть ошибка.
 
Последнее редактирование:

vetallic

Местный знаток
всем еще раз прет,
вот создаю индюк и вот хотел спросить как правильно записать патерн "молот"
у меня вышло так - ((C>O)&&(O<H)&&(C<H)&&(O==L)&&(O1<O)&&(C>H1))

нужно указание в пипсах наверно..., а то у меня бар на хз сколько уходит (вверх или низ) и фиксирует полот

Вроде нормально работает:
dd2fe78378c8.png


А потом такая фигня:
0a1e2b009d11.png
 
Последнее редактирование:

Ugar

Гуру форума
всем еще раз прет,
вот создаю индюк и вот хотел спросить как правильно записать патерн "молот"
у меня вышло так - ((C>O)&&(O<H)&&(C<H)&&(O==L)&&(O1<O)&&(C>H1))

нужно указание в пипсах наверно..., а то у меня бар на хз сколько уходит (вверх или низ) и фиксирует полот

Вроде нормально работает:


А потом такая фигня:
молот2.JPG
1. У молотка ручка всегда длиннее чем сам молот. То есть тень должна быть длиннее тела.
2. Молот может быть и с двумя тенями. Но вторая тень должна быть ничтожно малой.
3. Цвет тела молотка не имеет значения.
4. Молоток бесполезен если он не на вершине
Лучше искать соотношение длинны тела к длине свечи
 

saenko

Интересующийся
Ребята...помогите кто знает!!!!

У меня появилась проблема и я не представляю как ее можно решить постараюсь объяснить.
Значит в коде есть, который я выложил, есть 2 функции
//+------------------------------------------------------------------+
//| подготовить массив тикетов для закрытия |
//+------------------------------------------------------------------+
void PrepareTicketsToClose(int signal, bool Revers, int & ticketsClose[][2], double & lots[],double arrayTickets[][9])
{
int size=ArrayRange(arrayTickets,0);
//----
if (size==0) return;

int i,type,ticket,closeSize;
for (i=0;i<size;i++)
{
type=arrayTickets[1];
// если тип ордера не рыночный, то пропускаем
if (type>OP_SELL) continue;

if (Revers) // перевернем тип рыночного ордера
{
if (type==OP_BUY) type=OP_SELL; else type=OP_BUY;
}

// тут решаем для каждого открытого ордера его судьбу
// оставить в рынке или добавить в массив на закрытие
if (type==OP_BUY)
{
//
// код разрешающий оставить покупку

// как пример
if (signal==OP_BUY) continue;
}

if (type==OP_SELL)
{
//
// код разрешающий оставить продажу

// как пример
if (signal==OP_SELL) continue;
}

closeSize=ArrayRange(ticketsClose,0);
ArrayResize(ticketsClose,closeSize+1);
ArrayResize(lots,closeSize+1);
ticketsClose[closeSize][0] = arrayTickets[0]; // # тикета
ticketsClose[closeSize][1] = arrayTickets[1]; // тип ордера

// здесь укажем сколько лотов нужно закрыть
lots[closeSize] = arrayTickets[2]; // закрываемый объем
// можно закрывать частично, тогда нужно переписать строку сверху
}
//----
return;
}

//+------------------------------------------------------------------+
//| Закрывает ордера с указанными тикетами |
//+------------------------------------------------------------------+
void CloseMarketOrders(int ticketsArray[][2], double lotsArray[])
{
//----
int i,size=ArrayRange(ticketsArray,0);
if (size==0) return;

int ticket,type;
double lots;
bool res;

int total=OrdersTotal();

for (i=0;i<size;i++)
{
ticket = ticketsArray[0];
type = ticketsArray[1];
lots = lotsArray;
RefreshRates(); // на всякий случай обновим сведения о рыночном окружении

// блок закрытия покупок
if (type==OP_BUY)
{
res = OrderClose(ticket,lots,Bid,Slippage,Orange);
if (!res)
{
Print("Не удалось закрыть ордер в покупку #",ticket,"! Ошибка №",GetLastError());
// дальнейшая обработка ошибки, написать самостоятельно
}
}

// блок закрытия продаж
if (type==OP_SELL)
{
res = OrderClose(ticket,lots,Ask,Slippage,Orange);
if (!res)
{
Print("Не удалось закрыть ордер в продажу #",ticket,"! Ошибка №",GetLastError());
// дальнейшая обработка ошибки, написать самостоятельно
}
}

}
//----
return;
}

В функции void PrepareTicketsToClose(int signal, bool Revers, int & ticketsClose[][2], double & lots[],double arrayTickets[][9]) нужно поставить условие после которого решиться оставлять ордер или закрывать его...
Вроде бы ставил доп.условия, но так и ничего не получалось...
Может кто нибуть посмотрит и кажет есть ли в этих функциях ошибка или это я накасячил....
 

Вложения

manechka

Прохожий
Здравствуйте возможно ли написать осциллятор который будет показывать свечной график старшего таймфрейма одного инструмента. Допустим ставлю 15М график евро
открываю осциллятор и в окне дневной график, далее перехожу в обзор рынка перетаскиваю инструмент на график показывает сразу два графика М15 и D1
 
Верх