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

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

#5726
23 минуты назад, Partorius сказал:

я так понимаю предлагается поставить таймер чтобы он сигналил один раз в таймфрейм, правильно?

нет, я не предлагаю таймер, я проверил работу флага one на похожем коде, Вам нужно просто проверенный код перенести в свой советник:

if (StopBuy < 10000 && Stochastic < 20)
{
	if (one && AlertOn) 
	{
		one = false;
		Alert(_Symbol," сигнал на покупку ");
		if (PushMessagesOn) 
		{ 
			SendNotification(_Symbol + " сигнал на покупку");
			Print ("Алерт на мобильник покупка", Stochastic);
		}
	}
} else one = true;

 

#5727

Здравствуйте! хочу использовать в советнике данное выражение

ArrayCopy(Old_Hay_mass,Old_Hay_mass,1,0,5);

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

#5728
1 час назад, delyaro сказал:

Есть ли в этом примере подвох?

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

#5729
1 час назад, 0ll сказал:

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

Oll благодарю! Может поможете еще в одном вопросе?

Занимаюсь отображением уровней поддержки-сопр. на графике. ObjectCreate тип прямоугольник, OBJPROP_TIME1 - вычисляется, OBJPROP_TIME2 - TimeCurrent. При этом одни уровни тянуться за ценой, другие остаются на каких то определенных (или наоборот неопределенных) точках графика. Перерисовка на каждом баре..

#5730

@delyaro по идее сами по себе они должны стоять на месте (в смысле относительно баров графика) и двигать их надо принудительно (опять-же двигать относительно баров)

Вы тоже уточните - что имеете в виду, желательно скрин и что хотите в итоге получить. А чего уровни прямоугольником? линии -же есть.

#5731

Уровни прямоугольником для охвата зон т.к. у зоны больше возможности для применения (выделенная область идет как критерий для работы торговых функций, ну и визуализация дополнительно). Для визуализации желательно видеть от какого экстремума зона началась(т.е. закрепление за свечой в истории) и двигаться полоса должна вместе с ценой пока условия ее существования действительны. Сейчас действительно прямоугольники двигаются, но не растягиваются а перемещаются с привязкой к последнему бару, но периодически некоторые теряются и остаются позади.(на скрине2 в круге выделено)

 

Спойлер

2.gif

 

 

Спойлер

1.gif

 

Изменено 24 сентября, 2019 пользователем delyaro

#5732
15 часов назад, delyaro сказал:

периодически некоторые теряются и остаются позади

ну раз иногда работает правильно - значит ошибка в учёте объектов или Вы по имени все модифицируете? нужно реализацию смотреть.

#5733
5 часов назад, 0ll сказал:

ну раз иногда работает правильно - значит ошибка в учёте объектов или Вы по имени все модифицируете? нужно реализацию смотреть.

 

Спойлер

1.thumb.gif.8856860e1f9d311c3116e6113e6392d9.gif

 

Спойлер

 

 

Спойлер

 

 if (Hay_mass[n]>0)s="high "+IntegerToString(n);else break;
         ObjectCreate(s, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
         ObjectSet(s, OBJPROP_TIME1, iTime(NULL, teamefreme, Old_Count_Hay_mass[n]));
         ObjectSet(s, OBJPROP_TIME2, TimeCurrent());
         ObjectSet(s, OBJPROP_PRICE1, Old_Hay_mass[n]);
         ObjectSet(s, OBJPROP_PRICE2, Old_Hay_mass_down[n]);
         ObjectSet(s, OBJPROP_BACK, zone_solid);
         ObjectSet(s, OBJPROP_WIDTH, zone_linewidth);
         ObjectSet(s, OBJPROP_STYLE, zone_style);
         ObjectSet(s, OBJPROP_COLOR, clrMediumSlateBlue);Введите текст или фрагмент кода...

 

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

Изменено 25 сентября, 2019 пользователем delyaro

#5734

@delyaro аккуратно делаете, - люблю так работать. Алгоритм такой:

1. Найдена новая зона. Рисуете объект с именем "Zona_", далее что хотите (советую дата/время - имя должно быть уникально!)

2. Здесь можете удалить старую зону (которую цена только-что прошла), если расстояние менее 20 ст.п.(например)

3. На каждом новом баре запускается цикл по всем объектам графика с фильтром по имени "Zona_" (см. справку ObjectsTotal)

3.1. Модифицируем последнюю координату каждого объекта: ObjectSet(s, OBJPROP_TIME2, TimeCurrent());

4. Здесь можно оценить количество объектов и если много, то удалить самый старый или самый дальний

#5735

С третьего пункта мой алгоритм пошел в другом направлении... Вернее даже на третьем. Хотя и первый кривой в принципе))

Теперь процесс пойдет веселее)

Изменено 25 сентября, 2019 пользователем delyaro

#5736

Здравствуйте, подскажите пожалуйста функцию открытия ордеров от Horizontal Line? То есть , что бы автоматически открывались ордера от выставленной мною Horizontal Line на графике!

#5737

@molot_1 такой функции в MQL нет, но есть несколько советников, которые позволяют настроить торговлю от линий, в том числе на нашем форуме.

#5738

Всем привет. Увлекся массивами, построил вот такую вот функцию:

Профит еще не закрытых ордеров на покупку

Спойлер

void OrderProfitBuy(double &cBuyProfitOpen[])
  {
//use counter and size of the array or CArrayInt* and do not resize every time
   int counter=0,size=OrdersTotal();
   ArrayResize(cBuyProfitOpen,size);
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderType()==OP_BUY)
           {
            cBuyProfitOpen[counter++]=OrderProfit();
           }
        }
     }
   ArrayResize(cBuyProfitOpen,counter);
   return;
  }

 

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

Вывод ячейки массива с помощью перебора

Спойлер

OrderProfitBuy(cBuyProfitOpen);
   for(int n=0; n<OrdersTotal(); n++)
     {
      if(OrderSelect(n,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY && OrderMagicNumber()== Magic_buy)
           {
            cBuyProfitOpen[n];
           }
        }
     }
   if(!cBuyProfitOpen[5] && (cBuyProfitOpen[5]>=0 || cBuyProfitOpen[5]<=0))
     {
      Comment("\n","Профит еще не закрытого ордера на покупку: ",cBuyProfitOpen[5]);
     }

... и тут тестер останавливается и я не пойму в чем причина. 

Если кто знает прошу помощи. Долго занимаюсь этим вопросом, но результат только в том что пока загнал в массив числа. Где-то надо что-то исправить)

 

Изменено 26 сентября, 2019 пользователем diodio

#5739
1 час назад, diodio сказал:

Если кто знает прошу помощи.

У Вас есть размер массива, прежде чем обратиться к элементу нужно удостовериться что №элемента < размера массива.

Условия выбора ордеров в цикле должны быть одинаковые, а у Вас магик появляется. И зачем перебор ордеров в основной функции?

что Вы хотели сделать с этим - cBuyProfitOpen[n];? напишите просто:

for(int n=0; n < ArraySize( cBuyProfitOpen ) ; n++ )    Print( "Профит №", n, "=", DoubleToStr(cBuyProfitOpen[n],2) );

 

#5740

@diodio :-o

  1. Когда тестер останавливается от должен писать причину остановки, смотри логи. В твоем случае, я предполагаю, это буде неправильное обращение к массиву, к не существующему элементу.
  2. по первому коду я понял, что хотим хранить профит каждого ордера отдельно. Итак:
  • для чего тут int counter=0 и  в конце ArrayResize(cBuyProfitOpen,counter);
  • не правильно так работать с массивами cBuyProfitOpen[counter++]=OrderProfit();

Я не знаю ваших намерений поэтому ваш код, только правильно написаный:

Спойлер

void OrderProfitBuy(double &cBuyProfitOpen[])
  {
//use counter and size of the array or CArrayInt* and do not resize every time
   int counter=0,size=OrdersTotal();
   ArrayResize(cBuyProfitOpen,size);
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderType()==OP_BUY)
           {
            cBuyProfitOpen[i]=OrderProfit();			//Вот тут исправление !!!!!!!!!!!!!!!
            counter++;
           }
        }
     }
   ArrayResize(cBuyProfitOpen,counter);			// но в вашем случае этот кусок портит все сделанное вверху, зачем это?
   return;
  }

 

 

  1. по в второму коду
  •  что вы хотели сделать вот этим "cBuyProfitOpen[n];"

Массив это как банк с депозитными ячейками или вокзал с камерой хранения. Сейф или камера хранения это массив, а вот что мы пишем в скобках [№] это как раз ячейка. С этими ячейками взаимодействие такие, либо положить, либо взять. Пример: с записью в ячейку cBuyProfitOpen[n]=3 или возьмем с ячейки int q=cBuyProfitOpen[n]. В вашем случае пришли глазками хлопать, от этого ни чего не изменится.

  • что вы хотели сделать вот этим "!cBuyProfitOpen[5]" в принципе тут все выражение под вопросом.
  • откуда взялась цифра "5" в "!cBuyProfitOpen[5]" и cBuyProfitOpen[5], что она обозначает?

Изменено 26 сентября, 2019 пользователем MikR0ReR

#5741
В 26.09.2019 в 21:37, diodio сказал:

 if(!cBuyProfitOpen[5] && (cBuyProfitOpen[5]>=0 || cBuyProfitOpen[5]<=0))

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

Изменено 28 сентября, 2019 пользователем delyaro

#5742

Здравствуйте!

Есть в советнике функция:

Спойлер

//+-------------------------------------------------------------------------------------------------------------------------------------------------+
//| Функция закрывает последнюю позицию buy                                                                                                         |
//+-------------------------------------------------------------------------------------------------------------------------------------------------+
void CloseBuyLast(void)
  {
   while(true)
      if(OrderClose(gv.grid.last.ticket,gv.grid.last.volume,Bid,0))
        {
         if(OrderSelect(gv.grid.last.ticket,SELECT_BY_TICKET))
            gv.grid.profit+=OrderProfit()+OrderSwap();

         break;
        }
      else
        {
         Sleep(1000);
         RefreshRates();
        }

   gv.grid.number--;
   gv.grid.volume      -= gv.grid.last.volume;
   gv.grid.nextOpVolume = gv.grid.last.volume;
   gv.grid.nextOpPrice  = gv.grid.last.openPrice;

   for(int i=MAX-1; i>=0; i--)
      if(gv.grid.pos.isOpened)
        {
         gv.grid.pos.isOpened   = false;
         gv.grid.pos.allowClose = false;
         gv.grid.pos.ticket     = 0;
         gv.grid.pos.type       = -1;
         gv.grid.pos.volume     = 0;
         gv.grid.pos.openPrice  = 0;
         gv.grid.pos.takeProfit = 0;
         break;
        }

   for(int i=0; i<MAX; i++)
      if(gv.grid.pos.isOpened)
        {
         gv.grid.last.isOpened   = gv.grid.pos.isOpened;
         gv.grid.last.allowClose = gv.grid.pos.allowClose;
         gv.grid.last.ticket     = gv.grid.pos.ticket;
         gv.grid.last.type       = gv.grid.pos.type;
         gv.grid.last.volume     = gv.grid.pos.volume;
         gv.grid.last.openPrice  = gv.grid.pos.openPrice;
         gv.grid.last.takeProfit = gv.grid.pos.takeProfit;
        }

   CheckPanel();
  }

 

 

 

Можно ли видя эту функцию написать аналогичную функцию, которая закрывала бы ПЕРВЫЙ ордер.

Если возможно, то прошу помочь.

Спасибо, заранее!!! 

 

Изменено 29 сентября, 2019 пользователем 0ll

#5743
39 минут назад, Владимир Стариков сказал:

Можно ли видя эту функцию написать аналогичную функцию, которая закрывала бы ПЕРВЫЙ ордер.

Функция основана на классах, нужно видеть его устройство. В советнике сделан учёт ордеров сетки и после закрытия идёт обновление учёта. Задачка не для слабонервных даже при наличии полного кода.

#5744
50 минут назад, 0ll сказал:

Функция основана на классах, нужно видеть его устройство. В советнике сделан учёт ордеров сетки и после закрытия идёт обновление учёта. Задачка не для слабонервных даже при наличии полного кода.

В любом случае, спасибо!!!

Хотя бы утвердился в мысли. что классы - это не просто так....

#5745

Всем привет!  MikR0ReR спасибо, вставил ваше исправление в код, это действительно правильный цикл перебора:

void OrderProfitBuy(double &cBuyProfitOpen[])
  {
   int counter=0,size=OrdersTotal();
   ArrayResize(cBuyProfitOpen,size);
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderType()==OP_BUY)
           {
            cBuyProfitOpen[i]=OrderProfit();
            counter++;
           }
        }
     }
   ArrayResize(cBuyProfitOpen,counter); // здесь мы уже получаем итоговый размер массива, т.к. в счетчик  counter++ стикается эта цифра
   return;
  }

Далее, как заметил 0ll вставляем нужный нам перебор с проверкой по размеру массива, как тоже подсказал delyaro

   OrderProfitBuy(cBuyProfitOpen);
   for(int n=0; n < ArraySize(cBuyProfitOpen); n++)
     {
     if(ArraySize(cBuyProfitOpen)>5)
     Print("Профит ячейки №3= ", DoubleToStr(cBuyProfitOpen[3],2));
     break;
     }

И вот что интересно получилось, тестер берет данные с ордеров которые в рынке на данный момент, по картинке можно понять что пересчет и выдача результата происходит после каждого завершенного бара, я это показал на картинке внизу. Все работает так как надо, спасибо) Ну и тут возникает вопрос, а куда делись те предыдущие параметры этого массива? Возможно они сохранились если верить учебникам и возможно они занимают какую-то память. Можно их как-то подчищать?

 

1.jpg

Изменено 29 сентября, 2019 пользователем diodio

#5746

 

@diodio я думаю при наличии "других" ордеров этот код будет глючить (здесь я не согласен с MikR0ReR):

cBuyProfitOpen[i]=OrderProfit();
counter++;

думаю надо вместо i использовать counter, ибо i может быть значительно больше counter (числа "наших" ордеров).

59 минут назад, diodio сказал:

Ну и тут возникает вопрос, а куда делись те предыдущие параметры этого массива?

Не понял про параметры, может значения? значения перезаписываются, как в обычной переменной.

Изменено 29 сентября, 2019 пользователем 0ll

#5747
Доброго времени суток, господа программисты. Подскажите, пожалуйста. Пытаюсь написать стрелочный индикатор на основе фигур разворота и прочих. Вроде все хорошо. Но, считает он только первых 2 свечи, вместо 4. При компиляции редактор ругается о возможной потере точности при присвоении различных типов данных. Причем, только на iVolume. Заранее спасибо.
Спойлер

//+------------------------------------------------------------------+
//|                                                       Figaro.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2     
#property indicator_color1 Blue   
#property indicator_color2 Red    
double Buy[];                   
double Sell[];                  
#define BUY 0
#define SELL 1
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{

SetIndexBuffer (0, Buy);
SetIndexBuffer (1, Sell);  

SetIndexEmptyValue (0, 0);
SetIndexEmptyValue (1, 0);

SetIndexStyle (0, DRAW_ARROW);
SetIndexStyle (1, DRAW_ARROW); 
SetIndexArrow(0, 233);  // Стрелка "вверх" для покупок
SetIndexArrow(1, 234);  // Стрелка "вниз" для продаж

IndicatorDigits (Digits);

IndicatorShortName ("FIGARO");

SetIndexLabel(0, "Покупаем");
SetIndexLabel(1, "Продаём");

return(INIT_SUCCEEDED);

}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{

int counted_bars = IndicatorCounted();
int limit, signal;

if (counted_bars>0) 
counted_bars-- ;

limit=Bars-counted_bars;

for(int i = 2; i < limit; i++) 
{
signal = Signal(i-1);
if (signal == BUY)
{ 
Buy[i-1] = low[i-1];
}
else
if (signal == SELL)
{
Sell[i-1] = high[i-1];
}
}
return(rates_total); } 
//+------------------------------------------------------------------+
int Signal(int i)
{
     double O_1 = iOpen(Symbol(), 0, 1);
     double O_2 = iOpen(Symbol(), 0, 2);
     double O_3 = iOpen(Symbol(), 0, 3);
     double O_4 = iOpen(Symbol(), 0, 4);
     double C_1 = iClose(Symbol(), 0, 1);
     double C_2 = iClose(Symbol(), 0, 2);
     double C_3 = iClose(Symbol(), 0, 3);
     double C_4 = iClose(Symbol(), 0, 4);
     double H_1 = iHigh(Symbol(), 0, 1);
     double H_2 = iHigh(Symbol(), 0, 2);
     double L_1 = iLow(Symbol(), 0, 1);
     double L_2 = iLow(Symbol(), 0, 2);
     double S_1 = iVolume(NULL, 0, 1);
     double S_2 = iVolume(NULL, 0, 2);
     double S_3 = iVolume(NULL, 0, 3);
if ((O_1<C_1 && S_1>=8 && S_2==0 && O_3>C_3 && O_4>C_4 && (H_2-O_2)>=6 && (C_2-L_2)>=6) || (O_1<C_1 && S_1>=10 && O_2>C_2 && S_2>=8 && O_3>C_3 &&
O_4>C_4 && S_3>=8 && O_1<=C_2 && O_1<C_3 && O_2<C_1 && O_3<C_1) || (O_1<C_1 && O_2>C_2 && O_3>C_3 && O_4>C_4 && S_1<=1 && (O_1-L_1)>=5 && (H_1-C_1)<=2) || (O_1<C_1 && S_1>=10 &&
O_2>C_2 && O_3>C_3 && S_2>=10 && S_1>=S_2*0.6 && O_1<C_2 && (H_1-C_1)<=2 && (O_1-L_1)<=2 && (H_2-O_2)<=2 && (C_2-L_2)<=2) || (O_1<C_1 && S_1>=10 && O_2>C_2 &&
S_2>=8 && C_1<=C_2 && (H_1-C_1)<=2 && (O_1-L_1)<=2 && (H_2-O_2)<=2 && (C_2-L_2)<=2))
     
     return (BUY);
     
if ((O_1>C_1 && S_1>=8 && S_2==0 && O_3<C_3 && O_4<C_4 && (H_2-O_2)>=6 && (C_2-L_2)>=6) || (O_1>C_1 && S_1>=10 && O_2<C_2 && O_3<C_3 && O_4<C_4 &&
S_2>=8 && S_3>=8 && O_1>=C_2 && O_1>C_3 && O_2>C_1 && O_3>C_1) || (O_1>C_1 && O_2<C_2 && O_3<C_3 && O_4<C_4 && S_1<=1 && (C_1-L_1)>=5 && (H_1-O_1)<=2) || (O_1>C_1 && S_1>=10 && 
O_2<C_2 && O_3<C_3 && O_4<C_4 && S_2>=10 && S_1>=S_2*0.6 && O_1>C_2 && (H_1-O_1)<=2 && (C_1-L_1)<=2 && (H_2-C_2)<=2 && (O_2-L_2)<=2) || (O_1>C_1 && S_1>=10 && O_2<C_2 &&
O_3<C_3 && O_4<C_4 && S_2>=8 && C_1>=C_2 && (H_1-O_1)<=2 && (C_1-L_1)<=2 && (H_2-C_2)<=2 && (O_2-L_2)<=2))

     return (SELL);
     
     return(-1);
     
}

 

 

 

Изменено 1 октября, 2019 пользователем 0ll

#5748

@VAS35 а в чем проблема поменять тип данных с double на long

double S_1 = iVolume(NULL, 0, 1);
на
long S_1 = iVolume(NULL, 0, 1);

@VAS35 считает он только первых 2 свечи, вместо 4

не нашел ни каких проблем с этим считает все бары

Но заметил функцию с передачей параметра signal = Signal(i-1);

int Signal(int i)

{

хотя здесь этот параметр не используется.

}

По конкретней опишите проблему. Может чего то я не понял.

#5749

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

#5750

@VAS35 почему решили что проблема на 3 свече. У вас Выдает ошибку?? так дайте скрин! Я например проверил ошибок нет. И я так понимаю вы дали не весь код, урезанный?? мне нужно конкретика.

Изменено 30 сентября, 2019 пользователем MikR0ReR

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

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