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

 
Если мы тестируем систему на достаточно длинной истории возникает проблема нормировки (например, кажется очевидным, что 100 пунктов при курсе 0.8 вовсе не эквивалентны 100 пунктам при курсе 1.36).

¡¡¡Creo que este es un punto muy valioso!!! Tal vez tenga sentido normalizar el diferencial de precios, por ejemplo por el precio medio del último mes o dos y luego calcular el valor normalizado del diferencial para una serie de barras. Intentaré mejorar el indicador en un futuro próximo de acuerdo con este principio.

He finalizado el indicador de acuerdo con esta propuesta. Lo publicaré ahora. Si ha utilizado un indicador de una versión anterior, debe realizar el recálculo forzado de valores cuando ejecute la nueva versión (force_recalculation=true) para no esperar al día siguiente.
A continuación se muestran capturas de pantalla de la nueva versión del indicador para compararlas con la primera versión.
//+------------------------------------------------------------------+
//|                                     AMPLITUDE_STAT_LEVELS_v2.mq4 |
//|                                        Copyright © 2006, Solandr |
//|                                                solandr99@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Solandr"
#property link      "solandr99@mail.ru"
#property indicator_chart_window

//В версии 2 происходит относительный расчёт размахов в соответствии со средней ценой за 25 баров.
//В принципе при достаточном количестве баров истории это эквивалентно отношению среднеарифметического значения размаха
//к среднему значению цены на истории, умноженное затем на текущее среднее значение цены (например по последним 25 барам).
//Но решено оставить всё-таки более сложный алгоритм расчёта (нормировка значений амплитуд), поскольку он наверное будет вполне 
//уместен и в случаях когда баров истории совсем немного. 
// ============================================================================================
//"Купи подешевле, продай подороже" - основа, на которой базируется спекуляция на финансовых рынках. 
//Данный индикатор предлагает своё видение этих уровней "подешевле" и "подороже". Он основан на простом 
//статистическом расчёте размахов (амплитуд High-Low) баров по имеющейся истории котировок.
//Расчёт амплитуд происходит по сериям от 1 до 10 баров. То есть в выбранной серии на истории находитcя разница между 
//максимальным и минимальным значением цены. Далее окно серии смещается на 1 бар и получаем следующий размах амплитуды 
//баров для выбранной серии баров. После усреднения значения полученных размахов мы имеем среднее арифметическое диапазона 
//колебания цены для выбранной серии баров. 
//
//Полученное таким образом значение амплитуды откладывается на графике по следующему принципу. К минимуму текущей серии 
//баров прибавляется значение среднеарифметического размаха, посчитанного на истории. Так мы получаем возможный 
//среднестатистический максимум цены для текущей серии баров. То же самое делаем для нахождения среднестатистического 
//минимума для текущей серии баров. То есть от максимума текущей серии баров отнимаем среднеарифметический размах, 
//посчитанный для данной серии баров по историческим данным. Индикатор производит описанные выше действия для серий 
//от 1 до 10 баров. На уровнях присутствуют надписи, поясняющие для какого текущего временного промежутка построен данный 
//уровень. С параметром TF_needed="AUTO" уровни строятся для серий баров текущего таймфрейма. Если требуется зафиксировать
// уровни какого-то таймфрейма на остальных периодах, то необходимо установить это значение в MN, W1, D1, H4, H1, M30, 
//M15, M5, или в M1. Например для значения TF_needed="D1" на всех периодах будут отображаться уровни для временных 
//промежутков от 1 до 10 дней, обозначаемых соответственно как D1,...,D10.
//
//При настройках по умолчанию индикатор производит перерасчёт среднестатистических амплитуд по истории один раз в день 
//с их внесением в глобальные переменные терминала. Если по какой-то причине (например импортирование дополнительных 
//котировок) требуется произвести перерасчёт среднеарифметических значений амплитуд для серий баров не дожидаясь 
//следующего дня, то необходимо установить force_recalculation=true и будет произведён перерасчёт 
//среднеарифметических значений размахов для серий баров при следующей инициализации индикатора.
//
//Данный индикатор может быть полезен при принятии решений о входе в позицию. Может поспособствовать сохранению депозита
//особенно начинающих трейдеров. Продавайте на красных уровнях и покупайте на зелёных и за Вас будет играть математика! ;o))) 
//Если Вы например купили на зелёных уровнях и курс пошёл резко против Вас, то убыточную позицию есть смысл удерживать лишь 
//до тех пор пока красные уровни не окажутся ниже Вашей открытой позиции. И когда цена окажется на этих красных уровнях - 
//закройте убыточную позицию с минимальным убытком, а во многих случаях и с маленьким плюсом. Желаю успехов!:o)
// ============================================================================================
extern string TF_needed="AUTO";
extern bool force_recalculation=false;//принудительный перерасчёт

double average_price;
bool recalculation_needed=false;
bool aver_pr_recalc_needed=true;
int last_aver_pr_recalc_bars;
double delta[11];
string work_symbol;
int TF;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   int i,k,all_bars,counter_counted_bars;
   string b_str,global_name;
   double average_price_array[10];
 
   work_symbol=Symbol();
   
   //Выбор требуемого тайфрейма для расчёта;
   if(TF_needed=="AUTO" || (TF_needed!="MN" && TF_needed!="W1" && TF_needed!="D1" && TF_needed!="H4" && TF_needed!="H1" && TF_needed!="M30" && TF_needed!="M15" && TF_needed!="M5" && TF_needed!="M1")) TF=Period();
   if(TF_needed=="MN") TF=43200;
   if(TF_needed=="W1") TF=10080;
   if(TF_needed=="D1") TF=1440;
   if(TF_needed=="H4") TF=240;
   if(TF_needed=="H1") TF=60;  
   if(TF_needed=="M30") TF=30;  
   if(TF_needed=="M15") TF=15;  
   if(TF_needed=="M5") TF=5;  
   if(TF_needed=="M1") TF=1;  
      
   //Проверяем наличие посчитанных данных амплитуд для данного TF, а также производим проверку дня, в который был произведен расчёт этих данных
   global_name=work_symbol+"_"+TF+"_counted_day";
   if(GlobalVariableCheck(global_name) && !force_recalculation) 
   {  
      if(MathAbs(GlobalVariableGet(global_name)-DayOfYear())>0) recalculation_needed=true;
   }
   else recalculation_needed=true;
         
   if(recalculation_needed)
   {//Производим расчёт средней амплитуды бара (серии баров) по таймфрейму TF на символе work_symbol
      all_bars=iBars(work_symbol,TF);
      ArrayResize(average_price_array,all_bars);
   
      //Рассчитываем массив средних цен для каждого расчётного момента времени на основе 25 баров
      for(k=all_bars-1;k>=0;k--) 
      {      
            average_price_array[k]=0;
            counter_counted_bars=0;
            for(i=k;i<=k+24;i++)//вычисляем среднюю цену на 25 барах
            {
               if(i<all_bars) 
               {
                  average_price_array[k]=average_price_array[k]+(iOpen(work_symbol,TF,i)+iHigh(work_symbol,TF,i)+iLow(work_symbol,TF,i)+iClose(work_symbol,TF,i))/4;
                  counter_counted_bars++;
               }
            }
            if(counter_counted_bars>0) average_price_array[k]=average_price_array[k]/counter_counted_bars;
      }
   
      for(i=1;i<=10;i++) delta[i]=0;
   
      for(i=1;i<=10;i++)
      {      
         for(k=all_bars-i;k>=0;k--) 
         {  
            if(average_price_array[k]>0) delta[i]=delta[i]+(iHigh(work_symbol,TF,Highest(Symbol(),TF,MODE_HIGH,i,k))-iLow(work_symbol,TF,Lowest(Symbol(),TF,MODE_LOW,i,k)))/average_price_array[k];
            else Print("average_price_array[",k,"]<=0 при i=",i," и k=",k);
         }
         delta[i]=NormalizeDouble(delta[i]/(all_bars-i+1),Digits);   
         global_name=work_symbol+"_"+TF+"_"+i;
         GlobalVariableSet(global_name,delta[i]); 
         //Print("delta",i,"=",delta[i]);
      } 
      global_name=work_symbol+"_"+TF+"_counted_day";
      GlobalVariableSet(global_name,DayOfYear()); 
      recalculation_needed=false;
   }//if(recalculation_needed)
   else
   {//Если данные имеются в глобальных переменных терминала, то берём имеющиеся расчётные данные амплитуд из глобальных переменных терминала
      for(i=1;i<=10;i++)
      {
         global_name=work_symbol+"_"+TF+"_"+i;
         delta[i]=GlobalVariableGet(global_name);
         //Print("Глобал ",i," ",delta[i]);
      }
   }
}   
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
//----
   int i;
   string b_str;
   for(i=1;i<=10;i++)
   {
      b_str="up_line"+i;
      ObjectDelete(b_str);
      b_str="down_line"+i;
      ObjectDelete(b_str);
      b_str="up_line_txt"+i;
      ObjectDelete(b_str);      
      b_str="down_line_txt"+i;
      ObjectDelete(b_str);       
   }
}   

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int i;
   string line_name;
  
   /*
   for(i=iBars(work_symbol,TF)-1;i>=0;i--) average_price=average_price+(iOpen(work_symbol,TF,i)+iHigh(work_symbol,TF,i)+iLow(work_symbol,TF,i)+iClose(work_symbol,TF,i))/4;
   average_price=average_price/iBars(work_symbol,TF);
   Print("Средняя цена по всей выборке=",NormalizeDouble(average_price,Digits));
   average_price=0;
   */
   
   if(iBars(work_symbol,TF)!=last_aver_pr_recalc_bars) aver_pr_recalc_needed=true;
   
   if(aver_pr_recalc_needed)
   {  
      average_price=0;
      for(i=0;i<=24;i++) average_price=average_price+(iOpen(work_symbol,TF,i)+iHigh(work_symbol,TF,i)+iLow(work_symbol,TF,i)+iClose(work_symbol,TF,i))/4;
      average_price=average_price/25;
      aver_pr_recalc_needed=false;
      last_aver_pr_recalc_bars=iBars(work_symbol,TF);
   }
   //Print("average_price=",NormalizeDouble(average_price,Digits));
   
   for(i=1;i<=10;i++)
   {  
      if(TF==43200) line_name="MN"+i;   
      if(TF==10080) line_name="W"+i;
      if(TF==1440) line_name="D"+i;
      if(TF==240) line_name="H"+4*i;
      if(TF==60) line_name="H"+i;
      if(TF==30) line_name="M"+30*i;
      if(TF==15) line_name="M"+15*i;
      if(TF==5) line_name="M"+5*i;
      if(TF==1) line_name="M"+i;
            
      up_line(i,iLow(NULL,TF,Lowest(work_symbol,TF,MODE_LOW,i,0))+delta[i]*average_price,line_name);
      down_line(i,iHigh(NULL,TF,Highest(work_symbol,TF,MODE_HIGH,i,0))-delta[i]*average_price,line_name);
   }

   return(0);
  }
//+------------------------------------------------------------------+
int up_line(int q_days, double level, string ln)
{
   string b_str="up_line"+q_days;

   if(ObjectFind(b_str) == -1) 
   {
     ObjectCreate(b_str, OBJ_TREND, 0, Time[1], level, Time[1]+2700000,level);
     ObjectSet(b_str, OBJPROP_STYLE, STYLE_DOT);
     ObjectSet(b_str, OBJPROP_COLOR, Brown);
     ObjectSet(b_str, OBJPROP_RAY, true);
     ObjectSet(b_str, OBJPROP_WIDTH, 1);
     ObjectMove(b_str, 0, Time[1],  level);
   }
   else 
   {
      if(MathAbs(level-ObjectGet(b_str, OBJPROP_PRICE1))>0.9*Point) ObjectDelete(b_str);
   }
   
   b_str="up_line_txt"+q_days;
   string b_txt=ln;
   datetime t_bar;
   if(ObjectFind(b_str) == -1) 
   {
     ObjectCreate(b_str, OBJ_TEXT, 0, Time[0], 0);
     ObjectSetText(b_str, b_txt, 8, "Arial", Brown);
     ObjectMove(b_str, 0, Time[0]+2*q_days*Period()*60,  level);
   }
   else 
   {
     ObjectMove(b_str, 0, Time[0]+2*q_days*Period()*60,  level);
   }      
   
   return(0);
}

int down_line(int q_days, double level, string ln)
{
   string b_str="down_line"+q_days;
   
   if(ObjectFind(b_str) == -1) 
   {
     ObjectCreate(b_str, OBJ_TREND, 0, Time[1], level, Time[1]+2700000,level);
     ObjectSet(b_str, OBJPROP_STYLE, STYLE_DOT);
     ObjectSet(b_str, OBJPROP_COLOR, DarkGreen);
     ObjectSet(b_str, OBJPROP_RAY, true);
     ObjectSet(b_str, OBJPROP_WIDTH, 1);
     ObjectMove(b_str, 0, Time[1],  level);
   }
   else 
   {
      if(MathAbs(level-ObjectGet(b_str, OBJPROP_PRICE1))>0.9*Point) ObjectDelete(b_str);
   }
   
   b_str="down_line_txt"+q_days;
   string b_txt=ln;
   if(ObjectFind(b_str) == -1) 
   {
     ObjectCreate(b_str, OBJ_TEXT, 0, Time[0], 0);
     ObjectSetText(b_str, b_txt, 8, "Arial", DarkGreen);
     ObjectMove(b_str, 0, Time[0]+2*q_days*Period()*60,  level);
   }
   else 
   {
     ObjectMove(b_str, 0, Time[0]+2*q_days*Period()*60,  level);
   }      
   
   return(0);
}







 
Tal vez no me esté explicando correctamente. Lo que digo es que el uso de algoritmos para el emparejamiento de grafos (grafos combinatorios) puede utilizarse para el reconocimiento de patrones. Ir a:
http://citeseer.ist.psu.edu/ y busque:
Algoritmo de reconocimiento de patrones gráficos
 
Señalémoslo así (no estoy seguro de que sea la forma científica) pero...
La teoría de las ondas de Elliott trata de los patrones en el precio. El precio se representa como gráfico (precio en el tiempo).
La teoría de las ondas de Elliott identifica patrones -impulso, zigzag, planos- que están dentro del precio. Cómo-
Retroceso de Fibonacci. A continuación, las ondas encontradas se trazan en orden de probabilidad, pero esto es muy difícil de hacer (para tomar una decisión bruja movimiento es el siguiente o 100% "seguro". Así que lo que sugiero es mejor para resolver ese problema si se considera la tabla como un gráfico y se encuentran los patrones de acuerdo con la teoría de los gráficos. Tal vez (?) sea más preciso y la decisión sea estrictamente matemática?
 
Tal vez (?) sea más preciso y la decisión sea estrictamente matemática?

Por cierto, una amiga mía de Irlanda (lleva cinco años viviendo allí) dice que los nativos no dicen may be, sino probably. ¿Está seguro?
 
Candid, he pedido a algunos matemáticos que trabajan en el campo de la combinatoria y los gráficos que expliquen si es posible utilizar los gráficos combinatorios para encontrar patrones en los datos. Aquí está la respuesta de Janet M.Six:
"Hola Dave,

Estoy seguro de que los gráficos combinatorios se pueden utilizar para encontrar patrones
dentro de los gráficos del mercado. También supongo que el trabajo sobre este tema ha
se ha hecho.


Janet Six "
 
2 Dave Mason
¿Cómo se llama el término grafos combinatorios? Si lo que Candid escribió
Los grafos combinatorios pueden representarse a veces de forma pictórica como redes de puntos (llamados vértices) conectados por líneas (llamadas aristas)

apenas se puede utilizar esto para el reconocimiento de patrones. Una red de vértices puede estar conectada por todo tipo de líneas, que formarán, entre otras cosas, bucles cerrados. Mientras que un gráfico de precios es una simple línea única, ya que sólo hay un valor de precio para cada momento del tiempo. En términos de teoría de grafos (grafos combinatorios), dicha línea es el objeto más primitivo. No creo que se pueda hacer nada al respecto.

Además, un gráfico (los gráficos combinatorios) tiene una estructura espacial constante. Un gráfico de precios cambia constantemente en el tiempo.

Pero todo esto es IMHO. Si esta pregunta es relevante para usted, será mejor que pregunte a especialistas en el campo de la combinatoria y los grafos. Janet Six, por ejemplo. Si está segura de "que los gráficos combinatorios pueden utilizarse para encontrar patrones dentro de los gráficos de mercado" y de "que se ha trabajado en este tema", que dé el enlace.
 
Dave Mason, no te ofendas, pero la situación recuerda un poco a una vieja historia de ciencia ficción: allí un grupo de investigadores estaba convencido de que el problema de la antigravedad ya estaba resuelto, y luego lo resolvieron de verdad :).
Debo decir que mis ideas sobre la teoría de grafos son bastante superficiales, y consisten en que esta ciencia se interesa principalmente por la topología de los objetos buscados. La topología del patrón en sí es demasiado simple, es decir, probablemente no sea interesante para la teoría de grafos. En principio, podemos imaginar que hemos formalizado (codificado) patrones estándar e intentar buscarlos en un gráfico. Algunas partes del gráfico pueden identificarse con más de un patrón. Además, los propios patrones, si son algún tipo de primitivos, pueden relacionarse entre sí. De este modo, obtenemos un objeto, quizás similar a lo que hace la teoría de grafos. Es mucho trabajo, y no está claro si este enfoque dará resultados.
 
Yurixx
¿Cómo se llaman los gráficos combinatorios? Si lo que Candid escribió
Los gráficos combinatorios pueden representarse a veces de forma pictórica como redes de puntos (llamados vértices) conectados por líneas (llamadas aristas)

No lo he escrito yo, hay un enlace :))
Básicamente sí, es fácil establecer que hay una Janet M. Seis y se ocupa de los gráficos. Sin embargo, las simples declaraciones no son suficientes. Sería bueno obtener al menos breves consideraciones que se convirtieran en la base de las conclusiones. O, de hecho, una referencia específica, si no a una solución, sí a una "clave" potencial para entrar en el problema.
 
Creo que realmente no sabes de qué va la teoría de las ondas de Elliott.
Se trata de FRACTALS.
Los fractales forman parte de los gráficos combinatorios. Así que será mejor que estés más preparado cuando hables.
Si quieres "cabellera" lee algo antes.

http://www.math.utah.edu/vigre/reu/reports/harris_fall2005.pdf#search=%22%20Ralph%20Nelson%20Elliott%20elliott%20wave%20theory%20%22
 
No lo he escrito yo, hay un enlace :))

¡No puede ser! ¡Demasiado tarde para negarlo ahora! :))