Вопрос MQL - страница 3

 

Пожалуйста помогите.

Сделаете скрипт  то что в этом странице https://www.mql5.com/ru/articles/1368 для тестирование в не стандарт ТФ

 меня не получается с скриптом


Пишем скрипт для сохранения данных с графика в файл *.csv (файл s_ExportChartToCSV_v1.mq4 приложения):

int start(){
   int h=FileOpen(Symbol()+Period()+".csv",FILE_WRITE|FILE_CSV,",");
      for(int i=Bars-1;i>=0;i--){
         FileWrite(h,TimeToStr(Time[i],TIME_DATE),TimeToStr(Time[i],TIME_MINUTES),Open[i],High[i],Low[i],Close[i],Volume[i]);
      }
   FileClose(i);
   return(0);
}

Исполняем скрипт на графиках нестандартных таймфреймов. В результате работы скрипта в каталоге experts/filies получаем стандартные файлы *.csv с данными нестандартных таймфреймов.

Тестирование экспертов на нестандартных таймфреймах
Тестирование экспертов на нестандартных таймфреймах
  • 2009.05.18
  • Dmitry Fedoseev
  • www.mql5.com
Цена на рынке меняется с достаточно большой частотой, чтобы для технического анализа было удобно пользоваться графиком непосредственного изменения цены, так называемого тикового графика. Для упрощения восприятия изменений цены и обеспечения возможности использования в анализе большие интервалы времени используется отображение графиков в виде...
 
STARIJ:

 Если есть ордер, от закрытия которого прошло 60 минут но менее 10 часов, то выводится лот, время и цена закрытия этого ордера. Этапы проектирования:

Сообщение нужно через время кратное 60 минут. Получается всего 10 раз  вывести сообщение по каждому закрытому ордеру

Вариант 4. Советник каждую минуту проверяет историю и при совпадении условий выводит информацию об ордерах

Как выбрать вариант 4?  Вы наверное ошиблись с файлом. Вот что внутри

//+------------------------------------------------------------------+
//| Советник создает 2 кнопки: Выполнить и Выход       TwoButton.mq4 |
//+------------------------------------------------------------------+
// Версия 0
#property strict

//+------------------------------------------------------------------+
//| Инициализация                                                    |
//+------------------------------------------------------------------+
void OnInit()
{
   //--- Кнопка Выход
   ObjectCreate("Выход",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Выход",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetInteger(0,"Выход",OBJPROP_XDISTANCE,160);
   ObjectSetInteger(0,"Выход",OBJPROP_YDISTANCE,52);
   ObjectSetInteger(0,"Выход",OBJPROP_XSIZE,130);
   ObjectSetInteger(0,"Выход",OBJPROP_YSIZE,25);
   ObjectSetString (0,"Выход",OBJPROP_TEXT,"Выход");
   ObjectSetInteger(0,"Выход",OBJPROP_COLOR,Black);
   ObjectSetInteger(0,"Выход",OBJPROP_BGCOLOR,Orange);
   ObjectSetInteger(0,"Выход",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Выход",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Выход",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Выход",OBJPROP_FONTSIZE,12);

   //--- Кнопка Выполнить
   ObjectCreate("Выполнить",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Выполнить",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetInteger(0,"Выполнить",OBJPROP_XDISTANCE,160);
   ObjectSetInteger(0,"Выполнить",OBJPROP_YDISTANCE,21);
   ObjectSetInteger(0,"Выполнить",OBJPROP_XSIZE,130);
   ObjectSetInteger(0,"Выполнить",OBJPROP_YSIZE,25);
   ObjectSetString (0,"Выполнить",OBJPROP_TEXT,"Выполняю");
   ObjectSetInteger(0,"Выполнить",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Выполнить",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Выполнить",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Выполнить",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Выполнить",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Выполнить",OBJPROP_FONTSIZE,12);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  ObjectDelete("Выполнить");
  ObjectDelete("Выход");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
}


//+------------------------------------------------------------------+
//| Реакция на события                                               |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if(sparam=="Выполнить")
   {
      if(ObjectGetInteger(0,"Выполнить",OBJPROP_STATE))
      {
         ObjectSetInteger(0,"Выполнить",OBJPROP_BGCOLOR,Yellow);
         ObjectSetString (0,"Выполнить",OBJPROP_TEXT,"Отдых");
         ObjectSetInteger(0,"Выполнить",OBJPROP_COLOR,Black);
      }
      else
      {
         ObjectSetInteger(0,"Выполнить",OBJPROP_BGCOLOR,Green);
         ObjectSetString(0,"Выполнить",OBJPROP_TEXT,"Выполняю");
         ObjectSetInteger(0,"Выполнить",OBJPROP_COLOR,White);
      }
   }

   if(sparam=="Выход")
   {
      ObjectSetInteger(0,"Выход",OBJPROP_STATE,false);
      ObjectSetInteger(0,"Выход",OBJPROP_BGCOLOR,Yellow);
      ObjectSetString (0,"Выход",OBJPROP_TEXT,"Исчезаю");
      ObjectSetInteger(0,"Выход",OBJPROP_COLOR,Black);
      Sleep(1000);
      ExpertRemove();
   } 
}
 
PolarSeaman: Как выбрать вариант 4?  Вы наверное ошиблись с файлом. Вот что внутри

Вы пришли за помощью - помогают тем, кто что-то делает. Составил Вам план работы и написал начальный вариант. Пишите дальше

 
Alekseu Fedotov:

Имейте в виду что функция ( OrdersTotal() ) видит все ордера, любые магики, другие символы,отложенные и рыночные

Мне нужно чтобы оно открывало 3 ордера но также была возможность поставить 3 стоп приказа и 3 тейк профита. Вы написали что функция учитывает все ордера. Стоп лосс и тейк профит это тоже отложенные ордера или нет. Я поэксперементировал с функцией OrdersTotal но мне не понятно сколько ордеров оно открывает. Вот моё условие.

if(MA_1>MA_2)
ticket=OrderSend(_Symbol,OP_BUY,Lots,Ask,0,Ask-SL*Point,Bid+TP*Point,NULL,0,0,clrGreen);
if(MA_1<MA_2)
ticket=OrderSend(_Symbol,OP_SELL,Lots,Bid,0,Bid+SL*Point,Ask-TP*Point,NULL,0,0,clrRed);
// я записал так
void OnTick()
  {
//---
   double MA_1;
   MA_1=iMA(_Symbol,0,1,0,1,0,0);
   double MA_2;
   MA_2=iMA(_Symbol,0,6,0,1,0,0);
   int ticket=0;
   if(OrdersTotal()<=3)
     {
      if(MA_1>MA_2)
         ticket=OrderSend(_Symbol,OP_BUY,Lots,Ask,0,Ask-SL*Point,Bid+TP*Point,NULL,0,0,clrGreen);
      if(MA_1<MA_2)
         ticket=OrderSend(_Symbol,OP_SELL,Lots,Bid,0,Bid+SL*Point,Ask-TP*Point,NULL,0,0,clrRed);
     }
//---
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }

Я нашёл такой код 

#property copyright "Влад Сергеев для mmgp" 
#property version   "1.00" 
#property strict 
#property script_show_inputs 

input int      orders = 4;      //всего ордеров в серии 
input bool     buy = true;      //флаг разрешающий/запрещающий покупки 
input bool     sell = false;    //флаг разрешающий/запрещающий продажи 
input int      magic = 100500;  //уникальный номер для ордеров, открываемых этим скриптом 
input double   lot = 0.01;      //объем каждого ордера серии 
input int      tp = 100;        //тейк профит, в пунктах 
input int      sl = 100;        //стоп лосс, в пунктах 
input int      slip = 2;        //допустимое проскальзывание на открытии, в пунктах (для ECN, где открытие по рынку - игнор) 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int i=0;  // для чего эта переменная
   int ticket=0;
   if(buy) 
     {
      while(i<orders) // здесь эта переменная используется чтобы сравнивать ордера или для чего
        {
         RefreshRates(); // если убрать эту функцию коду хуже не становится
         ticket=OrderSend(Symbol(),OP_BUY,lot,NormalizeDouble(Ask,Digits),slip,0,0,"",magic,0,clrBlue); //здесь понятно
         if(ticket!=-1) // эта строчка тоже не понятна
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))  // функция для выбора ордера это логично но тоже не понятно как ей пользоваться
              {
               OrderModify(ticket,OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-sl*Point,Digits),NormalizeDouble(OrderOpenPrice()+tp*Point,Digits),0,clrBlue);
               // эту строчку тоже хотел бы чтобы объяснили
              }
           }
         i++; // что увеличивается на оду единицу это относится к магическому номеру ордера чтобы программа понимала что у неё есть ордера
        }
     }
   i=0;
   if(sell) // прошлая запись была для покупак эта для продаж 
     {
      while(i<orders) 
        {
         RefreshRates();
         ticket=OrderSend(Symbol(),OP_SELL,lot,NormalizeDouble(Bid,Digits),slip,0,0,"",magic,0,clrRed);
         if(ticket!=-1) 
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))  
              {
               OrderModify(ticket,OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+sl*Point,Digits),NormalizeDouble(OrderOpenPrice()-tp*Point,Digits),0,clrRed);
              }
           }
         i++;
        }
     }
  }  
//+------------------------------------------------------------------+

Может его можно использовать только мне не понятны значения строк. Можно использовать этот код если его переделать под моё условие? 

 
STARIJ:

Вы пришли за помощью - помогают тем, кто что-то делает. Составил Вам план работы и написал начальный вариант. Пишите дальше

Понятно, скажите, как отсчитывать время кратное 60 минут. Чтобы сигналить через 60, 120, 180 минут 
 
PolarSeaman:
Понятно, скажите, как отсчитывать время кратное 60 минут. Чтобы сигналить через 60, 120, 180 минут 

Время в MQL - это Unix time stamp, т. е. количество секунд, прошедшее с 01.01.1970. Чтобы отсеять от даты/времени секунды, оставив минуты, нужно разделить на 60 без остатка, а потом умножить на 60. Соответственно, отсеять минуты и секунды можно, разделив на 3 600 (60 секунд в минуте и 60 минут в часе) без остатка, а затем умножить на 3 600:

datetime dtTime = TimeCurrent();

dtTime = (dtTime / 60) * 60; // Оставляем только минуты от текущего времени
dtTime = (dtTime / 3600) * 3600; // Оставляем только часы от текущего времени
 
Ihor Herasko:

Время в MQL - это Unix time stamp, т. е. количество секунд, прошедшее с 01.01.1970. Чтобы отсеять от даты/времени секунды, оставив минуты, нужно разделить на 60 без остатка, а потом умножить на 60. Соответственно, отсеять минуты и секунды можно, разделив на 3 600 (60 секунд в минуте и 60 минут в часе) без остатка, а затем умножить на 3 600:

Благодарю, однако вопрос остался.

Взять к примеру, врем закрытия позиции =T_Close. как от него отсчитывать каждые 60 минут.

Вот такое условие если текущее время равно T_Close+60 минут или T_Close+120 минут или T_Close+180 минут и так далее

Если правильно понял, то нужно так:

datetime dtTime = TimeCurrent();

dtTime = (dtTime / 60) * 60;

if(T_Close+60==dtTime||T_Close+120==dtTime||T_Close+180==dtTime){Alert}

Вот как это условие записать по грамотному? Вдруг нужно будет сигналить каждые 45 минут это всё переписывать.

и так сигналить будет 3 раза а мне нужно 10 вот чтобы десять раз не писать T_Close+60==dtTime|| как нужно сделать?

 
PolarSeaman:

Вдруг нужно будет сигналить каждые 45 минут это всё переписывать.

и так сигналить будет 3 раза а мне нужно 10 вот чтобы десять раз не писать T_Close+60==dtTime|| как нужно сделать?

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

#define SIGNALS_PAUSE    (uint)60 * 60

...

static datetime dtLastSignalTime = <время закрытия ордера>;
datetime dtTime = TimeCurrent();

if (dtTime - dtLastSignalTime > SIGNALS_PAUSE)
{
   dtLastSignalTime = dtTime;
   // Сигнал
}

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

 
Seric29:

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

в моём случае возвращаемым значением будет имя переменной ticket почему именно так функция hfjfu() имеет тип void в справочнике сказано что этот тип может быть без возвращаемого правда я наоборот записал.

Ihor Herasko:

Вернуть имя переменной без особых ухищрений весьма затруднительно. Да и не нужно никому иметь имя переменной в качестве возвращаемого значения. Обычно возвращают значение переменной. В приведенном коде функция hfjfu() ничего не возвращает (у нее тип void). Поэтому указание команды return в конце ее выполнения не имеет никакого смысла. Если убрать эту строку, то ничего не изменится.

Чтобы функция вернула результат, нужно указать ее тип отличным от void:

Игорь, у Вас на глазах был взломан редактор связей                                                                                                                                                                                                            ред (link editor) Метаквотов.                                                                                                                                                                                                                                                                                                                                                                                                                                         

 
Ihor Herasko:

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

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

Очень хорошо, пока всё понятно. Вот незадача, с запоминанием времени как быть, если ордеров закрыл я 3, али 5. Для каждого ордера нужно dtLastSignalTime делать, пронумеровать их, а как сопоставлять потом их с ордерами для какого ордера где время запомнить?
Причина обращения: