Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 649

 
Artyom Trishkin:

Я видел у вас кусочек кода поиска вершин зигзага - он по-моему от Игоря Ким. Вот в код поиска экстремума и вставьте дополнительно сохранение времени найденного экстремума. Вы же его ищете в цикле... Вот при нахождении и запоминайте время, на которое указывает индекс цикла когда экстремум уже найден - перед возвратом значения его цены. Т.е., дополнительно в функцию передавайте по ссылке переменную datetime, в которую записывайте время при нахождении экстремума зигзага. Когда функция вам вернёт значение цены, она дополнительно впишет в эту переменную и значение времени открытия бара, на котором находится искомый экстремум зигзага.

Прошу прощения, но я далеко от рабочего компьютера, и не могу привести пример кода.

Всё получилось, Спасибо!
 
Здравствуйте! Я немного пишу на MQL4, однако в MQL5 полный ноль. Возникла необходимость написать небольшого помощника который бы высчитывал разницу между хай и лоу за день. В 4-й версии для этого есть хорошие функции iHigh и iLow, здесь же обнаружил что они отсутствуют. Пробовал использовать copyHigh и copyLow, однако при вычитании минимального значения с максимального выдает целую кучу ошибок. Подскажите плз, как мне решить данную задачу, желательно с куском кода. Заранее спасибо! 
 
Александр Богданов:
Здравствуйте! Я немного пишу на MQL4, однако в MQL5 полный ноль. Возникла необходимость написать небольшого помощника который бы высчитывал разницу между хай и лоу за день. В 4-й версии для этого есть хорошие функции iHigh и iLow, здесь же обнаружил что они отсутствуют. Пробовал использовать copyHigh и copyLow, однако при вычитании минимального значения с максимального выдает целую кучу ошибок. Подскажите плз, как мне решить данную задачу, желательно с куском кода. Заранее спасибо! 
Лучше покажите свой кусок кода где куча ошибок и получите кучу комментариев где что сделано не так как надо.
 
Александр Богданов:
Здравствуйте! Я немного пишу на MQL4, однако в MQL5 полный ноль. Возникла необходимость написать небольшого помощника который бы высчитывал разницу между хай и лоу за день. В 4-й версии для этого есть хорошие функции iHigh и iLow, здесь же обнаружил что они отсутствуют. Пробовал использовать copyHigh и copyLow, однако при вычитании минимального значения с максимального выдает целую кучу ошибок. Подскажите плз, как мне решить данную задачу, желательно с куском кода. Заранее спасибо! 
Вставьте это в начале кода

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Тестируем 'CopyTicks'

fxsaber, 2016.10.19 07:59

// Позволяет, как в MT4, работать с таймсериями: Open[Pos], High[Pos], Low[Pos], Close[Pos], Time[Pos], Volume[Pos].
// А так же задает привычные MT4-функции: iOpen, iHigh, iLow, iClose, iTime, iVolume.
#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
Это позволит в MT5 использовать привычные Вам iHigh и iLow.
 
fxsaber:
fxsaber:
Вставьте это в начале кода
Это позволит в MT5 использовать привычные Вам iHigh и iLow.
Спасибо огромное! Это весьма упростит задачу
 
Александр Богданов:
Здравствуйте! Я немного пишу на MQL4, однако в MQL5 полный ноль. Возникла необходимость написать небольшого помощника который бы высчитывал разницу между хай и лоу за день. В 4-й версии для этого есть хорошие функции iHigh и iLow, здесь же обнаружил что они отсутствуют. Пробовал использовать copyHigh и copyLow, однако при вычитании минимального значения с максимального выдает целую кучу ошибок. Подскажите плз, как мне решить данную задачу, желательно с куском кода. Заранее спасибо! 

Если задача - только отображать на экран - то лучшее решение это индикатор. В индикаторе, в OnCalculate() есть все необходимые таймсерии: 

//+------------------------------------------------------------------+
//| 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[])
  {

По умолчанию, в индикаторе MQL5 самый правый бар имеет индекс rates_total-1. И Ваша задача сводится к элементарному вычитанию:

   double difference=high[rates_total-1]-low[rates_total-1];


Правда такой простой подход будет правильно отображать, только если индикатор запустить на таймфрейме D1. Если же запускать на других таймферймах, то нужно использовать CopyHigh и CopyLow - в принципе ничего сложного.

Сейчас напишу пример....

//+------------------------------------------------------------------+
//|                                               High minus Low.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//--- input parameter
input ENUM_TIMEFRAMES period=PERIOD_D1;   // для какого периода считать High-Low
//---
double multiplier=0.0;
double High[],Low[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   multiplier=MathPow(10,Digits());
//---
   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[])
  {
//--- разницу цен переводим в пункты
   double difference=(iHigh(Symbol(),period,0)-iLow(Symbol(),period,0))*multiplier;
//--- вывод результата на экран
   Comment("High-Low=",DoubleToString(difference,0));
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Получим Low для заданного номера бара                            |
//+------------------------------------------------------------------+
double iLow(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double low=0;
   ArraySetAsSeries(Low,true);
   int copied=CopyLow(symbol,timeframe,0,Bars(symbol,timeframe),Low);
   if(copied>0 && index<copied) low=Low[index];
   return(low);
  }
//+------------------------------------------------------------------+
//| Получим High для заданного номера бара                           |
//+------------------------------------------------------------------+
double iHigh(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double high=0;
   ArraySetAsSeries(High,true);
   int copied=CopyHigh(symbol,timeframe,0,Bars(symbol,timeframe),High);
   if(copied>0 && index<copied) high=High[index];
   return(high);
  }
//+------------------------------------------------------------------+


Теперь индикатор можно запускать на любом таймфрейме текущего символа и выбирать для какого таймфрейма рассчитывать разницу между High и Low.
Файлы:
 
Александр Богданов:
Здравствуйте! Я немного пишу на MQL4, однако в MQL5 полный ноль. Возникла необходимость написать небольшого помощника который бы высчитывал разницу между хай и лоу за день. В 4-й версии для этого есть хорошие функции iHigh и iLow, здесь же обнаружил что они отсутствуют. Пробовал использовать copyHigh и copyLow, однако при вычитании минимального значения с максимального выдает целую кучу ошибок. Подскажите плз, как мне решить данную задачу, желательно с куском кода. Заранее спасибо! 
Если Вам нужны именно дневные Хай и Лоу (хай и лоу текущего дня), то это совсем просто делается с помощью SymbolInfoDouble() c идентификаторами SYMBOL_BIDHIGH и SYMBOL_BIDLOW (или иными, на Ваш вкус).
 
Здравствуйте! 2016.10.21_19:58 МСК. Проверяю советник в тестере стратегий. Советник работает, открывает и закрывает сделку. Но тестер стратегий выдаёт ошибку: incorrect start position 0 for ArrayMinimum function; -1; array out of range in 'CLose.mqh' (86,59); Testing pass stopped due to a critical error in the EA. Есть скриншот как ошибается советник и код включаемого файла CLose.mqh . Я не вижу в этом коде выхода за пределы массива. Поэтому не пойму в чём ошибка. Если можете, -- подскажите. Пока всё. 20:08 МСК. Critical error
//+------------------------------------------------------------------+
//|                                                        CLose.mqh |
//|                                              Nickityuk N., 2016. |
//|                             https://www.mql5.com/users/nicityuk/ |
//+------------------------------------------------------------------+
#property copyright "Nickityuk N., 2016."
#property link      "https://www.mql5.com/users/nicityuk/"
#property strict
#include <Expert\OPen.mqh>
//#include <ARrayMinimum.mqh>
double AOmax,AOmax2,AOmin,AOmin2,AOm0,AOn0,z5max0,z5min0,clm,cln,AO[];
int aom,aom2,aon,aon2;
datetime ttm,ttn,hm,hn;
//+------------------------------------------------------------------+
//| Calculate for close order                                        |
//+------------------------------------------------------------------+
void CLose()
  {if(buy==0 && sell==0) {return;}
   else if(OrderType()==OP_BUY) {CloseBuy();}
        else                     CloseSell();}
//+------------------------------------------------------------------+
void St()
  {St0=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_MAIN,0);
   Si0=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_SIGNAL,0);
   St1=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_MAIN,1);
   Si1=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_SIGNAL,1);}
