Осциллятор Equity средствами MQL5 - страница 4

 
joo:

Объявите на глобальном уровне в эксперте два массива Equity[] и Time[]

Заносите значение эквити и время в соответствующем массиве при тестировании эксперта.

Скриптом прочитать файл по завершении тестирования и построить объектами эквити на на нужном чарте.

Для Ваших целей именно такой способ более всего и подходит, не понимаю - зачем Вам нужен индикатор.

 

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

( Измененяющиеся значения в OnCalculated уже есть, так что же еще надо? ) 

Насчет глобальных переменных уже думал, но  по определению:

datetime  GlobalVariableSet(
   string  name,      // имя
   double  value      // устанавлимое значение
   );

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

А что касается объектов, то я хочу соединить две вещи:

1. Линии сделок обозначать в зависимости от результата (красным - все убыточные, синим - все прибыльные)

2. А внизу в Индикаторе строить график доходности от начального депо.

Иначе при использовании объектов при небольшом масштабе мешают видеть ценовую динамику даже кружочки сделок (от которых, кстати, хотел бы избавиться, но опять же не знаю как).

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

 

sergey1294:
Даже не знаю как вам объяснить. AccountInfoDouble(ACCOUNT_EQUITY) хранит последнее значение эквити. После тестирования как сказал Ренат индикатор инициилизируется заново и пересчитывается. По этому данные эквити накопленные в буфере индикатора за время прогона стираются.

 

А вот это - про стирание - уже "горячее"!

Но что мешает записывать эти значения в OnCalculated в другой посторонний и "нестираемый" массив Индикатора, чтобы потом восстановить без более громоздкой и ресурсоемкой процедуры записи и чтения файлов?

Или тут - уже вопрос системного уровня (по принудальному авто-освобождению массивов, обойти которое уже нельзя)?

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

 
DV2010:

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

( Измененяющиеся значения в OnCalculated уже есть, так что же еще надо? ) 

Насчет глобальных переменных уже думал, но  по определению:

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

А что касается объектов, то я хочу соединить две вещи:

1. Линии сделок обозначать в зависимости от результата (красным - все убыточные, синим - все прибыльные)

2. А внизу в Индикаторе строить график доходности от начального депо.

Иначе при использовании объектов при небольшом масштабе мешают видеть ценовую динамику даже кружочки сделок (от которых, кстати, хотел бы избавиться, но опять же не знаю как).

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

Я имел ввиду глобальные переменные программы, а не терминала.

Построить объекты можно хоть на минутном графике, что бы добиться  максимальной точности (частоты). Потом уже, читая объекты с графика можно строить индикатором лини (если уж наличествует невероятной силы желание рисовать именно индикатором), в настройках индикатора можно даже ввести поправочный коэффициент, что бы можно было посмотреть эквити от любого начального депо.

Опять же, все линии и диаграммы можно построить и скриптом.

 
joo:

Я имел ввиду глобальные переменные программы, а не терминала.

Построить объекты можно хоть на минутном графике, что бы добиться  максимальной точности (частоты). Потом уже, читая объекты с графика можно строить индикатором лини, в настройках индикатора можно даже ввести поправочный коэффициент, что бы можно было посмотреть эквити от любого начального депо.  

Насчет глобальных переменных программы - как я понимаю, могут существовать глобальные переменные в коде Индикатора и в коде эксперта.

Одной из таких переменных и является массив значений Индикатора, из которого после тестирования они, как выясняется,  по каким-то причинам (видимо, системного плана) стираются.

Но тогда я правильно понимаю, что брать значения для отображения истории Equty будь то история из глобальных переменных, объектов или из файла, нужно именно в OnCalculated Индикатора? 

 
DV2010:

Но тогда я правильно понимаю, что брать значения для отображения истории Equty будь то история из глобальных переменных, объектов или из файла, нужно именно в OnCalculated Индикатора? 

Именно так.
 
joo:
Именно так.

 

А разве глобальные переменные программы использовать в данном случае удастся?

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

И еще, если можно, вопрос по объектам текущего графика. Попытался сейчас найти, как извлечь список объектов ему принадлежащих, но найти пока сложно. Не подскажите как это сделать программно?

Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Основы языка / Переменные / Глобальные переменные - Документация по MQL5
 
DV2010:

 

И еще, если можно, вопрос по объектам текущего графика. Попытался сейчас найти, как извлечь список объектов ему принадлежащих, но найти пока сложно. Не подскажите как это сделать программно?

Используйте функцию ObjectsTotal, чтобы получить количество объектов на графике

int  ObjectsTotal(
   long  chart_id,     // идентификатор графика
   int   nwin=-1,      // индекс окна
   int   type=-1       // тип объекта     
   );
Идентификатор графика получите с помощью ChartID
 

Грубо, примерно так:

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2010, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
input int TradeHistoy=10000;

//Глобальные пременные
double   Equity[];
datetime EquityTime[];
int      cnt;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   ArrayResize(Equity,TradeHistoy);ArrayInitialize(Equity,0.0);
   ArrayResize(EquityTime,TradeHistoy);ArrayInitialize(Equity,1);
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

//Записать накопленные данные в файл
   D_ArrayToCsv("DATA",Equity,TradeHistoy,";");
   D_ArrayToCsv("TIME",Equity,TradeHistoy,";");

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

//В нужном месте эксперта проверить значение эквити
//записать эквити и время замера 
   if(cnt<TradeHistoy)
     {
      Equity[cnt]=AccountInfoDouble(ACCOUNT_EQUITY);
      EquityTime[cnt]=TimeTradeServer();
     }

  }
//+------------------------------------------------------------------+

void D_ArrayToCsv(string filename,double &mass[],int line,string Separator)
  {
// запись массива в файл
   string str;
   int handle=FileOpen(filename,FILE_CSV|FILE_WRITE,Separator);
//Цикл записи строчек в файл
   for(int l=0;l<line;l++)
     {
      str=DoubleToString(mass[l],8);
      FileWrite(handle,str);
     }
   FileClose(handle);
  }
//+------------------------------------------------------------------+
Потом с созданными файлами можно делать что душе угодно.
 

 Спасибо, Rosh, за подсказку по объектам, с этой частью своей задачи, думаю, что теперь справлюсь.

...А вот с файловыми операциями, которые попробовал освоить только что, все несколько более запутанно (чего я, собственно, и боялся!)

: )

Удивлений сразу несколько:

1. Файл на запись в цикле почему-то записывает вместо нескольких только одно-единственное значение.

2. В операции FileWriteArray несмотря на успешность получения указателя и проверку непустоты передаваемого массива 

количество записанных элементов равно -1.

3. В документации сказано о том, что на этапе тестации операции открытия происходят в папке  MQL5\tester\files, а на этапе основной работы - в  MQL5/files, в связи с чем сразу же возник вопрос о том, каким образом Индикатор сможет получать данные, записанные на этапе тестации, во время основной работы (причем путь к папке весбма непрост и скорее всего способный к изменению со временем  - \tester\Agent-127.0.0.1-3000\MQL5\Files  )

 
DV2010:


3. В документации сказано о том, что на этапе тестации операции открытия происходят в папке  MQL5\tester\files, а на этапе основной работы - в  MQL5/files, в связи с чем сразу же возник вопрос о том, каким образом Индикатор сможет получать данные, записанные на этапе тестации, во время основной работы (причем путь к папке весбма непрост и скорее всего способный к изменению со временем  - \tester\Agent-127.0.0.1-3000\MQL5\Files  )

Ручками переносить.

Вот Вам код на чтение из файла:

void CsvTo1D_Array(string nameFile,double &array[],int line,string Separator)
{
        int end=0;
        int handle=FileOpen(nameFile,FILE_CSV|FILE_READ,Separator);

        if (handle!=1)
        {
                Alert("Файл ",nameFile," не найден!");
        }
        else
        {
                for (int l=0;l<line;l++)
                {
                        array[l]=StringToDouble(FileReadString(handle));
                }
                FileClose(handle);
        }
}
//+------------------------------------------------------------------+
Причина обращения: