Rosh: Пишите значения эквити в файл. Потом стройте индикатор по этим значениям. Но файл данных придется переносить вручную, так как при тестировании файлы пишутся в папку имя_агента/MQL5/Files.
Только теперь понял, насколько все заморочено.
Но вручную - явно не решение этого вопроса, так как речь идет о сотнях тестаций.
И казалось бы: в начале есть доступные данные, но - о, Чудо! -- программа устроена так, что возможность их как-то и где-то сохранить до момента их программного извлечения и использования полностью отсутствует!
Я - не профессиональный программист, но в голове у меня такая ситуация не укладывается.
Огромнейшая документация.., широчайшие возможности в построении, казалось бы, всего и вся.., управление памятью, ООП, а тут, в фундаментально-простом и критически-нужном (что, надеюсь, уже объяснил) - тупик.
...И все-таки... Вопрос!
Неужели отсутствует возможность записи в режиме тестирования в какие-то принудительно-нестираемые программные массивы, которые впоследствии можно было бы использовать для построения индикатора?
В т.ч. есть ли возможность передачи через глобальную переменную указателя на такой массив?
И в чем вообще проблема хранения и переброски данных между этапом тестации и временем основной работы не с точки зрения текущей реализации, а в принципе?
Renat упоминал о сотнях мегабайтах данных, но, во-первых, зачем перебрасывать данные всегда, если можно такую возможность предусмотреть лишь при прямом волеизъявлении программиста, и во-вторых, объем данных в смысле поставленной задачи гораздо меньше, и составляет какую-то несколько тысяч цифр.
Еще раз заявляю, что с позиции пользователя вариант ручной переброски файлов при многократном тестировании (а рынок в силу своей сложности требует многократности) абсолютно неудобен и бесперспективен, в то время, как, готов спорить с кем угодно о том, что динамика показателей состояния счета в непосредственном их соотнесении с динамикой цен на истории тестирования является одной из самых важных вообще.
В чем вопрос расширения области видимости в основном режиме операций открытия файлов в режиме чтения до папки файлов тестера? Какая в этом может быть хотя бы гипотетическая угроза?
И в чем вопрос отсутствия возможности принудительного хранения нужных данных между основным режимом и режимом тестации в оперативной памяти?
Неужели отсутствует возможность записи в режиме тестирования в какие-то принудительно-нестираемые программные массивы, которые впоследствии можно было бы использовать для построения индикатора?
Расположение файла в общей папке всех клиентских терминалов. Флаг используется при открытии файлов (FileOpen()), копировании файлов (FileCopy(), FileMove()) и проверке существования файлов (FileIsExist())
Вариант с общей папкой кажется более... интегрированным.
Единственное, что удивляет, так это то, что при запуске этого кода в рамках индикатора выводится сообщение о неудачной записи, хотя запись сама все-таки производится. Плюс - пока еще открытый вопрос о том, как и когда именно лучше записывать данные (отдельно по каждому тику, но это ресурсоемко, или в самом конце - целый массив, но с записью массивов пока чего-то не совсем и, кроме того, трудно понять, как в таком случае будет действовать OnCalculated по его извлечению - во второй, получается проход уже после тестирования?)
И еще вопрос, несколько не в тему, но по уже затронутому вчера вопросу.
Вставил в OnTick и в OnCalculated:
Print("ObjectsTotal =", ObjectsTotal(ChartID()));
но после завершения тестирования несмотря на наличие объектов, связанных с открытием и закрытием позиций (стрелки и линии - видны в Терминале: Графики>Обэекты>Список объектов), возвращаемое значение почему-то равно 0.
ПисАть в файл лучше как можно реже, поэтому лучше целым массивом. Значения замерять не чаще, чем один раз в минуту, иначе будут проблемы с отображением на чарте (да и неоправданно ресурсоемко это). То есть в конце прогона. Но возможен и такой вариант:
Вариант с общей папкой кажется более... интегрированным.
Единственное, что удивляет, так это то, что при запуске этого кода в рамках индикатора выводится сообщение о неудачной записи, хотя запись сама все-таки производится.
У меня ничего такого не выводится. Попробуйте:
//+------------------------------------------------------------------+//| Demo_File_Common_Indicator.mq5 |//| Copyright 2011, MetaQuotes Software Corp. |//| http://www.mql5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2011, MetaQuotes Software Corp."#property link "http://www.mql5.com"#property version "1.00"#property indicator_chart_window#property indicator_buffers 1#property indicator_plots 1#property indicator_type1 DRAW_LINE#property indicator_color1 Reddouble buffer[];
inputstring filename="file_common.txt";
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- indicator buffers mappingSetIndexBuffer(0,buffer,INDICATOR_DATA);
string common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//---int handle=FileOpen(filename,FILE_WRITE|FILE_COMMON);
if(handle!=INVALID_HANDLE)
{
uint written=FileWrite(handle,"Общая папка всех терминалов - ",common_folder);
if(written>0)
{
PrintFormat("Записано %d байт в общую папку всех терминалов - %s",written,common_folder);
}
}
else
{
Print("Не удалось открыть на запись файл ",filename,". Ошибка ",GetLastError());
}
//---return(0);
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
//---//--- return value of prev_calculated for next callreturn(rates_total);
}
//+------------------------------------------------------------------+
Сделал сейчас на основе Вашего кода аналогичный простейший эксперт, который потиково должен записывать все значения Equity в файл (в коде изменил лишь вывод любого, в т.ч. нулевого количества записанных байтов, переменные сделал глобальными, а открытие файла и запись разнес в OnInit и OnTick), но хотя ошибка записи отсутствует и файл создается, записи и файл пусты.
#property copyright "Copyright 2010, Pavlov Sergei" #property link "" #property version "1.00"
#include <\..\Experts\_My\Classes\ClassExpert\ClassExpert.mqh> ClassExpert Expert1; int handle; string common_folder; string filename;
voidOnInit(){ Expert1.Init(); //-- filename="equity.txt"; common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH); int handle=FileOpen(filename,FILE_WRITE|FILE_COMMON); } voidOnTick(){ Expert1.OnTick(); //--- if(handle!=INVALID_HANDLE){ uint written=FileWrite(handle, AccountInfoDouble(ACCOUNT_EQUITY),common_folder); PrintFormat("Expert OnTick: Записано %d байт в общую папку всех терминалов - %s",written,common_folder); } else{ Print("Expert OnTick: Не удалось открыть на запись файл ",filename,". Ошибка ",GetLastError()); } } voidOnDeinit(constint reason){ Expert1.Deinit(); //--- FileClose(filename); }
2011.01.2114:00:46 Core 1 connect closed 2011.01.2114:00:46 Core 1log file "C:\Program Files\MetaTrader 5\Tester\Agent-127.0.0.1-3000\logs\20110121.log" written 2011.01.2114:00:46 Core 1 EURUSD,H1: 5516 ticks (23 bars) generated within 47 ms (total bars in history 6419, total time 3093 ms) 2011.01.2114:00:46 Core 1 OnTester result 0 2011.01.2114:00:46 Core 12011.01.1423:59:59 order performed sell 0.15 at 1.33829 [#13 sell 0.15 EURUSD at 1.33829] 2011.01.2114:00:46 Core 12011.01.1423:59:59 deal performed [#13 sell 0.15 EURUSD at 1.33829] 2011.01.2114:00:46 Core 12011.01.1423:59:59 deal #13 sell 0.15 EURUSD at 1.33829 done (based on order #13) 2011.01.2114:00:46 Core 12011.01.1423:59:59 position closed due end of test at 1.33829 [buy 0.15 EURUSD 1.33593] 2011.01.2114:00:46 Core 12011.01.1422:00:00 Expert OnTick: Записано 0 байт в общую папку всех терминалов - C:\Documents and Settings\All Users\Application Data\MetaQuotes\Terminal\Common 2011.01.2114:00:46 Core 12011.01.1421:00:00 Expert OnTick: Записано 0 байт в общую папку всех терминалов - C:\Documents and Settings\All Users\Application Data\MetaQuotes\Terminal\Common
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Вот Вам код на чтение из файла:
Почему FileReadString() ?
не лучше воспользоваться FileReadArray(), тогда цикл ненадо делать.
Почему FileReadString() ?
не лучше воспользоваться FileReadArray(), тогда цикл ненадо делать.
Rosh:
Пишите значения эквити в файл. Потом стройте индикатор по этим значениям. Но файл данных придется переносить вручную, так как при тестировании файлы пишутся в папку имя_агента/MQL5/Files.
Только теперь понял, насколько все заморочено.
Но вручную - явно не решение этого вопроса, так как речь идет о сотнях тестаций.
И казалось бы: в начале есть доступные данные, но - о, Чудо! -- программа устроена так, что возможность их как-то и где-то сохранить до момента их программного извлечения и использования полностью отсутствует!
Я - не профессиональный программист, но в голове у меня такая ситуация не укладывается.
Огромнейшая документация.., широчайшие возможности в построении, казалось бы, всего и вся.., управление памятью, ООП, а тут, в фундаментально-простом и критически-нужном (что, надеюсь, уже объяснил) - тупик.
...И все-таки... Вопрос!
Неужели отсутствует возможность записи в режиме тестирования в какие-то принудительно-нестираемые программные массивы, которые впоследствии можно было бы использовать для построения индикатора?
В т.ч. есть ли возможность передачи через глобальную переменную указателя на такой массив?
И в чем вообще проблема хранения и переброски данных между этапом тестации и временем основной работы не с точки зрения текущей реализации, а в принципе?
Renat упоминал о сотнях мегабайтах данных, но, во-первых, зачем перебрасывать данные всегда, если можно такую возможность предусмотреть лишь при прямом волеизъявлении программиста, и во-вторых, объем данных в смысле поставленной задачи гораздо меньше, и составляет какую-то несколько тысяч цифр.
Еще раз заявляю, что с позиции пользователя вариант ручной переброски файлов при многократном тестировании (а рынок в силу своей сложности требует многократности) абсолютно неудобен и бесперспективен, в то время, как, готов спорить с кем угодно о том, что динамика показателей состояния счета в непосредственном их соотнесении с динамикой цен на истории тестирования является одной из самых важных вообще.
В чем вопрос расширения области видимости в основном режиме операций открытия файлов в режиме чтения до папки файлов тестера? Какая в этом может быть хотя бы гипотетическая угроза?
И в чем вопрос отсутствия возможности принудительного хранения нужных данных между основным режимом и режимом тестации в оперативной памяти?
Для записи и чтения файлов из произвольно расположенных на диске папок используйте dll. Просто функции записи и чтения файла перенесите в dll и всё.
...И все-таки... Вопрос!
Неужели отсутствует возможность записи в режиме тестирования в какие-то принудительно-нестираемые программные массивы, которые впоследствии можно было бы использовать для построения индикатора?
Попробуйте указывать при открытии файла флаг FILE_COMMON - https://www.mql5.com/ru/docs/constants/io_constants/fileflags
Идентификатор
Значение
Описание
FILE_COMMON
4096
Расположение файла в общей папке всех клиентских терминалов. Флаг используется при открытии файлов (FileOpen()), копировании файлов (FileCopy(), FileMove()) и проверке существования файлов (FileIsExist())
Попробуйте указывать при открытии файла флаг FILE_COMMON - https://www.mql5.com/ru/docs/constants/io_constants/fileflags
Запустите этот скрипт и посмотрите куда он пишет
joo, Rash, спасибо!
Вариант с общей папкой кажется более... интегрированным.
Единственное, что удивляет, так это то, что при запуске этого кода в рамках индикатора выводится сообщение о неудачной записи, хотя запись сама все-таки производится. Плюс - пока еще открытый вопрос о том, как и когда именно лучше записывать данные (отдельно по каждому тику, но это ресурсоемко, или в самом конце - целый массив, но с записью массивов пока чего-то не совсем и, кроме того, трудно понять, как в таком случае будет действовать OnCalculated по его извлечению - во второй, получается проход уже после тестирования?)
И еще вопрос, несколько не в тему, но по уже затронутому вчера вопросу.
Вставил в OnTick и в OnCalculated:
но после завершения тестирования несмотря на наличие объектов, связанных с открытием и закрытием позиций (стрелки и линии - видны в Терминале: Графики>Обэекты>Список объектов), возвращаемое значение почему-то равно 0.ПисАть в файл лучше как можно реже, поэтому лучше целым массивом. Значения замерять не чаще, чем один раз в минуту, иначе будут проблемы с отображением на чарте (да и неоправданно ресурсоемко это). То есть в конце прогона. Но возможен и такой вариант:
Алгоритм вырисовывается так:
1) Запустили эксперт в тестере.
2) Замерили интересующее значение.
3) Записали в файл это значение.
4) Записали в отдельный файл true, означающее, что записано новое значение
5) Запустили бесконечный цикл, условием выхода из которого является флаг false в файле с флагом.
6) В отдельном чарте скриптом читаем файл с флагом, если появилось новое значение, то рисуем риску на чарте, пишем в файл false.
Примерно так будет выглядеть визуальный режим тестирования в тестере.
Подождите немного, закончится конкурс, возможно будут представлены более изящные и красивые решения.
joo, Rash, спасибо!
Вариант с общей папкой кажется более... интегрированным.
Единственное, что удивляет, так это то, что при запуске этого кода в рамках индикатора выводится сообщение о неудачной записи, хотя запись сама все-таки производится.
У меня ничего такого не выводится. Попробуйте:
У меня ничего такого не выводится. Попробуйте:
Rosh
, не могу понять, в чем именно причина, но в отличии от моих индикаторов, при запуске с Вашим, выдается сообщение:Сделал сейчас на основе Вашего кода аналогичный простейший эксперт, который потиково должен записывать все значения Equity в файл (в коде изменил лишь вывод любого, в т.ч. нулевого количества записанных байтов, переменные сделал глобальными, а открытие файла и запись разнес в OnInit и OnTick), но хотя ошибка записи отсутствует и файл создается, записи и файл пусты.