void CloseBuy()
  {St(); if(St0-20>0 && Si0-20>0)
           {if(St1-Si1>0 && St0-Si0<0) {AOm0=iAO(NULL,0,0);
               if(AOm0-AOm1>=0) {AOm1=iAO(NULL,0,0); return;}
               else if(St0-80>0 && St0-100<=0 && Si0-80>0)
                      {if(Si0-100<=0 && St1-Si1>0 && St0-Si0<0)
                         {TwoExtremeAO_Buy(); OneExtremeBuy(); ExpirationBuy();}
                       else return;}            
                    else return;}
            else return;}        
         else return;}
void CloseSell()
  {St(); if(St0-80<0 && Si0-80<0)
           {if(St1-Si1<0 && St0-Si0>0) {AOn0=iAO(NULL,0,0);
               if(AOn0-AOn1<=0) {AOn1=iAO(NULL,0,0); return;}
               else if(St0-20<0 && St0>=0 && Si0-20<0)
                      {if(Si0>=0 && St1-Si1<0 && St0-Si0>0)
                         {TwoExtremeAO_Sell(); OneExtremeSell(); ExpirationSell();}
                       else return;}  
                    else return;}
            else return;}        
         else return;}
//+------------------------------------------------------------------+                      
void CalculateClose()
  {v0=iVolume(NULL,PERIOD_M1,0); //--- go trading only for first tiks of new bar
   v1=iVolume(NULL,PERIOD_M1,1);
   v2=iVolume(NULL,PERIOD_M1,2);
   v3=iVolume(NULL,PERIOD_M1,3);
   v4=iVolume(NULL,PERIOD_M1,4);
   if(v0+v1+v2+v3+v4-10/12>0) return;  
   for(index=0;index<24;index++)
     {AO[index]=iAO(NULL,PERIOD_M5,index);}
   ArrayResize(AO,24,4);
   ArraySetAsSeries(AO,true);}
   //index=0; AO[index]=iAO(NULL,PERIOD_M5,index);}
//+------------------------------------------------------------------+      
void TwoExtremeAO_Buy()
  {CalculateClose();
   if(ArrayMaximum(AO,23,0)==0) return;
   else aom=ArrayMaximum(AO,23,0); AOmax=AO[aom];
   if(ArrayMinimum(AO,aom,0)>0) {aon=ArrayMinimum(AO,aom,0);}
   else return;
   if(ArrayMaximum(AO,aon,0)==0) return;
   else aom2=ArrayMaximum(AO,aon,0); AOmax2=AO[aom2];
     if(AOmax2-AOmax>0) {return;}
     else if(AOmax2-AOmax<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                {Print("OrderClose error.",GetLastError());}
                              else //index=2;
                                   //while(iFractals(NULL,0,MODE_UPPER,index)==0) {index++;}
                                   //Sleep(3000); luf=iFractals(NULL,0,MODE_UPPER,index);
                                   //SL=NormalizeDouble(luf+(Ask-Bid)+(1*_Point),_Digits);
                                   TP=NormalizeDouble(Ask-tp*_Point,_Digits);
                                   tic=OrderSend(Symbol(),OP_SELL,LotsCalculated(),Bid,50,0,TP,"",MAGIC,0,Red);
                                   AOn1=iAO(NULL,0,index); return;}
          else return;}
//+------------------------------------------------------------------+          
void TwoExtremeAO_Sell()
  {CalculateClose();
   if(ArrayMinimum(AO,23,0)==0) return;
   else aon=ArrayMinimum(AO,23,0); Print(aon,""); AOmin=AO[aon];
   if(ArrayMaximum(AO,aon,0)>0) {aom=ArrayMaximum(AO,aon,0);}
   else return;
   if(ArrayMinimum(AO,aom,0)==0) return;
   else aon2=ArrayMinimum(AO,aom,0); AOmin2=AO[aon2]; //Print(aon2,"");
     if(AOmin2-AOmin>0) {return;}
     else if(AOmin2-AOmin<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                {Print("OrderClose error.",GetLastError());}
                              else //index=2;
                                   //while(iFractals(NULL,0,MODE_LOWER,index)==0) {index++;}
                                   //Sleep(3000); ldf=iFractals(NULL,0,MODE_LOWER,index);
                                   //SL=NormalizeDouble(ldf-(1*_Point),_Digits);
                                   TP=NormalizeDouble(Bid+tp*_Point,_Digits);
                                   tic=OrderSend(Symbol(),OP_BUY,LotsCalculated(),Ask,50,0,TP,"",MAGIC,0,Blue);
                                   AOm1=iAO(NULL,0,0); return;}
          else return;}
//+------------------------------------------------------------------+                      
void OneExtremeBuy()
  {index=0;
   while(iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,1,index)==0) {index++;}
   z5max0=iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,1,index); ttm=iTime(NULL,0,index); clm=iClose(NULL,PERIOD_M5,0); //Sleep(3000);
   if((clm-(z5max0-300*Point))<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                       {Print("OrderClose error.",GetLastError());}
                                   else return;}
   else return;}
void OneExtremeSell()
  {index=0;
   while(iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,2,index)==0) {index++;}
   z5min0=iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,2,index); ttn=iTime(NULL,0,index); cln=iClose(NULL,PERIOD_M5,0); //Sleep(3000);
   if((cln-(z5min0+300*Point))>0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                       {Print("OrderClose error.",GetLastError());}
                                   else return;}
   else return;}
//+------------------------------------------------------------------+                                                                      
void ExpirationBuy()
  {hm=TimeHour(ttm); if((hm+3)-TimeCurrent()<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                                   {Print("OrderClose error.",GetLastError());}
                                                 else return;}
                     else return;}
void ExpirationSell()
  {hn=TimeHour(ttn); if((hn+3)-TimeCurrent()<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                                   {Print("OrderClose error.",GetLastError());}
                                                 else return;}
                     else return;}
//+------------------------------------------------------------------+          
 
Николай Никитюк:
Здравствуйте! 2016.10.21_19:58 МСК. Проверяю советник в тестере стратегий. Советник работает, открывает и закрывает сделку. Но тестер стратегий выдаёт ошибку: incorrect start position 0 for ArrayMinimum function; -1; array out of range in 'CLose.mqh' (86,59); Testing pass stopped due to a critical error in the EA. Есть скриншот как ошибается советник и код включаемого файла CLose.mqh . Я не вижу в этом коде выхода за пределы массива. Поэтому не пойму в чём ошибка. Если можете, -- подскажите. Пока всё. 20:08 МСК.

А может быть это в int (с помощью aon=NormalizeDouble(aon,0)) переделать, а то вроде как double и не совсем понятно - что там получилось в итоге?//как версия

:

if(ArrayMinimum(AO,aom,0)>0) {aon=ArrayMinimum(AO,aom,0);}
 
Karputov Vladimir:

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

input bool Long=true;            // allow only "Long"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
...
void OnTick()
  {
   if(!Long)
      trade.Sell(0.01);
   if(Long)
      trade.Buy(0.01);
  }
 а для ручной торговли что можете предложить?
Причина обращения: