Hilfe bei Vwap Indicator

 

Hallo,

Ich bin neu bei MT5 ( sowie Metatrader allgemein) und versuche eine Tradingview Pinescript Stragegy in MT5 umzusetzen. Die Strategie nuzt als Bedingung für das Kaufsignal den VWAP Indicator. 


www.tradingview.com/wiki/Volume_Weighted_Average_Price_(VWAP)

also vwap=   summe( typical price * volume) / summe ( volume)      für den jeweiligen Tag


Hier ist noch ein Pinescript code welchen ich gefunden habe, welcher der Standardmässigen VWAP in Tradingview entspricht:

study("VWAP MTF",overlay=true)

TimeFrame = input('D')
start = security(tickerid, TimeFrame, time)

//------------------------------------------------
newSession = iff(change(start), 1, 0)
//------------------------------------------------
vwapsum = iff(newSession, hl2*volume, vwapsum[1]+hl2*volume)
volumesum = iff(newSession, volume, volumesum[1]+volume)
v2sum = iff(newSession, volume*hl2*hl2, v2sum[1]+volume*hl2*hl2)
myvwap = vwapsum/volumesum
dev = sqrt(max(v2sum/volumesum - myvwap*myvwap, 0))
Coloring=close>myvwap?green:red
av=myvwap
showBcol = input(false, type=bool, title="Show barcolors")
showPrevVWAP = input(false, type=bool, title="Show previous VWAP close")
prevwap = iff(newSession, myvwap[1], prevwap[1])
plot(showPrevVWAP ? prevwap : na, style=circles, color=close > prevwap ? green : red)

A=plot(av, style=circles, color=Coloring)

barcolor(showBcol?Coloring:na)




Mein Problem ist dass dieser bei MT5 nicht standardmässig verfügbar ist. Ich wollte diesen nun selber programmieren, und anschliessend mit iCustom() in einem ExpertAdvisor verwenden. 

Leider funktioniert das ganze bisher nicht, ich weiss nicht ob ich nur einen Fehler im Code habe oder es grundsätzlich total falsch angehe.

Im Moment sieht das ganze so aus:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
  
   int start;
   double sumPriceVol =0;
   double sumVol =0;
   
   datetime    tm=TimeCurrent();
   MqlDateTime stm;
   TimeToStruct(tm,stm);
      

   
   if(prev_calculated==0) start=1;  
   else start=prev_calculated-1;    
   for(int i=start;i<rates_total;i++){
   
      sumPriceVol    += ((high[i]+ low[i]+close[i])/3) * double(volume[i]);
      sumVol      += volume[i];
      vwapBuffer[i]= sumPriceVol/sumVol;
      
      if (stm.hour == 0) //zurücksetzen für nächsten tag
      sumPriceVol =0;
      sumVol =0;
      ;
   } 


Leider funktioniert es nicht, wenn ich die Anfangswerte sumPriceVol und sumVol zu 1 ändere, sieht es aus wie im angehängten Screenshot. 

Wenn ich statt volume[] tick_volume[] verwende wird eine Linie geplottet, welche allerdings nicht der VWAP entspricht. 

Über Hilfe wäre ich extrem Dankbar!

Dateien:
mt5.png  170 kb
 

Hi,

Du musst tick_volume[i] an Stelle von volume[i] verwenden. volume[i] ist bei Währungspaaren immer 0;

Siehe Chart->Rechtsclick->Eigenschaften-Tab Show (oder F8).

Und start würde ich so definieren:

int start=(prev_calculated==0)?0:prev_calculated-1;

Zum Testen könntest du auch '#property indicator_separate_window' verwenden, falls unerwartete Werte berechnet werden siehst du es im Chart sonst nicht.

Die Aufsummierung funktioniert auf diese Weise aber sicher nicht. Da ist zumindest eine Periode erforderlich.

Bist du dir der Werte von rates_total und prev_calculated wirklich bewußt?

Die sind die meiste Zeit ident!

Nur beim ersten call von OnCalculate() ist prev_calculated 0.

Nur bei einer neuen Kerze ist rates_total um 1 größer als prev_calculate.

 

Hallo Otto,

Danke schonmal für deine Antwort. Das mit dem Volumen ist mir mittlerweile auch aufgefallen. 

Ich habe jetzt diesen indikator www.mql5.com/de/code/14484?fbclid=IwAR3xKU7_nMI4AX_uT2vhh51ddKQLJM7lvYRHUyk-X7p4NR31NISFsxA5U7w etwas reduziert, sodass dieser nurnoch die "vwap Daily" plottet. Die Werte stimmen mit denen auf Tradingview überein, somit bin ich vorerst zufrieden mit dem indikator. 

Hier mal der Komplette Code für die VWAP  , aus der Datei von Felipe Almeida 


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot VWAP
#property indicator_label1  "VWAP Daily"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrViolet
#property indicator_style1  STYLE_DASH
#property indicator_width1  2


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum DATE_TYPE 
  {
   DAILY,
   WEEKLY,
   MONTHLY
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum PRICE_TYPE 
  {
   OPEN,
   CLOSE,
   HIGH,
   LOW,
   OPEN_CLOSE,
   HIGH_LOW,
   CLOSE_HIGH_LOW,
   OPEN_CLOSE_HIGH_LOW
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime CreateDateTime(DATE_TYPE nReturnType=DAILY,datetime dtDay=D'2000.01.01 00:00:00',int pHour=0,int pMinute=0,int pSecond=0) 
  {
   datetime    dtReturnDate;
   MqlDateTime timeStruct;

   TimeToStruct(dtDay,timeStruct);
   timeStruct.hour = pHour;
   timeStruct.min  = pMinute;
   timeStruct.sec  = pSecond;
   dtReturnDate=(StructToTime(timeStruct));

   if(nReturnType==WEEKLY) 
     {
      while(timeStruct.day_of_week!=0) 
        {
         dtReturnDate=(dtReturnDate-86400);
         TimeToStruct(dtReturnDate,timeStruct);
        }
     }

   if(nReturnType==MONTHLY) 
     {
      timeStruct.day=1;
      dtReturnDate=(StructToTime(timeStruct));
     }

   return dtReturnDate;
  }

sinput  string              Indicator_Name="Volume Weighted Average Price (VWAP)";
input   PRICE_TYPE          Price_Type              = CLOSE_HIGH_LOW;
input   bool                Enable_Daily            = true;


bool        Show_Daily_Value    = true;


double      VWAP_Buffer_Daily[];

double      nPriceArr[];
double      nTotalTPV[];
double      nTotalVol[];
double      nSumDailyTPV = 0, nSumWeeklyTPV = 0, nSumMonthlyTPV = 0;
double      nSumDailyVol = 0, nSumWeeklyVol = 0, nSumMonthlyVol = 0;

int         nIdxDaily=0,nIdxWeekly=0,nIdxMonthly=0,nIdx=0;

bool        bIsFirstRun=true;

ENUM_TIMEFRAMES LastTimePeriod= PERIOD_M1;

string      sDailyStr   = "";

datetime    dtLastDay=CreateDateTime(DAILY),dtLastWeek=CreateDateTime(WEEKLY),dtLastMonth=CreateDateTime(MONTHLY);
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit() 
  {
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

   SetIndexBuffer(0,VWAP_Buffer_Daily,INDICATOR_DATA);


   ObjectCreate(0,"VWAP_Daily",OBJ_LABEL,0,0,0);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_CORNER,3);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_XDISTANCE,180);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_YDISTANCE,40);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_COLOR,indicator_color1);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_FONTSIZE,7);
   ObjectSetString(0,"VWAP_Daily",OBJPROP_FONT,"Verdana");
   ObjectSetString(0,"VWAP_Daily",OBJPROP_TEXT," ");


   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int pReason) 
  {
   ObjectDelete(0,"VWAP_Daily");

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int       rates_total,
                const int       prev_calculated,
                const datetime  &time[],
                const double    &open[],
                const double    &high[],
                const double    &low[],
                const double    &close[],
                const long      &tick_volume[],
                const long      &volume[],
                const int       &spread[]) 
  {

   if(PERIOD_CURRENT!=LastTimePeriod) 
     {
      bIsFirstRun=true;
      LastTimePeriod=PERIOD_CURRENT;
     }

   if(rates_total>prev_calculated || bIsFirstRun) 
     {
      ArrayResize(nPriceArr,rates_total);
      ArrayResize(nTotalTPV,rates_total);
      ArrayResize(nTotalVol,rates_total);

      if(Enable_Daily)   {nIdx = nIdxDaily;   nSumDailyTPV = 0;   nSumDailyVol = 0;}


      for(; nIdx<rates_total; nIdx++) 
        {
         if(CreateDateTime(DAILY,time[nIdx])!=dtLastDay) 
           {
            nIdxDaily=nIdx;
            nSumDailyTPV = 0;
            nSumDailyVol = 0;
           }

         nPriceArr[nIdx] = 0;
         nTotalTPV[nIdx] = 0;
         nTotalVol[nIdx] = 0;

         switch(Price_Type) 
           {
            case OPEN:
               nPriceArr[nIdx]=open[nIdx];
               break;
            case CLOSE:
               nPriceArr[nIdx]=close[nIdx];
               break;
            case HIGH:
               nPriceArr[nIdx]=high[nIdx];
               break;
            case LOW:
               nPriceArr[nIdx]=low[nIdx];
               break;
            case HIGH_LOW:
               nPriceArr[nIdx]=(high[nIdx]+low[nIdx])/2;
               break;
            case OPEN_CLOSE:
               nPriceArr[nIdx]=(open[nIdx]+close[nIdx])/2;
               break;
            case CLOSE_HIGH_LOW:
               nPriceArr[nIdx]=(close[nIdx]+high[nIdx]+low[nIdx])/3;
               break;
            case OPEN_CLOSE_HIGH_LOW:
               nPriceArr[nIdx]=(open[nIdx]+close[nIdx]+high[nIdx]+low[nIdx])/4;
               break;
            default:
               nPriceArr[nIdx]=(close[nIdx]+high[nIdx]+low[nIdx])/3;
               break;
           }

         if(tick_volume[nIdx]) 
           {
            nTotalTPV[nIdx] = (nPriceArr[nIdx] * tick_volume[nIdx]);
            nTotalVol[nIdx] = (double)tick_volume[nIdx];
              } else if(volume[nIdx]) {
            nTotalTPV[nIdx] = (nPriceArr[nIdx] * volume[nIdx]);
            nTotalVol[nIdx] = (double)volume[nIdx];
           }

         if(Enable_Daily && (nIdx>=nIdxDaily)) 
           {
            nSumDailyTPV += nTotalTPV[nIdx];
            nSumDailyVol += nTotalVol[nIdx];

            if(nSumDailyVol)
               VWAP_Buffer_Daily[nIdx]=(nSumDailyTPV/nSumDailyVol);

            if((sDailyStr!="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits)) && Show_Daily_Value) 
              {
               sDailyStr="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits);
               ObjectSetString(0,"VWAP_Daily",OBJPROP_TEXT,sDailyStr);
              }
           }



         dtLastDay=CreateDateTime(DAILY,time[nIdx]);
         dtLastWeek=CreateDateTime(WEEKLY,time[nIdx]);
         dtLastMonth=CreateDateTime(MONTHLY,time[nIdx]);
        }



        

      bIsFirstRun=false;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+




Nun bin ich mir jedoch nicht ganz sicher wie ich diesen in meinem ExpertAdvisor einsetze. In Pinescript sieht dieser folgendermassen aus:


if c > vwap + (c/200) //200
    if macd > 0
        strategy.entry("buy", true, when = a ==true  )


ich hatte gehofft ich könnte den indikator mit iCustom verwenden, etwa so: 

      vwap = iCustom(NULL,0,"Vwap_3.mq5");
  
      if ( PRICE_CLOSE < vwap + (PRICE_CLOSE /200) )
VWAP - Volume Weighted Average Price
VWAP - Volume Weighted Average Price
  • www.mql5.com
2016-02-04; v1.47: Die Erhöhung der Produktivität.2016-01-15; v1.46: Die Erhöhung der Produktivität.2015-12-31; v1.45: Die Erhöhung der Produktivität.2015-12-31; v1.44: Die Erhöhung der Produktivität.2015-12-31; v1.43: Die Erhöhung der Produktivität.2015-12-26; v1.42: Die Erhöhung der Produktivität.2015-12-26; v1.41: Kleine Änderungen für die...
 

Da spricht nichts dagegen.

Zeile 68 würde ich aber entfernen, 'Indicator_Name' wird sowieso nirgends verwendet und stört bei der Parameterübergabe vom EA zum Indikator.

Viel Erfolg damit!

Das mit iCustom geht so:

ha1=iCustom(_Symbol,Timeframe,"Dateiname ohne .ex5",optional parameter1, optional parameter2, usw...);
if(HandleError(ha1,"MYMA fast"))
   return;


bool HandleError(int _handle, string _name)
{
   if(_handle!=INVALID_HANDLE)
      return(false);
      
   if(MQLInfoInteger(MQL_TESTER))
      Print("*ERROR* creating ",_name," handle.");
   else
      Alert("*ERROR* creating ",_name," handle.");

   return(true);
}


In der OnTick() wird dann der buffer mit CopyBuffer() ausgelesen.

 

Hallo, 

ich stehe wieder vor einem Rätsel. Und zwar möchte ich den Preis der aktuellen Position in einer Bedingung verwenden.  Grundsätzlich kann ich mir den Wert auch als Kommentar ausgeben lassen.

double posPrice = PositionGetDouble(POSITION_PRICE_OPEN); 

Comment(posPrice); 

//funktioniert
                


das komische ist aber , dass sobald ich die variable posPrice verwende (Zb in einer if Bedingung, oder sie an eine Funktion übergebe)  diese plötzlich =0 wird. 


double posPrice = PositionGetDouble(POSITION_PRICE_OPEN); 

if ( posPrice != 0 )
        irgendwas;

//funktioniert nicht, posPrice wird/bleibt null 
                


kann mir jemand auf die Sprünge helfen?

 

ist überhaupt eine position offen?

PositionSelect(_Symbol)

Check mal das. Sonst geht garnix.

 
Otto Pauser:

ist überhaupt eine position offen?

Check mal das. Sonst geht garnix.


Ohje, das wars schon. Danke du bist ein Retter!


Ich hoffe ich überflute dich nicht zu sehr mit Fragen, aber ich hätte noch zwei:

- ist es möglich einen Variablenwert aus dem EA auf dem Chart zu plotten, oder muss ich dazu einen Indikator erstellen?

-ist es normal dass der Strategietest sehr langsam ist? Für einen Monat (jeder Tick) dauert es ca eine halbe dreiviertel Stunde.

 

Die einfachste Methode was auf dem Chart auszugeben ist die Funktion 'Comment()'

Die Geschwindigkeit des Testers hängt von der Anzahl der zu berechnenden Kombinationen ab und von der Länge des Testzeitraumes.

Prozessorleistung ist hier gefragt. Oder die Cloud.

'Fast genetic based algorithm' sollte ausgewählt sein.

 

Hallo,

Mal wieder eine kleine Frage:  Ist es möglich in einem EA den EURUSD Kurs auszulesen?

Ich habe das Volumen für meine Orders ( für eine CFD, nicht Forex) bisher so berechnet:


   double orderVolumen = round(Einsatz/currentPrice);        // Einsatz = input double

        if(kaufbedingung)
          executeLong(orderVolumen);


Dabei ist der Einsatz eine Input Variable. Nun würde ich aber lieber einen Prozentsatz meines Kontostands investieren lassen. Grundsätzlich wäre das auch kein Problem, unglücklicherweise ist aber mein Account auf Euro, die Aktie jedoch in Dollar. Mir fehlt also eine Möglichkeit umzurechnen.

        double kontoStand = AccountInfoDouble(ACCOUNT_BALANCE); // in €
        double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);  // in $

        double EURUSD =  ???????  
        

        orderVolumen = ( ( kontoStand * EURUSD)/ currentPrice);
 

Mann!

Weißt Du wie viel Zeit Du dir erspart hättest zB. nach "multi currency ea" und dann unter "Artikel" (links) zu suchen (finde auf Anhieb dutzende), statt als Newbie sich irgendetwas zusammen zu basteln und sich so von Fehler zu Fehler zu hangeln?

So findest Du 1.) nicht nur Programme ohne Kompilerfehler, 2.) die Algorithmen stimmen auch und sind auch noch erklärt!!

 

hallo,

bei wortwörtlich diesem suchbegriff unter artikel finde ich exakt 8 suchergebnisse, haben wir das selbe verständnis von "duzend(e)" ? 

die suchfunktion sowie google habe ich schon verwendet, da ich aber zu keiner lösung gekommen bin frage ich hier. ich denke dafür sind foren da. ich verstehe schon dass neulinge manchmal etwas anstrengend wirken mögen, aber irgendwo muss man ja anfangen. 


ps: entschuldigt die mangelnden grossbuchstaben, meine umschalttasten haben sich vorher verabschiedet.


edit

mein ursprünglicher versuch mit symbolinfodouble funktioniert, ich hatte nur die anführungszeichen um das symbol vergessen

        double kontoStand = AccountInfoDouble(ACCOUNT_BALANCE); // in €
        double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);  // in $

        double EURUSD =  SymbolInfoDouble("EURUSD", SYMBOL_BID);
        

        orderVolumen = ( ( kontoStand * EURUSD)/ currentPrice);
Grund der Beschwerde: