Moving Average der letzten 10-100 Ticks

 

Hallo,

ich gestehe, dass ich noch nicht in die i(average)Funktionen eingetaucht bin, da ich nicht weiß, ob ich sie in meinen nächsten Schritten anwenden werde; ich finde das Thema auch nicht ganz so einfach.

Kann ich eine dieser Funktion nutzen, um an den Durchschnitt der letzten 5,10 und 100 Ticks zu kommen? Wenn ja, welche sollte ich mir da ansehen?

Oder muss ich den Durchschnitt der letzten Ticks zu Fuß rechnen?

1000 Dank & VG,
Christian

 

Die normale Funktion iMA() arbeitet mit Bars, nicht Ticks.

Da meiner Erfahrung kein großer Unterschied zwischen einem ema und einem sma besteht (wenn der (kleine) Unterschied einen Ergebnis-Unterschied macht, wäre meiner Meinung nach das System nichts wert), würde ich einen ema empfehlen, ist schneller weil viel leichter zu berechnen:

Hier zwei Versionen des ema (nxt=der neue Tick, prv= der noch alte Wert des ema, c=Verzögerungskonstante):

#define ema(nxt,prv,c) (c >= 0.99 ? nxt : (((nxt)-(prv))*(c) +(prv)))

double c = 2.0/double(n+1);

double emaCalc(const double nxt, const double prv, const double c) { 
   return( (nxt-prv)*c + prv );
}
 
Carl Schreiber:

Die normale Funktion iMA() arbeitet mit Bars, nicht Ticks.

Da meiner Erfahrung kein großer Unterschied zwischen einem ema und einem sma besteht (wenn der (kleine) Unterschied einen Ergebnis-Unterschied macht, wäre meiner Meinung nach das System nichts wert), würde ich einen ema empfehlen, ist schneller weil viel leichter zu berechnen:

Hier zwei Versionen des ema (nxt=der neue Tick, prv= der noch alte Wert des ema, c=Verzögerungskonstante):

Danke für die schnelle Antwort!

Was soll die Verzögerungskonstante bezwecken?

Ich habe hier leider wohl grundlegene Verständnisprobleme:

Beim ersten: "Wenn c>= 0.99 'was macht hier das ?' nxt 'was macht hier das :' ? Diese Zeichen bedeuten in fast jeder Sprache was anderes..

Das zweite verstehe ich wohl nicht, weil ich das mit der VK nicht verstehe..

Spricht was dagegen mit aus den Arraywerten [elements-n] den AVG selbst zu berechnen? Das könnte doch sogar das schnellste sein als noch eine Funktion aufzurufen?

Vielen Dank & Gruß

 
lindomatic:

Danke für die schnelle Antwort!

Was soll die Verzögerungskonstante bezwecken?

Ich habe hier leider wohl grundlegene Verständnisprobleme:

Beim ersten: "Wenn c>= 0.99 'was macht hier das ?' nxt 'was macht hier das :' ? Diese Zeichen bedeuten in fast jeder Sprache was anderes..

Das zweite verstehe ich wohl nicht, weil ich das mit der VK nicht verstehe..

Spricht was dagegen mit aus den Arraywerten [elements-n] den AVG selbst zu berechnen? Das könnte doch sogar das schnellste sein als noch eine Funktion aufzurufen?

Vielen Dank & Gruß

dann gibts noch zu beachten, du bekommst die Echteste nicht, dein Broker sendet x Ticks pro Sekunde maximal, das steht leider nirgends was maximal ist. Aber das hat nix mit den real Ticks zu tun, die es wirklich gibt.

 
lindomatic:

Danke für die schnelle Antwort!

Beim ersten: "Wenn c>= 0.99 'was macht hier das ?' nxt 'was macht hier das :' ? Diese Zeichen bedeuten in fast jeder Sprache was anderes..

Spricht was dagegen mit aus den Arraywerten [elements-n] den AVG selbst zu berechnen? Das könnte doch sogar das schnellste sein als noch eine Funktion aufzurufen?

Frage 1: siehe https://www.mql5.com/de/docs/basis/operators/ternary

Frage 2: Da spricht absolut nix dagegen.

Wie du mit Ticks umgehen kannst etwas adaptiert:

//+------------------------------------------------------------------+
//|                                                        Ticks.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//|       Original code was found on https://www.mql5.com/de/code/89 |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Bid
#property indicator_label1  "Bid"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Ask
#property indicator_label2  "Ask"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
input int points_indent = 10;
//--- indicator buffers
double    BidBuffer[];
double    AskBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0,BidBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,AskBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total, const int prev_calculated, const int begin, const double& price[])
{
   static int ticks=0;

   if(ticks==0)
      {
         ArrayInitialize(AskBuffer,0);
         ArrayInitialize(BidBuffer,0);
      }
   setMaxMinPrice(ticks,points_indent);

   MqlTick last_tick;
   if(SymbolInfoTick(Symbol(),last_tick))
      {
         BidBuffer[ticks]=last_tick.bid;
         AskBuffer[ticks]=last_tick.ask;
         int shift=rates_total-1-ticks;
         ticks++;
         BidBuffer[rates_total-1]=last_tick.bid;
         AskBuffer[rates_total-1]=last_tick.ask;
         PlotIndexSetInteger(0,PLOT_SHIFT,shift);
         PlotIndexSetInteger(1,PLOT_SHIFT,shift);
         Comment("Bid =",last_tick.bid,"   Ask =",last_tick.ask);
      }

   return(rates_total);
}

//+------------------------------------------------------------------+
//| set Maximum and Minimum for an indicator window based on last values
//+------------------------------------------------------------------+
void setMaxMinPrice(int last_values,int indent)
{
   int visiblebars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
   int depth=MathMin(last_values,visiblebars);
   int startindex=last_values-depth;
   if(startindex<0) startindex=0;
   int max_index=ArrayMaximum(AskBuffer,startindex,depth);
   max_index=max_index>=0?max_index:0;
   int min_index=ArrayMinimum(BidBuffer,startindex,depth);
   min_index=min_index>=0?min_index:0;
   double MaxPrice=AskBuffer[max_index]+indent*_Point;
   double MinPrice=BidBuffer[min_index]-indent*_Point;
   IndicatorSetDouble(INDICATOR_MAXIMUM,MaxPrice);
   IndicatorSetDouble(INDICATOR_MINIMUM,MinPrice);
}

Dieser Indi berechnet SMA,EMA,WMA auf tickbasis. Beide Indis sind nur im Tester getestet und reine versuchsindikatoren.

//+------------------------------------------------------------------+
//|                                                     Tick_MAs.mq5 |
//|                               Copyright © 2018, Ing. Otto Pauser |
//|                       https://www.mql5.com/de/users/kronenchakra |
//+------------------------------------------------------------------+

#property copyright     "Copyright © 2018, Ing. Otto Pauser"
#property link          "https://www.mql5.com/de/users/kronenchakra"
#property version       "1.00"
#property description   "Study of MAs on Ticks\n\nTo hide a lines set it's color to NONE"
#property indicator_separate_window

#define   BUFFERS 6

#property indicator_buffers BUFFERS
#property indicator_plots   BUFFERS

//#include <Info.mqh>
//#include <HLine.mqh>

//+------------------------------------------------------------------+
//| input parameters                                                 |
//+------------------------------------------------------------------+
input int   inpPeriod      =  120;           // Period
input color inpColorAsk    =  clrRed;        // Color Ask
input color inpColorMid    =  clrNONE;       // Color Mid
input color inpColorBid    =  clrSteelBlue;  // Color Bid
input color inpColorSMA    =  clrLime;       // Color SMA
input color inpColorEMA    =  clrAqua;       // Color EMA
input color inpColorWMA    =  clrRed;        // Color WMA
//input bool  inpShowInfo    =  true;          // Show Info
//input bool  inpInfoSubwin  =  true;          // Show Info in subwindow
//input bool  inpShowBid     =  true;          // Show bid price line
//input bool  inpShowAsk     =  true;          // Show ask price line
      int   inpLineWidth   =  1;             // Linewidth
//+------------------------------------------------------------------+

double   Ask[], Bid[], Mid[],       // buffers for rates
         SMA[], EMA[], WMA[];       // buffers for MAs
double   slSMA, slEMA, slWMA;       // slopes

string   IndiName = "Tick_MAs";     // indicator shortname
//CHLine   bidLine, askLine; 

//+------------------------------------------------------------------+
//| initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   Indi.InitLine (Ask,STYLE_SOLID,inpLineWidth,inpColorAsk,"ASK");
   Indi.InitLine (Mid,STYLE_DOT  ,inpLineWidth,inpColorMid,"MID");
   Indi.InitLine (Bid,STYLE_SOLID,inpLineWidth,inpColorBid,"BID");

   Indi.InitLine (EMA,STYLE_SOLID,inpLineWidth,inpColorEMA,"EMA("+IntegerToString(inpPeriod)+")");
   Indi.InitLine (WMA,STYLE_SOLID,inpLineWidth,inpColorWMA,"WMA("+IntegerToString(inpPeriod)+")");
   Indi.InitLine (SMA,STYLE_SOLID,inpLineWidth,inpColorSMA,"SMA("+IntegerToString(inpPeriod)+")");

   IndicatorSetString (INDICATOR_SHORTNAME,IndiName);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| mainloop of indicator                                            |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total, const int prev_calculated, const int begin, const double& price[])
{
   static int ticks=0;
   int shift,i;
   MqlTick last_tick;

   if(ticks==0)                              // first call of OnCalculate()
      {
         //if(inpInfoSubwin)                   // not possible in OnInit
         //   Info.SetSubwindow();
         if(!MQLInfoInteger(MQL_TESTER))     // does not work in tester
            ticks=LoadTicks(Ask,Mid,Bid);       // load ticks from cache

         if(ticks<0)
            return(NULL);                    // no ticks available

         for(i=inpPeriod; i<ticks; i++)      // calculate the MAs
            {
               SMA[i]=iSMA(i,inpPeriod,Mid);
               EMA[i]=iEMA(i,inpPeriod,Mid);
               WMA[i]=iWMA(i,inpPeriod,Mid);
               //shift=rates_total-1-ticks;       // calculate shift of buffers
               //for(i=0; i<BUFFERS; i++)        // shift all buffers
               //   PlotIndexSetInteger(i,PLOT_SHIFT,shift);
            }
      }
      
   if(SymbolInfoTick(Symbol(),last_tick))    // get current tick
         {
            Ask[ticks]= last_tick.ask;       // copy to buffers
            Mid[ticks]=(last_tick.ask+last_tick.bid)*0.5;
            Bid[ticks]= last_tick.bid;
                                             // calculate the MAs
            if(ticks>inpPeriod)
               {
                  SMA[ticks]=iSMA(ticks,inpPeriod,Mid);
                  EMA[ticks]=iEMA(ticks,inpPeriod,Mid);
                  WMA[ticks]=iWMA(ticks,inpPeriod,Mid);
      
                  slSMA=(SMA[ticks]-SMA[ticks-1])/_Point;
                  slEMA=(EMA[ticks]-EMA[ticks-1])/_Point;
                  slWMA=(WMA[ticks]-WMA[ticks-1])/_Point;
               }
            shift=rates_total-1-ticks;       // calculate shift of buffers
            
            for(i=0; i<BUFFERS; i++)        // shift all buffers
               PlotIndexSetInteger(i,PLOT_SHIFT,shift);

            //if(inpShowAsk) askLine.Draw("Ask",last_tick.ask,inpColorAsk,1,STYLE_DASHDOT,IndiName);
            //if(inpShowBid) bidLine.Draw("Bid",last_tick.bid,inpColorBid,1,STYLE_DASHDOT,IndiName);
//            if(inpShowInfo)
//               {
//                  Info.Info(   "Symbol :",_Symbol);
//                  Info.Info("Slope SMA :",slSMA);
//                  Info.Info("Slope EMA :",slEMA);
//                  Info.Info("Slope WMA :",slWMA);
//                  Info.Info(   "Spread :",SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));
//                  Info.Info(    "Shift :",shift);
//                  
//                  //Info.Info(       "Ask :",last_tick.ask);
//                  //Info.Info(       "Bid :",last_tick.bid);
//                  //Info.Info( "Swap Long :",SymbolInfoDouble (_Symbol,SYMBOL_SWAP_LONG ),2);
//                  //Info.Info("Swap Short :",SymbolInfoDouble (_Symbol,SYMBOL_SWAP_SHORT),2);
//               }
            ticks++;                         // increment tick counter
         }

   return(rates_total);                      // return rates_total for next call of OnCalculate()
}

//+------------------------------------------------------------------+
//| calculate EMA                                                    |
//+------------------------------------------------------------------+
double iEMA(const int position,const int period, const double &price[])
{
   static bool first=true;
   static double prev_value;
   if(first)
      {   
         first=false;
         prev_value=price[position];
         return(prev_value);
      }
   double result=0.0;
   if(period>0)
     {
      double pr=2.0/(period+1.0);
      result=price[position]*pr+prev_value*(1-pr);
     }
   prev_value=result;
   return(result);
}

//+------------------------------------------------------------------+
//| calculate SMA                                                    |
//+------------------------------------------------------------------+
double iSMA(const int position,const int period, const double &buffer[])
{
   int i;
   static double sum=NULL;
   if(sum==NULL)
      {   
         if(position>=period-1 && period>0)
           {
            for(i=period; i>0 ;i--)
               sum+=buffer[position-i+1];
           }
      }
  sum=sum+(buffer[position]-buffer[position-period]);
  return(sum/period);
}

//+------------------------------------------------------------------+
//| calculate LWMA                                                   |
//+------------------------------------------------------------------+
double iWMA(const int position,const int period,const double &price[])
{
   double result=0.0,sum=0.0;
   int    i,wsum=0;
   if(position>=period-1 && period>0)
     {
      for(i=period; i>0 ;i--)
        {
         wsum+=i;
         sum+=price[position-i+1]*(period-i+1);
        }
      result=sum/wsum;
     }
   return(result);
}

//+------------------------------------------------------------------+
//| load tickdata from cache                                         |
//+------------------------------------------------------------------+
int LoadTicks(double &askBuf[], double &midBuf[], double &bidBuf[])
{  
   MqlTick TickArray[];                                     // array of ticks
   int loaded=CopyTicks(_Symbol,TickArray);                 // load ticks from cache
   for(int i=0; i<loaded; i++)                              // copy ticks to buffers 
      {
       askBuf[i]= TickArray[i].ask;
       midBuf[i]=(TickArray[i].ask+TickArray[i].bid)*0.5;
       bidBuf[i]= TickArray[i].bid;
      }
   return(loaded);                                          // return number of ticks loaded
}

//+------------------------------------------------------------------+
//| define a class for easy and cmfortable buffer definition         |
//+------------------------------------------------------------------+
class CIndi
{
   private:
      int  m_BufIdx;                                                 // counter for bufferindex
   public:
      bool InitLine (double                 &aBuffer[],              // the buffer
                     ENUM_LINE_STYLE         aLineStyle=STYLE_SOLID, // STYLE_SOLID .. STYLE_DASHDOTDOT
                     int                     aLineWidth=1,           // PLOT_LINE_WIDTH
                     int                     aLineColor=clrRed,      // PLOT_LINE_COLOR
                     string                  aPlotLabel="")          // PLOT_LABEL - "Any String"
         {
            SetIndexBuffer     (m_BufIdx,aBuffer, INDICATOR_DATA);
            PlotIndexSetInteger(m_BufIdx,PLOT_DRAW_TYPE,  DRAW_LINE);
            PlotIndexSetInteger(m_BufIdx,PLOT_LINE_STYLE, aLineStyle);
            PlotIndexSetInteger(m_BufIdx,PLOT_LINE_WIDTH, aLineWidth);
            PlotIndexSetInteger(m_BufIdx,PLOT_LINE_COLOR, aLineColor);
            PlotIndexSetString (m_BufIdx,PLOT_LABEL,      aPlotLabel);
            PlotIndexSetDouble (m_BufIdx,PLOT_EMPTY_VALUE,NULL);
            ArrayInitialize    (aBuffer,NULL);                       // initialize arrays
            m_BufIdx++;                                              // increment bufferindex for next Init()
            return(true);
         } 
};

CIndi Indi;                                                          // instance of CIndi

Da hab ich ziemlich 'herumgewütet' weil CopyTicks() im Tester nicht funktioniert, hat es aber früher, oder ich bilde es mir blos ein.

Dokumentation zu MQL5: Grundlagen der Sprache / Operatoren / Ternärer Operator ?:
Dokumentation zu MQL5: Grundlagen der Sprache / Operatoren / Ternärer Operator ?:
  • www.mql5.com
wird der dritte Operand - "Ausdruck3" durchgeführt. Der zweite und der dritte Operand muessen Werte eines Typs Typs zurückgeben und den Typ void nicht haben. Ergebnis der Durchführung des Wenn-Operators ist das Ergebnis des Ausdrucks2 oder Ergebnis des Ausdrucks3, abhängig vom Ergebnis des Ausdrucks1. Einschränkungen bezüglich der Verwendung...
 
Otto Pauser:

Frage 1: siehe https://www.mql5.com/de/docs/basis/operators/ternary

Frage 2: Da spricht absolut nix dagegen.

Wie du mit Ticks umgehen kannst etwas adaptiert:

Dieser Indi berechnet SMA,EMA,WMA auf tickbasis. Beide Indis sind nur im Tester getestet und reine versuchsindikatoren.

Da hab ich ziemlich 'herumgewütet' weil CopyTicks() im Tester nicht funktioniert, hat es aber früher, oder ich bilde es mir blos ein.

Danke Otto, ist ja interessant mit dem ? :.. immer das selbe in einer anderen Form.. danke für den Link und Deinen Code, den ich mir morgen etwas länger ansehen werde.

Bei mir im Tester funktioniert CopyTicks; also zumindest sehe ich im Array, in das ich kopiere, alle Werte.. bzw. last, volume und volume_real sind leider stets 0.000.

VG

 
amando:

dann gibts noch zu beachten, du bekommst die Echteste nicht, dein Broker sendet x Ticks pro Sekunde maximal, das steht leider nirgends was maximal ist. Aber das hat nix mit den real Ticks zu tun, die es wirklich gibt.

Ja, habe ich schon in einem Artikel hier gelesen, dass es von Bloomberg eine andere Tickqualität bzw. Menge gibt.. aber was soll man machen? Ich kann mir jetzt nicht für ein paar 1000€/Monat einen Bloomberg-Zugriff kaufen.

QTrade bringt bis 6 Ticks pro Sekunde; ich denke bei ordentlich Momentum bei frischen Wirtschaftsdaten noch mehr; damit muss ich erstmal arbeiten. Oder hast Du, von enormen Investitionen abgesehen, eine Alternative?

VG

Grund der Beschwerde: