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

 
Andrey.Sabitov:

Добрый день, уважаемые эксперты.

Подскажите, пожалуйста, где в коде ошибка, которая не позволяет открыться позиции BUY на одном баре с SELL, который закрыл предыдущую позицию?

Правила простые (чтобы научиться):
1 Вход- пересечение медленным индикатором 0 + быстрый также в зоне (покупка/продажа)

2 Выход - пересечение быстрым индикатором 0

я тут пытаюсь разобраться с вашем кодом - пока только запустил его, ведь не весь код, Вы выложили

Снимок 

Ваш код - и мои до -думки .

Реверс добавил и Индикатор в положенное место переставил 
//+------------------------------------------------------------------+
//|                                                      TestDPO.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\Trade.mqh>
CTrade trade;
//---
input int    dpo_fast_period = 9;     // DPO Fast Period
input int    dpo_slow_period = 40;    // DPO Fast Period
input int    Inpmagic        = 1000;  // Magic советника
input ulong  slippage        = 10;    // Проскальзывание цены
input double Inpvolume       = 0.01;  // размер позиции
input bool   Revers          = false; // Revers
//---
double fDPOVal[];    // Динамический массив для хранения значений fast DPO
double sDPOVal[];    // Динамический массив для хранения значений slow DPO
int    DPO_fast = 0; // Хэндл для быстрого DPO
int    DPO_slow = 0; // Хэндл для медленного DPO
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- prepare trade class to control positions if hedging mode is active
   trade.SetExpertMagicNumber(Inpmagic);
   trade.SetMarginMode();
   trade.SetTypeFillingBySymbol(Symbol());
//--- DPO indicator
   DPO_fast=iCustom(NULL,0,"Examples\\DPO",dpo_fast_period);
   if(DPO_fast==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//--- DPO indicator
   DPO_slow=iCustom(NULL,0,"Examples\\DPO",dpo_slow_period);
   if(DPO_slow==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
//---------------Задаем цены покупки и продажи------------------------
   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

   int signal=0;  // сигнал на покупку, продажу

//--------------Проверка на новый бар
   if(!isNewBar())
      return;
//--------------------------------------------------------------------
   ArraySetAsSeries(fDPOVal,true);              // задаем направление индексов массива
   ArraySetAsSeries(sDPOVal,true);
   if(CopyBuffer(DPO_fast,0,0,10,fDPOVal)<0)    // наполняем массив значений DPO fast
     {
      Alert("Ошибка копирования буфера индикатора fast DPO. Ошибка ", GetLastError());
     }
   if(CopyBuffer(DPO_slow,0,0,10,sDPOVal)<0)    // наполняем массив значений DPO slow
     {
      Alert("Ошибка копирования буфера индикатора slow DPO. Ошибка ", GetLastError());
     }

   double DPO_fast_c_value=NormalizeDouble(fDPOVal[1],6);  // запоминаем значение индикатора DPO fast на предыдущем баре
   double DPO_slow_c_value=NormalizeDouble(sDPOVal[1],6);  // запоминаем значение индикатора DPO slow на предыдущем баре
   double DPO_fast_p_value=NormalizeDouble(fDPOVal[2],6);  // запоминаем значение индикатора DPO fast на пред-предыдущем баре
   double DPO_slow_p_value=NormalizeDouble(sDPOVal[2],6);  // запоминаем значение индикатора DPO slow на пред-предыдущем баре

   if(DPO_slow_c_value>0 && DPO_slow_p_value<0 && DPO_fast_c_value>0)  // если медленный индикатор пересекает 0 снизу вверх и быстрый находится выше 0
      signal=1;                                                        // сигнал на открытие покупки
   if(DPO_slow_c_value<0 && DPO_slow_p_value>0 && DPO_fast_c_value<0)  // если медленный индикатор пересекает 0 сверху вниз и быстрый находится ниже 0
      signal=-1;                                                       // сигнал на открытие продажи
   if(DPO_fast_c_value>0 && DPO_fast_p_value<0)                        // если быстрый индикатор пересекает 0 снизу вверх
      signal=-2;                                                       // сигнал на закрытие продажи
   if(DPO_fast_c_value<0 && DPO_fast_p_value>0)                        // если быстрый индикатор пересекает 0 сверху вниз
      signal=2;                                                        // сигнал на закрытие покупки
   if(!Revers)
     {
      switch(signal)
        {
         case -1:
            trade.Buy(Inpvolume,NULL,Ask,0,0,NULL);
            break;
         case 1:
            trade.Sell(Inpvolume,NULL,Bid,0,0,NULL);
            break;
         case -2:
            trade.PositionClose(_Symbol,slippage);
            break;
         case 2:
            trade.PositionClose(_Symbol,slippage);
            break;
        }
     }
   if(Revers)
     {
      switch(signal)
        {
         case -1:
            trade.Sell(Inpvolume,NULL,Bid,0,0,NULL);
            break;
         case 1:
            trade.Buy(Inpvolume,NULL,Ask,0,0,NULL);
            break;
         case -2:
            trade.PositionClose(_Symbol,slippage);
            break;
         case 2:
            trade.PositionClose(_Symbol,slippage);
            break;
        }
     }
  }
//+------------------------------------------------------------------+
//| Возвращает true, если появился новый бар для пары символ/период  |
//+------------------------------------------------------------------+
bool isNewBar()
  {
//--- в статической переменной будем помнить время открытия последнего бара
   static datetime last_time=0;
//--- текущее время
   datetime lastbar_time=(int)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);

//--- если это первый вызов функции
   if(last_time==0)
     {
      //--- установим время и выйдем
      last_time=lastbar_time;
      return(false);
     }

//--- если время отличается
   if(last_time!=lastbar_time)
     {
      //--- запомним время и вернем true
      last_time=lastbar_time;
      return(true);
     }
//--- дошли до этого места - значит бар не новый, вернем false
   return(false);
  }
//+------------------------------------------------------------------+
 

Спасибо откликнувшимся.

Но остается проблема того, что при закрытии ордера и наличии сигнала на этом же баре позиция не открывается.

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


 
Andrey.Sabitov:

Спасибо откликнувшимся.

Но остается проблема того, что при закрытии ордера и наличии сигнала на этом же баре позиция не открывается.

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


На вскидку: Вы проверяете новый бар:

//--------------Проверка на новый бар
   if(!isNewBar())
      return;

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

 

может что то так ? 

//+------------------------------------------------------------------+
//|                                                      TestDPO.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\Trade.mqh>
CTrade trade;
//---
input int    dpo_fast_period = 9;     // DPO Fast Period
input int    dpo_slow_period = 40;    // DPO Fast Period
input int    Inpmagic        = 1000;  // Magic советника
input ulong  slippage        = 10;    // Проскальзывание цены
input double Inpvolume       = 0.01;  // размер позиции
input bool   Revers          = false; // Revers
//---
double fDPOVal[];    // Динамический массив для хранения значений fast DPO
double sDPOVal[];    // Динамический массив для хранения значений slow DPO
int    DPO_fast = 0; // Хэндл для быстрого DPO
int    DPO_slow = 0; // Хэндл для медленного DPO
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- prepare trade class to control positions if hedging mode is active
   trade.SetExpertMagicNumber(Inpmagic);
   trade.SetMarginMode();
   trade.SetTypeFillingBySymbol(Symbol());
//--- DPO indicator
   DPO_fast=iCustom(NULL,0,"Examples\\DPO",dpo_fast_period);
   if(DPO_fast==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//--- DPO indicator
   DPO_slow=iCustom(NULL,0,"Examples\\DPO",dpo_slow_period);
   if(DPO_slow==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
//---------------Задаем цены покупки и продажи------------------------
   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

   int signal=0;  // сигнал на покупку, продажу

//*******************************************************************
// эта часть программы выполняется каждый тик
//-if(!isNewBar(PERIOD_M1))
   Print("Новый бар M1 ",  TimeCurrent());
//-if(!isNewBar(PERIOD_M5))
   Print("Новый бар M5 ",  TimeCurrent());
//-if(!isNewBar(PERIOD_CURRENT))
   Print("Новый бар M15",  TimeCurrent());
//*******************************************************************
//--------------Проверка на новый бар
   if(!isNewBar(PERIOD_CURRENT))
      return;
//--------------------------------------------------------------------
   ArraySetAsSeries(fDPOVal,true);              // задаем направление индексов массива
   ArraySetAsSeries(sDPOVal,true);
   if(CopyBuffer(DPO_fast,0,0,10,fDPOVal)<0)    // наполняем массив значений DPO fast
     {
      Alert("Ошибка копирования буфера индикатора fast DPO. Ошибка ", GetLastError());
     }
   if(CopyBuffer(DPO_slow,0,0,10,sDPOVal)<0)    // наполняем массив значений DPO slow
     {
      Alert("Ошибка копирования буфера индикатора slow DPO. Ошибка ", GetLastError());
     }

   double DPO_fast_c_value=NormalizeDouble(fDPOVal[1],6);  // запоминаем значение индикатора DPO fast на предыдущем баре
   double DPO_slow_c_value=NormalizeDouble(sDPOVal[1],6);  // запоминаем значение индикатора DPO slow на предыдущем баре
   double DPO_fast_p_value=NormalizeDouble(fDPOVal[2],6);  // запоминаем значение индикатора DPO fast на пред-предыдущем баре
   double DPO_slow_p_value=NormalizeDouble(sDPOVal[2],6);  // запоминаем значение индикатора DPO slow на пред-предыдущем баре

   if(DPO_slow_c_value>0 && DPO_slow_p_value<0 && DPO_fast_c_value>0)  // если медленный индикатор пересекает 0 снизу вверх и быстрый находится выше 0
      signal=1;                                                        // сигнал на открытие покупки
   if(DPO_slow_c_value<0 && DPO_slow_p_value>0 && DPO_fast_c_value<0)  // если медленный индикатор пересекает 0 сверху вниз и быстрый находится ниже 0
      signal=-1;                                                       // сигнал на открытие продажи
   if(DPO_fast_c_value>0 && DPO_fast_p_value<0)                        // если быстрый индикатор пересекает 0 снизу вверх
      signal=-2;                                                       // сигнал на закрытие продажи
   if(DPO_fast_c_value<0 && DPO_fast_p_value>0)                        // если быстрый индикатор пересекает 0 сверху вниз
      signal=2;                                                        // сигнал на закрытие покупки
   if(!Revers)
     {
      switch(signal)
        {
         case -1:
            trade.Buy(Inpvolume,NULL,Ask,0,0,NULL);
            break;
         case 1:
            trade.Sell(Inpvolume,NULL,Bid,0,0,NULL);
            break;
         case -2:
            trade.PositionClose(_Symbol,slippage);
            break;
         case 2:
            trade.PositionClose(_Symbol,slippage);
            break;
        }
     }
   if(Revers)
     {
      switch(signal)
        {
         case -1:
            trade.Sell(Inpvolume,NULL,Bid,0,0,NULL);
            break;
         case 1:
            trade.Buy(Inpvolume,NULL,Ask,0,0,NULL);
            break;
         case -2:
            trade.PositionClose(_Symbol,slippage);
            break;
         case 2:
            trade.PositionClose(_Symbol,slippage);
            break;
        }
     }
  }
/*
//+------------------------------------------------------------------+
//| Возвращает true, если появился новый бар для пары символ/период  |
//+------------------------------------------------------------------+
bool isNewBar()
  {
//--- в статической переменной будем помнить время открытия последнего бара
   static datetime last_time=0;
//--- текущее время
   datetime lastbar_time=(int)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);

//--- если это первый вызов функции
   if(last_time==0)
     {
      //--- установим время и выйдем
      last_time=lastbar_time;
      return(false);
     }

//--- если время отличается
   if(last_time!=lastbar_time)
     {
      //--- запомним время и вернем true
      last_time=lastbar_time;
      return(true);
     }
//--- дошли до этого места - значит бар не новый, вернем false
   return(false);
  }
*/
//+------------------------------------------------------------------+
//| возвращает true если появился новый бар, иначе false             |
//+------------------------------------------------------------------+
bool isNewBar(ENUM_TIMEFRAMES timeFrame)
  {
//----
   static datetime old_Times[21];// массив для хранения старых значений
   bool res=false;               // переменная результата анализа
   int  i=0;                     // номер ячейки массива old_Times[]
   datetime new_Time[1];         // время нового бара

   switch(timeFrame)
     {
      case PERIOD_M1:
         i= 0;
         break;
      case PERIOD_M2:
         i= 1;
         break;
      case PERIOD_M3:
         i= 2;
         break;
      case PERIOD_M4:
         i= 3;
         break;
      case PERIOD_M5:
         i= 4;
         break;
      case PERIOD_M6:
         i= 5;
         break;
      case PERIOD_M10:
         i= 6;
         break;
      case PERIOD_M12:
         i= 7;
         break;
      case PERIOD_M15:
         i= 8;
         break;
      case PERIOD_M20:
         i= 9;
         break;
      case PERIOD_M30:
         i=10;
         break;
      case PERIOD_H1:
         i=11;
         break;
      case PERIOD_H2:
         i=12;
         break;
      case PERIOD_H3:
         i=13;
         break;
      case PERIOD_H4:
         i=14;
         break;
      case PERIOD_H6:
         i=15;
         break;
      case PERIOD_H8:
         i=16;
         break;
      case PERIOD_H12:
         i=17;
         break;
      case PERIOD_D1:
         i=18;
         break;
      case PERIOD_W1:
         i=19;
         break;
      case PERIOD_MN1:
         i=20;
         break;
     }
// скопируем время последнего бара в ячейку new_Time[0]
   int copied=CopyTime(_Symbol,timeFrame,0,1,new_Time);

   if(copied>0) // все ок. данные скопированы
     {
      if(old_Times[i]!=new_Time[0])       // если старое время бара не равно новому
        {
         if(old_Times[i]!=0)
            res=true;    // если это не первый запуск, то истина = новый бар
         old_Times[i]=new_Time[0];        // запоминаем время бара
        }
     }
//----
   return(res);
  }
//+------------------------------------------------------------------+
 
Alexsandr San:

может что то так ? 

если здесь сменить цифры

   double DPO_fast_c_value=NormalizeDouble(fDPOVal[1],6);  // запоминаем значение индикатора DPO fast на предыдущем баре
   double DPO_slow_c_value=NormalizeDouble(sDPOVal[0],6);  // запоминаем значение индикатора DPO slow на предыдущем баре
   double DPO_fast_p_value=NormalizeDouble(fDPOVal[0],6);  // запоминаем значение индикатора DPO fast на пред-предыдущем баре
   double DPO_slow_p_value=NormalizeDouble(sDPOVal[1],6);  // запоминаем значение индикатора DPO slow на пред-предыдущем баре

чище работает 

Снимок
 

 

Коллеги приветствую!

Подскажите следующее. В функции ОнТестер рассчитываются два параметра. Существует ли возможность при оптимизации по одному параметру, второй параметр просто выводить в таблицу оптимизации??? И как это сделать если да?. Спасибо!

 
Всем привет!! Подкажите, возможно ли в мт5 загрузить историю котировок? 2й день ищу инфу, но не могу разобраться
 
Igorz2006:
Всем привет!! Подкажите, возможно ли в мт5 загрузить историю котировок? 2й день ищу инфу, но не могу разобраться

Функции:

CopyRates

Получает в массив исторические данные структуры Rates для указанных символа и периода

CopyTime

Получает в массив исторические данные по времени открытия баров по соответствующим символу и периоду

CopyOpen

Получает в массив исторические данные по цене открытия баров по соответствующим символу и периоду

CopyHigh

Получает в массив исторические данные по максимальной цене баров по соответствующим символу и периоду

CopyLow

Получает в массив исторические данные по минимальной цене баров по соответствующим символу и периоду

CopyClose

Получает в массив исторические данные по цене закрытия баров по соответствующим символу и периоду

CopyTickVolume

Получает в массив исторические данные по тиковым объемам для соответствующих символа и периода

CopyRealVolume

Получает в массив исторические данные по торговым объемам для соответствующих символа и периода

CopySpread

Получает в массив исторические данные по спредам для соответствующих символа и периода

CopyTicks

Получает в массив тики в формате MqlTick

CopyTicksRange

Получает в массив тики в указанном диапазоне дат

Документация по MQL5: Доступ к таймсериям и индикаторам / CopyRates
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyRates
  • www.mql5.com
Получает в массив rates_array исторические данные структуры MqlRates указанного символа-периода в указанном количестве. Отсчет элементов от стартовой позиции ведется от настоящего к прошлому, то есть стартовая позиция, равная 0, означает текущий бар. При копировании заранее неизвестного количества данных рекомендуется в качестве приемного...
 
Igorz2006:
Всем привет!! Подкажите, возможно ли в мт5 загрузить историю котировок? 2й день ищу инфу, но не могу разобраться

штуки на подобии HistoryCenter (как в четвёрке) нет. просто жмите PgUp. так же проверьте в настройках, сколько баров для графика разрешено.

 
Спасибо, буду пробовать. Историю котировок по биткоину и крипте нужно импортировать для анализа