торговая стратегия на базе Волновой теории Эллиота - страница 22

 
Я вот по описанию с этого сайта http://impb.psn.ru/~sychyov/html/soft.shtml
скачал программу, которая расчитывает показатель Хёрста. В скрипте сформировал файл цен отрытия баров.
Открыл файл программой и программа посчитала показатель Хёрста. Но только какую бы выборку я не выбирал программа всегда выдаёт значения показателя, приближающиеся к 1. Но это ведь не укладывается в рамки теории? То есть на разных выборках показания должны меняться от 0 до 1? А в этой программе этот показатель прямо как приклеился к цифре 1 :o(. А так вообще я уже обрадовался, что готовые функции расчёта на сайте выложены. А теперь опасаюсь по ним что-то расчитывать.

А у меня пока что этот коэффициент лежит в пределах 0.21-0.39. И не понятно почему :o(.
Вот мой код скрипта, за основу которого я взял Ваш код:
//+------------------------------------------------------------------+
//|                                                        Herst.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net"
#property show_inputs

extern int start_bar=500;
extern int end_bar=0;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A,8));

double disp=dispercia(viborka,S_A);
Print("Дисперсия выборки = ",DoubleToStr(disp,8));

double S=CKO(disp);
Print("СКО выборки (размах) = ",DoubleToStr(S,8));

double pMin=Low[Lowest(NULL,0,MODE_LOW,size_of_array,end_bar)];
double pMax=High[Highest(NULL,0,MODE_HIGH,size_of_array,end_bar)];
double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
if( (R>0)&&(S>0)) Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}


//функция для расчёта дисперсии
double dispercia(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-1);
   return(disper);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}


Vladislav, может быть Вы просто взглянете и скажете где нужно что подправить для корректного вычисления коэффициента? Ведь согласно теории все вычисления элементарные и где у меня ошибка даже и не знаю :o(

 
Что у Вас выбирается в качестве переменной centr когда Вы осуществляете вызов функции для расчета дисперсии ? Там, как минимум, должен быть массив с прогнозируемыми значениями - вы же прогноз для каждого бара делаете или делали, обратным прогоном и смотрите на точность прогноза - все еще удовлетворяет или нет.
И потом такое количество вызовов функций на алгоритме, который и без того не сильно облегчен расчетами..... ИМХО тормозить будет значительно. (Вызов функции самая длительная по времени процедура, потом идет операция деления с плавающей точкой).
А чем не устроил стандартный алгоритм расчета стандартного отклонения ? Он есть в поставке - только там за прогноз берется значение мувинга на соответствующем баре - возьмите то, что Вам нужно - это оно и есть и никаких вызовов функций. Просто пробежались циклом по массиву взяли квадраты разниц от прогнозируемой цены на данном баре с той, что получилась реально, потом корень квадратный один раз - всего делов.

Удачи и попутных трендов.
 

http://forex.ua/forum/viewtopic.php?t=1574
http://forex.ua/forum/viewtopic.php?t=1634&postdays=0&postorder=asc&start=50
Здесь было краткосрочное сравнение прогнозов по ФА и ТА (после того как некоторое количество флэма в ветке просто достало).
http://forex.ua/forum/viewtopic.php?t=1780

Спасибо за ссылки! Почитал. Очень содержательно! Мне это ещё раз подтвердило, что я правильно понимаю суть Вашей стратегии. Уже сам стал что-то программировать в этом направлении. О стоящих на повестке дня текущих проблемах уже написал выше. Но даже первые полученные результаты расчётов весьма впечатляют! Действительно пока сам не попробуешь не сможешь понять почему всё на самом деле происходит так как Вы говорите! Именно в этом и заключается столь низкая популярность сложноописываемой Вашей стратегии среди основной массы трейдеров. Куда гораздо привлекательнее смотреть на красивые разноцветные графики разных осцилляторов ;o) и почитывать разных платных аналитиков, чем подойти к вопросу игры на Форекс на основе знаний, накапливаемых людьми уже в течение весьма длительного времени. Хотя в принципе пока сохраняется такое положение вещей - до тех пор возможно будет неплохо зарабатывать на Форексе!
 
Хотя в принципе пока сохраняется такое положение вещей - до тех пор возможно будет неплохо зарабатывать на Форексе!


:).

Удачи и попутных трендов.
 
Что у Вас выбирается в качестве переменной centr когда Вы осуществляете вызов функции для расчета дисперсии ? Там, как минимум, должен быть массив с прогнозируемыми значениями - вы же прогноз для каждого бара делаете или делали, обратным прогоном и смотрите на точность прогноза - все еще удовлетворяет или нет.
И потом такое количество вызовов функций на алгоритме, который и без того не сильно облегчен расчетами..... ИМХО тормозить будет значительно. (Вызов функции самая длительная по времени процедура, потом идет операция деления с плавающей точкой).
А чем не устроил стандартный алгоритм расчета стандартного отклонения ? Он есть в поставке - только там за прогноз берется значение мувинга на соответствующем баре - возьмите то, что Вам нужно - это оно и есть и никаких вызовов функций. Просто пробежались циклом по массиву взяли квадраты разниц от прогнозируемой цены на данном баре с той, что получилась реально, потом корень квадратный один раз - всего делов.
Полностью с Вами согласен! Тормоза в будущем будут страшными при массовых расчётах, хотя на мелких расчётах сейчас пока что не заметно. Но это вызвано пока что разработкой самого алгоритма, по которому затем всё будет расчитываться. Такое обилие примитивнейших функций вызвано просто удобством (ну по крайней мере мне так кажется :o)) использования при поиске алгоритма. То есть эти функции СКО, Дисперсия, Среднее арифметическое, я просто использую во многих других вещах. Когда будет всё станет ясно -что считать и каким образом, а также объёмы вычислений, то естественно будет всё соптимизировано. Ну а пока что имеем - то и используем - так сказать первые прикидки на коленке ;o).
В этом примере я использовал в качестве переменной centr среднее арифметическое по выборке.
Также вчера пробовал в качестве этой переменной задавать линию линейной регрессии. То есть тогда мы получаем, что S=СКО ошибок линейной регрессии. Но почему-то результат также не впечатлил меня :o(.
Привожу код срипта, в котором за прогноз мы берём линию линейной регрессии. Тем более, что текущий тренд по EURUSD этому как нельзя кстати подходит.
//+------------------------------------------------------------------+
//|                                                        Herst.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property show_inputs

extern int start_bar=500;
extern int end_bar=0;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10],oshibki_lin_reg[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
ArrayResize(oshibki_lin_reg, size_of_array);

for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A_viborki=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A_viborki,8));

//-----Расчёт коэффициента a уравнения линейной регрессии
double sred_znach_i=(size_of_array-1)/2.0; //среднее значение по оси индекса
double a_lin_regres=0;//коэффициент a линейной регрессии
double buffer=0;

for(i=size_of_array-1;i>=0;i--)
{
   a_lin_regres=a_lin_regres+(i-sred_znach_i)*(viborka[i]-S_A_viborki);
   buffer=buffer+MathPow((i-sred_znach_i),2);
}
a_lin_regres=a_lin_regres/buffer;
Print("a_lin_regres = ",DoubleToStr(a_lin_regres,8));

//-----Расчёт коэффициента b уравнения линейной регрессии
double b_lin_regres=S_A_viborki-a_lin_regres*sred_znach_i;
Print("b_lin_regres = ",DoubleToStr(b_lin_regres,8));

//-----Расчёт ошибок линейной регрессии
for(i=size_of_array-1;i>=0;i--) oshibki_lin_reg[i]=viborka[i]-(a_lin_regres*i+b_lin_regres);

double S_A_oshibok;//среднее значение ошибок линейной регрессии
S_A_oshibok=srednee_arifmeticheskoe(oshibki_lin_reg);
Print("Среднее значение ошибок = ",DoubleToStr(S_A_oshibok,8));

double disp_oshibok=dispercia_oshibok(oshibki_lin_reg,S_A_oshibok);
Print("Дисперсия ошибок= ",DoubleToStr(disp_oshibok,8));

double S=CKO(disp_oshibok);
Print("S= ",DoubleToStr(S,8));

double pMin=0;
double pMax=0;
for(i=size_of_array-1;i>=0;i--)
{  
   if(oshibki_lin_reg[i]<pMin) pMin=oshibki_lin_reg[i];
   if(oshibki_lin_reg[i]>pMax) pMax=oshibki_lin_reg[i];
}

double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта дисперсии ошибок
double dispercia_oshibok(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-2);
   return(disper);
}

//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}


Берём период H1 на EURUSD. Берём выборку 500 баров - коэф Хёрста = 0.26
300 баров - 0.31, 100 баров - 0.39, 30 баров - 0.51. Не понятно почему :o(.

Будем ещё пробовать рекомендованный Вами мувинг. Хотя чем принципиально будут отличаться результаты от того, что есть пока что ещё не ясно.

 
УРА! Похоже, что я разобрался с тем как считать Хёрста. Вот привожу текст скрипта, где показатель расчитывается относительно канала линейной регрессии.
//+------------------------------------------------------------------+
//|                                                Herst_lin_reg.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property show_inputs

extern int start_bar=800;
extern int end_bar=570;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10],oshibki_lin_reg[10],data_for_drawing[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
ArrayResize(oshibki_lin_reg, size_of_array);
ArrayResize(data_for_drawing, size_of_array);

for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A_viborki=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A_viborki,8));

//-----Расчёт коэффициента a уравнения линейной регрессии
double sred_znach_i=(size_of_array-1)/2.0; //среднее значение по оси индекса
double a_lin_regres=0;//коэффициент a линейной регрессии
double buffer=0;

for(i=size_of_array-1;i>=0;i--)
{
   a_lin_regres=a_lin_regres+(i-sred_znach_i)*(viborka[i]-S_A_viborki);
   buffer=buffer+MathPow((i-sred_znach_i),2);
}
a_lin_regres=a_lin_regres/buffer;
Print("a_lin_regres = ",DoubleToStr(a_lin_regres,8));

//-----Расчёт коэффициента b уравнения линейной регрессии
double b_lin_regres=S_A_viborki-a_lin_regres*sred_znach_i;
Print("b_lin_regres = ",DoubleToStr(b_lin_regres,8));

for(i=size_of_array-1;i>=0;i--) data_for_drawing[i]=a_lin_regres*i+b_lin_regres; 

linregres_grafic_c(0,data_for_drawing,end_bar);

//-----Расчёт ошибок линейной регрессии
for(i=size_of_array-1;i>=0;i--) oshibki_lin_reg[i]=viborka[i]-(a_lin_regres*i+b_lin_regres);

double S_A_oshibok;//среднее значение ошибок линейной регрессии
S_A_oshibok=srednee_arifmeticheskoe(oshibki_lin_reg);
Print("Среднее значение ошибок = ",DoubleToStr(S_A_oshibok,8));

double disp_oshibok=dispercia_oshibok(oshibki_lin_reg,S_A_oshibok);
Print("Дисперсия ошибок= ",DoubleToStr(disp_oshibok,8));

double S=CKO(disp_oshibok);
Print("S= ",DoubleToStr(S,8));

double pMin=Low[Lowest(NULL,0,MODE_LOW,size_of_array,end_bar)];
double pMax=High[Highest(NULL,0,MODE_HIGH,size_of_array,end_bar)];
double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
Comment("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта дисперсии ошибок
double dispercia_oshibok(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-2);
   return(disper);
}

//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}

//функция рисования канала линейной регрессии 
int linregres_grafic_c(int window_number, double data[], int ended_bar)
{
   int deletedArrows,k,size;
   string line_name;
   //очистка предыдущего рисунка
   deletedArrows=ObjectsDeleteAll(window_number,OBJ_TREND);
   
   //находим размер массива
   size=ArraySize(data);
   
   //рисуем центральную линию линейной регрессии
   for(k=size-1;k>=1;k--)
   {
      line_name="line_lin_reg"+k;
      ObjectCreate(line_name,OBJ_TREND,window_number,Time[k+ended_bar],data[k],Time[k+ended_bar-1],data[k-1]);
      ObjectSet(line_name,OBJPROP_COLOR,Yellow);
      ObjectSet(line_name,OBJPROP_STYLE,DRAW_LINE);
      ObjectSet(line_name,OBJPROP_WIDTH,2);
      ObjectSet(line_name,OBJPROP_BACK,true);
      ObjectSet(line_name,OBJPROP_RAY,false);
   }
   
   //рисуем проекцию центральной линии линейной регрессии
   line_name="line_lin_reg_proec";
   ObjectCreate(line_name,OBJ_TREND,window_number,Time[size-1+ended_bar],data[size-1],Time[ended_bar],data[0]);
   ObjectSet(line_name,OBJPROP_COLOR,Red);
   ObjectSet(line_name,OBJPROP_STYLE,DRAW_LINE);
   ObjectSet(line_name,OBJPROP_WIDTH,1);
   ObjectSet(line_name,OBJPROP_BACK,false);
   ObjectSet(line_name,OBJPROP_RAY,true);
   
      
   
   return(0);

}


Вот по этой ссылке лежат скриншоты https://c.mql5.com/mql4/forum/2006/05/Herst.zip
Я сначала пытался закачать на сайт эти файлы картинок, чтобы здесь было удобно смотреть в самой теме, но почему-то эти gif файлы на сайт www.mql4.com после смены движка упорно вставляться не хотят :o(. Ну ничего хорошо, что хоть zip закачивается.

Краткие пояснения к скрипту. Скрипт наносит на график толстую жёлтую линию канала линейной регрессии, на основе которого происходит оасчёт показателя Хёрста, а также рисует проекцию этого канала в будущее тонкой красной линией.
Судя по скриншотам наверное теперь я угадал с расчётом :o). Хотя нужно будет ещё перепроверять в будущем.

PS: Vladislav, расчёт показателя Хёрста по мувингу мне кажется несколько сомнительным, так как неизвестно какое значение периода усреднения нужно брать. Я так предполагаю, что это значение для каждого конкретного расчёта в зависимости от количества точет должно как-то меняться. Поэтому я пока что остановился на канале линейной регрессии.

 
Я влезу в беседу, если остальные не против. В методику Владислава сильно не вникал, хотя смутно догадываюсь. Высказаться решил из-за картинок. Ну нет в них никакого зерна в таком виде, мне кажется расчеты должны быть ползучими (наверно и Владисла так предлагает). Допустим, рассчитываем на 20(30-40 и так далее, на вкус ) барах ту самую желтую линию, для нее рассчитыаем Херста (СКО и т.д.), далее на новом барем из выборки выпадает самый старый бар (на которром и была получена желтая линия) и добавляется новый(вновь сформиовавшийся) бар, и на этой выборке производится расчет Херста (СКО и тд.).До тех пор, пока эти расчеты уклаываются в доверительный интервал (вот и вероятность стала востребована) - ничего не делаем , все развивается в пределах допустимомго, как только интервал нарушен - заново производится расчсет канала и прочих коэффициентов. ТО есть, вот такой ползучий канал , который ползет по намеченному пути, пока рынок не прикажет заново пересчитаться.

Вот что я из этого понял (возможно и неправильно).
 
Ну на самом деле всё немножко глубже! Мои картинки со скриптом расчёта показателя Хёрста - это просто некоторое дополнение к самой сути идеи по определению значимых на текущий момент времени каналов как линейной регрессии так и каналов, оптимальных с точки зрения квадратичных форм. То есть Хёрст в этой стратегии является всего лишь некоторой подтверждающей характеристикой, но никак не основной! Основа - это актуальные каналы с расчитанными доверительными интервалами например 90%,95% и 99%. И смысл стратегии - это правильно их определеить, то есть взять именно ТО количество баров, какое является оптимальным для построения действующего канала и аппроксимировать его функцией именно того порядка, который будет наиболее приемлемым. Никто конечно же выкидывать старые бары из выборки по той причине, что появился новый бар не собирается! Это всё глупости, на которых строятся ВСЕ обычные индикаторы. А так индикаторов, основанных на ползучих каналах придумано уже изрядное количество. Например ниже приведу один из них. Весь бред его работы можно оценить понаблюдав за ним некоторое время. Вы увидите моменты когда при появлении нового бара (и соответсвенно удалении одного последнего) угол наклона индикатора может поменяеться с 45 градусов на -45 градусов! А потом при появлении ещё одного может вернуться обратно на 45 градусов!:o)))) Правда в этом индикаторе всё работает не совсем так как я написал. Там берётся период, ограниченный количеством баров, на котором ищутся опорные точки - фракталы. И естественно не производится никакого учёта чем эти опорные точки являются на самом деле - потому что не производится оценки какому доверительному интервалу они принадлежат - отсюда и все вытекающие ошибки по построению линий индикатора.
//+------------------------------------------------------------------+
//|                                                  SHI_Channel.mq4 |
//|                                 Copyright © 2004, Shurka & Kevin |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, Shurka & Kevin"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
double ExtMapBuffer1[];
//---- input parameters
extern int       AllBars=240;
extern int       BarsForFract=0;
int CurrentBar=0;
double Step=0;
int B1=-1,B2=-1;
int UpDown=0;
double P1=0,P2=0,PP=0;
int i=0,AB=300,BFF=0;
int ishift=0;
double iprice=0;
datetime T1,T2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,164);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
//----
	
	
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }

void DelObj()
{
	ObjectDelete("TL1");
	ObjectDelete("TL2");
	ObjectDelete("MIDL");
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- 
	if ((AllBars==0) || (Bars<AllBars)) AB=Bars; else AB=AllBars; //AB-количество обсчитываемых баров
	if (BarsForFract>0) 
		BFF=BarsForFract; 
	else
	{
		switch (Period())
		{
			case 1: BFF=12; break;
			case 5: BFF=48; break;
			case 15: BFF=24; break;
			case 30: BFF=24; break;
			case 60: BFF=12; break;
			case 240: BFF=15; break;
			case 1440: BFF=10; break;
			case 10080: BFF=6; break;
			default: DelObj(); return(-1); break;
		}
	}
	CurrentBar=2; //считаем с третьего бара, чтобы фрактал "закрепился
	B1=-1; B2=-1; UpDown=0;
	while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
	{
		//UpDown=1 значит первый фрактал найден сверху, UpDown=-1 значит первый фрактал
		//найден снизу, UpDown=0 значит фрактал ещё не найден.
		//В1 и В2 - номера баров с фракталами, через них строим опорную линию.
		//Р1 и Р2 - соответственно цены через которые будем линию проводить

		if((UpDown<1) && (CurrentBar==Lowest(Symbol(),Period(),MODE_LOW,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=Low[B1]; }
			else { B2=CurrentBar; P2=Low[B2];}
		}
		if((UpDown>-1) && (CurrentBar==Highest(Symbol(),Period(),MODE_HIGH,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=High[B1]; }
			else { B2=CurrentBar; P2=High[B2]; }
		}
		CurrentBar++;
	}
	if((B1==-1) || (B2==-1)) {DelObj(); return(-1);} // Значит не нашли фракталов среди 300 баров 8-)
	Step=(P2-P1)/(B2-B1);//Вычислили шаг, если он положительный, то канал нисходящий
	P1=P1-B1*Step; B1=0;//переставляем цену и первый бар к нулю
	//А теперь опорную точку противоположной линии канала.
	ishift=0; iprice=0;
	if(UpDown==1)
	{ 
		PP=Low[2]-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(Low[i]<PP+Step*i) { PP=Low[i]-i*Step; }
		}
		if(Low[0]<PP) {ishift=0; iprice=PP;}
		if(Low[1]<PP+Step) {ishift=1; iprice=PP+Step;}
		if(High[0]>P1) {ishift=0; iprice=P1;}
		if(High[1]>P1+Step) {ishift=1; iprice=P1+Step;}
	} 
	else
	{ 
		PP=High[2]-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(High[i]>PP+Step*i) { PP=High[i]-i*Step;}
		}
		if(Low[0]<P1) {ishift=0; iprice=P1;}
		if(Low[1]<P1+Step) {ishift=1; iprice=P1+Step;}
		if(High[0]>PP) {ishift=0; iprice=PP;}
		if(High[1]>PP+Step) {ishift=1; iprice=PP+Step;}
	}
	//Теперь переставим конечную цену и бар на АВ, чтобы линии канала рисовались подлиннее
	P2=P1+AB*Step;
	T1=Time[B1]; T2=Time[AB];

	//Если не было пересечения канала, то 0, иначе ставим псису.
	if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
	DelObj();
	ObjectCreate("TL1",OBJ_TREND,0,T2,PP+Step*AB,T1,PP); 
		ObjectSet("TL1",OBJPROP_COLOR,Lime); 
		ObjectSet("TL1",OBJPROP_WIDTH,2); 
		ObjectSet("TL1",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("TL2",OBJ_TREND,0,T2,P2,T1,P1); 
		ObjectSet("TL2",OBJPROP_COLOR,Lime); 
		ObjectSet("TL2",OBJPROP_WIDTH,2); 
		ObjectSet("TL2",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("MIDL",OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
		ObjectSet("MIDL",OBJPROP_COLOR,Lime); 
		ObjectSet("MIDL",OBJPROP_WIDTH,1); 
		ObjectSet("MIDL",OBJPROP_STYLE,STYLE_DOT);
	//	Comment(" Channel size = ", DoubleToStr(MathAbs(PP - P1)/Point,0), " Slope = ", DoubleToStr(-Step/Point, 2));
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Тем не менее индикатор этот(Shi Channel) очень интересен - идея играть по тренду и от границ канала во флете сама по себя здравая.
 
Тем не менее индикатор этот(Shi Channel) очень интересен - идея играть по тренду и от границ канала во флете сама по себя здравая.

Этот индикатор взят от этой стратегии
http://fxovereasy.50webs.com/Example1.html
С сайта можно загрузить необходимые индикаторы для этой стратегии для MT4.
http://fxovereasy.50webs.com/Indicators.html
Всё выглядит на первый взгляд вполне здраво. Ну а других описаний стратегий и не бывает ;o).
Причина обращения: