Скачать MetaTrader 5

Ошибка при использовании класса CiCustom

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Запустили испанскую и португальскую версии сайта. Оцени сам!
Dima328
9
Dima328 2015.04.22 22:31 

Доброго времени суток! Проблема такая: есть советник, который имеет внутри себя переменную типа CiCustom. Инициализируется данный класс нормально, ошибки не выдает. Однако при попытке доступа к данным получается, что считывается пустой буфер. Вот собственно и код:

// Подключаемые модули
   #include <Indicators\Trend.mqh>
   #include <Indicators\Indicator.mqh>
   #include <Indicators\Custom.mqh>
   #include <Charts\Chart.mqh>   
   #include <Trade\Trade.mqh>
// Конец Подключаемые модули

// Блок входных параметров
   input int StopLoss = 30;
   input int TakeProfit = 100;
// Конец блок входных параметров

//Блок глобальных переменных
   const ulong MagicNumber = 171717;
   const ulong Deviation = 10;
// Конец блока глобальных переменных

// Блок классов   
   CTrade TradeMain;
   CiCustom cAngle;
// Конец блока классов

// функция инициализации - запускается раз при старте
int OnInit(){
   EventSetTimer(60); // Устанавливаем таймер
   
   // Инициализация пользовательского класса Angle
   MqlParam cAngleParams[1];
   cAngleParams[0].type = TYPE_STRING;
   cAngleParams[0].string_value = "test1.ex5";
   
   if(!cAngle.Create(Symbol(), Period(), IND_CUSTOM, 1, cAngleParams)){
      printf(__FUNCTION__ + ": error initializing object");
      return(false);
   }
   /*if(!cAngle.NumBuffers(2)){
      printf(__FUNCTION__ + ": error initializing object");
      return(false);
   }*/

   
   return(INIT_SUCCEEDED);
}

// Функция деинициализации - запускается раз при завершении работы
void OnDeinit(const int reason){
   EventKillTimer();  
   
}

// функция запускается при поступлении тика
void OnTick(){

   cAngle.Refresh(OBJ_ALL_PERIODS);
   for (int k = 0; k <= SeriesInfoInteger(Symbol(), Period(), SERIES_BARS_COUNT); k++){
      printf(DoubleToString(NormalizeDouble(cAngle.GetData(0, k), 2), 2));   
   }
   
}

// Функция запускается при наступлении события таймера
void OnTimer(){

}

// Функция запускается при изменении списка ордеров
void OnTrade(){

}

// Функция запускается при действии со счетом
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result){

}

//Функция необходима для оптимизации в тестере стратегий - не используется
double OnTester(){
   double ret=0.0;
   return(ret);
}
//Функция необходима для оптимизации в тестере стратегий - не используется
void OnTesterInit(){

}
//Функция необходима для оптимизации в тестере стратегий - не используется
void OnTesterPass(){

}
//Функция необходима для оптимизации в тестере стратегий - не используется
void OnTesterDeinit(){
}
// Запускается при действиях с графиком
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam){
}
// Функция запускается при изменении стакана цен (без инициализации не работает)
void OnBookEvent(const string &symbol){
}

// Основные функции compass
bool CheckDayCrossTime(void){
   datetime TC;
   TC = TimeCurrent();
   if ((TC < StringToTime("00:05")) || (TC > StringToTime("23:55"))){return(true);}
   else {return(false);}
}

bool IsTrend(void){
   return(false);
}

Специально для тестирования написал индикатор test1. Он ничего не делает, просто возвращает одно значение.

//+------------------------------------------------------------------+
//|                                                        test1.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
   
//---
   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[])
  {
   for (int i = prev_calculated; i < rates_total; i++){
     
         Label1Buffer[i] = 1.073;
      }   

   return(rates_total);
  }
//+------------------------------------------------------------------+

 Заранее спасибо!

Mikhail Filimonov
5931
Mikhail Filimonov 2015.04.22 22:59  
Dima328:

Доброго времени суток! Проблема такая: есть советник, который имеет внутри себя переменную типа CiCustom. Инициализируется данный класс нормально, ошибки не выдает. Однако при попытке доступа к данным получается, что считывается пустой буфер. Вот собственно и код:

Специально для тестирования написал индикатор test1. Он ничего не делает, просто возвращает одно значение.

 Заранее спасибо!

Добрый день!

Используйте iCustom

my_handle = iCustom( _Symbol, TimeFrame, "test1.ex5", Param1, Param2 );
Dima328
9
Dima328 2015.04.26 18:09  

Разобрался самостоятельно. При инициализации индикатора нужно обязательно установить размер буфера! Иначе работать не будет.

// Обязательно установить размер буфера!!!
   cAngle.BufferResize(SeriesInfoInteger(Symbol(), Period(), SERIES_BARS_COUNT));

 А также не забыть вызвать метод .Refresh

cAngle.Refresh(OBJ_ALL_PERIODS);
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий