Открытый проект - тестер-оптимизатор своими силами - страница 2

 
Правда, не знаю заранее реакцию компилятора, пропустит он торговые константы в теле индикатора или нет?
Скорей всего пропустит.

Конечно должен, это же все просто целые, а не отдельный тип.

Маленький совет.

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

Сделать это можно с помощью библиотек.
1. Все функции связанные с торговлей чуть меняем названия (my... - не очень хорошо, м.б. лучше _....).
2. Создаем 2 библиотеки. Первая содержит код для тестирования (без реальной отправки ордеров), вторая просто дублирует параметры в вызовы стандартных функций. Переключение Работа/Тестирование делается просто заменой библиотеки.

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

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

Т.е. пусть у нас есть 1000 баров в истории на которой тестируем.
Определяем 200 бар как последний, и тогда везде вместо Close[0] подставляется Close[200]. И эта фича должна работать (влиять на) во всех встроенных функциях.

Тестер тогда будет выглядеть как цикл по номеру бара, в котором устанавливается это значение (последнего в тестировании бара) и вызов функции start в стратегии.

На самом деле не все так просто :))
Нужну еще некоторые моменты ..
 
Не понял этого, объясни
2. Создаем 2 библиотеки. Первая содержит код для тестирования (без реальной отправки ордеров), вторая просто дублирует параметры в вызовы стандартных функций. Переключение Работа/Тестирование делается просто заменой библиотеки.

Фраза "Код для тестирования" - это код тестера или код советника? Уточни.

И это тоже
Т.е. пусть у нас есть 1000 баров в истории на которой тестируем.
Определяем 200 бар как последний, и тогда везде вместо Close[0] подставляется Close[200].
И эта фича должна работать (влиять на) во всех встроенных функциях.


Любой код советника легко переделывается в код для индикатора :
Берем блок start() советника, добавляем после объявления переменных конструкцию for(testerconter=Bars;testerconter>=0;testerconter--)
{
в конце закрываем скобкой
}
Все места, использующие ссылки, заменяем на [testerconter+ссылка]

Вот пример из встроенного советника MACD_sample.mq4 .
Исходный текст:
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,MODE_EMA,0,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,MODE_EMA,0,PRICE_CLOSE,1);


Измененный

   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,testerconter+0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,testerconter+1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,testerconter+0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,testerconter+1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,MODE_EMA,0,PRICE_CLOSE,testerconter+0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,MODE_EMA,0,PRICE_CLOSE,testerconter+1);


Как видите, никаких проблем нет. При желании всегда потом можно переопределить testerconter=0 если
код исполняется в теле эксперта, а не советника .

 
Фраза "Код для тестирования" - это код тестера или код советника? Уточни.

В первой библиотеке функция
_OrderSend(Symbol(), OP_SELL, 1, Bid, 5, Bid + Stop * Point, Bid - Take * Point);


эмулирует исполнение ордера в тестере, т.е. добавляет его в список ордеров в тестере и не отправляет ордер серверу.

Во второй библиотеке эта функция просто вызывает встроенную функцию

int _OrderSend( string symbol, int cmd, double volume, double price, int slippage, 
                double stoploss, double takeprofit, string comment=NULL, int magic=0, 
                datetime expiration=0, color arrow_color=CLR_NONE) 
{
   return (OrderSend(symbol, cmd, volume, price, slippage, stoploss, 
                        takeprofit, comment, magic, expiration, arrow_color) );
}


Любой код советника легко переделывается в код для индикатора :
Берем блок start() советника, добавляем после объявления переменных конструкцию for(testerconter=Bars;testerconter>=0;testerconter--)
{
в конце закрываем скобкой
}
Все места, использующие ссылки, заменяем на [testerconter+ссылка]

Ну я про то же.
Было бы проще вместо замены вызвать функцию устанавливающую в МТ значение переменной testerconter (по умолчанию 0), и эта подстановка ([testerconter+ссылка]) делалась бы в самом МТ.
Тогда в самой стратегии эти подстановки делать бы не пришлось.

for(testerconter=Bars;testerconter>=0;testerconter--)
{
   SetTestPoint(testerconter);
      далее текст эксперта без переделки,
      или лучше вызов его функции start (или _start)
}



Замени плз. pre на quote в "Т.е. пусть у нас есть 1000 баров в ..."
а то опять страница уехала.

 
У себя заменил на quote, похоже у тебя уезжает текст, сделай принудительный перевод строки в своем примере
про
int _OrderSend( string symbol,....


Сделал вывод: кажется мы говорим об одном и том же. Про просьбу о текущем последнем баре можно пока забыть -
надо попробовать так сделать.
Пока просто переопределить стандартные торговые функции, можно и с префиксом _.. , так даже солиднее :)
 
to avm
Тестировать таким образом можно. И достаточно качественно. Но, к сожалению, универсализма не получится.
Я потратил на такие тесты пару недель. На первый взгляд кажется всё просто.


Я подозреваю, что ты тестил "большой кровью", то есть не делал переопределения торговых функций. И каждый новый тест
требовал написания нового индикатора-тестера. А ведь достаточно сделать это всего один раз - и дальше нет проблем.
Если я не прав - выкладывай функции - не скупись.
 
Еще момент.

Вызвать функцию start из эксперта напрямую видимо не удастся.
Поэтому лучше сам код эксперта тоже написать в библиотеке и завести там функции _init, _deinit и _start.

Тогда в самом эксперте пишем:
#include ".....";
   ...............

int init()
{
   return(_init());
}

int deinit()
{
   return(_deinit());
}

int start()
{
   return(_start());
}


Немного непонятно правда как с параметрами быть.

 
Так кстати можно и несколько экспертов/сигналов вместе на одном чарте объдинять.
Как это в Омеге сделано:
#include "A1.....";
#include "A2.....";
   ...............

int init()
{
   _initA1();
   _initA2();
   return(0);
}

int deinit()
{
   _deinitA1();
   _deinitA2();
   return(0);
}

int start()
{
   _startA1();
   _startA2();
   return(0);
}


Не очень красиво, но работать будет.
В общем самопальная система обработки событий получается :))

 
Может проще? Делается скрипт-парсер, который натравливается на mq4-файл (с кодом советника).
Он этот код обрабатывает - вставляет всякие include, рабочие массивы под Balance , Equity и прочее,
переименовывает переменные Lots в и _Lots (и другие). В общем, черновую работу сделает он.
Надо будет только на выходе обработать напильником - и вперед. :)
Простой конвейерный метод.
 
to avm
Тестировать таким образом можно. И достаточно качественно. Но, к сожалению, универсализма не получится. Я потратил на такие тесты пару недель. На первый взгляд кажется всё просто.

Я подозреваю, что ты тестил "большой кровью", то есть не делал переопределения торговых функций. И каждый новый тест требовал написания нового индикатора-тестера. А ведь достаточно сделать это всего один раз - и дальше нет проблем. Если я не прав - выкладывай функции - не скупись.

Абсолютно прав. "Большой кровью". Замен никаких не было. Я такие тестеры делал еще в МТ3.х. MQL4 от MQL2 отличается, как небо от земли. Но возможностями MQL4 не воспользовался. Психологический ступор. Надо было сначала подумать, потом поработать.
Женщине посоветовали: "Сначала подумай, потом говори". Женщина ответила: "Как же я могу подумать о том, чего я ещё не сказала".
 
Про парсер я немного вперед забежал, сначала функции надо написать. Но вот я помню, что разработчики сказали - мультивалютного тестера не будет(портфельного). Или я чего-то путаю? Если не путаю - тем более надо свой написать.
Причина обращения: