Особых проблем нет - вот куски кода, которые нужно добавить/исправить - и у Вас там, похоже, описка была.
// переменные shiftfast и shiftslow следует сразу установить в 1 - то есть с учетом того, что значение
//мувингов на последнем баре нас не интересуют
extern double shiftfast = 1;
extern double shiftslow = 1;
int nT=0,nB=0;
int init()
{
symbol=Symbol();
for(int i=MABARSCOUNT-1;i>=0;i--){
ma_fast[i]=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,i+shiftfast);
ma_slow[i]=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,i+shiftslow);
}
nT = Time[0];
nB = Bars;
return(0);
}
void CheckForOpen(double f[], double s[]) {
/*
fast1=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,1+shiftfast);
fast2=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,2+shiftfast);
slow1=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,1+shiftfast);????????? Описка, наверное ????????
slow2=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,2+shiftfast);????????? Описка, наверное ????????
*/
if ((f[0]>s[0]) && (f[1]<s[1])) {
OrderSend(symbol,OP_BUY,Lots,Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Green);
}
else
{
if ((f[0]<s[0]) && (f[1]>s[1]))
OrderSend(symbol,OP_SELL,Lots,Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Green);
}
}
int start() {
static bool money=true;
if((nT!=Time[0])||(nB!=Bars) ){
for(int i=MABARSCOUNT-1;i>0;i--) {
ma_fast[i] = ma_fast[i-1];
ma_slow[i] = ma_slow[i-1];
}
ma_fast[0]=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,shiftfast);
ma_slow[0]=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,shiftslow);
nT = Time[0];
nB = Bars;
}
if (OrdersTotal() < 1)
{
int hour=Hour();
if ((hour >= hour_work_from) && (hour < hour_work_to) && money) {
CheckForOpen(ma_fast,ma_slow); // в принципе, здесь можно вставить код самой функции
// будет работать еще немного быстрее
if(GetLastError()==134) money=false;
}
..........................................................................
Думаю, идея понятна.
Проблемы с использованием этого эксперта начнутся как только Вы его повесите, хотя бы на демку - совершенно не слушает, что говорит сервер и не оценивает можно ли выставлять ордера - возможно просто зацикливание, а если повесите еще пару экспертов на разные пары - узнаете много нового. Лучше сразу сходите на форум мкл4 и почитайте уроки программирования - будет полезно.
Удачи и попутных трендов.
PS А если еще слегка подумать, то можно понять, что если пересечения мувингов не произошло на момент открытия бара, то соотвественно не произойдет вплоть до открытия следующего и соотвественно проверять пересечение запросто можно один раз на бар, но это уже самостоятельно.
To: Vladislav
Уважаемый. Вашу последнюю идею можно фактически воплотить вот так (за исключением кеширования данн индикатора):
hr = Hour();
if (nT != Time[1] && total < 1 && hr >= hour_work_from && hr < hour_work_to) {
CheckForOpen();
nT = Time[1];
}
Таким образом эксперт будет работать быстрей за счет того что только на новооткрывшемся баре будет делать попытку стать в позицию (а больше собственно и не требуется). Но. Самое парадаксальное. С этим изменением он работает МЕДЛЕННЕЙ на длинной истории (в 3 года). Сначала он бежит вроде как немного быстрей, а вот под конец явно начинает захлебыватся. Причем так. Первые полтора года, он пролетает буквально за 13 секунд. А с оставшимся периодом возится 38 секунд (сумарно выодит 51 секунда). При использовании того же кода только без nT, мы проходим по истории за 40 секунд. Медленее в начале, зато быстрее в конце. Обьясните пожалуйста.
Так по поводу особенностей работы тестера - это не ко мне.
Для того чтобы посмотреть на реальную экономию: дописываем хронометраж в каждом вариатне экперта, вешаем на демку - и смотрим.
Думаю, что сказывается разница в качестве моделирования баров в начале и конце периода. В какой-то из веток обсуждали, что в отличие от стандарта под оператором if(....) проверяются все условия, а не до первого сработавшего или не сработавшего в зависимости от условий. Так ли это не проверял - попробуте самостоятельно. Я лично паредпочитаю писать такие коды, в которых это значения не имеет.
И еще - нумерация массивов начинается от 0, а не от 1. То есть, Вам нужен бар со временем Time[0], а не Time[1].
Так по поводу особенностей работы тестера - это не ко мне.
Для того чтобы посмотреть на реальную экономию: дописываем хронометраж в каждом вариатне экперта, вешаем на демку - и смотрим.
А ради чего тогда вы писали столько про мое "тормозное искуство"? Или вы разделяете теоретичесуцю и практическую часть, причем первая для вас важне?.. да действительно: если на каждом баре не пытатся влезть в позицию то так ТЕОРЕТИЧЕКИ быстрей. Но как оказалось эта проверка а не поменялся ли бар на ПРАКТИКЕ оказалась сложней, и результат во времени паршивит заметно. И я вас умоляю, не нужно мне расказывать с какого значения начинается нумерация масива... Особенно если это ВООБЩЕ не будет иметь значения 1 там будет или 0. Вобщем ладно. Проехали.
Практика для меня = работа на счету ( реал, как минимум демо). Работа же тестера - это даже не теория, только небольшая часть. Как будете запускать МТС на реале, тогда, возможно, оцените разность в производительности. Или ее оценят покупатели Вашей МТС. Заодно оцените как влияет на профитность системы запаздывание в исполнении сигналов не по тестеру ;). Тогда весьма будет иметь значение с какого индекса начинаются массивы и нужно или нет пересчитывать мувинги на каждом тике, а пока, судя по всему (возможно ошибаюсь) Вы и с теорией не очень то разобрались.
// переменные shiftfast и shiftslow следует сразу установить в 1 - то есть с учетом того, что значение //мувингов на последнем баре нас не интересуют extern double shiftfast = 1; extern double shiftslow = 1; int nT=0,nB=0; int init() { symbol=Symbol(); for(int i=MABARSCOUNT-1;i>=0;i--){ ma_fast[i]=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,i+shiftfast); ma_slow[i]=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,i+shiftslow); } nT = Time[0]; nB = Bars; return(0); } void CheckForOpen(double f[], double s[]) { /* fast1=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,1+shiftfast); fast2=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,2+shiftfast); slow1=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,1+shiftfast);????????? Описка, наверное ???????? slow2=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,2+shiftfast);????????? Описка, наверное ???????? */ if ((f[0]>s[0]) && (f[1]<s[1])) { OrderSend(symbol,OP_BUY,Lots,Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Green); } else { if ((f[0]<s[0]) && (f[1]>s[1])) OrderSend(symbol,OP_SELL,Lots,Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Green); } } int start() { static bool money=true; if((nT!=Time[0])||(nB!=Bars) ){ for(int i=MABARSCOUNT-1;i>0;i--) { ma_fast[i] = ma_fast[i-1]; ma_slow[i] = ma_slow[i-1]; } ma_fast[0]=iMA(NULL,0,fast,0,MA_Type,PRICE_CLOSE,shiftfast); ma_slow[0]=iMA(NULL,0,slow,0,MA_Type,PRICE_CLOSE,shiftslow); nT = Time[0]; nB = Bars; } if (OrdersTotal() < 1) { int hour=Hour(); if ((hour >= hour_work_from) && (hour < hour_work_to) && money) { CheckForOpen(ma_fast,ma_slow); // в принципе, здесь можно вставить код самой функции // будет работать еще немного быстрее if(GetLastError()==134) money=false; } ..........................................................................Думаю, идея понятна.
Проблемы с использованием этого эксперта начнутся как только Вы его повесите, хотя бы на демку - совершенно не слушает, что говорит сервер и не оценивает можно ли выставлять ордера - возможно просто зацикливание, а если повесите еще пару экспертов на разные пары - узнаете много нового. Лучше сразу сходите на форум мкл4 и почитайте уроки программирования - будет полезно.
Удачи и попутных трендов.
PS А если еще слегка подумать, то можно понять, что если пересечения мувингов не произошло на момент открытия бара, то соотвественно не произойдет вплоть до открытия следующего и соотвественно проверять пересечение запросто можно один раз на бар, но это уже самостоятельно.
Уважаемый. Вашу последнюю идею можно фактически воплотить вот так (за исключением кеширования данн индикатора):
hr = Hour(); if (nT != Time[1] && total < 1 && hr >= hour_work_from && hr < hour_work_to) { CheckForOpen(); nT = Time[1]; }Таким образом эксперт будет работать быстрей за счет того что только на новооткрывшемся баре будет делать попытку стать в позицию (а больше собственно и не требуется). Но. Самое парадаксальное. С этим изменением он работает МЕДЛЕННЕЙ на длинной истории (в 3 года). Сначала он бежит вроде как немного быстрей, а вот под конец явно начинает захлебыватся. Причем так. Первые полтора года, он пролетает буквально за 13 секунд. А с оставшимся периодом возится 38 секунд (сумарно выодит 51 секунда). При использовании того же кода только без nT, мы проходим по истории за 40 секунд. Медленее в начале, зато быстрее в конце. Обьясните пожалуйста.
Для того чтобы посмотреть на реальную экономию: дописываем хронометраж в каждом вариатне экперта, вешаем на демку - и смотрим.
Думаю, что сказывается разница в качестве моделирования баров в начале и конце периода. В какой-то из веток обсуждали, что в отличие от стандарта под оператором if(....) проверяются все условия, а не до первого сработавшего или не сработавшего в зависимости от условий. Так ли это не проверял - попробуте самостоятельно. Я лично паредпочитаю писать такие коды, в которых это значения не имеет.
И еще - нумерация массивов начинается от 0, а не от 1. То есть, Вам нужен бар со временем Time[0], а не Time[1].
Удачи и попутных трендов.
Для того чтобы посмотреть на реальную экономию: дописываем хронометраж в каждом вариатне экперта, вешаем на демку - и смотрим.
А ради чего тогда вы писали столько про мое "тормозное искуство"? Или вы разделяете теоретичесуцю и практическую часть, причем первая для вас важне?.. да действительно: если на каждом баре не пытатся влезть в позицию то так ТЕОРЕТИЧЕКИ быстрей. Но как оказалось эта проверка а не поменялся ли бар на ПРАКТИКЕ оказалась сложней, и результат во времени паршивит заметно. И я вас умоляю, не нужно мне расказывать с какого значения начинается нумерация масива... Особенно если это ВООБЩЕ не будет иметь значения 1 там будет или 0. Вобщем ладно. Проехали.
Проехали, так проехали.
Удачи и попутных трендов.