Хотя, я не понял, разве OnTesterPass() должен реагировать на фреймы ?
Вот моя функция OnTesterPasss():
В ней я беру следующий фрейм, и собираю из него информацию по статистике тестирования, записанную в специальной структуре.
Затем эта информация записывается в коллекцию фреймов.
Когда все проходы позади - коллекция анализируется, фреймы разделяются на пары бек-форвард (или только бек, если тестирование было без
форварда), и выбираются лучшие проходы.
OnTesterPasss() только для того и
существует, чтобы реагировать на фреймы. Я использовал почти такую же обработку фреймов как у вас. Дело не в этом, а втом как вы заставляете
метод MyOnTesterPass() реагировать на новый фрейм. Да и это не нужно - лучше сделать всё в OnTesterDeinit(). Я обновился до бета-билда
2151. Может быть всё будет работать, но без мультитестера толку от этого мало.
Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты форвард-теста.
При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом режиме, но собирать там
фреймы на лету не удобно и чревато потерями.
Вот результаты извлечения из фреймов в разных функциях:
Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.
3-й столбик - значение MQLInfoInteger(MQL_FORWARD).
Вот кусок кода, где шло извлечение:
voidOnTesterDeinit()
{
////---ulong pass_num=0;// получение номера прохода из фреймаstring fr_name="";// публичное имя/метка из фреймаlong publ_id=0;// публичный id из фреймаdouble frm_val=0;// значение из фреймаdouble rep_data[1];// массив приёма результатаArrayInitialize(rep_data,0);
double test_result[1];//Масиив сбора результатов теста: [0]-бэк, [1]-форвардArrayInitialize(test_result,0);
//--Пишем фреймы в файлif(filehandle!=INVALID_HANDLE)
{
FrameFirst();
int str_count=0;
while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
{
str_count++;
FileWrite(filehandle,__FUNCTION__,fr_name,DoubleToString(frm_val,2),DoubleToString(rep_data[0],2),"pass_num=",pass_num);
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
}//whileFileClose(filehandle);
}
elsePrint(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
if(filehandle!=INVALID_HANDLE)
{
FileClose(filehandle);
}//ChartClose();//Закрыть чарт оптимизации
}//OnTesterDeinit()
Для сравнения - прогон на билде 2085 с форвардом
Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!
Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты
форвард-теста. При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом
режиме, но собирать там фреймы на лету не удобно и чревато потерями.
Вот результаты извлечения из фреймов в разных функциях:
Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.
3-й столбик - значение MQLInfoInteger(MQL_FORWARD).
Вот кусок кода, где шло извлечение:
Для сравнения - прогон на билде 2085 с форвардом
Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!
Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто, как я
уже написал, я их различаю по времени запуска. Получается надежнее.
Vladimir Baskakov: Оптимизация дело хорошее, правда
чем она отличается от подгонки под историю
Это те же монеты, но только в профиль. Здесь обсуждается форвард-оптимизация, когда результат подгонки определяется на последующем периоде.
В результате определяется 1) Прибыльность советника; 2) Периоды подгонки и торговли для с оптимальным соотношением прибыль/убыток; 3)
Совершенствуется алгоритм советника. Я считаю, что лучше еще ничего не придумали. Всякие там математические вычисления и монтекарлы не
отражают структуру живого рынка.
Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто,
как я уже написал, я их различаю по времени запуска. Получается надежнее.
Если не починят рот, для приёма пищи придётся искать альтернативные пути.
Здравствуйте.У меня такой вопрос советник работал хорошо полтора года,приносил прибыль.А сейчас уже полтора месяца не открыл ни одной сделки.Такое
бывает с советниками?Может его надо оптимизировать?
Leon_28: Здравствуйте.У меня такой вопрос советник работал
хорошо полтора года,приносил прибыль.А сейчас уже полтора месяца не открыл ни одной сделки.Такое бывает с советниками?Может его
надо оптимизировать?
Если у вас период контроля более 4-х часов - это может и нормально. Может быть что угодно, но разбираться следует при любом подозрении.
1) Проверьте разрешение торогвли: рядом со значком советника в левом верхнем углу графика должен быть зеленый кружочек.
2) Прочитайте журнал советника в разделе "эксперты": ести ли ошибки и сообщения от советника или брокера.
3) Выставтьте небольшой период контроля (например мувинг с периодом в 10) если такой есть, если нет - на маленький ТФ (напр. М-1) и
минимальный риск. В настройках тестера "только цены открытия" и оптимизация "отключена". Форвард - отключить. Сделайте прогон на
периоде оптимизации в 1 неделю. И смотрите: открываются ли сделки и ошибки в журнале. Если проблема не нашлась - теребите изготовителя
вашего советника. Может быть всё что угодно.
Тестировать имеет смысл только полностью рабочий советник.
Вышел новый билд 2170. "Исправлены ошибки и оптимизирована работа с фреймами"
написано в
п. 24 в анонса. Посмотрим. Я тоже пересмотрел советник для теста работы с фреймами.
Были там места, дающие возможность записи одних строк поверх других. Удалил записи данных "сразу в файл" потому что функция FileWrite() не
работает в функциях OnInit(), OnDeinit() и OnTester(), о чём в
документации не предупредили.
Вот и код:
inputdouble param_1=1.0;//Тестовый параметрint filehandle;
intOnTesterInit()
{
ResetLastError();
string subfolder="Opt_reports";
string rep_name="\\"+"Forw_Test"+".csv";
//--- общая папка всех клиентских терминаловstring common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- выведем имя этой папкиPrintFormat("Откроем файл в общей папке клиентских терминалов %s",common_folder);
//--- откроем файл в общей папке (указан флаг FILE_COMMON)
filehandle=FileOpen(subfolder+rep_name,FILE_WRITE|FILE_READ|FILE_COMMON);
if(filehandle!=INVALID_HANDLE)
{
string fram_name="back_test";
if(MQLInfoInteger(MQL_FORWARD)==1)fram_name="forward";
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файлаFileWrite(filehandle,__FUNCTION__,"mode=",fram_name,"файл создан");
}// filehandle==truereturnINIT_SUCCEEDED;
}//OnTesterInit()//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--Функция FileWrite()не работаетreturn(INIT_SUCCEEDED);
}//OnDeinit//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--Функция FileWrite()не работает
}//OnDeinit//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+doubleOnTester()
{
string fram_name="back_test";
//---staticlong pass_calk;
pass_calk++;
//---Переменные для фреймаdouble frame_val=0;//Значение фреймаif(MQLInfoInteger(MQL_FORWARD)==true)
{
fram_name="forward";
frame_val=1;
}//double pass_result[1];//Оптимизируемый символArrayInitialize(pass_result,0);
pass_result[0]=param_1*pass_calk;
if(FrameAdd(fram_name,pass_calk,frame_val,pass_result)==false)
Print("OnTester(): Фрейм не создан");
return(pass_result[0]);
}//OnTester()voidOnTesterPass()
{
staticint frm_count=0;
frm_count++;
string mode="back_test";
if(MQLInfoInteger(MQL_FORWARD)==1)mode="forward";
ulong pass_num=0;// получение номера прохода из фреймаstring fr_name="";// публичное имя/метка из фреймаlong publ_id=0;// публичный id из фреймаdouble frm_val=0;// значение из фреймаdouble rep_data[1];// массив приёма результатаArrayInitialize(rep_data,0);
double test_result[1];//Масиив сбора результатов теста: [0]-бэк, [1]-форвардArrayInitialize(test_result,0);
//--Пишем фреймы в файлif(filehandle!=INVALID_HANDLE)
{
string fram_name="back_test";
if(MQLInfoInteger(MQL_FORWARD)==1)
fram_name="forward";
//---while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
{
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файлаFileWrite(filehandle,__FUNCTION__,"mode=",mode,"fr_name=",fr_name,"frm_val=",DoubleToString(frm_val,2),"rep_data=",DoubleToString(rep_data[0],2),"pass_num=",frm_count);
}//while
}
elsePrint(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
}////+------------------------------------------------------------------+//| TesterDeinit function |//+------------------------------------------------------------------+voidOnTesterDeinit()
{
////---string mode="back_test";
if(MQLInfoInteger(MQL_FORWARD)==1)mode="forward";
ulong pass_num=0;// получение номера прохода из фреймаstring fr_name="";// публичное имя/метка из фреймаlong publ_id=0;// публичный id из фреймаdouble frm_val=0;// значение из фреймаdouble rep_data[1];// массив приёма результатаArrayInitialize(rep_data,0);
double test_result[1];//Масиив сбора результатов теста: [0]-бэк, [1]-форвардArrayInitialize(test_result,0);
//--Пишем фреймы в файлif(filehandle!=INVALID_HANDLE)
{
//--- if(FrameFirst()==true)
{
int str_count=0;
while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
{
str_count++;
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файлаFileWrite(filehandle,__FUNCTION__,"mode=",mode,"fr_name=",fr_name,"frm_val=",DoubleToString(frm_val,2),"rep_data=",DoubleToString(rep_data[0],2),"pass_num=",str_count);
}//while
}//FrameFirst()==trueelse
{
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файлаFileWrite(filehandle,__FUNCTION__," Ошибка функции FrameFirst");
}
FileClose(filehandle);
}
elsePrint(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
ChartClose();//Закрыть чарт оптимизации
}//OnTesterDeinit()
Результат прогона с включенным форвардом:
Mode - это показатель MQLInfoInteger(MQL_FORWARD) внутри текущей функции, а fr_name - показатель записанный во фрейм во время его создания
в функции OnTester(). pass_num - это счётчик фреймов. Остальное очевидно.
Получается что было создано 10 фреймов - по 5 в форварде и бэк-тесте, а в OnTesterDeinit() пришло только 5 с форвардом. Куда делись фреймы
бек-теста? В общем, еще не конец. Но с этим уже можно работать, хотя в OnTesterPas() фреймы при обработке будут теряться, особенно в
облачных агентах. Обратите внимание, что признак MQLInfoInteger(MQL_FORWARD) работает только в OnTester() - везде mode= back_test.
При отключённом форварде фреймы в OnTesterDeinit() приходят в полном объёме:
Возможно, взаимосокращаются фреймы бэк и форвард-теста с одинаковыми данными в одинаковых проходах, т.е когда результаты оптимизаций
совпадают. но для этого нужен тест на реальных данных. Буду пробовать.
Ну, это и есть те самые тонкости.
Хотя, я не понял, разве OnTesterPass() должен реагировать на фреймы ?
Вот моя функция OnTesterPasss():
В ней я беру следующий фрейм, и собираю из него информацию по статистике тестирования, записанную в специальной структуре.
Затем эта информация записывается в коллекцию фреймов.
Когда все проходы позади - коллекция анализируется, фреймы разделяются на пары бек-форвард (или только бек, если тестирование было без форварда), и выбираются лучшие проходы.
OnTesterPasss() только для того и существует, чтобы реагировать на фреймы. Я использовал почти такую же обработку фреймов как у вас. Дело не в этом, а втом как вы заставляете метод MyOnTesterPass() реагировать на новый фрейм. Да и это не нужно - лучше сделать всё в OnTesterDeinit(). Я обновился до бета-билда 2151. Может быть всё будет работать, но без мультитестера толку от этого мало.
Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты форвард-теста. При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом режиме, но собирать там фреймы на лету не удобно и чревато потерями.
Вот результаты извлечения из фреймов в разных функциях:
Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.
3-й столбик - значение MQLInfoInteger(MQL_FORWARD).
Вот кусок кода, где шло извлечение:
Для сравнения - прогон на билде 2085 с форвардом
Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!
Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты форвард-теста. При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом режиме, но собирать там фреймы на лету не удобно и чревато потерями.
Вот результаты извлечения из фреймов в разных функциях:
Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.
3-й столбик - значение MQLInfoInteger(MQL_FORWARD).
Вот кусок кода, где шло извлечение:
Для сравнения - прогон на билде 2085 с форвардом
Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!
Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто, как я уже написал, я их различаю по времени запуска. Получается надежнее.
Оптимизация дело хорошее, правда чем она отличается от подгонки под историю
Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто, как я уже написал, я их различаю по времени запуска. Получается надежнее.
Здравствуйте.У меня такой вопрос советник работал хорошо полтора года,приносил прибыль.А сейчас уже полтора месяца не открыл ни одной сделки.Такое бывает с советниками?Может его надо оптимизировать?
Если у вас период контроля более 4-х часов - это может и нормально. Может быть что угодно, но разбираться следует при любом подозрении.
1) Проверьте разрешение торогвли: рядом со значком советника в левом верхнем углу графика должен быть зеленый кружочек.
2) Прочитайте журнал советника в разделе "эксперты": ести ли ошибки и сообщения от советника или брокера.
3) Выставтьте небольшой период контроля (например мувинг с периодом в 10) если такой есть, если нет - на маленький ТФ (напр. М-1) и минимальный риск. В настройках тестера "только цены открытия" и оптимизация "отключена". Форвард - отключить. Сделайте прогон на периоде оптимизации в 1 неделю. И смотрите: открываются ли сделки и ошибки в журнале. Если проблема не нашлась - теребите изготовителя вашего советника. Может быть всё что угодно.
Тестировать имеет смысл только полностью рабочий советник.
Вышел новый билд 2170. "Исправлены ошибки и оптимизирована работа с фреймами" написано в п. 24 в анонса. Посмотрим. Я тоже пересмотрел советник для теста работы с фреймами. Были там места, дающие возможность записи одних строк поверх других. Удалил записи данных "сразу в файл" потому что функция FileWrite() не работает в функциях OnInit(), OnDeinit() и OnTester(), о чём в документации не предупредили.
Вот и код:
Результат прогона с включенным форвардом:
Mode - это показатель MQLInfoInteger(MQL_FORWARD) внутри текущей функции, а fr_name - показатель записанный во фрейм во время его создания в функции OnTester(). pass_num - это счётчик фреймов. Остальное очевидно.
Получается что было создано 10 фреймов - по 5 в форварде и бэк-тесте, а в OnTesterDeinit() пришло только 5 с форвардом. Куда делись фреймы бек-теста? В общем, еще не конец. Но с этим уже можно работать, хотя в OnTesterPas() фреймы при обработке будут теряться, особенно в облачных агентах. Обратите внимание, что признак MQLInfoInteger(MQL_FORWARD) работает только в OnTester() - везде mode= back_test.
При отключённом форварде фреймы в OnTesterDeinit() приходят в полном объёме:
Возможно, взаимосокращаются фреймы бэк и форвард-теста с одинаковыми данными в одинаковых проходах, т.е когда результаты оптимизаций совпадают. но для этого нужен тест на реальных данных. Буду пробовать.
Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.
Воспроизвели описанную проблему. Исправляем