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); } } //+------------------------------------------------------------------+
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))...
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))...
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
- www.mql5.com
Nachfolgend finden Sie den Oszillatorcode, der in seiner Einfachheit kein Ergebnis liefert.
- 2010.02.23
- MetaQuotes Software Corp.
- www.mql5.com
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
vonEquity 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 0Und hier ist das Diagramm der Balance mit zugewiesenen Werte für den Testzeitraum
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)
Wir überprüfen Equity-Wert auf dem Indikator-Diagramm als von 2011.01.14 22:00
Laut Protokoll
vom14 .01
.201122
: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
?
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
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?