MetaTrader 5 herunterladen

Berechnung wesentlicher Merkmale von Indikator-Emissionen

27 Juni 2016, 16:02
Sergey Pavlov
0
255

Einleitung

Indikator-Emissionen repräsentieren eine neue und ziemlich vielversprechende Richtung des Studiums von Zeitreihen. Dies ist charakterisiert durch die Tatsache, dass sich die Analyse nicht auf Indikatoren als solche konzentriert, sondern auf ihre Emissionen in der Zukunft oder Vergangenheit, je nach dem Zeitraum, in dem wir tatsächlich eine Prognose der Marktumgebung fällen können:

  • Stütz- und Widerstandsebenen in der Zukunft;
  • Richtung des Trends (Kursbewegung);
  • Stärke der im Laufe der Vergangenheit angesammelten Bewegung.

Mein vorangegangener Beitrag mit dem Titel "Die Emissionen eines Indikators in MQL5 zeichnen" hat sich mit dem Algorithmus zum Zeichnen von Emissionen beschäftigt und seine wichtigsten Merkmale spezifiziert. Eine kurze Erinnerung daran:

Eine Emission ist eine Reihe von Punkten, die sich an den Kreuzungen der für die beobachteten Indikatoren eigenen Linien befinden.

Emissionspunkte ihrerseits, haben ebenfalls einige Auffälligkeiten:

  • Emissionspunkte derselben Art neigen zur Clusterbildung.
  • Dichte Punkt-Cluster können den Kurz anziehen oder, umgekehrt, eben auch abstoßen.

Emissionen-Galerie:

DCMV-Emission iMA- & iEnvelopes-Emission
DCMV-Emission iMA- & iEnvelopes-Emission

Abb.1 Beispiele von grafischen Darstellungen von Indikator-Emissionen. Links:Emission des DCMV-Indikators. Rechts: Emission der iMA- und iEnvelopes-Indikatoren.

Bei der Veranschaulichung der Berechnung der wesentlichen Merkmale von Emissionen, nehmen wir Gleitender Mittelwert Envelopes (Envelopes) und Gleitende Mittelwerte (Gleitender Mittelwert) selbst her, mit den folgenden Eingabe-Parametern:

//--- external variable for storing averaging period of the iEnvelopes indicator
input int   ma_period=140; // averaging period of the iEnvelopes indicator
//--- array for storing deviations of the iEnvelopes indicator
double      ENV[]={0.01,0.0165,0.0273,0.0452,0.0747,01234,0.204,0.3373,0.5576,0.9217,1.5237};
//--- array for storing iMA indicator periods
int         MA[]={4,7,11,19,31,51,85};

Daher suchen wir nach Kreuzungen der diesen ausgewählten Indikatoren eigenen Linien. Die Zahl der Linien und ihre Merkmale (mittelnde Zeiträume und Abweichungen) werden auf Zufallsbasis gewählt. Emissionen können in der Tat mit Hilfe jedes Parameter-Sets für diese Indikatoren grafisch dargestellt werden (so lange sie sich im Raum überschneiden ).

Da wir nun ja die Indikatoren gewählt haben, fahren wir mit der Erzeugung eines Expert Advisors fort, der uns als Basisprogramm für die Analyse von Emissionen dienen soll. Dazu benötigen wir die berechneten Daten aus den iMA und iEnvelopes technischen Indikatoren. Ich schlage dazu die Verwendung einer Methode vor, die im Beitrag Leitfaden zur Verwendung technischer Indikatoren in Expert Advisors beschrieben wurde.

Zur grafischen Darstellung der Linien, deren Kreuzungen wir finden müssen, brauchen wir für jede dieser Linien nur zwei Punkte zu setzen. Daher reicht es aus Indikator-Werte für nur zwei Bars zu bekommen (z.B. den aktuellen und den vorangegangenen). Der Kurs auf dem vorangegangenen Bar ist statisch, während der Kurs auf dem aktuellen Bar dynamisch ist und daher bei jeder neuen Kursschwankung (Tick) ständig neue Punkte generiert werden. Und das ist der Code:

//+------------------------------------------------------------------+
//|                                      emission_of_MA_envelope.mq5 |
//|                                           Copyright 2013, DC2008 |
//|                           https://www.mql5.com/ru/users/DC2008 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, DC2008"
#property link      "https://www.mql5.com/ru/users/DC2008"
#property version   "1.00"
//---
#include <GetIndicatorBuffers.mqh>
#include <Emission.mqh>
//--- external variable for storing averaging period of the iEnvelopes indicator
input int   ma_period=140;      // averaging period of the iEnvelopes indicator
//--- array for storing deviations of the iEnvelopes indicator
double      ENV[]={0.01,0.0165,0.0273,0.0452,0.0747,01234,0.204,0.3373,0.5576,0.9217,1.5237};
//--- array for storing the iMA indicator periods
int         MA[]={4,7,11,19,31,51,85};
//--- array for storing pointers to the iMA and iEnvelopes indicators
int         handle_MA[];
int         handle_Envelopes[];
//--- market data
datetime    T[],prevTimeBar=0;
double      H[],L[];
#define     HL(a, b) (a+b)/2
//--- class instances
CEmission      EnvMa(0,300);
PointEmission  pEmission;
//--- drawing styles for points of emission
#define     COLOR_UPPER  C'51,255,255'
#define     COLOR_LOWER  C'0,51,255'
#define     COLOR_MA     C'255,51,255'
color       colorPoint[]={COLOR_UPPER,COLOR_LOWER,COLOR_MA};
CodeColor   styleUpper={158,COLOR_UPPER,SMALL};
CodeColor   styleLower={158,COLOR_LOWER,SMALL};
CodeColor   styleMA={158,COLOR_MA,SMALL};
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   ArraySetAsSeries(T,true);
   ArraySetAsSeries(H,true);
   ArraySetAsSeries(L,true);
//---
   int size=ArraySize(MA);
   ArrayResize(handle_MA,size);
//--- create a pointer to the object - the iMA indicator
   for(int i=0; i<size; i++)
     {
      handle_MA[i]=iMA(NULL,0,MA[i],0,MODE_SMA,PRICE_MEDIAN);
      //--- if an error occurs when creating the object, print the message
      if(handle_MA[i]<0)
        {
         Print("The iMA object[",MA[i],"] has not been created: Error = ",GetLastError());
         //--- forced program termination
         return(-1);
        }
     }
//---
   size=ArraySize(ENV);
   ArrayResize(handle_Envelopes,size);
//--- create a pointer to the object - the iEnvelopes indicator
   for(int i=0; i<size; i++)
     {
      handle_Envelopes[i]=iEnvelopes(NULL,0,ma_period,0,MODE_SMA,PRICE_MEDIAN,ENV[i]);
      //--- if an error occurs when creating the object, print the message
      if(handle_Envelopes[i]<0)
        {
         Print("The iEnvelopes object[",ENV[i],"] has not been created: Error = ",GetLastError());
         //--- forced program termination
         return(-1);
        }
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- market data
   CopyTime(NULL,0,0,2,T);
   CopyHigh(NULL,0,0,2,H);
   CopyLow(NULL,0,0,2,L);
//--- fill the declared arrays with current values from all indicator buffers
   string name;
   uint GTC=GetTickCount();
//---- indicator buffers
   double   ibMA[],ibMA1[];      // arrays for the iMA indicator
   double   ibEnvelopesUpper[];  // array for the iEnvelopes indicator (UPPER_LINE)
   double   ibEnvelopesLower[];  // array for the iEnvelopes indicator (LOWER_LINE)
   for(int i=ArraySize(handle_MA)-1; i>=0; i--)
     {
      if(!CopyBufferAsSeries(handle_MA[i],0,0,2,true,ibMA))
         return;
      //---
      for(int j=ArraySize(handle_Envelopes)-1; j>=0; j--)
        {
         if(!GetEnvelopesBuffers(handle_Envelopes[j],0,2,ibEnvelopesUpper,ibEnvelopesLower,true))
            return;
         //--- find the intersection point of the iEnvelopes(UPPER_LINE) and iMA indicators
         pEmission=EnvMa.CalcPoint(ibEnvelopesUpper[1],ibEnvelopesUpper[0],ibMA[1],ibMA[0],T[0]);
         if(pEmission.real) // if the intersection point is found, draw it in the chart
           {
            name="iEnvelopes(UPPER_LINE)"+(string)j+"=iMA"+(string)i+(string)GTC;
            EnvMa.CreatePoint(name,pEmission,styleUpper);
           }
         //--- find the intersection point of the iEnvelopes(LOWER_LINE) and iMA indicators
         pEmission=EnvMa.CalcPoint(ibEnvelopesLower[1],ibEnvelopesLower[0],ibMA[1],ibMA[0],T[0]);
         if(pEmission.real) // if the intersection point is found, draw it in the chart
           {
            name="iEnvelopes(LOWER_LINE)"+(string)j+"=iMA"+(string)i+(string)GTC;
            EnvMa.CreatePoint(name,pEmission,styleLower);
           }
        }
      //---
      for(int j=ArraySize(handle_MA)-1; j>=0; j--)
        {
         if(i!=j)
           {
            if(!CopyBufferAsSeries(handle_MA[j],0,0,2,true,ibMA1))
               return;
            //--- find the intersection point of the iMA and iMA indicators
            pEmission=EnvMa.CalcPoint(ibMA1[1],ibMA1[0],ibMA[1],ibMA[0],T[0]);
            if(pEmission.real) // if the intersection point is found, draw it in the chart
              {
               name="iMA"+(string)j+"=iMA"+(string)i+(string)GTC;
               EnvMa.CreatePoint(name,pEmission,styleMA);
              }
           }
        }
     }
//--- deletion of the graphical objects of emission not to stuff the chart
   if(T[0]>prevTimeBar) // delete once per bar
     {
      int  total=ObjectsTotal(0,0,-1);
      prevTimeBar=T[0];
      for(int obj=total-1;obj>=0;obj--)
        {
         string obj_name=ObjectName(0,obj,0,OBJ_TEXT);
         datetime obj_time=(datetime)ObjectGetInteger(0,obj_name,OBJPROP_TIME);
         if(obj_time<T[0])
            ObjectDelete(0,obj_name);
        }
      Comment("Emission © DC2008       Objects = ",total);
     }
//---
  }

Ich halte mich hier nicht mit jedem Detail dieses Expert Advisors auf. Als wichtigster Punkt sei herausgehoben, dass wir zu grafischen Darstellung der Emissionen eine CEmission Klassen-Instanz verwenden, die für die Berechnung und Anzeige der Kreuzungspunkte jeder x-beliebigen zwei Linien verantwortlich ist.

//+------------------------------------------------------------------+
//|                                                     Emission.mqh |
//|                                           Copyright 2013, DC2008 |
//|                           https://www.mql5.com/ru/users/DC2008 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, DC2008"
#property link      "https://www.mql5.com/ru/users/DC2008"
#property version   "1.00"
#define  BIG   7    // point size
#define  SMALL 3    // point size
//+------------------------------------------------------------------+
//| pMABB structure                                                  |
//+------------------------------------------------------------------+
struct PointEmission
  {
   double            x;       // X-coordinate of the time point
   double            y;       // Y-coordinate of the price point
   datetime          t;       // t-coordinate of the point's time
   bool              real;    // whether the point exists
  };
//+------------------------------------------------------------------+
//| CodeColor structure                                              |
//+------------------------------------------------------------------+
struct CodeColor
  {
   long              Code;    // point symbol code 
   color             Color;   // point color
   int               Width;   // point size
  };
//+------------------------------------------------------------------+
//| Base class for emissions                                         |
//+------------------------------------------------------------------+
class CEmission
  {
private:
   int               sec;
   int               lim_Left;   // limiting range of visibility in bars
   int               lim_Right;  // limiting range of visibility in bars

public:
   PointEmission     CalcPoint(double   y1,  // Y-coordinate of straight line 1 on bar [1]
                               double   y0,  // Y-coordinate of straight line 1 on bar [0]
                               double   yy1, // Y-coordinate of straight line 2 on bar [1] 
                               double   yy0, // Y-coordinate of straight line 2 on bar [0]
                               datetime t0   // t-coordinate of the current bar Time[0]
                               );
   bool              CreatePoint(string name,            // point name
                                 PointEmission &point,   // coordinates of the point
                                 CodeColor &style);      // point drawing style
                                 CEmission(int limitLeft,int limitRight);
                    ~CEmission();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CEmission::CEmission(int limitLeft,int limitRight)
  {
   sec=PeriodSeconds();
   lim_Left=limitLeft;
   lim_Right=limitRight;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CEmission::~CEmission()
  {
  }
//+------------------------------------------------------------------+
//| The CalcPoint method of the CEmission class                      |
//+------------------------------------------------------------------+
PointEmission CEmission::CalcPoint(double   y1, // Y-coordinate of straight line 1 on bar [1]
                                   double   y0, // Y-coordinate of straight line 1 on bar [0]
                                   double   yy1,// Y-coordinate of straight line 2 on bar [1]
                                   double   yy0,// Y-coordinate of straight line 2 on bar [0]
                                   datetime t0  // t-coordinate of the current bar Time[0]
                                   )
  {
   PointEmission point={NULL,NULL,NULL,false};
   double y0y1=y0-y1;
   double y1yy1=y1-yy1;
   double yy0yy1=yy0-yy1;
   double del0=yy0yy1-y0y1;
   if(MathAbs(del0)>0)
     {
      point.x=y1yy1/del0;
      if(point.x<lim_Left || point.x>lim_Right) return(point);
      point.y=y1+y0y1*y1yy1/del0;
      if(point.y<0) return(point);
      point.t=t0+(int)(point.x*sec);
      point.real=true;
      return(point);
     }
   return(point);
  }
//+------------------------------------------------------------------+
//| The CreatePoint method of the CEmission class                    |
//+------------------------------------------------------------------+
bool CEmission::CreatePoint(string name,            // point name
                            PointEmission &point,  // coordinates of the point
                            CodeColor &style)      // point drawing style
  {
   if(ObjectCreate(0,name,OBJ_TEXT,0,0,0))
     {
      ObjectSetString(0,name,OBJPROP_FONT,"Wingdings");
      ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,style.Width);
      ObjectSetString(0,name,OBJPROP_TEXT,CharToString((uchar)style.Code));
      ObjectSetDouble(0,name,OBJPROP_PRICE,point.y);
      ObjectSetInteger(0,name,OBJPROP_TIME,point.t);
      ObjectSetInteger(0,name,OBJPROP_COLOR,style.Color);
      return(true);
     }
   return(false);
  }

Es sollte auch beachtet werden, dass Emissionspunkte mit Hilfe von grafischen Objekten wie z.B. Text abgebildet werden. Das liegt zunächst an der Tatsache, dass Objektanker zur Mitte des Symbols ausgerichtet werden sollten. Und zweitens daran, dass man die Objektgröße über einen weiten Bereich variieren kann. Diese Punkt-Eigenschaften bieten ein großes Potenzial, um komplexe Emissionen zu bekommen.

Abb. 2 Original-Emission der iMA- und iEnvelopes-Indikatoren

Abb. 2 Original-Emission der iMA- und iEnvelopes-Indikatoren

 

Wesentliche Merkmale von Emissionen

Nachdem wir den vorgeschlagenen Expert Advisor auf dem Chart platziert haben, haben wir eine Menge Punkte in verschiedenen Farben erhalten (vgl. Abb. 2):

  • Aquamarin - Kreuzungen von iMA und iEnvelopes, UPPER_LINE Puffer.
  • Blau - Kreuzungen von iMA und iEnvelopes, LOWER_LINE Puffer.
  • Magenta - Kreuzungen von iMA und iMa.

Dieses Chaos ist für einen Einsatz im automatischen Handel absolut undenkbar. Wir brauchen Signale, Stufen oder andere quantitative Marktcharakteristika. Doch hier haben wir nur visuelle Bilder zur Meditation, aber absolut keine Zahlen welcher Art auch immer.

Wesentliche Merkmale von Emissionen dienen zur Verallgemeinerung von Daten, die man als Ergebnis von Indikator-Emissionen erhalten hat. 

Die Notwendigkeit von wesentlichen Merkmalen von Emissionen ist zudem auch von der Tatsache angetrieben, dass sie Möglichkeiten zur Markterforschung mittels neuer Arten von Indikatoren bieten: wesentliche Kanäle, Stufen, Signale, usw. Um die typischsten Emissionswerte festzustellen, beginnen wir klein und berechnen den Durchschnittskurs für jede Art Punkt, um durch sie weitere waagrechte Linien, wie unten gezeigt, ziehen zu können:

Abb. 3 Waagrechte Linien des Durchschnittskurses für jede Art Punkt

Abb. 3 Waagrechte Linien des Durchschnittskurses für jede Art Punkt

Daher werden wir den bestehenden Code durch einige zusätzliche Codeblocks ergänzen. Im Datenbereich:

//--- arrays for calculation and display of integral characteristics of emissions
#define     NUMBER_TYPES_POINT   3
double      sum[NUMBER_TYPES_POINT],sumprev[NUMBER_TYPES_POINT];
datetime    sum_time[NUMBER_TYPES_POINT];
int         n[NUMBER_TYPES_POINT],W[NUMBER_TYPES_POINT];
color       colorLine[]={clrAqua,clrBlue,clrMagenta};

Im OnTick()-Modul:

//--- calculation of integral characteristics of emissions
   ArrayInitialize(n,0);
   ArrayInitialize(sum,0.0);
   ArrayInitialize(sum_time,0.0);
   for(int obj=total-1;obj>=0;obj--)
     {
      string   obj_name=ObjectName(0,obj,0,OBJ_TEXT);
      datetime obj_time=(datetime)ObjectGetInteger(0,obj_name,OBJPROP_TIME);
      if(obj_time>T[0])
        {
         color    obj_color=(color)ObjectGetInteger(0,obj_name,OBJPROP_COLOR);
         double   obj_price=ObjectGetDouble(0,obj_name,OBJPROP_PRICE);
         for(int i=ArraySize(n)-1; i>=0; i--)
            if(obj_color==colorPoint[i])
              {
               n[i]++;
               sum[i]+=obj_price;
               sum_time[i]+=obj_time;
              }
        }
     }
//--- displaying integral characteristics of emissions
   for(int i=ArraySize(n)-1; i>=0; i--)
     {
      if(n[i]>0)
        {
         name="H.line."+(string)i;
         ObjectCreate(0,name,OBJ_HLINE,0,0,0,0);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DASHDOT);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         ObjectSetDouble(0,name,OBJPROP_PRICE,sum[i]/n[i]);
        }
     }

Und weiter. Berechnen wir nun den durchschnittlichen Zeitwert für jeden gesetzten Punkt und markieren ihn auf der entsprechenden Zeile des Durchschnittskurses (vgl. Abb. 4). Damit haben wir die ersten quantitativen Merkmale der Emissionen erhalten, die niemals statisch sind, sondern sich ständig im Raum bewegen.

Das Chart zeigt nur ihre augenblicklichen Positionen an. Wir müssen sie in der History irgendwie fixiert bekommen, um sie später dann studieren zu können. Bislang ist noch immer unklar, wie dies gelingen könnte und daher müssen wir sehr gründlich darüber nachdenken... In der Zwischenzeit führen wir weitere Verbesserungen durch und zeigen die Zahl der an der Berechnung beteiligten Punkte neben den Markierungen im Chart an. Sie sind quasi so was wie Gewichtungen der erhaltenen Merkmale, die uns für eine spätere Analyse noch nützen werden.

Abb. 4 Markierungen an den Kreuzungspunkten von Durchschnittskurs und durchschnittlicher Zeit

Abb. 4 Markierungen an den Kreuzungspunkten von Durchschnittskurs und durchschnittlicher Zeit

Aus Gründen einer bequemen Analyse arbeiten wir jedoch mit ihrem Prozentverhältnis. Da die hauptsächlichen Emissionspunkte diejenigen sind, die aus den Kreuzungen der iMA- und iEnvelopes-Indikatoren entstanden sind, betrachten wir ihre Summe als 100%. Mal sehen, was wir jetzt so haben:

Abb. 5 Prozentverhältnis für jede Art Emissionspunkte

Abb. 5 Prozentverhältnis für jede Art Emissionspunkte

Wenn wir die drei Werte zusammenzählen, dann ergeben sie mehr als 100%. Der Wert von 34,4, dargestellt in Magenta, ist die Eigenschaft der Kreuzungspunkte von iMA und iMA zu einem gewinnen Zeitpunkt, d.h. der Indikator hat sich selbst gekreuzt, doch mit anderen Eingabedaten. In diesem Fall handelt es sich hier um einen Referenzwert. Wir werden uns später überlegen, auf welche Weise er bei einer Marktanalyse evtl. verwendet werden könnte.

Doch wenn wir die Prozentverhältnisse der Anzahl der Punkte erhalten, entsteht noch ein weiteres Problem: Wie können wir Prozentwert von Emissionen-Merkmale in der History fixieren, ganz insbesondere, da sie ja auch noch variieren?!

 

Grafische Analyse

Obwohl wir jetzt die wesentlichen Merkmale von Emissionen haben, sind wir der Analyse und der Entwicklung einer Handelsstrategie auf Basis der erhaltenen Daten noch nicht nahe genug. Doch jedem aufmerksamen Leser ist wahrscheinlich schon eine Lösung zu diesem Problem aufgefallen (vgl. Abb.1). Sie lautet folgendermaßen: Ich schlage vor wesentliche Kurven mit unterschiedlicher Dicke zu zeichnen, die proportional zum Prozentverhältnis der hauptsächlichen Emissionspunkte sind.

Der aktuelle Teil der Kurve wird entlang der Linie des Durchschnittskurses zwischen dem aktuellen und vorherigen Bar gezeichnet, wobei man nicht vergessen sollte, dass diese Koordinaten in der Tat aus der Zukunft genommen sind. Das ist eine Art führender wesentlicher Kanal von Indikator-Emissionen. Ich weiß schon, das klingt wirklich ziemlich verwirrend.. Und jetzt überlegen Sie gerade, ob Sie überhaupt noch weiterlesen wollen. Ich hoffe jedoch, dass das Ganze, je weiter wir fortschreiten, immer interessanter wird.

Abb. 6 Wesentlicher Kanal der Indikator-Emissionen

Abb. 6 Wesentlicher Kanal der Indikator-Emissionen

Es scheint, als hätten wir herausgefunden, wie wir die "iMA- & iMA"-Emission verwenden können (auf dem Chart in Magenta dargestellt). Und wir haben einen neuen Indikator bekommen - den integrierten gleitenden Mittelwert.

Wenden wir uns also nun dem Code des Expert Advisors, um herauszufinden, welche Vernderungen imOnTick() Modul stattgefundenhaben:

//--- displaying integral characteristics of emissions
   ArrayInitialize(W,10);
   W[ArrayMaximum(n)]=20;
   W[ArrayMinimum(n)]=3;
   for(int i=ArraySize(n)-1; i>=0; i--)
     {
      if(n[i]>0)
        {
         //--- horizontal lines of mean prices
         name="H.line."+(string)i;
         ObjectCreate(0,name,OBJ_HLINE,0,0,0,0);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DASHDOT);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         ObjectSetDouble(0,name,OBJPROP_PRICE,sum[i]/n[i]);
         //--- markers
         name="P."+(string)i;
         ObjectCreate(0,name,OBJ_TEXT,0,0,0);
         ObjectSetString(0,name,OBJPROP_FONT,"Wingdings");
         ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
         ObjectSetInteger(0,name,OBJPROP_FONTSIZE,17);
         ObjectSetString(0,name,OBJPROP_TEXT,CharToString(163));
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         ObjectSetDouble(0,name,OBJPROP_PRICE,sum[i]/n[i]);
         ObjectSetInteger(0,name,OBJPROP_TIME,sum_time[i]/n[i]);
         //--- integral curves
         name="T"+(string)i+".line"+(string)T[1];
         ObjectCreate(0,name,OBJ_TREND,0,0,0);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,W[i]);
         if(sumprev[i]>0)
           {
            ObjectSetDouble(0,name,OBJPROP_PRICE,0,sumprev[i]);
            ObjectSetInteger(0,name,OBJPROP_TIME,0,T[1]);
            ObjectSetDouble(0,name,OBJPROP_PRICE,1,(sum[i]/n[i]));
            ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
           }
         //--- numerical values of integral characteristics
         name="Text"+(string)i+".control";
         ObjectCreate(0,name,OBJ_TEXT,0,0,0);
         ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
         ObjectSetInteger(0,name,OBJPROP_FONTSIZE,30);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         string str=DoubleToString((double)n[i]/(double)(n[0]+n[1])*100,1);
         ObjectSetString(0,name,OBJPROP_TEXT,str);
         ObjectSetDouble(0,name,OBJPROP_PRICE,0,(sum[i]/n[i]));
         ObjectSetInteger(0,name,OBJPROP_TIME,0,sum_time[i]/n[i]);
        }
     }

Fahren wir mit unserer grafischen Analyse fort. Doch da fehlt noch was... Es scheint so, als hätten wir ein weiteres wichtiges Emissions-Merkmal übersehen. Wesentliche Kurven wurden nur auf Grundalge der Durchschnittskurse grafisch dargestellt. Doch müssen wir die Durchschnittszeit-Koordinate berücksichtigen. Betrachten Sie sich die Abbildung unten und achten Sie genau auf die Kanalgrenzen:

  • Die aquamarine Linie ist die Obergrenze des Kanals.
  • Die blaue Linie ist die Obergrenze des Kanals.

Wir müssen die Markierung finden, der zeitlich näher am "0"-Bar war.

Führende Obergrenze des Kanals
Führende Untergrenze des Kanals

Abb. 7 Wesentliche Merkmale, zeitlich führend. Links:führende Obergrenze des Kanals. Rechts: führende Untergrenze des Kanals.

Das Problem kann folgendermaßen gelöst werden: wir fügen die Kurslinie (PRICE_MEDIAN) dem Kurschart hinzu und lassen die Linie ihre Farbe ändern, je nach der Farbe der Markierung (aquamarin oder blau), die sich sich näher am letzten Bar befindet (vgl. Abb.7). Des Weiteren fügen wir den folgenden Codeblock in den bestehenden Code ein:

//---
   if(n[ArrayMinimum(n)]>0)
     {
      datetime d[2];
      for(int j=0;j<2;j++)
        {
         d[j]=sum_time[j]/n[j];
        }
      int i=ArrayMinimum(d);

      name="Price.line"+(string)T[1];
      ObjectCreate(0,name,OBJ_TREND,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_WIDTH,8);
      ObjectSetDouble(0,name,OBJPROP_PRICE,0,HL(H[1],L[1]));
      ObjectSetInteger(0,name,OBJPROP_TIME,0,T[1]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,1,HL(H[0],L[0]));
      ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
      ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine1[i]);
     }
//---

Jetzt sind wir bereit für den nächsten Schritt. Und was wäre, wenn wir versuchen würden, Emissionen auf Grundlage der wesentlichen Merkmale von Original-Emissionen grafisch darzustellen, so etwas wie wie nachrangige Emissionen? Denn schließlich kreuzen sich diese Linie ja auch miteinander und sollten daher folglich Emissionspunkte haben. Schauen wir mal, was dabei herauskommt. Erweitern wir den vorigen Codeblock, indem wir die folgenden Codezeilen hinzufügen:

      //--- emissions of integral characteristics of the original emissions
      pEmission=EnvMa.CalcPoint(sumprev[0],sum[0]/n[0],sumprev[2],sum[2]/n[2],T[0]);
      if(pEmission.real) // if the intersection point is found, draw it in the chart
        {
         name="test/up"+(string)GTC;
         EnvMa.CreatePoint(name,pEmission,styleUpper2);
        }
      pEmission=EnvMa.CalcPoint(sumprev[1],sum[1]/n[1],sumprev[2],sum[2]/n[2],T[0]);
      if(pEmission.real) // if the intersection point is found, draw it in the chart
        {
         name="test/dn"+(string)GTC;
         EnvMa.CreatePoint(name,pEmission,styleLower2);
        }

Und die folgenden Zeilen in den Datenabschnitt einfügen:

#define     COLOR_2_UPPER  C'102,255,255'
#define     COLOR_2_LOWER  C'51,102,255'
CodeColor   styleUpper2={178,COLOR_2_UPPER,BIG};
CodeColor   styleLower2={178,COLOR_2_LOWER,BIG};

Die Ergebnisse können Sie in der Abbildung unten überprüfen. Wir erkennen, dass die neuen Punkte bislang auf gar nichts hinweisen.

Abb. 8 Emissionen wesentlicher Linien

Abb. 8 Emissionen wesentlicher Linien

Wesentliche Merkmale können offensichtlich auch für neue Punkte berechnet werden (vgl. Abb. 9), deren Emissionen grafisch im Chart dargestellt sind, usw. solange bis es nicht mehr machbar ist!

Emission Emission
Emission Emission

Abb. 9 Wesentliche Merkmale von Emissionen

Also haben wir alles, was wir gebraucht haben, grafisch dargestellt und die wesentlichen Merkmale von Emissionen erhalten. Daher können wir uns nun mit ihrer Analyse und der Entwicklung einer Handelsstrategie beschäftigen. Doch das scheint immer noch unmöglich! Was hält uns denn jetzt noch ab?

 

Zeitreihen von Emissionen

Mit Hilfe der grafischen Analyse können wir wesentliche Merkmale von Emissionen studieren, doch dies kostet viel zu viel Ressourcen. Wenn wir den vorgeschlagenen Code im visuellen Modus des Strategietesters laufen lassen, dann fällt die Testgeschwindigkeit bald buchstäblich auf Null! Dies liegt an der großen Anzahl grafischer Objekte im Chart.

Daher möchte man natürlich all diese Unmengen von Punkte loswerden und nur noch die wesentlichen Kuren übrig lassen. Dazu bedienen wir uns spezieller Arrays (Puffer).

Zeitreihen von Emissionen sind speziell angeordnete Arrays, in denen die Information über Emissionen angehäuft ist.

Sie unterscheiden sich von Standard-Zeitreihen dadurch, dass die Daten, die sie enthalten, nicht zeitlich aufeinander folgen, obwohl natürlich Zeit das Schlüsselfeld ist.

Zeitreihen von Emissionen

Abb. 10 Zeitreihen von Emissionen-Merkmalen

Diese Arrays sind so angeordnet, dass neue Elemente in leeren Zellen oder in Zellen mit alten werten abgelegt werden. Zu diesem Zweck verwenden wir die CTimeEmission Klasse. Und so wird sie in den Code implementiert:

//+------------------------------------------------------------------+
//|                                                 TimeEmission.mqh |
//|                                           Copyright 2013, DC2008 |
//|                           https://www.mql5.com/ru/users/DC2008 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, DC2008"
#property link      "https://www.mql5.com/ru/users/DC2008"
#property version   "1.00"
//---
#include <Emission.mqh>
#define ARRMAX       64
#define ARRDELTA     8
//+------------------------------------------------------------------+
//| pIntegral structure                                              |
//+------------------------------------------------------------------+
struct pIntegral
  {
   double            y;       // Y-coordinate of the price point (mean price of the points with the same time)
   datetime          t;       // t-coordinate of the point's time
   int               n;       // n-number of points with the same time
  };
//+------------------------------------------------------------------+
//| Base class for time series of emissions                          |
//+------------------------------------------------------------------+
class CTimeEmission
  {
private:
   pIntegral         time_series_Emission[]; // time series of emission
   int               size_ts; // number of elements in time series 
   datetime           t[1];
public:
   //--- method of writing new elements to time series of emission
   void              Write(PointEmission &point);
   //--- method of reading integral characteristics of emissions
   pIntegral         Read();
                     CTimeEmission();
                    ~CTimeEmission();
  };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTimeEmission::CTimeEmission()
  {
   ArrayResize(time_series_Emission,ARRMAX,ARRMAX);
   size_ts=ArraySize(time_series_Emission);
   for(int i=size_ts-1; i>=0; i--)
      time_series_Emission[i].t=0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTimeEmission::~CTimeEmission()
  {
  }
//+------------------------------------------------------------------+
//| The Write method of the CTimeEmission class                      |
//+------------------------------------------------------------------+
void CTimeEmission::Write(PointEmission &point)
  {
   CopyTime(NULL,0,0,1,t);
   size_ts=ArraySize(time_series_Emission);
   for(int k=0;k<size_ts;k++)
     {
      if(time_series_Emission[k].t<t[0]) // find the first empty cell
        {
         if(k>size_ts-ARRDELTA)
           {   // increase the array size, if necessary
            int narr=ArrayResize(time_series_Emission,size_ts+ARRMAX,ARRMAX);
            for(int l=size_ts-1;l<narr;l++)
               time_series_Emission[l].t=0;
           }
         time_series_Emission[k].y=point.y;
         time_series_Emission[k].t=point.t;
         time_series_Emission[k].n=1;
         return;
        }
      if(time_series_Emission[k].t==point.t) // find the first similar cell
        {
         time_series_Emission[k].y=(time_series_Emission[k].y*time_series_Emission[k].n+point.y)/(time_series_Emission[k].n+1);
         time_series_Emission[k].n++;
         return;
        }
     }
  }
//+------------------------------------------------------------------+
//| The Read method of the CTimeEmission class                       |
//+------------------------------------------------------------------+
pIntegral CTimeEmission::Read()
  {
   CopyTime(NULL,0,0,1,t);
   pIntegral property_Emission={0.0,0,0};
   size_ts=ArraySize(time_series_Emission);
   for(int k=0;k<size_ts;k++)
     {
      if(time_series_Emission[k].t>=t[0])
        {
         property_Emission.y+=time_series_Emission[k].y*time_series_Emission[k].n;
         property_Emission.t+=(time_series_Emission[k].t-t[0])*time_series_Emission[k].n;
         property_Emission.n+=time_series_Emission[k].n;
        }
     }
   if(property_Emission.n>0)
     {
      property_Emission.y=property_Emission.y/property_Emission.n;
      property_Emission.t=property_Emission.t/property_Emission.n+t[0];
     }
   return(property_Emission);
  }

Hier sehen wir die Implementierung von zwei Klassen-Methoden: das Schreiben von Emissionspunkten in Zeitreihen und das Lesen von Werten wesentlicher Merkmale von Emissionen.

 

Sparsame Berechnung wesentlicher Merkmale

Da wir nun die Zeitreihen der Emissionen haben, können wir mit der Erzeugung eines sparsamen Algorithmus zur Berechnung der wesentlichen Merkmale für eine weitere Entwicklung einer Handelsstrategie beginnen. Aktualisieren wir dazu den ursprünglichen Expert Advisor:

//+------------------------------------------------------------------+
//|                                   emission_of_MA_envelope_ts.mq5 |
//|                                           Copyright 2013, DC2008 |
//|                           https://www.mql5.com/ru/users/DC2008 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, DC2008"
#property link      "https://www.mql5.com/ru/users/DC2008"
#property version   "1.00"
//---
#include <GetIndicatorBuffers.mqh>
#include <Emission.mqh>
#include <TimeEmission.mqh>
//--- number of point types
#define     NUMBER_TYPES_POINT   3
//--- array for storing the iMA indicator periods
int      MA[]={4,7,11,19,31,51,85};
//--- external variable for storing averaging period of the iEnvelopes indicator
input int ma_period=140; // averaging period of the iEnvelopes indicator
//--- array for storing deviations of the iEnvelopes indicator
double   ENV[]={0.01,0.0165,0.0273,0.0452,0.0747,01234,0.204,0.3373,0.5576,0.9217,1.5237};
//--- array for storing pointers to the iMA indicator
int      handle_MA[];
//--- array for storing pointers to the iEnvelopes indicator
int      handle_Envelopes[];
//--- market data
datetime    T[],prevTimeBar=0;
double      H[],L[];
#define     HL(a, b) (a+b)/2
//--- class instances
CEmission      EnvMa(0,200);
PointEmission  pEmission;
CTimeEmission  tsMA[NUMBER_TYPES_POINT];
pIntegral      integral[NUMBER_TYPES_POINT];
//--- drawing styles for points of emission
#define     DEL            500
//--- arrays for calculation and display of integral characteristics of emissions
double      sumprev[NUMBER_TYPES_POINT];
int         n[NUMBER_TYPES_POINT],W[NUMBER_TYPES_POINT];
color       colorLine[]={clrAqua,clrBlue,clrMagenta};
int         fontPoint[]={30,30,30};
int         fontMarker[]={16,16,16};
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   ArraySetAsSeries(T,true);
   ArraySetAsSeries(H,true);
   ArraySetAsSeries(L,true);
   ArrayInitialize(sumprev,0.0);
//---
   int size=ArraySize(MA);
   ArrayResize(handle_MA,size);
//--- create a pointer to the object - the iMA indicator
   for(int i=0; i<size; i++)
     {
      handle_MA[i]=iMA(NULL,0,MA[i],0,MODE_SMA,PRICE_MEDIAN);
      //--- if an error occurs when creating the object, print the message
      if(handle_MA[i]<0)
        {
         Print("The iMA object[",MA[i],"] has not been created: Error = ",GetLastError());
         //--- forced program termination
         return(-1);
        }
     }
//+------------------------------------------------------------------+
   size=ArraySize(ENV);
   ArrayResize(handle_Envelopes,size);
//--- create a pointer to the object - the iEnvelopes indicator
   for(int i=0; i<size; i++)
     {
      handle_Envelopes[i]=iEnvelopes(NULL,0,ma_period,0,MODE_SMA,PRICE_MEDIAN,ENV[i]);
      //--- if an error occurs when creating the object, print the message
      if(handle_Envelopes[i]<0)
        {
         Print("The iEnvelopes object[",ENV[i],"] has not been created: Error = ",GetLastError());
         //--- forced program termination
         return(-1);
        }
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- market data
   CopyTime(NULL,0,0,2,T);
   CopyHigh(NULL,0,0,2,H);
   CopyLow(NULL,0,0,2,L);
//--- fill the declared arrays with current values from all indicator buffers
   string name;
   uint GTC=GetTickCount();
//---- indicator buffers
   double   ibMA[],ibMA1[];      // arrays for the iMA indicator
   double   ibEnvelopesUpper[];  // array for the iEnvelopes indicator (UPPER_LINE)
   double   ibEnvelopesLower[];  // array for the iEnvelopes indicator (LOWER_LINE)
   for(int i=ArraySize(handle_MA)-1; i>=0; i--)
     {
      if(!CopyBufferAsSeries(handle_MA[i],0,0,2,true,ibMA))
         return;
      //---
      for(int j=ArraySize(handle_Envelopes)-1; j>=0; j--)
        {
         if(!GetEnvelopesBuffers(handle_Envelopes[j],0,2,ibEnvelopesUpper,ibEnvelopesLower,true))
            return;
         //--- find the intersection point of the iEnvelopes(UPPER_LINE) and iMA indicators
         pEmission=EnvMa.CalcPoint(ibEnvelopesUpper[1],ibEnvelopesUpper[0],ibMA[1],ibMA[0],T[0]);
         if(pEmission.real) // if the intersection point is found, add it to the time series of emission
            tsMA[0].Write(pEmission);
         //--- find the intersection point of the iEnvelopes(LOWER_LINE) and iMA indicators
         pEmission=EnvMa.CalcPoint(ibEnvelopesLower[1],ibEnvelopesLower[0],ibMA[1],ibMA[0],T[0]);
         if(pEmission.real) // if the intersection point is found, add it to the time series of emission
            tsMA[1].Write(pEmission);
        }
      //---
      for(int j=ArraySize(handle_MA)-1; j>=0; j--)
        {
         if(i!=j)
           {
            if(!CopyBufferAsSeries(handle_MA[j],0,0,2,true,ibMA1))
               return;
            //--- find the intersection point of the iMA and iMA indicators
            pEmission=EnvMa.CalcPoint(ibMA1[1],ibMA1[0],ibMA[1],ibMA[0],T[0]);
            if(pEmission.real) // if the intersection point is found, add it to the time series of emission
               tsMA[2].Write(pEmission);
           }
        }
     }
//--- deletion of the graphical objects of emission not to stuff the chart
   if(T[0]>prevTimeBar)
     {
      prevTimeBar=T[0];
      //---
      for(int i=ArraySize(n)-1; i>=0; i--)
         sumprev[i]=integral[i].y;
      //---
      for(int obj=ObjectsTotal(0,0,-1)-1;obj>=0;obj--)
        {
         string obj_name=ObjectName(0,obj,0,OBJ_TREND);
         datetime obj_time=(datetime)ObjectGetInteger(0,obj_name,OBJPROP_TIME);
         if(obj_time<T[0]-DEL*PeriodSeconds())
            ObjectDelete(0,obj_name);
        }
      Comment("Emission © DC2008   Graphical objects = ",ObjectsTotal(0,0,-1));
     }
//--- calculation of integral characteristics of emission
   for(int i=ArraySize(n)-1; i>=0; i--)
      integral[i]=tsMA[i].Read();
//--- displaying integral characteristics of emission
   ArrayInitialize(W,5);
   if(integral[0].n>integral[1].n)
     {
      W[0]=20;
      W[1]=10;
     }
   else
     {
      W[0]=10;
      W[1]=20;
     }
   for(int i=ArraySize(n)-1; i>=0; i--)
     {
      //--- horizontal lines of mean prices
      name="H.line."+(string)i;
      ObjectCreate(0,name,OBJ_HLINE,0,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
      ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DASHDOT);
      ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
      ObjectSetDouble(0,name,OBJPROP_PRICE,integral[i].y);
      //--- markers
      name="P."+(string)i;
      ObjectCreate(0,name,OBJ_TEXT,0,0,0);
      ObjectSetString(0,name,OBJPROP_FONT,"Wingdings");
      ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontMarker[i]);
      ObjectSetString(0,name,OBJPROP_TEXT,CharToString(163));
      ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,integral[i].y);
      ObjectSetInteger(0,name,OBJPROP_TIME,integral[i].t);
      //--- integral curves
      name="T"+(string)i+".line"+(string)T[1];
      ObjectCreate(0,name,OBJ_TREND,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
      ObjectSetInteger(0,name,OBJPROP_WIDTH,W[i]);
      if(sumprev[i]>0)
        {
         ObjectSetDouble(0,name,OBJPROP_PRICE,0,sumprev[i]);
         ObjectSetInteger(0,name,OBJPROP_TIME,0,T[1]);
         ObjectSetDouble(0,name,OBJPROP_PRICE,1,integral[i].y);
         ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
        }
      //--- numerical values of integral characteristics
      if(integral[0].n+integral[1].n>0)
        {
         name="Text"+(string)i+".control";
         ObjectCreate(0,name,OBJ_TEXT,0,0,0);
         ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
         ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontPoint[i]);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colorLine[i]);
         string str=DoubleToString((double)integral[i].n/(double)(integral[0].n+integral[1].n)*100,1);
         ObjectSetString(0,name,OBJPROP_TEXT,str);
         ObjectSetDouble(0,name,OBJPROP_PRICE,0,integral[i].y);
         ObjectSetInteger(0,name,OBJPROP_TIME,0,integral[i].t);
        }
     }
  }

Der Code ist kürzer geworden, doch die Berechnungsspanne hat zugenommen. Jetzt können Sie Ihre Handelsroboter ohne Visualisierung testen und optimieren! 

 

Einsatz wesentlicher Merkmale beim Handel

Wesentliche Merkmale können verwendet werden als ein Generator von Signalen für:

  • Kanal-Durchbruch,
  • Kreuzung miteinander oder dem Kurs,
  • Wechsel der Richtung.
So zeigt z.B. die Abbildung unten wie wesentliche Merkmale von Emissionen hypothetisch als Kreuzungen mit dem Kurs benutzt werden können. Kauf-Signale werden generiert wenn der Kurs ansteigend von der blauen Kurve gekreuzt wird und Verkauf-Signale werden generiert an der rückläufigen Kreuzung des Kurses mit der Kurve in Aquamarin.

Abb. 11 Handelssignale an Kreuzungen wesentlicher Merkmale von Emissionen

Abb. 11 Handelssignale an Kreuzungen wesentlicher Merkmale von Emissionen

 

Fazit

  1. Die Berechnung der wesentlichen Merkmale von Indikator-Emissionen bietet neue Tools und Methoden zur Marktanalyse (Zeitreihen).
  2. Mit Hilfe von Zeitreihen ist es uns gelungen, die Berechnungsgeschwindigkeit von wesentlichen Merkmalen zu steigern.
  3. Und es hat sich für uns die Möglichkeit aufgetan, automatische Handelsstrategien zu entwickeln, die diese Emissionen nutzen.

Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/610

Allgemeine Informationen zu Handelssignalen für MetaTrader 4 und MetaTrader 5 Allgemeine Informationen zu Handelssignalen für MetaTrader 4 und MetaTrader 5

MetaTrader 4 / MetaTrader 5 Handelssignale ist ein Service, mit dessen Hilfe Händler Handelsoperationen eines Signale-Anbieters kopieren können. Unser Ziel war es, diesen neuen, intensiv genutzten Service zu entwickeln und somit Abonnenten zu schützen und ihnen zugleich unnötige Kosten zu ersparen.

MetaTrader 4 und MetaTrader 5 Handelssignale-Widgets MetaTrader 4 und MetaTrader 5 Handelssignale-Widgets

Vor kurzem wurde den Nutzern von MetaTrader 4 und MetaTrader 5 die Möglichkeit geboten, Anbieter von Signalen zu werden und damit zusätzliche Einkünfte zu erzeugen. Und jetzt können Sie die Erfolge Ihres Handels mit Hilfe neuer Widgets auch auf Ihrer Website, Blog oder sozialen Netzwerk-Seiten anzeigen. Die Vorteile dieser Widgets sind klar: damit lässt sich der Bekanntheitsgrad eines Anbieters von Signalen erhöhen und sein Ruf als erfolgreicher Händler festigen, was natürlich auch neue Abonnenten anzieht. Alle Händler, die auf ihren Websites Widgets platzieren, können von diesen Vorteilen profitieren.

Programmierungsgrundlagen für MQL5 Zeit Programmierungsgrundlagen für MQL5 Zeit

Dieser Beitrag konzentriert sich auf Standard MQL5-Funktionen zur Arbeitsweise mit Zeit sowie Programmiertechniken und praktisch sinnvolle Funktionen zur Arbeitsweise mit Zeit, die für die Erzeugung von Expert Advisors und Indikatoren erforderlich sind. Besondere Aufmerksamkeit wird auf die allgemeine Theorie der Zeitmessung gelegt. Dieser Beitrag sollte vor allem für Anfänger unter den MQL5-Programmierern von großem Interesse sein.

Forex VPS von Fozzy Inc. Forex VPS von Fozzy Inc.

VPS (Virtueller Privater Server) ist ein Service, bei dem dem Anwender ein sog. virtueller privaten Server zur Verfügung gestellt wird. Ein virtueller Server ahmt den Betrieb eines physikalischen Standardservers nach. Auf diesem physikalischen Server sind mehrere virtuelle Server konfiguriert, die sich seine Ressourcen teilen.