Equity-Oszillator von MQL5 bedeutet

 

Hallo zusammen!

Ich habe einen Tag lang mit dem Problem gekämpft, den Equity-Oszillator unter dem Diagramm zu erstellen, an das er angehängt ist (weil dem Diagramm im Tester das Wichtigste fehlt, nämlich die einfache Vergleichbarkeit mit Marktveränderungen, wie andere übrigens geschrieben haben).

Das Problem hat meines Erachtens zwei Seiten.

Zum einen funktioniert die Methode zur Ermittlung des Eigenkapitals AccountInfoDouble(ACCOUNT_EQUITY) für jeden Bar in der OnCalculate-Methode des Oszillators nicht.

Andererseits ist es schwierig zu erkennen, ob der Oszillator-Chart (bzw. sein Datenpuffer) vom OnTick-Code des Expert Advisors aus geändert werden kann, wo die Methode AccountInfoDouble(ACCOUNT_EQUITY) funktioniert.

Im Folgenden finden Sie den Code des Oszillators, der trotz seiner Einfachheit keine Ergebnisse liefert.

//+------------------------------------------------------------------+
//|                                                       Equity.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double        Values[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   //--- indicator buffers mapping
   SetIndexBuffer(0,Values,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 100);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   ArraySetAsSeries(Values, false);
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 toCount = (int)MathMin(rates_total, rates_total - prev_calculated + 1);
   for (int i = toCount - 2; i >= 0; --i){
      Values[i] = AccountInfoDouble(ACCOUNT_EQUITY);  
   }
   return rates_total;
}

Intuitiv verstehe ich, dass das Problem auf einfache Weise gelöst werden muss, aber ich weiß nicht, wie.

Vielleicht hat jemand eine Idee in dieser Hinsicht?

 
DV2010:

Hallo zusammen!

Ich habe einen Tag lang mit dem Problem gekämpft, den Equity-Oszillator unter dem Diagramm zu erstellen, an das er angehängt ist (weil dem Diagramm im Tester das Wichtigste fehlt, nämlich die einfache Vergleichbarkeit mit Marktveränderungen, über die andere übrigens geschrieben haben).

Das Problem hat meines Erachtens zwei Seiten.

Zum einen funktioniert die Methode zur Ermittlung des Eigenkapitals AccountInfoDouble(ACCOUNT_EQUITY) für jeden Bar in der OnCalculate-Methode des Oszillators nicht.

Andererseits ist es schwierig zu erkennen, ob der Oszillator-Chart (bzw. sein Datenpuffer) vom OnTick-Code des Expert Advisors aus geändert werden kann, wo die Methode AccountInfoDouble(ACCOUNT_EQUITY) funktioniert.

Im Folgenden finden Sie den Code des Oszillators, der trotz seiner Einfachheit keine Ergebnisse liefert.


Intuitiv verstehe ich, dass das Problem auf einfache Weise gelöst werden muss, aber ich weiß nicht, wie.

Vielleicht hat jemand eine Idee zu diesem Thema?

AccountInfoDouble(ACCOUNT_EQUITY); liefert den aktuellen Stand des Eigenkapitals und hat keine Historie. In Ihrem Beispiel werden alle Zellen des Indikatorpuffers mit demselben Wert beschrieben. Hier ein Beispiel für den Aktienindikator, der jedoch erst ab dem Zeitpunkt funktioniert, zu dem er auf dem Chart erscheint

//+------------------------------------------------------------------+
//|                                                       Equity.mq5 |
//|                                                    Сергей Грицай |
//|                                               sergey1294@list.ru |
//+------------------------------------------------------------------+
#property copyright "Сергей Грицай"
#property link      "sergey1294@list.ru"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  MediumAquamarine
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         Label1Buffer1[];
double         Label1Buffer2[];
double         Label1Buffer3[];
double         Label1Buffer4[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer1,INDICATOR_DATA);
   SetIndexBuffer(1,Label1Buffer2,INDICATOR_DATA);
   SetIndexBuffer(2,Label1Buffer3,INDICATOR_DATA);
   SetIndexBuffer(3,Label1Buffer4,INDICATOR_DATA);

   ArraySetAsSeries(Label1Buffer1,true);
   ArraySetAsSeries(Label1Buffer2,true);
   ArraySetAsSeries(Label1Buffer3,true);
   ArraySetAsSeries(Label1Buffer4,true);
   
   ArrayInitialize(Label1Buffer1,0.0);
   ArrayInitialize(Label1Buffer2,0.0);
   ArrayInitialize(Label1Buffer3,0.0);
   ArrayInitialize(Label1Buffer4,0.0);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   Label1Buffer1[0]= AccountInfoDouble(ACCOUNT_EQUITY);
   Label1Buffer2[0]= AccountInfoDouble(ACCOUNT_EQUITY);
   Label1Buffer3[0]= AccountInfoDouble(ACCOUNT_EQUITY);
   Label1Buffer4[0]= AccountInfoDouble(ACCOUNT_EQUITY);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Der Indikator wurde ein wenig korrigiert, so dass er besser ist.

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  MediumAquamarine
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         Label1Buffer1[];
double         Label1Buffer2[];
double         Label1Buffer3[];
double         Label1Buffer4[];

datetime Time[1];
datetime curbar[1];
datetime lastbar[1];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer1,INDICATOR_DATA);
   SetIndexBuffer(1,Label1Buffer2,INDICATOR_DATA);
   SetIndexBuffer(2,Label1Buffer3,INDICATOR_DATA);
   SetIndexBuffer(3,Label1Buffer4,INDICATOR_DATA);

   ArraySetAsSeries(Label1Buffer1,true);
   ArraySetAsSeries(Label1Buffer2,true);
   ArraySetAsSeries(Label1Buffer3,true);
   ArraySetAsSeries(Label1Buffer4,true);

   ArrayInitialize(Label1Buffer1,0.0);
   ArrayInitialize(Label1Buffer2,0.0);
   ArrayInitialize(Label1Buffer3,0.0);
   ArrayInitialize(Label1Buffer4,0.0);

//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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(NewBar())
     {
      Label1Buffer1[0]= AccountInfoDouble(ACCOUNT_EQUITY);
      Label1Buffer2[0]= AccountInfoDouble(ACCOUNT_EQUITY);
      Label1Buffer3[0]= AccountInfoDouble(ACCOUNT_EQUITY);
      Label1Buffer4[0]= AccountInfoDouble(ACCOUNT_EQUITY);
     }
   if(AccountInfoDouble(ACCOUNT_EQUITY)>Label1Buffer2[0])Label1Buffer2[0]= AccountInfoDouble(ACCOUNT_EQUITY);
   if(AccountInfoDouble(ACCOUNT_EQUITY)<Label1Buffer3[0])Label1Buffer3[0]= AccountInfoDouble(ACCOUNT_EQUITY);
   Label1Buffer4[0]=AccountInfoDouble(ACCOUNT_EQUITY);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
bool NewBar()
  {
   if(CopyTime(_Symbol,0,0,1,Time)<1)return(false);

   curbar[0]=Time[0];
   if(lastbar[0]!=curbar[0])
     {
      lastbar[0]=curbar[0];
      return(true);
     }
   else
     {
      return(false);
     }
  }
//+------------------------------------------------------------------+
 

Das Bild, das sich ergibt, sieht ungefähr so aus

т

 

Sergej, ich danke dir!

Aber ist es wirklich möglich, einen robusten Aktien-Oszillator unter Berücksichtigung der Historie zu entwickeln?

Der Expert Advisor zeigt alle Aktienwerte für den im Tester ausgewählten Zeitraum auf einfachste Weise an

Drucken(AccountInfoDouble(ACCOUNT_EQUITY))...

 
DV2010:

Sergej, ich danke dir!

Aber ist es wirklich möglich, einen robusten Aktien-Oszillator unter Berücksichtigung der Historie zu entwickeln?

Der Expert Advisor zeigt alle Aktienwerte für den im Tester ausgewählten Zeitraum auf einfachste Weise an

Drucken(AccountInfoDouble(ACCOUNT_EQUITY))...

Das kann man, aber es ist nicht so einfach. Sie müssen den Handel nach der Historie der Geschäfte emulieren, und es kann auch Probleme mit der Synchronisierung von Daten über verschiedene Instrumente geben. Und verwechseln Sie den Indikator nicht mit dem Tester. Es ist das Prüfgerät, das den Handel emuliert.
 

Nach den sich ändernden Werten in Print(AccountInfoDouble(ACCOUNT_EQUITY)) zu urteilen, gibt es Änderungen im Eigenkapital, weil der aktuelle Zustand des Eigenkapitals aus der Historie in der OnCalculatde(...)-Methode des Indikators nachgebildet wird und dies synchron mit der Verarbeitung in der OnTick-Methode des EA geschieht.

Wo liegt also das Problem? Warum variiert der Gewinn in der Ausgabe, während er im Indikator unverändert bleibt (in meinem Fall - 10000)?

Der Code ist einfach (ich habe ihn ein wenig umgeschrieben):

//+------------------------------------------------------------------+
//|                                                       Equity.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double Values[];


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   //--- indicator buffers mapping
   SetIndexBuffer(0,Values,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 100);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   ArraySetAsSeries(Values, false);
   return(0);
  }


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[]){


   //---Блок контрольных показателей
   HistorySelect(0,TimeCurrent());
   Print("Equity - OnCalculate: HistoryDealsTotal()=", HistoryDealsTotal());
   Print("Equity - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=", AccountInfoDouble(ACCOUNT_EQUITY));
   Print("Equity - OnCalculate: rates_total=", rates_total);
   Print("Equity - OnCalculate: prev_calculated=", prev_calculated);
   Print("Equity - OnCalculate: ArraySize(open)= ", ArraySize(open));
   Print("Equity - OnCalculate: ArraySize(Values)= ", ArraySize(Values));
   Print("Equity - OnCalculate: datetime(time[",ArraySize(time)-1,"])= ", datetime(time[ArraySize(time)-1]));  


   //---Блок заполнения Индикатора и журнала сообщений значениями
   for (int i = prev_calculated; i <= rates_total-1; ++i){
      //Путем сопоставления с выводом значений в Print() исследуются 2 варианта:
      // - Первый вариант - индикатор показывает динамику цен - правильно
      //Values[i] = open[i]; //То есть в соответствии с выводом в Print(...)
      // - Второй вариант - индикатор показывает динамику Equity - неправильно, так как объем остается постоянным
      Values[i] = AccountInfoDouble(ACCOUNT_EQUITY); //Хотя в выводе Print(...) он меняется 
      //---Блок проверки даты и показателей цены открытия и Equity в цикле заполнения в рамках диапазона тестирования:
      if(prev_calculated > 0){
         Print("Equity - OnCalculate - Cycle: datetime([",i,"])= ", datetime(time[i]));
         Print("Equity - OnCalculate - Cycle: ArraySize([",i,"])= ", open[i]);
         Print("Equity - OnCalculate - Cycle: AccountInfoDouble(ACCOUNT_EQUITY) = ", AccountInfoDouble(ACCOUNT_EQUITY));    
      }
   }
   return rates_total;
}


Infolgedessen ist der Saldowert im Indikator konstant und = 10000, während sich in der Ausgabe Print ändert, und im Falle der Dynamik nicht des Saldos, sondern der Preise wird er korrekt angezeigt.

Für den letzten Balken des getesteten Zeitraums lauten die Parameter zum Beispiel wie folgt

2011.01.19 19:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate - Zyklus: AccountInfoDouble(ACCOUNT_EQUITY) = 9949.299999999999
2011.01.19 19:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate - Zyklus: ArraySize([6418])= 1.33724
2011.01.19 19:27:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate - Zyklus: datetime([6418])= 2011.01.14 22:00:00
2011.01.19 19:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate: datetime(time[6418])= 2011.01.14 22:00:00
2011.01.19 19:27:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate: ArraySize(Werte)=6419
2011.01.19 19 19:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate: ArraySize(open)= 6419
2011.01.19 19 19:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate: prev_calculated=6418
2011.01.19 19:27:27:27 Kern 1 2011.01.14 22:00:00 Aktien - OnCalculate: rates_total=6419
2011.01.19 19:27:27:27 Kern 1 2011.01.14 22:00:00 Eigenkapital - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=9949.299999999999
2011.01.19 19:27:27 Kern 1 2011.01.14 22:00:00 Aktien - OnCalculate: HistoryDealsTotal()=12

Документация по MQL5: Общие функции / Print
Документация по MQL5: Общие функции / Print
  • www.mql5.com
Общие функции / Print - Документация по MQL5
Dateien:
Equity.mq5  4 kb
 

So ist es hübscher.

 
DV2010:

Nachfolgend finden Sie den Oszillatorcode, der in seiner Einfachheit kein Ergebnis liefert.

Fügen Sie den Code korrekt ein, so dass er hervorgehoben ist.
MQL5.community - Памятка пользователя
MQL5.community - Памятка пользователя
  • 2010.02.23
  • MetaQuotes Software Corp.
  • www.mql5.com
Вы недавно зарегистрировались и у вас возникли вопросы: Как вставить картинку в сообщение на форуме, как красиво оформить исходный код MQL5, где находятся ваши Личные сообщения? В этой статье мы подготовили для вас несколько практических советов, которые помогут быстрее освоиться на сайте MQL5.community и позволят в полной мере воспользоваться доступными функциональными возможностями.
 
DV2010:

Nach den sich ändernden Werten in Print(AccountInfoDouble(ACCOUNT_EQUITY)) zu urteilen, gibt es Änderungen im Eigenkapital, weil der aktuelle Zustand des Eigenkapitals aus der Historie in der OnCalculatde(...)-Methode des Indikators nachgebildet wird und dies synchron mit der Verarbeitung in der OnTick-Methode des EA geschieht.

Wo liegt also das Problem? Warum variiert der Gewinn in der Ausgabe, während er im Indikator konstant bleibt (in meinem Fall - 10000)?


Es genügt, alle unnötigen Ausgaben auszukommentieren und den Wert prev_calculated auszugeben, um zu verstehen, dass der Indikator nur zum ersten Mal berechnet wird und der Zyklus bei den nächsten Ticks nicht mehr funktioniert

   //---Блок контрольных показателей
   //HistorySelect(0,TimeCurrent());
   //Print("Equity - OnCalculate: HistoryDealsTotal()=", HistoryDealsTotal());
   //Print("Equity - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=", AccountInfoDouble(ACCOUNT_EQUITY));
   //Print("Equity - OnCalculate: rates_total=", rates_total);
   //Print("Equity - OnCalculate: prev_calculated=", prev_calculated);
   //Print("Equity - OnCalculate: ArraySize(open)= ", ArraySize(open));
   //Print("Equity - OnCalculate: ArraySize(Values)= ", ArraySize(Values));
   //Print("Equity - OnCalculate: datetime(time[",ArraySize(time)-1,"])= ", datetime(time[ArraySize(time)-1]));  
   Print("prev_calculated=",prev_calculated,"   rates_total=",rates_total);
 

Rosh, um ehrlich zu sein, habe ich dich nicht sehr gut verstanden . Die Ausgabe wurde nur benötigt, um sicherzustellen , dasssich dasEigenkapital innerhalb des Testbereichs ändert

.

Die Tatsache, dass die Schleife in OnCalculated in Bezug auf den Bereich vor dem Beginn des Testbereichs funktioniert, und dann innerhalb des Testbereichsjeder Aufruf von OnCalculated nur einen Tick und einen Durchlauf enthält, ist klar, aber warum wird der sich ändernde Wert

von

Equity nicht auf dem Indikator angezeigt, obwohl die sich ändernden Werte in das Indikator-Array geschrieben werden?

Hier ist der Code der gekürzten Version von OnCalculated:

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[]){
   Print("prev_calculated=",prev_calculated,"   rates_total=",rates_total);
   Print("Equity - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=", AccountInfoDouble(ACCOUNT_EQUITY));
   for (int i = prev_calculated; i <= rates_total-1; ++i){
      Values[i] = AccountInfoDouble(ACCOUNT_EQUITY);
   }
   return rates_total;
}

Hier sind die Ergebnisse am Ende des Testzeitraums, wo wir sehen können, dass Equity, die wir schreiben, um das Array von Indikator-Werte ändert und unterscheidet sich von der anfänglichen Gleichgewicht gleich 10000:

2011.01.20 13:32:07     Core 1  OnTester result 0
2011.01.20 13:32:07     Core 1  2011.01.14 23:59:59   order performed sell 0.15 at 1.33829 [#13 sell 0.15 EURUSD at 1.33829]
2011.01.20 13:32:07     Core 1  2011.01.14 23:59:59   deal performed [#13 sell 0.15 EURUSD at 1.33829]
2011.01.20 13:32:07     Core 1  2011.01.14 23:59:59   deal #13 sell 0.15 EURUSD at 1.33829 done (based on order #13)
2011.01.20 13:32:07     Core 1  2011.01.14 23:59:59   position closed due end of test at 1.33829 [buy 0.15 EURUSD 1.33593]
2011.01.20 13:32:07     Core 1  2011.01.14 22:00:00   Equity - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=9949.299999999999
2011.01.20 13:32:07     Core 1  2011.01.14 22:00:00   prev_calculated=6418   rates_total=6419
2011.01.20 13:32:07     Core 1  2011.01.14 21:00:00   CTrade::PositionOpen: instant buy 0.15 EURUSD at 1.33593 [done at 0.00000]
2011.01.20 13:32:07     Core 1  2011.01.14 21:00:00   order performed buy 0.15 at 1.33593 [#12 buy 0.15 EURUSD at 1.33593]
2011.01.20 13:32:07     Core 1  2011.01.14 21:00:00   deal performed [#12 buy 0.15 EURUSD at 1.33593]
2011.01.20 13:32:07     Core 1  2011.01.14 21:00:00   deal #12 buy 0.15 EURUSD at 1.33593 done (based on order #12)
2011.01.20 13:32:07     Core 1  2011.01.14 21:00:00   instant buy 0.15 EURUSD at 1.33593 (1.33577 / 1.33593 / 1.33577)
Und hier ist das Diagramm der Balance mit zugewiesenen Werte für den Testzeitraum

Wir überprüfen Equity-Wert auf dem Indikator-Diagramm als von 2011.01.14 22:00

Laut Protokoll

vom

14 .01

.2011

22

:00:00

sollte er gleich 9949 sein:
... 2011.01.14 22:00:00   Equity - OnCalculate: AccountInfoDouble(ACCOUNT_EQUITY)=9949.299999999999

Und was sehen wir auf dem Indikatordiagramm

?