Помощь - Поиск - Пользователи - Календарь
Полная версия: Определение тренда
Форум трейдеров рынка ФОРЕКС (FOREX). Анализ Форекс > Программы для Forex > MQL программирование
leonid553
В мультивалютном советнике Rosh-a "ProtoType-IX" приведен пример определения тренда по четырем последним экстремумам. http://codebase.mql4.com/ru/1256
В аннотации указано:
"Данный советник торговал без алгоритмических ошибок на чемпионате по автотрейдингу 2006 года. Требует для работы индикатор NRTR GATOR. Может являться примером мультивалютного эксперта и, надеюсь, облегчит написание такового новичкам в MQL4."
Похоже пришла пора разобраться с ТРЕНДОМ, - как это делается. Хотя бы "методом тыка".
Для примера можно взять любой простейший эксперт и использовать приемы определения тренда из советника "ProtoType-IX". (см. пост №2)
Возьмем оттуда всё, что касается тренда и вставим в любой простейший советник. В результате получим:
Function "GetSymbolString" is not referenced and will be removed from exp-file
Function "PeriodNumber" is not referenced and will be removed from exp-file
Function "TrendByWPR" is not referenced and will be removed from exp-file
Function "SetArrow" is not referenced and will be removed from exp-file
Function "SetUpArrows" is not referenced and will be removed from exp-file
Function "TrendExist" is not referenced and will be removed from exp-file

Мы получили шесть функций, которые вычисляются, но пока не принимают участия в торговле нашего эксперта.
Поскольку, наш эксперт пусть будет НЕ МУЛЬТИВАЛЮТНЫЙ, то первая функция нам неинтересна. Вторая функция, - пожалуй, тоже, т.к. она задает таймфрейм. Но оставим пока всё как есть.
Начнем с самого начала.
Во внешних нашего эксперта параметрах мы добавляем:

Код
extern int     PeriodWPR=8;
extern double  CriteriaWPR=25;
extern int     ATRPeriod=40;// период ATR для индикатора
extern double  kATR=0.5;
extern int     ZeroBar=8; // выход в безубыток через ZeroBar баров
extern double  MinTargetinSpread=5.0;
extern double  TP_SL_Criteria=2.0;
extern int     MaxOpenedOrders=3;
extern double  MaxOrderSize=5.0;

Понятно что пока чего-то не хватает а что-то будет лишним. Надеюсь разберемся...
Далее (после внешних параметров) задаем по аналогии глобальные переменные:
Код
int  LastUpArray[13,7];
int  PreLastUpArray[13,7];
int  LastDownArray[13,7];
int  PreLastDownArray[13,7];
double Complextrend[13,7];// собираем все тренды (Z,A и N тренды) в одно значение.
double TPvsSL[13,7];// отношение TakeProfit к StopLoss на данном символе и таймфрейме
int BestTPvsSLSymbol[20]; // лучшие символы по соотношению TP/SL
int BestTPvsSLPeriod[20]; // лучшие таймфреймы по соотношению TP/SL
//--------------------------------------------
string SymbolsArray[13]={"","USDCHF","GBPUSD","EURUSD","USDJPY","AUDUSD",
"USDCAD","EURGBP","EURAUD","EURCHF","EURJPY","GBPJPY","GBPCHF"};
int TrendOnSymbol[13,7]; //  тренд по символу и таймфрейму
int MyBarsArrays[13,7];// храним количество баров по инструменту и таймфрейму
int TimeNullArrays[13,7];// храним время Time[0] по инструменту и таймфрейму

Не будем пока особо вникать. Посмотрим дальше...
leonid553
Прежде всего (как я уже говорил), возьмем простейший эксперт-заготовку, код которого будет понятен всем присутствующим, - кому интересно. Пусть это будет советник на индикаторе Стохастик.
Вход в длинную позицию, - пересечение главной линией линии сигнальной снизу вверх! Вход в короткую позицию, - пересечение главной линией линии сигнальной сверху вниз.
Предусмотрим отдельные расчеты для длинных и коротких позиций. И работу по ценам открытия. Ну и трейлинг стоп конечно...
Код советника - в закачке.
И вот результат теста с приведенными ниже параметрами. На котировках Хистори Центр с янв. 2003г. по сей день.
Замечу, что оптимизация была до 31 авг. 2007г. Далее (почти +400) - пробег вне выборки за сентябрь!

Stochastic_Signal

Символ GBPUSD (Great Britain Pound vs US Dollar)
Период 30 Минут (M30) (2003.01.01 - 2007.10.06)
Параметры K_period=4; D_period=17; K_period_=10; D_period_=20; Slowing=2; TP=162; SL=72; TP_sell=123; SL_sell=83; Lot=0.1; Slippage=3; UseTrailing=true; lMinProfit=50; sMinProfit=60; lTrailingStop=58; sTrailingStop=59; lTrailingStep=8; sTrailingStep=3;

Начальный депозит 10000.00
Чистая прибыль 9722.54 Общая прибыль 47921.52 Общий убыток -38198.98
Прибыльность 1.25 Матожидание выигрыша 8.49
Абсолютная просадка 1077.12 Максимальная просадка 1329.56 (12.97%)
Относительная просадка 12.97% (1329.56)

Всего сделок 1145
Короткие позиции (% выигравших) 315 (58.41%)
Длинные позиции (% выигравших) 830 (50.24%)
Прибыльные сделки (% от всех) 601 (52.49%)
Убыточные сделки (% от всех) 544 (47.51%)
Самая большая прибыльная сделка 162.98 убыточная сделка -88.95
Средняя прибыльная сделка 79.74 убыточная сделка -70.22
Максимальное количество непрерывных выигрышей (прибыль) 12 (775.99) непрерывных проигрышей (убыток) 9 (-646.85)
Максимальная непрерывная прибыль (число выигрышей) 775.99 (12) непрерывный убыток (число проигрышей) -646.85 (9)
Средний непрерывный выигрыш 2 непрерывный проигрыш 2
leonid553
С внешними параметрами и глобальными переменными мы уже определились в пост №1.
Посмотрим дальше. Придется ещё добавить функции по символу и таймфрейму. Возможно, потом мы их уберем, а пока код нашего эксперта будет начинаться так:
Код
//|Stochastic_Signal_Trend.mq4.mq4
//| leonid553 & co
//| http://www.tradersforum.net.ru/
//+------------------------------------------------------------------+
#property copyright "leonid553 & co"
#property link      "http://www.tradersforum.net.ru/"

//---- input parameters---------
extern int     MagicNum    =96784;
extern int     K_period    =4;
extern int     D_period    =17;

extern int     K_period_   =10;
extern int     D_period_   =20;

extern int     Slowing=3;
//------------------------------
extern int     TP=130;
extern int     SL=57;
extern int     TP_sell=130;
extern int     SL_sell=57;
extern double  Lot=0.1;
extern int     Slippage=2;
//--------------------------------
extern bool UseTrailing = true;//трейлинг стоп
extern int lMinProfit = 55;
extern int sMinProfit = 55;
extern int lTrailingStop = 58;
extern int sTrailingStop = 60;
extern int lTrailingStep = 5;
extern int sTrailingStep = 5;
//-----------------------------------
extern int     PeriodWPR=8;
extern double  CriteriaWPR=25;
extern int     ATRPeriod=40;// период ATR для индикатора
extern double  kATR=0.5;
extern int     ZeroBar=8; // выход в безубыток через ZeroBar баров
extern double  MinTargetinSpread=5.0;
extern double  TP_SL_Criteria=2.0;
extern int     MaxOpenedOrders=3;
extern double  MaxOrderSize=5.0;
//-------------------------------------
int  LastUpArray[13,7];
int  PreLastUpArray[13,7];
int  LastDownArray[13,7];
int  PreLastDownArray[13,7];
double Complextrend[13,7];// собираем все тренды (Z,A и N тренды) в одно значение.
double TPvsSL[13,7];// отношение TakeProfit к StopLoss на данном символе и таймфрейме
int BestTPvsSLSymbol[20]; // лучшие символы по соотношению TP/SL
int BestTPvsSLPeriod[20]; // лучшие таймфреймы по соотношению TP/SL
//--------------------------------------------
string SymbolsArray[13]={"","USDCHF","GBPUSD","EURUSD","USDJPY","AUDUSD","USDCAD","EURGBP",
"EURAUD","EURCHF","EURJPY","GBPJPY","GBPCHF"};
int TrendOnSymbol[13,7]; //  тренд по символу и таймфрейму
int MyBarsArrays[13,7];// храним количество баров по инструменту и таймфрейму
int TimeNullArrays[13,7];// храним время Time[0] по инструменту и таймфрейму
//-------------------
//-- Подключаемые модули --
#include <stdlib.mqh>
//-------------------
int ticket;

//****************************************************************
//+------------------------------------------------------------------+
//| string SymbolByNumber                                                |
//+------------------------------------------------------------------+
string GetSymbolString(int Number)
  {
//----
   string res="";
   res=SymbolsArray[Number];  
//----
   return(res);
  }
//+------------------------------------------------------------------+
//| возвращает период                                                |
//+------------------------------------------------------------------+
int PeriodNumber(int number)
   {
   int per_min;
   switch (number)
      {
      case 0: per_min=PERIOD_M1;break;
      case 1: per_min=PERIOD_M5;break;
      case 2: per_min=PERIOD_M15;break;
      case 3: per_min=PERIOD_M30;break;
      case 4: per_min=PERIOD_H1;break;
      case 5: per_min=PERIOD_H4;break;
      default: per_min=PERIOD_D1;break;
      }
   return(per_min);  
   }
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
()
leonid553
Далее вне функции int start() вставляем начало функции определения тренда:
Код
//-------------------------------------------------------------------+
//| определение тренда по четырем последним экстремумам              |
//+------------------------------------------------------------------+
int TrendByWPR(int SymbolNumber,int period_counter)
  {
//----
   int res=0;
   string StringSymbol=GetSymbolString(SymbolNumber);
   int PeiodMinute=PeriodNumber(period_counter);
   int curPos,
   LastUpPos,
   PreLastUpPos,
   LastDownPos,
   PreLastDownPos,
   LastPeak,
   newPos;
   double LastPeakWPR=-1000;
   bool FindUp=true,FindDown=true,SearchCompleted=false;
   double CurWPR=iWPR(StringSymbol,PeiodMinute,PeriodWPR,0);
//----

Т.е. пока задаем переменные. Здесь пока всё ясно, за исключением строки
double LastPeakWPR=-1000; mad.gif
Почему именно =-1000 ? Странно! Ну ладно, - пойдем дальше.... cool.gif
Dimi
Привет! Эта переменная походу нигде не участвует в вычислениях LastPeakWPR=-1000; Хотел посмотреть для чего она нужна просмотрел весь код советника Rosh-a так и не нашел, удалил и скомпилировал. Показало что ошибок нет!!!
leonid553
Да действительно! Эта переменная не задействована. Убираем....
А вот перед определением тренда ещё нужно поставить функцию появления нового бара:

Код
//+------------------------------------------------------------------+
//| признак появления нового бара на периоде номер  period_counter   |
//+------------------------------------------------------------------+
bool isNewBar(int SymbolNumber,int period_counter)
   {
   bool res=false;
   if (IsTesting())
      {
      if (MyBarsArrays[SymbolNumber,period_counter]!=
      iBars(GetSymbolString(SymbolNumber),PeriodNumber(period_counter)))
         {
         MyBarsArrays[SymbolNumber,period_counter]=
         iBars(GetSymbolString(SymbolNumber),PeriodNumber(period_counter));
         //Print("Код ошибки в isNewBar=",GetLastError());
         //Print("isNewBar  SymbolNumber=",SymbolNumber,"  period_counter=",
         //period_counter," MyBarsArrays[SymbolNumber,period_counter]=",
         //MyBarsArrays[SymbolNumber,period_counter],
         //"iBars(GetSymbolString(SymbolNumber),PeriodNumber(period_counter))=",
         //iBars(GetSymbolString(SymbolNumber),PeriodNumber(period_counter))   );
         res=true;
         }
      }
   else
      {
      if (TimeNullArrays[SymbolNumber,period_counter]!=
      iTime(GetSymbolString(SymbolNumber),PeriodNumber(period_counter),0))
         {
         TimeNullArrays[SymbolNumber,period_counter]=
         iTime(GetSymbolString(SymbolNumber),PeriodNumber(period_counter),0);
         res=true;
         }
      }
   return(res);  
   }
leonid553
Начинаем вникать в определение тренда по индикатору WPR:
Код

//=======  определим - где мы находимся в данный момент
   if (CurWPR<=CriteriaWPR-100)
      {//ЕСЛИ значение индикатора WPR на текущем баре меньше или
   //   равно CriteriaWPR-100, то -
      FindDown=false;
      LastPeak=0;
      }  
   if (CurWPR>=-CriteriaWPR)
      {//ЕСЛИ значение индикатора WPR на текущем баре больше или
// равно >=-CriteriaWPR, то -
      FindUp=false;
      LastPeak=0;
      }  
   // ================   начинаем поиск пичков-донышков

Заметим, что так. наз. КритерийWPR=25 мы уже задали во внешних параметрах. И не будем забывать, что WPR на графике располагается в минусовой зоне т.е. имеет шкалу от 0 до "-100".
Иначе говоря, если индюк WPR лежит в областях меньше "-75" либо больше "-25", то :
FindUp=false;
LastPeak=0;
Получается что "-25" и "-75" - это своего рода границы зон перекупленности/перепроданности...

leonid553
Продолжаем....

Код
// ================   начинаем поиск пичков-донышков
   while(!SearchCompleted && curPos<Bars)
      {
      if (iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)>=-CriteriaWPR && LastPeak<0)
         {
         FindUp=false;
         LastPeak=curPos;
         curPos++;
         continue;
         }
        
      if (iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)<=CriteriaWPR-100 && LastPeak<0)
         {
         FindDown=false;
         LastPeak=curPos;
         curPos++;
         continue;
         }
        
      if (iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)>=-CriteriaWPR && FindUp)
         {//искали верхушку и нашли
         newPos=curPos;
         while(iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)>CriteriaWPR-100 && curPos<Bars)
            {// теперь нужно найти донышко, чтобы между ними найти точный пичок
            curPos++;
            }
         if (LastUpPos==0)
            {
            LastUpPos=Highest(StringSymbol,PeiodMinute,MODE_HIGH,curPos-LastPeak,LastPeak);  
            LastPeak=LastUpPos;
            }
         else
            {
            PreLastUpPos=Highest(StringSymbol,PeiodMinute,MODE_HIGH,curPos-LastPeak,LastPeak);
            LastPeak=PreLastUpPos;
            }
         curPos=newPos;
         FindUp=false;
         FindDown=true;
         curPos++;
         continue;
         }//==============

      if (iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)<=CriteriaWPR-100 && FindDown)
         {
         newPos=curPos;
         while(iWPR(StringSymbol,PeiodMinute,PeriodWPR,curPos)<-CriteriaWPR && curPos<Bars)
            {
            curPos++;
            }
         if (LastDownPos==0)
            {
            LastDownPos=Lowest(StringSymbol,PeiodMinute,MODE_LOW,curPos-LastPeak,LastPeak);
            LastPeak=LastDownPos;
            }  
         else
            {
            PreLastDownPos=Lowest(StringSymbol,PeiodMinute,MODE_LOW,curPos-LastPeak,LastPeak);
            LastPeak=PreLastDownPos;
            }
         curPos=newPos;
         FindDown=false;
         FindUp=true;
         curPos++;
         continue;
         }
      if (PreLastDownPos!=0 && PreLastUpPos!=0) SearchCompleted=true;
      curPos++;
      }
   if (Symbol()==StringSymbol && Period()==PeiodMinute)
      {
      Comment("LastUpPos=",LastUpPos,"  PreLastUpPos",PreLastUpPos,"   LastDownPos=",LastDownPos,"  PreLastDownPos=",PreLastDownPos," Время ",TimeToStr(CurTime()));
      SetUpArrows(LastUpPos,PreLastUpPos,LastDownPos,PreLastDownPos);
      }
   LastUpArray[SymbolNumber,period_counter]=LastUpPos;  
   PreLastUpArray[SymbolNumber,period_counter]=PreLastUpPos;  
   LastDownArray[SymbolNumber,period_counter]=LastDownPos;  
   PreLastDownArray[SymbolNumber,period_counter]=PreLastDownPos;  
   if (High[LastUpPos]-High[PreLastUpPos]>=kATR*iATR(StringSymbol,PeiodMinute,ATRPeriod,LastUpPos)&&Low[LastDownPos]>Low[PreLastDownPos]) res=1;    
   if (Low[PreLastDownPos]-Low[LastDownPos]>=kATR*iATR(StringSymbol,PeiodMinute,ATRPeriod,LastDownPos)&&High[PreLastUpPos]>High[LastUpPos]) res=-1;    

   return(res);
  }


Действительно, этот алгоритм определяет наличие "пичков и донышек", перебирая последовательно бары с нулевого. Причем, ищет экстремумы в "зонах перекупленности/перепроданности", согласно показаниям индикатора WPR. Тут всё понятно...
А также, задействует, неким образом, значения индикатора ATR с периодом=40 (по умолч) и коэффициент kATR=0.5; Каким образом?, - пока не стал вникать.
Итак, мы нашли два "пичка" и два "донышка" ...
leonid553
Далее, - отображаем найденные экстремумы на графике! К сожалению, картинка получится не совсем наглядной, т.к. из-за "дебильных" движений цены в прошедшую пятницу по этим экстремумам трудно сделать вывод о наличии или отсутствии тренда.
Тем не менее, - алгоритм эксперта будет отображать стрелками найденные пички и донышке, - см. рис -
Код
/+------------------------------------------------------------------+
//| поставим стрелку                                                 |
//+------------------------------------------------------------------+
void SetArrow(datetime _time,double _price,string _Description ,int _arrowType, color _arrowColor)
   {
   if (ObjectFind(_Description)==-1)
      {
      ObjectCreate(_Description,OBJ_ARROW,0,_time,_price);
      ObjectSet(_Description,OBJPROP_ARROWCODE,_arrowType);
      ObjectSet(_Description,OBJPROP_COLOR,_arrowColor);
      }
   else
      {
      ObjectSet(_Description,OBJPROP_TIME1,_time);
      ObjectSet(_Description,OBJPROP_PRICE1,_price);
      }    
   return;
   }

//+------------------------------------------------------------------+
//| установить стрелки экстермумов                                   |
//+------------------------------------------------------------------+
void SetUpArrows(int firstUpBar, int secondUpBar,int firstDownBar, int secondDownBar)
  {
//----
   SetArrow(Time[firstUpBar],High[firstUpBar],"FirstUp",241,Blue);
   SetArrow(Time[secondUpBar],High[secondUpBar],"SecondUp",241,Blue);
   SetArrow(Time[firstDownBar],Low[firstDownBar],"FirstDown",242,Red);
   SetArrow(Time[secondDownBar],Low[secondDownBar],"SecondDown",242,Red);
//----
   return(0);
  }
  
Moriarty
Цитата(leonid553 @ 7.10.2007, 20:21) *

Продолжаем....
Действительно, этот алгоритм определяет наличие "пичков и донышек", перебирая последовательно бары с нулевого. Причем, ищет экстремумы в "зонах перекупленности/перепроданности", согласно показаниям индикатора WPR. Тут всё понятно...
А также, задействует, неким образом, значения индикатора ATR с периодом=40 (по умолч) и коэффициент kATR=0.5; Каким образом?, - пока не стал вникать.
Итак, мы нашли два "пичка" и два "донышка" ...

Имхо всё черезчур усложнено. Все три последних функции можно описать всего лишь в нескольких строках.
У Роша сделаны универсальные функции, нам же они не нужны. Да и с самого начала можно
70% кода убрать, а то опять будем тестить экспов сутками. Может я конечно и ошибаюсь, но попробую
сейчас по быстрому написать код, определяющий пики/донышки по Т3 сглаженому ВПРу.
А вообще, думаю не совсем правильно использовать ВПР для определения тренда. Есть масса других,
менее затратных и более точных определений тренда...

P.S. Сейчас попробую написать определение Hi/Low ВПРа.

Цитата(leonid553 @ 7.10.2007, 21:02) *

Далее, - отображаем найденные экстремумы на графике! К сожалению, картинка получится не совсем наглядной, т.к. из-за "дебильных" движений цены в прошедшую пятницу по этим экстремумам трудно сделать вывод о наличии или отсутствии тренда.
Тем не менее, - алгоритм эксперта будет отображать стрелками найденные пички и донышке, - см. рис -
Поэтому я и стараюсь не использовать просто ВПР. Со сглаживанием всё выглядит гораздо лучше.
А если подключить ещё и АТР, то косяков станет ещё меньше.

P.S. Кстати, а зачем использовать чужой код (и пытаться понять его), если можно написать свой,
ничуть не хуже и полностью понимаемый ???
leonid553
Здесь немного остановимся! Вот сейчас обнаружил, что нужно добавить ещё глобальные переменные.
double GatorTrend[13,7];// тренд по каждому символу и тайм-фрейму из индикатора NRTR-GATOR (Alligator)
double NRTR_Trend[13,7];// тренд по каждому символу и тайм-фрейму из индикатора NRTR-GATOR (NRTR)
И ещё там кое что добавить. Как-то упустил.
Сильно мешает разбираться мультивалютность советника! В каждой функции из-за неё столько наворочено....
И кстати, обнаружил что советник в тестере не открывает сделок! Стал разбираться. Выяснилось, что эксперт не видит индикатора NRTR_Gator.
Хитрый Rosh вызывает его в эксперте, как "NRTR_Gator", а вот скачивается он по ссылке с другим названием, - "NRTR Gator" - без черты. И понятно, что тут не сразу понять, в чем проблема!
Наверное специально так сделано, - чтобы жизнь малиной не казалась.
Moriarty
Цитата(leonid553 @ 7.10.2007, 21:58) *

Хитрый Rosh вызывает его в эксперте, как "NRTR_Gator", а вот скачивается он по ссылке с другим названием, - "NRTR Gator" - без черты. И понятно, что тут не сразу понять, в чем проблема!
Наверное специально так сделано, - чтобы жизнь малиной не казалась.
Скорее всего это ещё и изменённый гатор (специально под экспа), это конечно мои догадки, просто я и сам постоянно переделываю индюков под экспертов (выкидываю всё лишнее, добавляю доп. буферы и т.д.)...
Иначе какой смысл менять название? плодить лишних индюков?
Moriarty
Вот что у меня получилось с определением пиков/донышек по Т3 сглаженому ВПРу.
Привязал уровни к графику цены из за того, что часто возникают диверы между ценой и ВВПРом.
Как в случаях d и e... В остальном же вроде неплохо получилось. Остаётся только сравнить
два последних верхних или нижних уровня между собой.

Нажмите для просмотра прикрепленного файла



Нажмите для просмотра прикрепленного файла
leonid553
Цитата(Moriarty @ 7.10.2007, 17:54) *

Имхо всё черезчур усложнено. Все три последних функции можно описать всего лишь в нескольких строках.
У Роша сделаны универсальные функции, нам же они не нужны. Да и с самого начала можно
70% кода убрать, а то опять будем тестить экспов сутками. Может я конечно и ошибаюсь, но попробую
сейчас по быстрому написать код, определяющий пики/донышки по Т3 сглаженому ВПРу.
А вообще, думаю не совсем правильно использовать ВПР для определения тренда. Есть масса других,
менее затратных и более точных определений тренда...

P.S. Сейчас попробую написать определение Hi/Low ВПРа.
P.S. Кстати, а зачем использовать чужой код (и пытаться понять его), если можно написать свой,
ничуть не хуже и полностью понимаемый ???

**************************************************************************

Я к сож. не могу пока в силу скромных знаний написать код, который удовлетворительно бы определял, - "тренд/не тренд"
Всё время получается так, что на переломах тренда (даже если он программно определён) всегда получаются убыточные входы и соотв. лоси...
leonid553
А у Роша действительно много лишнего.
Например, итоговое значение тренда определяется как сумма сигналов сразу по нескольким ТФ. Но из своего опыта автоматических сигналов по нескольким тф могу сказать, что достоверность их В СУММЕ невелика! Хотя по отдельности сигналы достаточно бывают хороши.
Лучше, думаю, при автоматич. торговле брать сигналы с одного тф не припутывая противоречивые данные с других.
****************************************************************
Вот сейчас наблюдаю за Вашим, Moriarty, индикатором в вмзуальном режиме.
Если, например, наложить моего эксперта с чемпионата на индикатор, - то заметно, что часть убыточных сделок можно отсеять...
Если, конечно, четко сформулировать условия.
leonid553
В визуальном режиме видно, что советник ProtoType открывает сделки почти всё время - уже на излете тренда! (с параметрами по умолчанию).
И наличие тренда там определяется как результат трех состовляющих:
По индикатору WPR и
double GatorTrend[13,7];// тренд по каждому символу и
тайм-фрейму из индикатора NRTR-GATOR (Alligator)
double NRTR_Trend[13,7];// тренд по каждому символу и
тайм-фрейму из индикатора NRTR-GATOR (NRTR)
Нам пока хватит первого, - по WPR(+ATR), кот. мы уже разобрали.
Программно он определен вроде так:
Код

   if (High[LastUpPos]-High[PreLastUpPos]>=
   kATR*iATR(StringSymbol,PeiodMinute,ATRPeriod,LastUpPos)&&
   Low[LastDownPos]>Low[PreLastDownPos]) res=1;
      
   if (Low[PreLastDownPos]-Low[LastDownPos]>=
   kATR*iATR(StringSymbol,PeiodMinute,ATRPeriod,LastDownPos)&&
   High[PreLastUpPos]>High[LastUpPos]) res=-1;    

   return(res);
  }


Второе выражение (res=-1;) примерно соответствует ситуации, приведенной на графике - Down/trend
Moriarty
Цитата(leonid553 @ 8.10.2007, 23:33) *
Вот сейчас наблюдаю за Вашим, Moriarty, индикатором в вмзуальном режиме.
Если, например, наложить моего эксперта с чемпионата на индикатор, - то заметно, что часть убыточных сделок можно отсеять...
Если, конечно, четко сформулировать условия.
На самом деле это писалось не как индикатор для использования на графике,
а как некая визуализация моего понимания уровней разворотов ВПР (и не только) в коде.
Поэтому не рекомендовал бы его использовать где либо, т.к. там много недоделок
и разных косяков. В общем сырой он ещё совсем. rolleyes.gif
leonid553
Ок!
Вот ещё идея подошла! По граалям... Изложу здесь чтобы мысль не потерялась.
Вспомнилась цитата Ю.Решетова на форуме MQ:
А что касаемо граалей, дык тут большого ума не надо. Надо лишь выполнить ряд условий:
1. Система должна открывать позиции либо вообще без стоплоссов, либо со стоплоссами на очень большом расстоянии, так чтобы вероятность их срабатывания была близка к 0
2. Воткнуть мощный фильтр на базе нескольких индикаторов с условиями срабатывания разделенными по логическому И (&&). И вытащить множество входных параметров этих самых индикаторов во внешние настройки МТС, так чтобы за несколько лет исторических данных на тестах открылось всего несколько позиций.
3. Ко всему этому добавить управление капиталом и риском с задранной фракцией


Первое условие сразу отсекаем! А второе условие будем использовать в соотв. со здравым смыслом.
Итак мы строим советник совершающий сделки "редко но метко" в соотв. с условием 2
При этом используем тактику с 2-3-мя индикаторами.
Пусть он открывает сделки хотя-бы 2-4 раза в месяц. С большой вероятностью выигрыша.
Далее берем другую тактику. С другими индикаторами. И строим второй советник с аналогичным результатом работы.
Далее берем третью тактику ... Ну и так далее... Идея понятна!
Обьединяем в один эксперт десяток-два таких "граалей" и "возрадуемся над оным" !
Думаю, что почти у всех трейдеров есть почти готовые такие тактики ,- с оч. редкими, но гарантированно прибыльными сделками.
Осталось собрать их в одну кучу и соотв. образом обработать.
Тут возможны вырианты:
1. Одну версию ориентировать на длинные позиции,
2. Вторую, - на короткие,
3. Третью, - исполнить по канальной тактике для тренда,
4. .... ... ... и т.п.
Готовы ли посетители ветки поделиться такими версиями в конкретном исполнении? или хотя бы в общем виде?
Вот уже сейчас я уже прикинул пару вариантов ....
Dm_35
Привет.
Очень интересная тема.
Чуть переделал код, тот, что Вы выложили на mql4, хотел собрать тренды с разных временных промежутков, но странно получилось, по идеи независимо от таймфрема, на котором стоит индикатор, тренд должен определяться одинаково, буду очень благодарен, если посмотрите, где-то я наверное накосячил.
Нажмите для просмотра прикрепленного файла
Dimi
Цитата(Dm_35 @ 27.10.2007, 13:22) *

Привет.
Очень интересная тема.
Чуть переделал код, тот, что Вы выложили на mql4, хотел собрать тренды с разных временных промежутков, но странно получилось, по идеи независимо от таймфрема, на котором стоит индикатор, тренд должен определяться одинаково, буду очень благодарен, если посмотрите, где-то я наверное накосячил.
Нажмите для просмотра прикрепленного файла

Привет, всем!!! Все вроде работает!!! Прогнал в визуале на м15 довольно не плохо вроде бы показывает трэнд. Только никак не получается его в советник вставить.... И через iCustom тож не пойму как его вызывать там же буферов нет или я что-то не так делаю..... Скорее всего не понимаю, что делаю wink.gif
Dm_35
Привет.
В советник надо скопировать этот индикатор, и вызывать примерно так: If(TrendByWPR(1)>=0 && TrendByWPR(2)>=0 && ... ) OrderSend(Symbol(),OP_BUY...) и наоборот для селла.
Но мне кажется что ещё рано для советника, разобраться бы почему на разных таймфреймах разные значения выдаёт.
Dimi
Если я правильно понимаю код, то на каждом ТФ ищутся пички и донышки. И по ним уже определяеться трэнд. Логично, что на каждом ТФ в какой-то период будут различные трэнды. К примеру если на м15 трэнд вверх, а на Н4 трэнд в низ, то можно предположить, что на м15 идет коррекция либо перелом и зарождение нового трэнда вверх. В общем здесь надо экспериментировать с ним и использовать его в какой-то системе. Сам по себе этот индюк многого не скажет.

Глянь в личку.
Dm_35
Привет.
Если поставить индикатор на М15 а потом поменять таймфрейм на М30 то результаты будут разные, а так по идеи быть не должно.
leonid553
Всем привет! У меня вот проблемы с инетом. Провайдер задним числом поднял тарифы в неск (!) раз без предупреждения. И соотв. счет прислал заоблачный! Меняю сейчас оператора. И редко (окольными путями) захожу в инет.
На MQL я выкладывал "кастрированный" вариант определителя тренда. ВОТ ОН:
вставляем во внеш. параметры глобальные переменные
//-----------------------------------------------------
extern int PeriodWPR=8;
extern double CriteriaWPR=25;
extern int ATRPeriod=40;// период ATR для индикатора
extern double kATR=0.5;
//-------------------------------------
int LastUpArray[13,7];
int PreLastUpArray[13,7];
int LastDownArray[13,7];
int PreLastDownArray[13,7];
Код

-------------------------------------------------------------------------------------------

Далее вне функции int start() вставляем функцию

/-------------------------------------------------------------------+
//| определение тренда по четырем последним экстремумам |
//+------------------------------------------------------------------+
int TrendByWPR()
{
//----
int res=0;
int curPos,LastUpPos,PreLastUpPos,LastDownPos,PreLastDownPos,LastPeak,newPos;
bool FindUp=true,FindDown=true,SearchCompleted=false;
double CurWPR=iWPR(NULL,0,PeriodWPR,0);
//----
//======= определим - где мы находимся в данный момент
if (CurWPR<=CriteriaWPR-100)
{
FindDown=false;
LastPeak=0;
}
if (CurWPR>=-CriteriaWPR)
{
FindUp=false;
LastPeak=0;
}
// ================ начианем поиск пичков-донышков
while(!SearchCompleted && curPos<Bars)
{
if (iWPR(NULL,0,PeriodWPR,curPos)>=-CriteriaWPR && LastPeak<0)
{
FindUp=false;
LastPeak=curPos;
curPos++;
continue;
}

if (iWPR(NULL,0,PeriodWPR,curPos)<=CriteriaWPR-100 && LastPeak<0)
{
FindDown=false;
LastPeak=curPos;
curPos++;
continue;
}

if (iWPR(NULL,0,PeriodWPR,curPos)>=-CriteriaWPR && FindUp)
{//искали верхушку и нашли
newPos=curPos;
while(iWPR(NULL,0,PeriodWPR,curPos)>CriteriaWPR-100 && curPos<Bars)
{// теперь нужно найти донышко, чтобы между ними найти точный пичок
curPos++;
}
if (LastUpPos==0)
{
LastUpPos=Highest(NULL,0,MODE_HIGH,curPos-LastPeak,LastPeak);
LastPeak=LastUpPos;
}
else
{
PreLastUpPos=Highest(NULL,0,MODE_HIGH,curPos-LastPeak,LastPeak);
LastPeak=PreLastUpPos;
}
curPos=newPos;
FindUp=false;
FindDown=true;
curPos++;
continue;
}//==============

if (iWPR(NULL,0,PeriodWPR,curPos)<=CriteriaWPR-100 && FindDown)
{
newPos=curPos;
while(iWPR(NULL,0,PeriodWPR,curPos)<-CriteriaWPR && curPos<Bars)
{
curPos++;
}
if (LastDownPos==0)
{
LastDownPos=Lowest(NULL,0,MODE_LOW,curPos-LastPeak,LastPeak);
LastPeak=LastDownPos;
}
else
{
PreLastDownPos=Lowest(NULL,0,MODE_LOW,curPos-LastPeak,LastPeak);
LastPeak=PreLastDownPos;
}
curPos=newPos;
FindDown=false;
FindUp=true;
curPos++;
continue;
}
if (PreLastDownPos!=0 && PreLastUpPos!=0) SearchCompleted=true;
curPos++;
}
/* if (Symbol()==StringSymbol && Period()==PeiodMinute)
{
Comment("LastUpPos=",LastUpPos," PreLastUpPos",PreLastUpPos,"
LastDownPos=",LastDownPos," PreLastDownPos=",PreLastDownPos,
" Время ",TimeToStr(CurTime()));
SetUpArrows(LastUpPos,PreLastUpPos,LastDownPos,PreLastDownPos);*/
LastUpArray[NULL,0] =LastUpPos;
PreLastUpArray[NULL,0]=PreLastUpPos;
LastDownArray[NULL,0]=LastDownPos;
PreLastDownArray[NULL,0]=PreLastDownPos;
if (High[LastUpPos]-High[PreLastUpPos]>=kATR*iATR(NULL,0,ATRPeriod,LastUpPos)
&&Low[LastDownPos]>Low[PreLastDownPos]) res=1;
if (Low[PreLastDownPos]-Low[LastDownPos]>=kATR*iATR(NULL,0,ATRPeriod,LastDownPos)
&&High[PreLastUpPos]>High[LastUpPos]) res=-1;

return(res);
} -----------------------------------------------------------------------------------


Чтобы в углу на графике отображалась функция нужно внутри int start() вставить -
Comment (TrendByWPR());
Тогда :
TrendByWPR()=0 - нет тренда
TrendByWPR()=1 -up-тренд
TrendByWPR()=-1 - down-тренд
Это всё расчитывается по одному тф, - на кот. мы ставим советник.
Но если взять "не кастрированный" кусочек кода (с массивами), - то он расчитывает функцию сразу по нескольким тф и выдается суммарный вариант и отображается на графике в углу- по каждому тф ! Да и ещё отображает стрелками последние экстремумы.
Dm_35
Привет.
Я на пред. станице выложил свою версию Вашей версии советника Роша smile.gif, посмотрите, если не трудно, там не суммарный вариант, а разбивка по таймфреймам и с этим как раз проблема т.к. по идеи не зависимо от таймфрейма где установлен индюк, тренд должен показываться одинаково, но этого почему-то не происходит.
leonid553
Цитата(Dm_35 @ 28.10.2007, 23:27) *

Привет.
Если поставить индикатор на М15 а потом поменять таймфрейм на М30 то результаты будут разные, а так по идеи быть не должно.

Именно так и должно быть! На разных тф последние экстремумы (- пики и донышки) могут существенно отличаться! Особенно на тф - напр. М5 от Н4
Кроме того пики и донышки КОД определяет вдобавок ещё и по показаниям индюков iWPR и iATR. Тут уж вообще полный разнос! На М5 может быть тренд, а на Н1 - это всего лишь малый участок коррекции!

А вообще то оч. неплохой индикатор получился! , Благодарю, Dm_35.
Но вот в советнике его использовать надо как-то не просто, складывая или сравнивая нули и единички от разных тф. Тут, пожалуй, нужно подумать...
Dm_35
Привет.
Это Вам спасибо за огромную работу, у меня была такая же мысль, но духу не хватило подступиться.
Боюсь советник только на этом не будет прибыльным, не зря Рош ещё туда и индикатор вставил.
Plastик
double vol_long= (iClose(NULL,0,1)- iOpen(NULL,0,1))*10000; // белая свеча
double vol_short= (iOpen(NULL,0,1)- iClose(NULL,0,1))*10000; // темная свеча
double vol = (iHigh(NULL,0,1)- iLow(NULL,0,1))*10000;

Леонид!
1)А разве последняя 1 это не сдвиг на бар назад???
2)И второй параметр 0, а не 1440?
3)умножение на 10000 на фуе не покатит

что думаешь?

leonid553
Умножение как раз необходимо! Вот смотри :
Чтобы задать размер свечи в пунктах надо от хая отнять лоу, например -
2.0850 - 2.0750 = 0.0100 , умножаем на 10000 и получаем значение в пунктах - 100 пипсов
------------------------------------------------------------------------
Второй параметр - 0, для того чтобы можно было использовать эксперт не только на тф=Д, но и на любом другом.
Т.е. эксперт будет работать на том графике(таймфрейме), на котором он стоит.
----------------------------------------------------------------------------
Последняя единичка - это предыдуший бар. Потому что текущий бар - пока еще не сформировался! Он только что открылся и вместо него (в момент открытия) пока точка стоит.
Т.е. У ТЕКУЩЕГО БАРА В МОМЕНТ ОТКРЫТИЯ
OPEN=CLOSE=HIGHT=LOW

Точно! Для Фуя надо на 100 умножать! Или в СВОЙСТВАХ эксперта задавать BarSize_long =100; не 100 пипсов, а 1
Plastик
Цитата(leonid553 @ 2.11.2007, 17:07) *

Умножение как раз необходимо! Вот смотри :
Чтобы задать размер свечи в пунктах надо от хая отнять лоу, например -
2.0850 - 2.0750 = 0.0100 , умножаем на 10000 и получаем значение в пунктах - 100 пипсов
------------------------------------------------------------------------
Второй параметр - 0, для того чтобы можно было использовать эксперт не только на тф=Д, но и на любом другом.
Т.е. эксперт будет работать на том графике(таймфрейме), на котором он стоит.
----------------------------------------------------------------------------
Последняя единичка - это предыдуший бар. Потому что текущий бар - пока еще не сформировался! Он только что открылся и вместо него (в момент открытия) пока точка стоит.
Т.е. У ТЕКУЩЕГО БАРА В МОМЕНТ ОТКРЫТИЯ
OPEN=CLOSE=HIGHT=LOW

Ну так а нам то надо параметры текущего дневного бара. Нафиг нам прошлый то

про умножение на 10000 я не спорю - у всех кто 4 цифры после запятой - а вот у кого 2 - не пойдет!

Для расчета данных НЕ нужен другой ТФ - строго запрещен!!! другой ТФ. Он должен БРАТЬ данные только за день потому, что значит будет работать на другом ТФ? ИМХО при таких параметрах он и данные будет брать НЕ с дневной текущей свечи, а это не правильно!
leonid553
Понял. Тогда надо определиться с моментом входа.
Я то думал, что мы оцениваем уже сформировавшийся бар. И по результатам оценки принимаем решение, - открыть позицию или нет.
Получается алгоритм должен быть такой:
Вот открылся бар (в 0:00ч.). Далее советник пассивно ждет, когда (и если) этот бар вырастет до заданного нами значения (в твоем примере BarSize_long(short)- до 100 пипсов). Если такое случилось, - то мы входим в рынок, - по направлению движения бара.
Если бар не достиг этого значения, - отслеживаем следующий... ?
leonid553
Вот вроде - то что надо. Но коэф.=10000 пока оставил. Для Фуя задавать размер с учетом этого!
Работает в рЕжиме по ВСЕМ ТИКАМ

Код

double vol_long = (iHigh(NULL,1440,0)- iOpen(NULL,1440,0))*10000;
double vol_short= (iOpen(NULL,1440,0)- iLow(NULL,1440,0))*10000;

  Comment (vol_long);
  Comment (vol_short);
//===== Ищем возможность войти в рынок ==========================================

int Orders=OrdersTotal ();     //получаем кол-во открытых ордеров
if (Orders==0)                 //если нет открытых ордеров
  {

//---------проверяем условие на покупку----------------------------
  if   (  
                   (vol_long>BarSize_long )  )
   {
  ...   }
//--------проверяем условие на продажу------------------------------
  if  (
                  (vol_short>BarSize_short))
leonid553
Похоже ещё надо добавить "блокировку". Чтобы на одном баре - не более одной сделки было....
Plastик
Цитата(leonid553 @ 2.11.2007, 17:54) *

Понял. Тогда надо определиться с моментом входа.
Я то думал, что мы оцениваем уже сформировавшийся бар. И по результатам оценки принимаем решение, - открыть позицию или нет.
Получается алгоритм должен быть такой:
Вот открылся бар (в 0:00ч.). Далее советник пассивно ждет, когда (и если) этот бар вырастет до заданного нами значения (в твоем примере BarSize_long(short)- до 100 пипсов). Если такое случилось, - то мы входим в рынок, - по направлению движения бара.
Если бар не достиг этого значения, - отслеживаем следующий... ?

Абсолютно верно! Только не забываем что бары у нас дневные!
И если я правильно понял ты теперь считаешь длину бара от оупена, а надо как в предыдущей версии от лоя до хая(предыдущя яверсия хорошо, тока на брала данные из предыдущей свечи, а надо из текущей!
И проверку на один открытый ордер в день тоже надо!

Почему то у меня пишет вот чего:
2007.11.02 22:19:42 TestGenerator: unmatched data error (volume limit 518 at 2007.06.29 20:00 exceeded)
Plastик
А вот еще вариантец
2007.11.02 22:24:45 TestGenerator: unmatched data error (high value 1.9782 at 2007.06.08 06:15 and price 1.9783 mismatched
2007.11.02 22:24:45 TestGenerator: unmatched data error (volume limit 12 at 2007.06.05 20:30 exceeded)
2007.11.02 22:24:45 TestGenerator: unmatched data error, rest errors will not be logged

leonid553
Ты, похоже, сам запутался! Как же я могу считать текущий бар от LOW до HIGHT, если он у нас еще не закрылся! У нас на текущем баре есть цена открытия и один из экстремумов! - или ЛОУ или ХАЙ ! - больше пока ничего нет.
Вот я и вычисляю величину бара от цены открытия до экстремума!
В закачке - версия строго для иеновых пар . Дневные свечи. По всем тикам.
С ЯНВ. 2007г. GBPJPY, D
Качество моделирования 90.00%
Начальный депозит 10000.00
Чистая прибыль 356.55
Общая прибыль 4329.64
Общий убыток -3973.09
Прибыльность 1.09
Матожидание выигрыша 2.49
Абсолютная просадка 517.82
Максимальная просадка 825.09 (8.00%)
Относительная просадка 8.00% (825.09)
Всего сделок 143
Короткие позиции (% выигравших) 73 (69.86%)
Длинные позиции (% выигравших) 70 (68.57%)
Прибыльные сделки (% от всех) 99 (69.23%)
Убыточные сделки (% от всех) 44 (30.77%)
Самая большая
прибыльная сделка 51.54
убыточная сделка -96.59
Средняя
прибыльная сделка 43.73
убыточная сделка -90.30
Максимальное количество
непрерывных выигрышей (прибыль) 12 (516.73)
непрерывных проигрышей (убыток) 5 (-453.33)
Максимальная
непрерывная прибыль (число выигрышей) 516.73 (12)
непрерывный убыток (число проигрышей) -453.33 (5)
Средний
непрерывный выигрыш 3
непрерывный проигрыш 1
----------------------------------------------------------------------------
Надо оптимизировать параметры. И попробовать с тралом погонять.
Код
//+------------------------------------------------------------------+
//|Stochastic_Env.mq4.mq4
//| leonid553
//| http://www.tradersforum.net.ru/
//+------------------------------------------------------------------+
#property copyright "leonid553 & co"
#property link      "http://www.tradersforum.net.ru/"

//---- input parameters---------
extern int     MagicNum    =6784;

extern int     BarSize_long    =100;
extern int     TP_long         =50;
extern int     SL_long         =100;

extern int     BarSize_short    =100;
extern int     TP_short         =50;
extern int     SL_short         =100;
//------------------------------
extern bool UseTrailing = false;
extern int lMinProfit = 30;
extern int sMinProfit = 30;
extern int lTrailingStop = 30;
extern int sTrailingStop = 30;
extern int lTrailingStep = 5;
extern int sTrailingStep = 5;

extern double  Lot=0.1;
extern int     Slippage=3;
//-- Подключаемые модули --
#include <stdlib.mqh>
//-------------------
int ticket;
int         ExpertBars;
static bool ZeroBarOrd;
//*********************************************************************

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
ExpertBars = Bars;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
  
//----
   return(0);
  }

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
bool isNewBar=false;
if (ExpertBars !=Bars) {ExpertBars=Bars; isNewBar=true; }  

int _Order=isExpertOrder();


if (isNewBar) {
if (_Order!=0) ZeroBarOrd=true;  //есть ордер
else           ZeroBarOrd=false; //нет ордера
}
    if (UseTrailing) TrailPositions();
//*********************************************************************

double vol_long = (iHigh(NULL,1440,0)- iOpen(NULL,1440,0))*100;
double vol_short= (iOpen(NULL,1440,0)- iLow(NULL,1440,0))*100;

  Comment (vol_long);
  Comment (vol_short);
//===== Ищем возможность войти в рынок ==========================================

int Orders=OrdersTotal ();     //получаем кол-во открытых ордеров
if (Orders==0)                 //если нет открытых ордеров
  {
if (!ZeroBarOrd) {      
//---------проверяем условие на покупку----------------------------
  if   (  
          //(vol_>0)  &&
          (vol_long>BarSize_long )  )
   {
  ticket=OrderSend(Symbol(),0,Lot,Ask,Slippage,Bid-SL_long *Point,
                                      Ask+TP_long *Point,NULL,MagicNum ,0,Green);
  if (ticket<0) { Print("Ошибка открытия ордера BUY #", GetLastError()); return (0); }      
   else ZeroBarOrd=true;
   }
//--------проверяем условие на продажу------------------------------
  if  (
          //(vol_<0)  &&
           (vol_short>BarSize_short))
   {      
  ticket=OrderSend(Symbol(),1,Lot,Bid,Slippage,Bid+SL_short*Point,
                                       Bid-TP_short *Point,NULL,MagicNum ,0,Blue);
if (ticket<0) { Print("Ошибка открытия ордера BUY #", GetLastError()); return (0); }            
  else ZeroBarOrd=true;
   }  
//------------------------------------------------------------------
}
   }
  return(0);
  }
  //****************************************************************
void TrailPositions()
{
  int Orders = OrdersTotal();
  for (int i=0; i<Orders; i++) {
    if (!(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))) continue;
    if (OrderSymbol() != Symbol()) continue;  

    if (OrderType() == OP_BUY) {
      if (Bid-OrderOpenPrice() > lMinProfit*Point) {
        if (OrderStopLoss() < Bid-(lTrailingStop+lTrailingStep-1)*Point) {
          OrderModify(OrderTicket(), OrderOpenPrice(), Bid-lTrailingStop*Point,
                                                      OrderTakeProfit(), 0, Blue);
        }}}
    if (OrderType() == OP_SELL) {
      if (OrderOpenPrice()-Ask > sMinProfit*Point) {
        if (OrderStopLoss() > Ask+(sTrailingStop+sTrailingStep-1)*Point ||
                                                             OrderStopLoss() == 0) {
          OrderModify(OrderTicket(), OrderOpenPrice(), Ask+sTrailingStop*Point,
                                                        OrderTakeProfit(), 0, Blue);
        }}}}}
//-------------------------------------------------------------------+
//=======================================================================================
//| Функция проверки наличия ордеров эксперта |==========================================
//| 0 - ордеров нет                           |==========================================
//| 1 - есть ордер Buy                        |==========================================
//| 2 - есть ордер Sell                       |==========================================
//=======================================================================================
int isExpertOrder() {

int _OrdersTotal=OrdersTotal();

//---------- При тестировании проводим упрощённую проверку ордеров.
if (IsTesting())                               {              
  if (_OrdersTotal==0) return (0);
  
  for (int i=0; i<_OrdersTotal; i++)               {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderType()==OP_BUY)  {return(1); break;  }    
      if (OrderType()==OP_SELL) {return(2); break; }
    }        
  }
}
leonid553
Цитата(Plastик @ 2.11.2007, 19:26) *

А вот еще вариантец
2007.11.02 22:24:45 TestGenerator: unmatched data error (high value 1.9782 at 2007.06.08 06:15 and price 1.9783 mismatched
2007.11.02 22:24:45 TestGenerator: unmatched data error (volume limit 12 at 2007.06.05 20:30 exceeded)
2007.11.02 22:24:45 TestGenerator: unmatched data error, rest errors will not be logged

А это не советник виноват. А твоя невнимательность! tongue.gif
smile.gif
leonid553
У тебя, видимо, нет котировок с разных тф на истории. Нужно подкачать по всем тф. Советник-то по всем тикам работает. Попробуй поставить дату в тестере с 1 окт. 2007 по " сегодня" ...
Plastик
Цитата(leonid553 @ 2.11.2007, 22:32) *

Ты, похоже, сам запутался! Как же я могу считать текущий бар от LOW до HIGHT, если он у нас еще не закрылся! У нас на текущем баре есть цена открытия и один из экстремумов! - или ЛОУ или ХАЙ ! - больше пока ничего нет.

Как это только открытие и один из экстремумов?? Я не согласен. Сначало есть открытие - потом например цена пошла вниз - до какого то момента у нас есть только опен и лоу(оно же равно клоуз и текущей цене). Потом цена остановилась и пошла вверх - в этот момент у нас есть опен, лоу и клоуз(текущая цена). Когда цена поднимется выше опен - сделает хай и откатит назад, то у нас будет и ЛОУ и ХАЙ и опен и слоуз(текущая цена). Вот нужна длина от хай до лоу
Plastик
Цитата(leonid553 @ 2.11.2007, 23:20) *

У тебя, видимо, нет котировок с разных тф на истории. Нужно подкачать по всем тф. Советник-то по всем тикам работает. Попробуй поставить дату в тестере с 1 окт. 2007 по " сегодня" ...

парадокс заключается в том, что это гадство происходит если стоит галочка у визуализации. Без нее все работает.
Plastик
Символ GBPUSD (Great Britan vs US Dollar)
Период День (D1) 2007.08.17 00:00 - 2007.11.01 00:00 (2007.08.17 - 2007.11.02)
Модель Все тики (наиболее точный метод на основе всех наименьших доступных таймфреймов)
Параметры MagicNum=6784; BarSize=69; TP=30; SL=66; UseTrailing=false; lMinProfit=30; sMinProfit=30; lTrailingStop=30; sTrailingStop=30; lTrailingStep=5; sTrailingStep=5; Lot=0.1; Slippage=5;

Баров в истории 2172 Смоделировано тиков 349072 Качество моделирования 90.00%
Ошибки рассогласования графиков 120

Начальный депозит 10000.00
Чистая прибыль 497.46 Общая прибыль 1169.38 Общий убыток -671.92
Прибыльность 1.74 Матожидание выигрыша 10.15
Абсолютная просадка 18.00 Максимальная просадка 204.92 (2.01%) Относительная просадка 2.01% (204.92)

Всего сделок 49 Короткие позиции (% выигравших) 23 (69.57%) Длинные позиции (% выигравших) 26 (88.46%)
Прибыльные сделки (% от всех) 39 (79.59%) Убыточные сделки (% от всех) 10 (20.41%)
Самая большая прибыльная сделка 30.08 убыточная сделка -70.00
Средняя прибыльная сделка 29.98 убыточная сделка -67.19
Максимальное количество непрерывных выигрышей (прибыль) 12 (360.08) непрерывных проигрышей (убыток) 2 (-136.00)
Максимальная непрерывная прибыль (число выигрышей) 360.08 (12) непрерывный убыток (число проигрышей) -136.00 (2)
Средний непрерывный выигрыш 4 непрерывный проигрыш 1


Почему то не работает режим визуализации пишет что и писал. Но заглянув ручками в убыточные дни пришла на ум однозначная мысль. После срабатывания Стоплоса надо переворачиваться. Т.е надо добавить в эксперт возможность выставлять обратный ордер на расстоянии заданном пользователем, а там ручками по эксперементировать опять таки на каом уровне он должен стоять.
leonid553
Такой результат не проходит!
"Ошибки рассогласования графиков 120 " - это недостоверный результат. В онлайне будет слив....
Вот в этом адресе http://forum.mql4.com/ru/5408
скачай мт4 (последний билд)- пост. 1 и загрузи котировки по нужной паре СТРОГО ТАК, как там описано. История сама будет сконвертирована по всем тф! Ну и демо счет открой. И у тебя всегда будет качественная история по всем тф с 1999г.
И все проблемы с тестированием снимутся...

И при тестировании (и оптимизации) лучше брать историю хотя бы с янв. 2007г , иначе получается обычная подгонка вместо оптимизации.
leonid553
Поймать тренд .... smile.gif
cool.gif
Dimi
Привет всем! Тут вот интересный скрипт, не помню где, скачал, мож кому пригодится

Нажмите для просмотра прикрепленного файла - но исходника у меня к сожалению нет.... unsure.gif

Вот его описание
____________________________________________________________________________________________________
____
ZZ_All Quotings 0-0050.mq4
Copyright © Zhunko
MF ZHUNKO zhunko@mail.ru
27.03.2007 - 09.05.2007
____________________________________________________________________________________________________
____
Скрипт для закачки истории по всем валютным парам и металлам.
С последующим контролем на "дыры" в истории.
В связи с функциональным расширением, скрипт "ZZ_All Quotings Exchange+Metals 0-0050"
переименован в "ZZ_All Quotings 0-0050". Перед использованием скрипта установите в МТ4 (сервис --> настройки --> графики) нужное максимальное количество баров в окне. Именно это количество баров будет загружаться и контролироваться. За тем перезагрузите МТ4 и воспользуйтесь скриптом.
Конец работы скрипта не означает конец загрузки истории. Процесс загрузки можете посмотреть в диспетчере задач (правая кнопка мыши на панели задач, вкладка «Сеть»). По окончании загрузки истории необходимо перезагрузить МТ4 для её сохранения в файлах *.hst.

ИЗМЕНЕНИЯ и ДОПОЛНЕНИЯ.
1.Дополнения в версии ZZ_All Quotings Exchange+Metals 0-0020 от 28.03.2007.
1.1.Изменён алгоритм опроса на наличие баров в истории.
1.2.Полная информация о дефектных барах выводится в файлы.
Валютные пары : ZZ_All_Quotings_Exchange_InCorrect.txt;
Металлы: ZZ_All_Quotings_Metals_InCorrect.txt.
2.Дополнения в версии ZZ_All Quotings Exchange+Metals 0-0030 от 31.03.2007.
2.1.Изменён принцип контроля загрузки.
2.2.Введён визуальный контроль всех процессов.
2.3.Введён полный контроль всей загруженной истории.
2.4.В файл записываются только интервалы отсутствия баров.
3.Дополнения в версии ZZ_All Quotings Exchange+Metals 0-0040 от 31.03.2007.
3.1.Введены диалоговые окна. Теперь можно подтвердить или отказаться от загрузки валютных
пар, металлов и контроля дефектных интервалов истории.
4.Дополнения в версии ZZ_All Quotings Exchange+Metals 0-0050 от 06.05.2007.
4.1.Устранена ошибка в создании файлов. Пустые файлы создавались при отказе от контроля на
"дыры" в истории.
4.2.Увеличено количество групп инструментов. Включены все инструменты "Alpari Ltd.",
"Forex Best", "MoneyRein Corporation", "North Finance Company Ltd" и основные инструменты "North-West Financial Broker".
5.Дополнения в версии ZZ_All Quotings 0-0050 от 09.05.2007.
5.1.Всвязи с функциональным расширением скрипт "ZZ_All Quotings Exchange+Metals 0-0050"
в "ZZ_All Quotings 0-0050".
___________________________________________________________________________________________


Dimi
Вот мое первое творение, если можно так сказать wink.gif . Индикатор, который показывает направление луча ZigZag на разных ТФ : минус 1 - луч направлен вниз, плюс 1- соответственно вверх.

Нажмите для просмотра прикрепленного файла

Для использования его в эксперте необходимо функцию TrendByZigZag вставить перед int start()

//+------------------------------------------------------------------+
//| Функция определение трэнда по лучу ZigZag |
//+------------------------------------------------------------------+
double TrendByZigZag(int period_counter)
{
int trend;
int GrossPeriod=PeriodNumber(period_counter);
int limit=300,bigshift;
double zigzag1;
//----

{
if(Time[1]>=daytimes[0]) bigshift=0;
else
{
bigshift = ArrayBsearch(daytimes,Time[1-1],WHOLE_ARRAY,0,MODE_DESCEND);
if(Period()<=GrossPeriod) bigshift++;
}
for (int cnt=bigshift; cnt<(100+bigshift); cnt++)
{
zigzag1=iCustom(NULL,GrossPeriod,"ZigZag",5,5,3,0,cnt+1);
if ( zigzag1!=0 ) break;
}

if ( iClose(NULL,0,1+1)<=zigzag1 ) trend=-1;
if ( iClose(NULL,0,1+1)>=zigzag1 ) trend=1;
}
return(trend);
}
//**********************************************************************************
int PeriodNumber(int number)
{
int per_min;
switch (number)
{
case 1: per_min=15;break;
case 2: per_min=60;break;
case 3: per_min=240;break;
case 4: per_min=1440;break;
}
return(per_min);
}
//**********************************************************************************

Было бы еще не плохо, если б кто-нибудь подсказал как эту функцию задать в эксперте один бар назад...
Dimi
Привет, всем!!! Вот индикатор для МТ4 для расчёта точек вращения. Пару лет назад делал для себя. До сих пор пользуюсь. Линии рассчитываются по формулам:
Точка Вращения P: ( H + L + C ) / 3
Сопротивление 1 : P * 2 - L
Поддержка 1: P * 2 - H

где:
H = Максимум,
L = Минимум,
C = Закрытие цен предшествующего торгового дня, часа, недели и т.д.

а вот Сопротивление 2, 3 и Поддержка 2, 3 рассчитываются немного иначе... Если хотите, чтоб они рассчитывались по тем формулам, что на сайте, которую Леонид дал, то просто измените их в коде на:

Сопротивление 2: P + H - L
Поддержка 2 : P - H + L

Нажмите для просмотра прикрепленного файла

И еще... На периодах от М1 до D1 расчёт происходит по предыдущему дню, а на периодах W1 и MN по предыдущей неделе. Ну вроде бы все написал... Пользуйтесь на здоровье!!! wink.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.