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

profit777

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

AlexeyVik

Программист mql4 mql5
может не по теме...я новичок...просто тут настоящие мозголомы!
скажите...как тестировать сову которая работает по индюку? ведь в тестер индюка не воткнуть, или я ошибаюсь?
Ты ошибаешься. Советник обращается к индикатору непосредственно командой кода. А если тестировать с визуализацией, то можно наложить индикатор на график для наглядности.
 

evgen_82

Активный участник
Уважаемые мастера прогеры!
Нашел на одном форуме функцию разрешения торговли по времени.
Однако сыплюстя ошибки. Подскажите в чем дело.
Также интересует, можно из нее сделать перевертышь, то бишь, при указании в extern string OpenTime советник наоборот не будет открывать позиций в указанное время?
HTML:
 extern string OpenTime = "10:00-10:05; 12:20-12:31; 13:40-13:55";

  string OTA[];
  string OTI[];
  split(OTA, OpenTime, ";");
  
  datetime tm0 = CurTime();
  datetime tm1, tm2;
  
  bool cond = false;
  
  int cnt = ArraySize(OTA);
  for (int i=0; i < cnt; i++) {
	split(OTI, OTA[i], "-");
	if (ArraySize(OTI) != 2) continue;
	
	tm1 = StrToTime(TimeToStr(CurTime(), TIME_DATE) + " " + OTI[0]);
	tm2 = StrToTime(TimeToStr(CurTime(), TIME_DATE) + " " + OTI[1]);
	
//	Print (OTI[0], " *** " ,OTI[1]);
	
	cond = cond || (tm1 <= tm0 && tm0 < tm2);
  }
  
		
  if (cond)
  {
	//Открываем позицию либо выполняем иные действия.
  }

void split(string& arr[], string str, string sym) 
{
  ArrayResize(arr, 0);

  string item;
  int pos, size;
  
  int len = StringLen(str);
  for (int i=0; i < len;) {
        pos = StringFind(str, sym, i);
        if (pos == -1) pos = len;
        
        item = StringSubstr(str, i, pos-i);
        item = StringTrimLeft(item);
        item = StringTrimRight(item);
        
        size = ArraySize(arr);
        ArrayResize(arr, size+1);
        arr[size] = item;
        
        i = pos+1;
  }
}
 
Последнее редактирование:

hoz

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

PHP:
//+-------------------------------------------------------------------------------------+
//| Открытие длинной позиции                                                            |
//+-------------------------------------------------------------------------------------+
bool OpenBuy()
{
   int ticket = -1;
   double OOP = High[1] + i_thresholdToUp * pt;
   pr ("ND(OOP) = " + ND(OOP) + " ; Ask = " + Ask);
   pr ("g_stopLevel = " + g_stopLevel);

   if (ND(OOP)> (Ask + g_stopLevel))
       ticket = OrderSend(Symbol(), OP_BUYSTOP, 0.1, ND(OOP), 3 * pt, 0, 0, NULL, i_magic, 0, CLR_NONE);
   else pr ("Ордер послать не удалось " + GetLastError());
   
   if (ticket > 0)
   {
 //      lastBarTime = Time[0];               // На текущем баре все необходимые действия..
                                            // .. успешно выполнены
       return (true);
   }
}


Написано согласно требованиям установки отложенного ордера _http://book.mql4.com/ru/appendix/limits Даже, более того, вставил зазор (Stoplevel), хотя в требованиях для открытия этого нет. Тем не менее, всё-равно выскакивают ошибки.

Как избавиться от этих ошибок?
Ведь даже при модификации ордера (установке стопа и тейка) и то хватает проверки на стоплевел а тут..
Вот вывод на экране функции pr(), которая вместо оператора принт у меня.

0_950d0_8a009cfa_orig.jpg
 
Последнее редактирование модератором:

SlioptiOn

Прохожий
Вопрос к программистам по поводу цвета

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

PHP:
color coli3;
int R1;

--------

coli3=C'255,150,150';

- необходимо вместо чисел '150' подставить значение переменной.

Помогите, кто знает.
 

qqmber

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

PHP:
color coli3;
int R1;

--------

coli3=C'255,150,150';

- необходимо вместо чисел '150' подставить значение переменной.

Помогите, кто знает.

coli3=255<<16 + X<<8 + X;
 

smartmans

Активный участник
Какая функция отвечает за уровень в индикаторе?
7c6bd8c60c889a37d8f290a31119691c.png
(Аналог #property INDICATOR_LEVELVALUE в МТ5)
 

ale002

::: __,,,^._.^,,,__ :::
Свойство:

#property indicator_levelX 100

Хэ - от 1 до 8

Функция:

SetLevelValue(X, 100);

Хэ - от 0 до 31. Почему до 31 - хз
 

ale002

::: __,,,^._.^,,,__ :::
Почему то работает и без строчки #property indicator_level1 100
И это правильно - это 2 разных варианта. Свойство удобно для ручной установки значения, бо к нему есть доступ у пользователя. А функцию лучше юзать когда надо вычислять / менять значение в коде индикатора. При её использовании заданное пользователем вручную значение будет каждый раз затираться при инициализации - даже при переключении ТФ
 

smartmans

Активный участник
Если быть точнее, #property indicator_level1 ..
это первое что поиском нашел. Не работает.
Вообщем спасибо, проблема решена вторым вариантом.
 

Smiles Jack

Почетный гражданин
Уважаемые программисты помогите дописать пару строчек

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

#property copyright "..............."
#property link "..........."

int ТекущийБар = -1;

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 MediumBlue
#property indicator_color2 Red
//--- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];

int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,234);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,233);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,0.0);
//----
return(0);
}


int start()
{
if(ТекущийБар==Bars) return(0);
ТекущийБар=Bars;
if (Open[1] > Open[0])
if (Open[1] < Open[0)
Суть - если условие выполняется, то на графике рисуется стрелка вверх/вниз, в зависимости от того какое условие выполнилось, убил все выходные на поиски, но так и неувидел внятного объяснения, :facepalm:

все примеры основаны на машках и выполняются через функцию iCustom
и пишут что-то вроде такого

double randomValue=iCustom(NULL,0,"RandomIndicator",barsToProcess,0,i);
или
double signalLast=iCustom("EURUSD",PERIOD_D1,"MACD",12,26,9,1,0); но мне туда нечего вставить, я же не беру никакой индикатор за основу????

Должно же быть что-то вроде такого if (Open[1] > Open[0]) то - Print arrow? но как это связать с основными буферами? Вам сейчас смешно, а я всю голову сломал, после выходных могу написать простенького советника, но немогу вывести стрелку на график :facepalm: Прошу не кидать камнями, всю сознательную жизнь я был художником и музыкантом и теперь другое полушарие мозга дает сбой)))

и еще небольшие нюансы - если я буду менять в коде условие if (Open[1] > Open[0]) , на другое, например на if (Close[2] > Close[3]) && (Close[1] > Close[2]) - то оно не доложно влиять ни на что, кроме выводимой на график стрелки. Стрелка должна рисоваться на только что открывшемся баре, если выполнено такое-то условие; не позже на бар, и не раньше, т.е некоторые индикаторы считают еще не закрывшийся бар и потом перерисовывают её на каждом баре в том же направлении, Стрелка не доложна стираться из истории - т.е мы доложны видеть все лоси:angry:

Посмотреть вложение 116753

Посмотреть вложение 116754

это пример выполнения условия

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

qqmber

Почетный гражданин
Надо непустое значение в соответствующий буфер закинуть.
if (Open[1] > Open[0]) ExtMapBuffer1[0]=Open[0];
if (Open[1] < Open[0]) ExtMapBuffer2[0]=Open[0];
 

hoz

Активный участник
Что-то не выходит у меня чётко прописать условия, чтоб на ТФ М5 в момент касания т.е. пересечения значения индикатора RSI открывался ордер. Как это условие задать?
У меня раньше было так:

PHP:
if (iRSI(NULL,5,14,PRICE_CLOSE,1) > i_RSIToUpLimit)
      if (iRSI(NULL,5,14,PRICE_CLOSE,0) < (i_RSIToUpLimit))
         return (SIGNAL_BUY);


Здесь i_RSIToUpLimit уровень индикатора RSI. Как я узнал, что значение индикатора получаются только по цене открытия (хотя в документации этого не встречал ранее).
Получается максимально точно факт пересечения уровня можо получить на ТФ М1 ? Тогда в параметр ТФ вставить 1, а значение периода 14 домножить на 5, верно?
Но вот всё равно иногда открытие ордера не там где нужно происходит в моё случае.
 

qqmber

Почетный гражданин
Как я узнал, что значение индикатора получаются только по цене открытия (хотя в документации этого не встречал ранее).
Ничего подобного, значение индикатора [0] пересчитывается на каждом тике.
 

Smiles Jack

Почетный гражданин
qqmber - Большое вам человеческое спасибо!!!!!!!!!!!!!! Вы мне облегчили понимание основ MQL, будем изучать дальше)))))))))
 

hoz

Активный участник
Понадобилось реализовать функцию, которая изменяет флаг открытия ордера, если есть причины.
У меня int GetGeneralSignal() - функция, которая получает сигнал для открытия позиций.
int FindOrders(bool& long, bool& short) - функция подсчитывает количество открытых позиций и изменяет флаг открытия, если требуется.
Суть такая. Изначально в GetGeneralSignal() флаги short и long имеют положение true. Дальше, если открытых ордеров нет, то флаги должны остаться в положении true. А если имеются открытые ордера, то проверяется профит ордеров. Если профит ордера заданного типа меньше заданного значения в моём случает меньше нуля, то открывать в ордера того типа нельзя и флаг соот-но переводится в режим false для данного типа.
Таким образом, я хочу, чтоб при наличии ордеров с минусовым профитом эксперт не открывал ордера, в тут сторону, где есть ордера с минусовым профитом.

Я сделал так:

PHP:
//+-------------------------------------------------------------------------------------+
//| Поиск своих ордеров                                                                 |
//+-------------------------------------------------------------------------------------+
int FindOrders(bool& long, bool& short)
{
   int t, total = OrdersTotal() - 1;
   
   for (int i=total; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if (OrderSymbol() != Symbol()) continue;
              if (OrderMagicNumber() != i_magic) continue;
              {
                 if (OrderType() == OP_BUY)        // Найден ордер типа OP_BUY
                 {
                     if (OrderProfit() < 0)        // Если профит ордера ниже заданного значения,..
                         long = false;              // .. покупка запрещена
                 }

                 if (OrderType() == OP_SELL)       // Найден ордер типа OP_SELL
                 {
                     if (OrderProfit() < 0)        // Если профит ордера ниже заданного значения,..
                         short = false;             // .. продажа запрещена
                 }
                 t++;
              }
   }
   
   return (t);
}

PHP:
//+-------------------------------------------------------------------------------------+
//| Получаем общий торговый сигнал                                                      |
//+-------------------------------------------------------------------------------------+
int GetGeneralSignal()
{
   bool short = true,
        long = true;
        
   if (FindOrders(short, long) > 3)
       return (SIGNAL_NO);
 
   if (GetRSI(1) < i_RSIToUpLimit)
      if (GetRSI(0) > i_RSIToUpLimit)
      {
         if (long == true)
             return (SIGNAL_BUY);
      }
   if (GetRSI(1) > i_RSIToDnLimit)
      if (GetRSI(0) < i_RSIToDnLimit)
      {
         if (short == true)
             return (SIGNAL_SELL);
      }
            
   return (SIGNAL_NO);
}


Но ордера открываются не всегда. Вот что я при старте эксперта вижу (флаг для покупок почему-то false), хотя ордеров типа OP_BUY нет, а значит режим false не должен быть.

PHP:
2013.05.10 12:11:23	2012.05.21 00:35  Kevin_Martens_RSI EURUSD,M5: short = 1
2013.05.10 12:11:23	2012.05.21 00:35  Kevin_Martens_RSI EURUSD,M5: long = 0
2013.05.10 12:11:15	2012.05.21 00:30  Kevin_Martens_RSI EURUSD,M5: short = 1
2013.05.10 12:11:15	2012.05.21 00:30  Kevin_Martens_RSI EURUSD,M5: long = 0
2013.05.10 12:11:14	2012.05.21 00:25  Kevin_Martens_RSI EURUSD,M5: short = 1
2013.05.10 12:11:14	2012.05.21 00:25  Kevin_Martens_RSI EURUSD,M5: long = 0
2013.05.10 12:11:14	2012.05.21 00:20  Kevin_Martens_RSI EURUSD,M5: short = 1
2013.05.10 12:11:14	2012.05.21 00:20  Kevin_Martens_RSI EURUSD,M5: long = 0


0_99773_c7d4969f_orig.jpg
 
Последнее редактирование модератором:

hoz

Активный участник
Касаясь предыдущего поста, я переписал функцию int FindOrders(bool& long, bool& short):

PHP:
//+-------------------------------------------------------------------------------------+
//| Поиск своих ордеров                                                                 |
//+-------------------------------------------------------------------------------------+
int FindOrders(bool& long, bool& short)
{
   int t, total = OrdersTotal() - 1;
   double profitL,               // Профит лонговой позиции
          profitS;               // Профит шортовой позиции
   
   for (int i=total; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if (OrderSymbol() != Symbol()) continue;
              if (OrderMagicNumber() != i_magic) continue;
              {
                 if (OrderType() == OP_BUY)        // Найден ордер типа OP_BUY
                 {
                     Print("if (OrderType() == OP_BUY)");
                     profitL = OrderProfit();
                     if (profitL < OrderProfit())
                         if (profitL < 0)
                         long = false;
                 }

                 else if (OrderType() == OP_SELL)       // Найден ордер типа OP_SELL
                 {
                     Print("if (OrderType() == OP_SELL)");
                     profitS = OrderProfit();
                     if (profitS < OrderProfit())
                         if (profitS < 0)
                         long = false;
                 }
                 t++;
              }
   }
   
   return (t);
}
 
Последнее редактирование модератором:

hoz

Активный участник
У вас порядок переменных в описании функции не соответствует порядку при вызове.


Поправил. Вот что щяс имеется. Я прописал комменты к коду:

PHP:
//+-------------------------------------------------------------------------------------+
//| Поиск своих ордеров                                                                 |
//+-------------------------------------------------------------------------------------+
int FindOrders(bool& long, bool& short)
{
   int t, total = OrdersTotal() - 1;
   double profitL,               // Профит лонговой позиции
          profitS;               // Профит шортовой позиции
   
   for (int i=total; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if (OrderSymbol() != Symbol()) continue;
              if (OrderMagicNumber() != i_magic) continue;
              {
                 if (OrderType() == OP_BUY)              // Найден ордер типа OP_BUY
                 {
                     if (profitL < OrderProfit())
                     {
                         profitL = OrderProfit();
                         pr("profitL =" + profitL);      // Выводим профим через коммент на график
                         if (profitL < 0)                // Если профит минусовой
                         long = false;                   // .. возводим флаг.. "покупки запрещены"
                     }
                 }

                 else if (OrderType() == OP_SELL)       // Найден ордер типа OP_SELL
                 {
                     if (profitS < OrderProfit())
                     {
                         pr("profitS =" + profitS);     // Выводим профим через коммент на график
                         profitS = OrderProfit();
                         if (profitS < 0)               // Если профит минусовой..
                         short = false;                 // .. возводим флаг.. "продажи запрещены"
                     }
                 }
                 t++;
              }
   }
   
   return (t);
}


PHP:
//+-------------------------------------------------------------------------------------+
//| Получаем общий торговый сигнал                                                      |
//+-------------------------------------------------------------------------------------+
int GetGeneralSignal()
{
   bool short = true,
        long = true;
        
   if (FindOrders(long, short) > 15)
       return (SIGNAL_NO);

   Print("long = ", long);
   Print("short = ", short);
      
   if (GetRSI(1) < i_RSIToUpLimit)
      if (GetRSI(0) > i_RSIToUpLimit)
      {
         if (long == true)
             return (SIGNAL_BUY);
      }
           
   if (GetRSI(1) > i_RSIToDnLimit)
      if (GetRSI(0) < i_RSIToDnLimit)
      {
         if (short == true)
             return (SIGNAL_SELL);
      }
            
   return (SIGNAL_NO);
}


Флаг "железно" в ТРУ постоянно (на скрине ТП баев минусовый, а флаг в ТРУ):

0_99bcb_49c3dac4_orig.jpg
 
Последнее редактирование модератором:
Верх