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

 
Mikhail Tkachev #:

Спасибо, Валерий)
Кастомный я и сам сделаю, мне нужно вывести в файл стандартный отчет тестера, если это возможно (как раз, чтобы не делать кастомный файл самому)

Когда то тоже искал, не нашел, видимо этот момент пропущен разрабами или спрятан так, что не найти.

 
Valeriy Yastremskiy #:

Когда то тоже искал, не нашел, видимо этот момент пропущен разрабами или спрятан так, что не найти.

Видимо так)

 
Здравствуйте. Скажите пожалуйста, как прочитать ячейку Excel, которая обновляется по DDE?  Прочитать просто ячейку из сохраненного файла получается, если читать ячейку с данными  DDE возвращается 0. Как я понял из поиска, перед чтением надо  инициализировать DDE, но те примеры которые я видел не работают либо я не правильно их адаптировал. Хотел читать данные из QUIK а через лист Excel по DDE. Можно ли через COM читать уже открытый лист? Читал с помощью библиотеки  Koldun Zloy  https://www.mql5.com/ru/code/28283
//+-----------------------------------------------------------------------------------------------+
//|                                                                                     Excel.mq4 |
//|                                                                                   Zloy Koldun |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Zloy Koldun"
#property version   "1.00"
#property strict

#define xlDouble -4119
#define xlThick 4
#define xlMedium -4138
#define xlContinuous 1

#define xlEdgeLeft 7
#define xlEdgeTop 8
#define xlEdgeBottom 9
#define xlEdgeRight 10

#define xlCenter -4108
#define xlLeft -4131
 string C;
#include <ComObject.mqh>
static ComObject* Excel = NULL; 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
#ifdef _WIN64
   if( !_IsX64 ){
      Alert( "The program only works in a 64-bit terminal!" );
      return;
   }
#else
   if( _IsX64 ){
      Alert( "The program only works in a 32-bit terminal!" );
      return;
   }
#endif

   HRESULT result = CoInitialize( 0 );
   if( result == S_OK ){
      Excel = new ComObject( "Excel.Application" );
      if( Excel.isValid() ){
         Excel.Function( "DDEInitiate", Variant( "MT4" ), Variant( "Z:\book.xls" ) ); // Так пытался инициализировать DDE
         string fileName = "Z:\book.xls";
         Read_Cell( fileName );
      }
      else {
         Print( "Excel не обнаружен" );
      }
      delete Excel;
      CoUninitialize();
   }
}
//+------------------------------------------------------------------+
void Read_Cell (string fileName)
{
ComObject Workbooks = Excel.GetProperty( "Workbooks" );  
   if( Workbooks.isValid() )
   {
   ComObject Workbook = Workbooks.Function( "Open", Variant( fileName )     ); 
      if( Workbook.isValid() )
      {
      ComObject Worksheet = Excel.GetProperty("ActiveSheet");
                  ComObject FRange = Worksheet.GetProperty( "Range", Variant( "D15" ) );
                  ComObject Value = FRange.GetProperty( "Value");
                  Alert ("Cell ", DoubleToString(Value.toDouble(),0) );
         
      }
            Workbook.Function( "Save"  );
            Workbook.Function( "Close" );
   }  
         
}

Вот что получаю от Excel. MT4 пока стоит, потому что могу от него получить данные в воскресенье.


Библиотека для работы с COM-объектами.
Библиотека для работы с COM-объектами.
  • www.mql5.com
Эта библиотека даёт возможность работать с COM-объектами, предоставленными некоторыми приложениями. Например: Excel, Word, Mathcad, Matlab. А также объект ADODB для работы с базами данных через драйвер ODBC. Библиотека работает и в MT4 и в MT5.
 
Прошу помощи сообщества ...
MQL4
Неправильно считается среднее значение в индикаторе.
Проверил в отладчике, функция ArrayCopy() заполняет массив назначения arr[]  EMPTY_VALUE (2147483647), только элемент arr[0] имеет правильное значение.
Во избежание вопросов, для чего так считать среднее - это для отладки, потом по скопированному массиву будет сортировка, поэтому нужен отдельный массив.
//+------------------------------------------------------------------+
//|                                                   Indicator1.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window 

#include <MovingAverages.mqh>

#property indicator_buffers 2
#property indicator_color1 clrAqua
#property indicator_color2 clrYellow

//--- indicator parameters
input int   InpPeriod=100; // Average Period
//--- buffers
double ExtCalcVlBuffer[];  // Буфер значений, по которому будет считаться среднее
double ExtMovingBuffer[];  // Буфер для значений среднего
//
double arr[];  // Временный массив для расчета

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- 1 buffer used for counting.
   IndicatorBuffers(2);
   IndicatorDigits(Digits);
//--- Average line
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexBuffer(0,ExtMovingBuffer);
   SetIndexLabel(0,"Av");
//--- ValuesLine
   SetIndexBuffer(1,ExtCalcVlBuffer); 
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexLabel(1,"Price");
//   
   SetIndexDrawBegin(0,InpPeriod);
   SetIndexDrawBegin(1,InpPeriod);

//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Average
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,       // количество баров, доступных индикатору для расчета = количеству баров, доступных на графике.
                const int prev_calculated,   // =возвращенному значению[return(rates_total)] в предыдущем вызове индикатора
                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 i,pos;
//---
   if(rates_total<=InpPeriod || InpPeriod<=0)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtCalcVlBuffer,false);  //
   ArraySetAsSeries(ExtMovingBuffer,false);
   ArraySetAsSeries(close,false);
   
//--- initial zero
   if(prev_calculated<1)   // prev_calculated==0 при первом вызове индикатора или (сам терминал устанавливает в ней 0) при изменении глубины истории или при заполнении пропусков в истории
     {
      for(i=0; i<InpPeriod; i++)
        {
         ExtCalcVlBuffer[i]=EMPTY_VALUE;
         ExtMovingBuffer[i]=EMPTY_VALUE;
        }
     }
//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=1;
//--- main cycle
    for(i=pos; i<rates_total-1 && !IsStopped(); i++)     // rates_total-1 -> Не будет пересчитываться на текущем баре
     {
         ExtCalcVlBuffer[i]=close[i];
         ArrayCopy(arr,ExtCalcVlBuffer,0,i,InpPeriod); 
         ExtMovingBuffer[i]= Average(arr);
         //ExtMovingBuffer[i]=SimpleMA(i, InpPeriod, ExtCalcVlBuffer);  // Для сравнения
     }
//---- OnCalculate done. Return new prev_calculated.
   return(rates_total); // Возвращаеи количество баров, доступных индикатору для расчета
  }

double Average(double &arr1[]) // среднее арифметическое по всей выборке
  {
   int size=ArraySize(arr1);
   double Sum=0.0;
   for(int i=0; i<size; i++)
       Sum+=arr1[i];
   return(Sum/size);
  }
 
Mikhail Tkachev #:
Прошу помощи сообщества ...
MQL4
Неправильно считается среднее значение в индикаторе.
Судя по всему, после ArrayCopy() массив назначения arr[] заполняется EMPTY_VALUE (2147483647), только элемент arr[0] имеет правильное значение.
Во избежание вопросов, для чего так считать среднее - это для отладки, потом по скопированному массиву будет сортировка, поэтому нужен отдельный массив.
ArrayCopy(arr,ExtCalcVlBuffer,0,i+1,InpPeriod); 
 
Tretyakov Rostyslav #:

Спасибо, Ростислав, но у Вас на графике индикатора только гистограмма цен. А среднего нет.
Цены и у меня выводятся нормально)

 
Mikhail Tkachev #:

Спасибо, Ростислав, но у Вас на графике индикатора только гистограмма цен. А среднего нет.
Цены и у меня выводятся нормально)

Так?

Файлы:
 
Tretyakov Rostyslav #:

Так?

На вид, так.
А почему Вы изменили строку цикла ?
Я её скопировал со штатного индикатора Bands, он работает нормально...

 
Mikhail Tkachev #:

На вид, так.
А почему Вы изменили строку цикла ?
Я её скопировал со штатного индикатора Bands, он работает нормально...

Привычка)
 
Tretyakov Rostyslav #:
Привычка)

Сделал вывод в Excel по Вашему варианту, всё сошлось)
А с первоначальным циклом никак не вывернуть ?