eine Handelsstrategie auf der Grundlage der Elliott-Wellen-Theorie - Seite 140

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

Ich denke, das ist ein sehr wichtiger Punkt!!! Vielleicht ist es sinnvoll, die Preisspanne zu normalisieren, zum Beispiel durch den Durchschnittspreis der letzten ein oder zwei Monate, und dann den normalisierten Wert der Spanne für eine Reihe von Balken zu berechnen. Ich werde versuchen, den Indikator in nächster Zeit nach diesem Prinzip zu verbessern.

Ich habe den Indikator entsprechend diesem Vorschlag fertiggestellt. Ich werde sie jetzt veröffentlichen. Wenn Sie einen Indikator einer früheren Version verwendet haben, sollten Sie die erzwungene Neuberechnung der Werte durchführen, wenn Sie die neue Version ausführen (force_recalculation=true) und nicht auf den nächsten Tag warten.
Nachstehend finden Sie Screenshots der neuen Version des Indikators zum Vergleich mit der ersten Version.
//+------------------------------------------------------------------+
//|                                     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);
}







 
Vielleicht habe ich mich nicht richtig ausgedrückt. Was ich damit sagen will, ist, dass Algorithmen zum Graphenabgleich (kombinatorische Graphen) für die Mustererkennung verwendet werden können. Gehen Sie zu:
http://citeseer.ist.psu.edu/ und suchen Sie nach:
Algorithmus zur Erkennung von Graphenmustern
 
Sagen wir es mal so (ich bin mir nicht sicher, ob es der wissenschaftliche Weg ist), aber...
Die Elliott-Wellen-Theorie befasst sich mit Kursmustern. Der Preis wird als Chart (Preis in der Zeit)-Grafik dargestellt.
Die Elliott-Wellen-Theorie identifiziert Muster - Impulse, ZigZag, Flats..., die im Preis enthalten sind. Wie-
Fibonacci-Retracement. Dann werden die gefundenen Wellen in Wahrscheinlichkeitsreihenfolge gezeichnet, aber das ist sehr schwer zu machen (eine Entscheidung zu treffen, welche Bewegung die nächste ist oder 100% "SICHER". Ich schlage also vor, das Problem besser zu lösen, indem man das Diagramm als Graph betrachtet und die Muster gemäß der Graphentheorie findet. Vielleicht (?) wird es genauer sein und die Entscheidung wird streng mathematisch sein?!
 
Vielleicht (?) wird es genauer sein und die Entscheidung wird rein mathematisch sein?!

Übrigens, eine Freundin von mir aus Irland (sie lebt dort seit fünf Jahren) sagt, dass Muttersprachler nicht may be, sondern probably sagen. Ist das sicher?
 
Ich habe einige Mathematiker, die auf dem Gebiet der Kombinatorik und der Graphen arbeiten, gebeten zu erklären, ob es möglich ist, kombinatorische Graphen zu verwenden, um Muster in Daten zu finden. Hier ist die Antwort von Janet M.Six:
"Hallo Dave,

Ich bin sicher, dass kombinatorische Graphen verwendet werden können, um Muster zu finden.
innerhalb der Marktcharts. Ich würde auch vermuten, dass die Arbeit zu diesem Thema
getan worden.


Janet Six "
 
2 Dave Mason
Wie nennen Sie den Begriff kombinatorische Graphen? Wenn das, was Candid schrieb
Kombinatorische Graphen lassen sich manchmal bildlich als Netze von Punkten (den so genannten Vertices) darstellen, die durch Linien (die so genannten Edges) verbunden sind
.
Dies kann man kaum für die Mustererkennung verwenden. Ein Netz von Knotenpunkten kann durch alle Arten von Linien verbunden werden, die unter anderem geschlossene Schleifen bilden werden. Ein Preisdiagramm hingegen ist eine einfache Linie, da es für jeden Zeitpunkt nur einen Preiswert gibt. Im Sinne der Graphentheorie (kombinatorische Graphen) ist eine solche Linie das primitivste Objekt. Ich glaube nicht, dass man etwas dagegen tun kann.

Außerdem hat ein Graph (kombinatorische Graphen) eine konstante räumliche Struktur. Ein Preisdiagramm verändert sich ständig im Laufe der Zeit.

Aber das ist alles IMHO. Wenn diese Frage für Sie relevant ist, sollten Sie sich an Spezialisten auf dem Gebiet der Kombinatorik und der Graphen wenden. Janet Six, zum Beispiel. Wenn sie sich sicher ist, dass "kombinatorische Graphen verwendet werden können, um Muster in Marktcharts zu finden" und dass "Arbeiten zu diesem Thema durchgeführt wurden", soll sie den Link angeben.
 
Dave Mason, nichts für ungut, aber die Situation erinnert ein wenig an eine alte Science-Fiction-Geschichte: Dort war eine Gruppe von Forschern davon überzeugt, dass das Problem der Antigravitation bereits gelöst sei, und dann haben sie es tatsächlich gelöst :).
Ich muss sagen, dass meine Vorstellungen von der Graphentheorie eher oberflächlich sind und darin bestehen, dass sich diese Wissenschaft hauptsächlich für die Topologie gesuchter Objekte interessiert. Die Topologie des Musters selbst ist zu einfach, d.h. für die Graphentheorie höchstwahrscheinlich nicht interessant. Im Prinzip können wir uns vorstellen, dass wir formalisierte (kodierte) Standardmuster haben und versuchen, sie in einem Graphen zu suchen. Bestimmte Teile des Diagramms können mit mehr als einem Muster identifiziert werden. Außerdem können die Muster selbst, wenn es sich um eine Art von Primitiven handelt, miteinander in Beziehung gesetzt werden. Auf diese Weise erhalten wir ein Objekt, das vielleicht dem ähnelt, was die Graphentheorie tut. Es ist eine Menge Arbeit, und es ist nicht klar, ob ein solcher Ansatz etwas bringt
 
Yurixx
Wie nennt man kombinatorische Graphen? Wenn das, was Candid schrieb
Kombinatorische Graphen lassen sich manchmal bildlich als Netze von Punkten (den so genannten Scheitelpunkten) darstellen, die durch Linien (den so genannten Kanten) verbunden sind.

Das habe ich nicht geschrieben, da ist ein Link :))
Grundsätzlich ja, es ist leicht festzustellen, dass es eine Janet M. gibt. Sechs und sie beschäftigt sich mit Diagrammen. Doch einfache Erklärungen reichen nicht aus. Es wäre gut, zumindest kurze Überlegungen zu erhalten, die die Grundlage für die Schlussfolgerungen bilden. Oder aber ein konkreter Hinweis, wenn schon nicht auf eine Lösung, so doch auf einen möglichen "Schlüssel" zur Lösung des Problems.
 
Ich glaube, Sie wissen wirklich nicht, worum es bei der Elliott-Wellen-Theorie geht!
Es geht um FRACTALS.
Fraktale sind Teil von kombinatorischen Graphen. Sie sollten also besser vorbereitet sein, wenn Sie sprechen.
Wenn Sie "skalpieren" wollen, lesen Sie vorher etwas.

http://www.math.utah.edu/vigre/reu/reports/harris_fall2005.pdf#search=%22%20Ralph%20Nelson%20Elliott%20elliott%20wave%20theory%20%22
 
Das habe ich nicht geschrieben, da ist ein Link :))

Niemals! Jetzt ist es zu spät, es zu leugnen! :))