Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2631

 
Aleksei Stepanenko #:

Интересно, заполнили массив тремя значениями: a[0]=1, a[1]=2, a[2]=3. Затем сделали массив тайм-серией. То есть после этого указания, по старым индексам находятся прежние значения, просто сменилось направление считывания? Почему добавив элемент в конец массива a[3]=4, он так и остаётся последним в обратном направлении считывания? Он же должен быть первым. Или инструкция действует только на элементы созданные до её применения?

результат: 3,2,1,4

ожидалось 4,3,2,1

Да. Это направление подсчета индекса. Массив не меняется. И при записи в конец или начало массива надо учитывать направление расчета индекса/индексации. Мудрёно)
 

Направление подсчёта - это хорошо. Почему добавленный в конец массива элемент не читается первым при чтении в обратном направлении?

void OnStart()
   {
   int a[];
   ArrayResize(a,3);
   a[0]=1;
   a[1]=2;
   a[2]=3; 
   ArraySetAsSeries(a,true);
   ArrayResize(a,4);
   a[3]=4;
   printf((string)a[0]+","+(string)a[1]+","+(string)a[2]+","+(string)a[3]);  
   }
series: 3,2,1,4
 
Либо массив переворачивается физически, либо кроме флага дополнительно хранится последний индекс на момент исполнения команды тайм серии. После этого индекса добавленные элементы уже читаются как обычно. Какая-то странная логика, чтобы добавить новый элемент нулевого бара, нужно отменить тайм серию - вставить - применить снова, чтобы этот элемент стал первым.
 
Aleksei Stepanenko #:
Либо массив переворачивается физически, либо дополнительно хранится последний индекс на момент исполнения команды тайм серии. После этого индекса добавленные элементы уже читаются как обычно. Какая-то странная логика, чтобы добавить новый элемент, нужно крутить туда-сюда, чтобы он стал первым.

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

 
Странная конструкция
 
Aleksei Stepanenko #:
Либо массив переворачивается физически, либо дополнительно хранится последний индекс на момент исполнения команды тайм серии. После этого индекса добавленные элементы уже читаются как обычно. Какая-то странная логика, чтобы добавить новый элемент нулевого бара, нужно крутить массив туда-сюда, чтобы он стал первым.
Так все верно. Перевернули. Третий элемент массива стал равен 1. Добавили 4 элемент. Присвоили значение 4. После 1 идет 4.
 

Приветствую.

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

Правильно ли я понимаю, что вот ниже данный блок отвечает за выбор ордера и, что нужно поменять? 

int FindOrderType()

  {

   int oticket,ticketNumber=0,type=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            oticket=OrderTicket();

            if(oticket>ticketNumber)

              {

               ticketNumber=oticket;

               type=OrderType();

              }

           }

        }

     }

   return(type);

  }
 
Evgen #:

Приветствую.

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

Правильно ли я понимаю, что вот ниже данный блок отвечает за выбор ордера и, что нужно поменять? 

в этой статье много ф-ий и эта есть - читайте и правьте под свои нужды https://www.mql5.com/ru/articles/13835

//+------------------------------------------------------------------+
//|     CountTrades                                                  |
//+------------------------------------------------------------------+
int CountTrades(string symb)
  {
   int count=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|     Lot                                                          |
//+------------------------------------------------------------------+  
double Lot()
  {
   double lot=Lots;

   if(Risk>0)
      lot=AccountInfoDouble(ACCOUNT_BALANCE)*Risk/100000;

   return(NormalizeDouble(lot,2));
  }
Упомянем также функции подсчета последней цены сделки для покупок и продаж (это мы используем позже) и функцию определения направления позиции.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastBuyPrice(string symb)
  {
   double pr=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            pr=PositionGetDouble(POSITION_PRICE_OPEN);
            break;
           }
        }
     }
   return(pr);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastSellPrice(string symb)
  {
   double pr=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==1)
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            pr=PositionGetDouble(POSITION_PRICE_OPEN);
            break;
           }
        }
     }
   return(pr);
  }
//+------------------------------------------------------------------+
//|  PositionType                                                    |
//+------------------------------------------------------------------+
int PositionType(string symb)
  {
   int type=8;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            type=(int)PositionGetInteger(POSITION_TYPE);
            break;
           }
        }
     }
   return(type);
  }
Количественный анализ на MQL5: реализуем перспективный алгоритм
Количественный анализ на MQL5: реализуем перспективный алгоритм
  • www.mql5.com
Разбираем вопрос, что такое количественный анализ, как его применяют крупные игроки, создадим один из алгоритмов количественного анализа на языке MQL5.
 
Roman Shiredchenko #:

в этой статье много ф-ий и эта есть - читайте и правьте под свои нужды https://www.mql5.com/ru/articles/13835

Спасибо, буду пробовать!!!
 

Наверное я тупой...

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

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

Сделал так, что он увеличивает ордер, на следующем сигнале если достиг стопа, но только в одностороннем порядке. Открыл покупки, всё, пока или стоп или тейк не сработает, продажи не набирает и наоборот. Одновременно открывать по сигналам например бай-1лот, селл-2лот, бай-4лот, селл-8 лот не могу сделать хоть убейте.

Покажите в чем ошибка, ткните носом пожалуйста, мозги уже кипят...

int CountTrades()

  {

   int count=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            if(OrderType()<2)

               count++;

           }

        }

     }

   return(count);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void PutOrder(int type,double price)

  {

   int r=0;

   color clr=Green;

   double sl=0,tp=0;


   if(type==1 || type==3 || type==5)

     {

      clr=Red;

      if(StopLoss>0)

         sl=NormalizeDouble(price+StopLoss*_Point,_Digits);

      if(TakeProfit>0)

         tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);

     }


   if(type==0 || type==2 || type==4)

     {

      clr=Blue;

      if(StopLoss>0)

         sl=NormalizeDouble(price-StopLoss*_Point,_Digits);

      if(TakeProfit>0)

         tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);

     }


   r=OrderSend(NULL,type,Lot(),NormalizeDouble(price,_Digits),Slip,sl,tp,"",Magic,0,clr);

   return;

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool TimeSession(int aStartHour,int aStartMinute,int aStopHour,int aStopMinute,datetime aTimeCur)

  {

//--- время начала сессии

   int StartTime=3600*aStartHour+60*aStartMinute;

//--- время окончания сессии

   int StopTime=3600*aStopHour+60*aStopMinute;

//--- текущее время в секундах от начала дня

   aTimeCur=aTimeCur%86400;

   if(StopTime<StartTime)

     {

      //--- переход через полночь

      if(aTimeCur>=StartTime || aTimeCur<StopTime)

        {

         return(true);

        }

     }

   else

     {

      //--- внутри одного дня

      if(aTimeCur>=StartTime && aTimeCur<StopTime)

        {

         return(true);

        }

     }

   return(false);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

int FindOrderType()

  {

   int oticket,ticketNumber=0,type=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            oticket=OrderTicket();

            if(oticket>ticketNumber)

              {

               ticketNumber=oticket;

               type=OrderType();

              }

           }

        }

     }

   return(type);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double FindLastBuyPrice()

  {

   int oticket,ticketNumber=0;

   double oprice=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY && OrderMagicNumber()==Magic)

           {

            oticket=OrderTicket();

            if(oticket>ticketNumber)

              {

               ticketNumber=oticket;

               oprice=OrderOpenPrice();

              }

           }

        }

     }

   return(oprice);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double FindLastSellPrice()

  {

   int oticket,ticketNumber=0;

   double oprice=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL && OrderMagicNumber()==Magic)

           {

            oticket=OrderTicket();

            if(oticket>ticketNumber)

              {

               ticketNumber=oticket;

               oprice=OrderOpenPrice();

              }

           }

        }

     }

   return(oprice);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool CloseAll(int ot=-1)

  {

   int err=0;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            if(OrderType()==0 && (ot==0 || ot==-1))

              {

               RefreshRates();

               if(!OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,_Digits),Slip,White))

                  err++;

              }

            if(OrderType()==1 && (ot==1 || ot==-1))

              {

               RefreshRates();

               if(!OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,_Digits),Slip,White))

                  err++;

              }

           }

        }

     }

   if(err>0)

      return(false);

   return(true);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ModifyOrders()

  {

   double all=0,count=0,sl=0,tp=0;


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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            if(OrderType()==OP_BUY || OrderType()==OP_SELL)

              {

               all+=OrderOpenPrice()*OrderLots();

               count+=OrderLots();

              }

           }

        }

     }

   all=NormalizeDouble(all/count,Digits);


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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol())

           {

            if(OrderType()==OP_BUY)

              {

               tp=NormalizeDouble(all+TakeProfit*Point,Digits);

               sl=NormalizeDouble(all-StopLoss*Point,Digits);

               if(OrderTakeProfit()!=tp || OrderStopLoss()!=sl)

                  bool mod=OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,Yellow);


              }

            else

               if(OrderType()==OP_SELL)

                 {

                  tp=NormalizeDouble(all-TakeProfit*Point,Digits);

                  sl=NormalizeDouble(all+StopLoss*Point,Digits);

                  if(OrderTakeProfit()!=tp || OrderStopLoss()!=sl)

                     bool mod=OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,Yellow);

                 }

           }

        }

     }

  }

//+------------------------------------------------------------------+

//| Профит всех ордеров по типу ордера                               |

//+------------------------------------------------------------------+

double AllProfit()

  {

   double pr=0;


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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            if(OrderType()==0)

              {

               pr+=OrderProfit()+OrderCommission()+OrderSwap();

              }


            if(OrderType()==1)

              {

               pr+=OrderProfit()+OrderCommission()+OrderSwap();

              }

           }

        }

     }

   return(pr);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double Lot()

  {

   double lot=Lots;

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

     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))

        {

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)

           {

            if(OrderProfit()>0)

               break;

            if(OrderProfit()<0)

              {

               lot=OrderLots()*KLot;

               break;

              }

           }

        }

     }

   if(lot>MaxLot)

      lot=Lots;

   return(lot);

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   if(AllProfit()>Profit && Profit>0)

      CloseAll();


   if(!TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))

     {

      if(CountTrades()==0)

         return;


      if(CloseTime)

         if(!CloseAll())

            return;

     }


   double up=iCustom(NULL,0,IndName,3,Shift);

   double dn=iCustom(NULL,0,IndName,4,Shift);


   if(CountTrades()<1 && MaxSpread>MarketInfo(Symbol(),MODE_SPREAD))

     {

      if(up!=EMPTY_VALUE)

         PutOrder(0,Ask);

      if(dn!=EMPTY_VALUE)

         PutOrder(1,Bid);

     }



   if(CountTrades()<Count)

     {

      if(FindOrderType()==0 && (FindLastBuyPrice()-Ask)/Point>=Step)

        {

         PutOrder(0,Ask);

         ModifyOrders();

        }

      if(FindOrderType()==1 && (Bid-FindLastSellPrice())/Point>=Step)

        {

         PutOrder(1,Bid);

         ModifyOrders();

        }

     }


   Comment("\n Profit: ",AllProfit(),

           "\n Trades: ",CountTrades());

  }

//+------------------------------------------------------------------+