una estrategia de negociación basada en la teoría de las ondas de Elliott - página 22

 
De la descripción de este sitio http://impb.psn.ru/~sychyov/html/soft.shtml
He descargado un programa que calcula el índice de Hurst. He creado un archivo con los precios de apertura de las barras en el script.
He abierto el archivo y el programa ha calculado el índice de Hurst. Pero sea cual sea la muestra que seleccione, el programa siempre muestra valores del indicador cercanos a 1. Pero no se ajusta a la teoría, ¿verdad? Es decir, ¿la lectura debe variar de 0 a 1 para diferentes muestras? Pero en este programa este parámetro está pegado a 1 :o(. En general, me alegro de que las funciones de cálculo listas estén disponibles en el sitio. Y ahora tengo miedo de usarlos para calcular algo.

Hasta ahora tengo este coeficiente dentro del rango 0,21-0,39. No sé por qué :o(.
Aquí está mi código de la secuencia de comandos, que me basé en su código:
//+------------------------------------------------------------------+
//|                                                        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, ¿podrías echar un vistazo y decirme dónde hay que retocar para calcular correctamente el coeficiente? Al fin y al cabo, según la teoría todos los cálculos son elementales y ni siquiera sé dónde está mi error :o(

 
¿Qué selecciona como variable central cuando llama a la función para calcular la varianza? Debería haber al menos una matriz con los valores predichos - está haciendo una predicción para cada barra, o lo ha hecho, una ejecución inversa y mirar la precisión de la predicción - todavía satisfactoria o no.
Y luego tal número de llamadas a funciones en un algoritmo que ya no se aligera mucho con los cálculos..... En mi opinión, se ralentizará considerablemente. (La llamada a la función es el procedimiento más largo, luego viene la operación de división en coma flotante).
¿Qué tiene de malo el algoritmo estándar para calcular la desviación estándar? Está disponible, pero la previsión toma el valor de un muving en la barra correspondiente - tomar lo que necesita, esto es todo y no hay llamadas a la función. Simplemente se ejecuta un bucle a través de un array y se eleva al cuadrado las diferencias entre el precio previsto en una barra determinada y el precio real, luego se hace la raíz cuadrada una vez - eso es todo.

Buena suerte y buena suerte con las tendencias.
 
<br / translate="no">http://forex.ua/forum/viewtopic.php?t=1574
http://forex.ua/forum/viewtopic.php?t=1634&postdays=0&postorder=asc&start=50
Hubo una comparación a corto plazo de las previsiones de FA y TA aquí (después de que algún flam en el hilo se hartara).
http://forex.ua/forum/viewtopic.php?t=1780

Gracias por los enlaces. Lea el artículo. ¡Muy informativo! Una vez más me ha confirmado que entiendo correctamente la esencia de su estrategia. Yo mismo he empezado a programar algo en este sentido. Ya he escrito más arriba sobre los problemas actuales de la agenda. Pero incluso los primeros resultados de los cálculos son muy impresionantes. Efectivamente, hasta que no lo pruebes tú mismo no podrás entender por qué las cosas suceden realmente como tú dices. Esto es lo que hace que su estrategia sea tan impopular entre la mayoría de los operadores. Es mucho más atractivo mirar hermosos gráficos multicolores de diferentes osciladores ;o) y leer a diferentes analistas pagados, que basar su estrategia de comercio de Forex en el conocimiento acumulado por la gente durante mucho tiempo. Aunque, en principio, mientras se mantenga este estado de cosas, ¡será posible ganar buen dinero en Forex!
 
En principio, sin embargo, mientras las cosas sigan así, es posible ganar buen dinero en Forex.


:).

Buena suerte y buenas tendencias.
 
¿Qué selecciona como variable central cuando llama a la función para calcular la varianza? Debería haber al menos un array con los valores predichos - se hace o se ha hecho una predicción para cada barra, se invierte la ejecución y se mira la exactitud de la predicción - sigue siendo satisfactoria o no. <br/ translate="no"> Y luego tal cantidad de llamadas a funciones en un algoritmo que ya no se aligera mucho con los cálculos..... En mi opinión, se ralentizará considerablemente. (La llamada a la función es el procedimiento más largo, luego viene la operación de división en coma flotante).
¿Qué tiene de malo el algoritmo estándar para calcular la desviación estándar? Está disponible, pero la previsión toma el valor de un muving en la barra correspondiente - toma lo que necesitas, esto es todo y no hay llamadas a la función. Basta con ejecutar un bucle a través de la matriz y tomar los cuadrados de las diferencias entre el precio previsto en la barra dada y el real, luego tomar la raíz cuadrada una vez - eso es todo.
Estoy completamente de acuerdo contigo. Los retrasos en el futuro serán terribles para los cálculos de masa, aunque en los cálculos pequeños todavía no se nota. Pero esto se debe al desarrollo del algoritmo, que luego se utilizará para calcular todo. Esta abundancia de funciones primitivas se debe simplemente a la comodidad (al menos a mí me lo parece :o)) de uso a la hora de buscar un algoritmo. Es decir, estas funciones RMS, Dispersión, Promedio, sólo uso en muchas otras cosas. Cuando todo se aclare: qué contar y cómo, así como el volumen de los cálculos, entonces, por supuesto, todo se cooptimizará. Hasta entonces, lo que tenemos es lo que usamos, por así decirlo, las primeras estimaciones de manivela ;o).
En este ejemplo he utilizado la media aritmética muestral como variable central.
También ayer intenté establecer una línea de regresión lineal como esta variable. Así pues, obtenemos que S=SCO de los errores de regresión lineal. Pero por alguna razón el resultado tampoco me impresionó :o(.
Aquí está el código del script, en el que tomamos una línea de regresión lineal como previsión. Además, la tendencia actual del EURUSD se ajusta muy bien a esto.
//+------------------------------------------------------------------+
//|                                                        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);
}


Tomemos el período H1 del EURUSD. Tomamos una muestra de 500 bares El coeficiente de Hearst = 0,26
300 bares - 0,31, 100 bares - 0,39, 30 bares - 0,51. No entiendo por qué :o(.

Probaremos su muving recomendado. Aunque todavía no sé por qué los resultados serán fundamentalmente diferentes de los que tengo.

 
¡HOORAY! Parece que he descubierto cómo calcular el Hurst. Aquí está el texto de la secuencia de comandos, donde el índice se calcula en relación con el canal de regresión lineal.
//+------------------------------------------------------------------+
//|                                                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);

}


Aquí está el enlace donde se encuentran las capturas de pantalla https://c.mql5.com/mql4/forum/2006/05/Herst.zip
Al principio traté de subir estos archivos de imagen al sitio, por lo que sería conveniente mirarlos en el propio tema, pero por alguna razón estos archivos gif en el sitio www.mql4.com después del cambio de motor persistentemente no quieren ser insertados :o(. No importa lo bueno que al menos suba la cremallera.

Una breve explicación del guión. El script dibuja una línea amarilla gruesa del canal de regresión lineal en el gráfico y al mismo tiempo traza la proyección del canal en el futuro con una línea roja fina.
A juzgar por las capturas de pantalla, debo estar en lo cierto en mis cálculos :o). Aunque tendré que volver a comprobarlo en el futuro.

PD: Vladislav, creo que el cálculo del índice de Hurst por parte de muving es un poco dudoso, porque no se sabe qué valor del periodo de promediación se debe tomar. Supongo que este valor para cada cálculo particular debe cambiar de alguna manera dependiendo del número de tochets. Por eso me he decantado por un canal de regresión lineal por ahora.

 
Me uniré a la conversación, si a los demás no les importa. No he profundizado mucho en la metodología de Vladislav, aunque tengo una vaga idea. Decidí hablar por las fotos. Bueno, no hay ningún grano en ellos en esta forma, me parece que los cálculos deben estar arrastrando (probablemente por lo que ofrece Vladislav). Supongamos que calculamos la línea amarilla para 20 (30-40 y así sucesivamente, como puede parecer) barras y realizamos los cálculos de Hearst (RMS, etc.), luego en una nueva barra eliminamos la barra más antigua de la muestra (en la que se obtuvo la línea amarilla) y añadimos una nueva barra (recién formada) y utilizamos esta muestra para realizar los cálculos de Hearst (RMS, etc.) hasta que aparezcan estas barras.Mientras estos cálculos encajen en el intervalo de confianza (ahora se ha exigido la probabilidad), no hacemos nada y todo se desarrolla dentro de los límites de lo aceptable, en cuanto se viola el intervalo, se vuelve a calcular el canal y otros factores. Se trata de un canal rastrero que sigue la trayectoria seleccionada hasta el recálculo de las órdenes de mercado.

Esto es lo que he entendido (probablemente de forma incorrecta).
 
Bueno, en realidad es un poco más profundo que eso. Mi script de Hearst es sólo una adición a la esencia de la idea de determinar los canales actualmente significativos de la regresión lineal y los canales óptimos en términos de formas cuadráticas. Es decir, Hearst en esta estrategia es sólo una característica confirmatoria, ¡pero no la principal! El principal: se trata de canales reales con intervalos de confianza calculados del 90%, 95% y 99%, por ejemplo. Y el punto de la estrategia - es determinarlas correctamente, es decir, tomar exactamente el número de barras, que es óptimo para construir un canal de actuación y aproximarlo con la función de ese orden, que es el más aceptable. Por supuesto, nadie va a eliminar las barras antiguas de la selección porque haya aparecido una nueva barra. Todo esto es un sinsentido en el que se basan TODOS los indicadores convencionales. Mientras tanto, ya se ha inventado un gran número de indicadores basados en canales de rastreo. Por ejemplo, citaré uno de ellos a continuación. El delirio de su trabajo se puede estimar después de observarlo durante algún tiempo. Verá los momentos en los que la pendiente del indicador puede cambiar de 45 a -45 grados en cuanto aparece una nueva barra (¡y la última desaparece en consecuencia!) Y luego, cuando veas otro puedes volver a los 45 grados!:o)))) Es cierto que este indicador no funciona exactamente como lo escribí. Se necesita un período limitado por el número de barras para encontrar puntos de referencia - fractales. Por supuesto, no tenemos en cuenta cuáles son realmente estos puntos de referencia -porque no estimamos a qué intervalo de confianza pertenecen-, de ahí que surjan todos los errores de trazado de las líneas del indicador.
//+------------------------------------------------------------------+
//|                                                  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);
  }
//+------------------------------------------------------------------+
 
Sin embargo, este indicador (Canal Shi) es muy interesante - la idea de jugar con la tendencia y de las fronteras del canal en el plano es sensible en sí mismo.
 
Sin embargo, este indicador (Canal Shi) es muy interesante - la idea de jugar con la tendencia y de las fronteras del canal en el plano es sensible en sí mismo.

Este indicador está tomado de esta estrategia
http://fxovereasy.50webs.com/Example1.html
Puede descargar los indicadores necesarios para esta estrategia para MT4 desde el sitio web.
http://fxovereasy.50webs.com/Indicators.html
Todo parece tener sentido a primera vista. No hay otra descripción de la estrategia ;o).