Wie meinst Du das? Wie würde der Code dann aussehen? Meinst Du das?
Damit funktioniert es nicht.
Ergänzung: Im Livetest zeigt sich, das es mit der IsNewBar Time Funktion nicht geht. Seltsam. Mit der oben geposteten Version klappt es.
In deiner version nimmst du die arrays bevor du die isnew bar aufrufst, das heist, er hat schon einen wert gespeichert, der muss nicht genau
bei isnewbar auftreten.
array index 0 bedeutet die aktuelle kerze, also bei isnewbar genau die jetzige, und da muss der wert gerade passen
In deiner version nimmst du die arrays bevor du die isnew bar aufrufst, das heist, er hat schon einen wert gespeichert, der muss nicht genau bei isnewbar auftreten.
array index 0 bedeutet die aktuelle kerze, also bei isnewbar genau die jetzige, und da muss der wert gerade passen
@ amando: Du hast vollkommen Recht.
Noch eine Ergänzung: Damit funktioniert es jetzt auch, sieht das für Euch okay aus? Oder was kann man daran noch optimieren?
//+------------------------------------------------------------------+#property copyright"Copyright 2020, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"#include<Trade\Trade.mqh> // Benötigte Library// Erstellung einer Instanz namens CTrade
CTrade trade;
// Eingaben und Array- und Variablendefinitioneninputint SL=200; // Stop Loss in Pointsinputint TP=100; // Take Profit in Pointsinputint setADX = 22; // ADX Setting for Crossing between D+ and D-inputint setPer = 14; // ADX Periode - Standard 14, größere Werte spätere Trends--> Genauerinputdouble myLotSize = 0.01; // Lotsize inputint MN = 12345; // IMMER EINE MAGIC NUMBER VERWENDEN BEI EINEM EA; NIEMALS OHNEinputstring Text = "myOwnText"; // Diesen kannst Du verwenden um den Komment in der Position anzuzeigen// für ADX-Wertdouble ArrayADX[];
// für D+-Wertdouble ArrayDpl[];
// für D- -Wertdouble ArrayDmi[];
// für unseren ADX-Indikatorint adx;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---für ADX-Indikator
adx=iADX(Symbol(),_Period,setPer);
//--- What if handle returns Invalid Handleif(adx<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
// sortiere die Preise abwärts von der aktuellen KerzeArraySetAsSeries(ArrayADX,true);
ArraySetAsSeries(ArrayDpl,true);
ArraySetAsSeries(ArrayDmi,true);
trade.SetExpertMagicNumber(MN); // Immer die Magic Number verwenden um Trades zu sortieren, den kommentar kann der Broker verändern return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Release our indicator handlesIndicatorRelease(adx);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
// Bevor wir unseren Kaufhandel eröffnen können - müssen wir den Nachfragekurs kennendouble Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Ask Price, is the price when we want to buy something, _Digits variable stores the number of digits after the decimal point// Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX DefinitionCopyBuffer(adx,0,0,3,ArrayADX); // ADX-WertCopyBuffer(adx,1,0,3,ArrayDpl); // DplusCopyBuffer(adx,2,0,3,ArrayDmi); // D-Minus// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden // Berechne den EA für für die aktuelle Kerze (ADX)double ADXWert=NormalizeDouble(ArrayADX[0],_Digits); // ADXdouble DplWert=NormalizeDouble(ArrayDpl[0],_Digits); // D+ Wert aktuelle Kerzedouble DminWert=NormalizeDouble(ArrayDmi[0],_Digits); // D- Wert aktuelle Kerze// Ende der ADX-Handelsstrategie Umsetzung // Testkommentar// Comment ("Aktueller D+ Wert: ",DplWert, "\n ", "Vorheriger D+ Wert: ", DplWert1);bool Buy=((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] < ArrayDmi[1]));
if(IsNewBar(_Symbol,0))
{ // Anfang is NewBar//--- Keine Position und kein Kaufsignalif(PositionsTotal()<1 && Buy)
{
trade.Buy(myLotSize,_Symbol,Ask,(Ask-SL*_Point),(Ask+TP*_Point),Text); // Parameter: myLotsize = Positionsgröße, _Symbol= akt. Chartsymbol, Ask = Ask Preis, SL, TP, letzte Parameter = für Kommentare
}
} // Ende is NewBar
} // Ende on Tick// Ab hier Funktionen einfügenbool IsNewBar(string symbol,ENUM_TIMEFRAMES timeframe)
{
//---- liefert die Zeit des aktuellen Balkens.datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));
datetime m_TOld=0;
//---Neuer Balkenif(TNew!=m_TOld && TNew)
{
m_TOld=TNew;
//--- Es gibt eine neue Bar!return(true);
Print("Neue Kerze!");
}
//--- noch keine neuen Balken!return(false);
}
bei meinem aktuellen Code wird nur dann ein Trade eröffnet, wenn der alte zuvor geschlossen wurde. Da ich aber gerne hätte, das immer dann ein Trade eröffnet wird, wenn die Signale stimmen, muss ich was an der Zeitfunktion ändern.
Dabei besteht immer noch das alte/neue Problem aus den vorherigen beschriebenen Seiten.
Interessant ist, das nur die Crossing Bedingung bei dem nachfolgenden Code ignoriert wird, die ich aktuell auskommentiert habe: ((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) /*&& (ArrayDpl[1] < ArrayDmi[1])*/))
//+------------------------------------------------------------------+#property copyright"Copyright 2020, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"#include<Trade\Trade.mqh> // Benötigte Library// Erstellung einer Instanz namens CTrade
CTrade trade;
// Eingaben und Array- und Variablendefinitioneninputint SL=200; // Stop Loss in Pointsinputint TP=100; // Take Profit in Pointsinputint setADX = 10; // ADX Setting for Crossing between D+ and D-inputint setPer = 14; // ADX Periode - Standard 14, größere Werte spätere Trends--> Genauerinputdouble myLotSize = 0.01; // Lotsize inputint MN = 12345; // IMMER EINE MAGIC NUMBER VERWENDEN BEI EINEM EA; NIEMALS OHNEinputstring Text = "myOwnText"; // Diesen kannst Du verwenden um den Komment in der Position anzuzeigen// für ADX-Wertdouble ArrayADX[];
// für D+-Wertdouble ArrayDpl[];
// für D- -Wertdouble ArrayDmi[];
// für unseren ADX-Indikatorint adx;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---für ADX-Indikator
adx=iADX(Symbol(),_Period,setPer);
//--- What if handle returns Invalid Handleif(adx<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
// sortiere die Preise abwärts von der aktuellen KerzeArraySetAsSeries(ArrayADX,true);
ArraySetAsSeries(ArrayDpl,true);
ArraySetAsSeries(ArrayDmi,true);
trade.SetExpertMagicNumber(MN); // Immer die Magic Number verwenden um Trades zu sortieren, den kommentar kann der Broker verändern return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Release our indicator handlesIndicatorRelease(adx);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
// Bevor wir unseren Kaufhandel eröffnen können - müssen wir den Nachfragekurs kennendouble Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Ask Price, is the price when we want to buy something, _Digits variable stores the number of digits after the decimal point// Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX DefinitionCopyBuffer(adx,0,0,3,ArrayADX); // ADX-WertCopyBuffer(adx,1,0,3,ArrayDpl); // DplusCopyBuffer(adx,2,0,3,ArrayDmi); // D-Minus// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden // Berechne den EA für für die aktuelle Kerze (ADX)double ADXWert=NormalizeDouble(ArrayADX[0],_Digits); // ADXdouble DplWert=NormalizeDouble(ArrayDpl[0],_Digits); // D+ Wert aktuelle Kerzedouble DminWert=NormalizeDouble(ArrayDmi[0],_Digits); // D- Wert aktuelle Kerze// Ende der ADX-Handelsstrategie Umsetzung // Für neue Kerzestaticdatetime Old_Time;
datetime New_Time[1];
bool IsNewBar=false;
// Kopieren der letzten Barzeit auf das Element New_Time[0]int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
if(copied>0) // ok, die Daten wurden erfolgreich kopiert
{
if(Old_Time!=New_Time[0]) // wenn die alte Zeit nicht gleich der neuen Barzeit ist
{
IsNewBar=true; // wenn es sich nicht um einen ersten Aufruf handelt, ist die neue Bar erschienenComment(TimeCurrent());
if ((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) /*&& (ArrayDpl[1] < ArrayDmi[1])*/)
{
trade.Buy(myLotSize,_Symbol,Ask,(Ask-SL*_Point),(Ask+TP*_Point),Text); // Parameter: myLotsize = Positionsgröße, _Symbol= akt. Chartsymbol, Ask = Ask Preis, SL, TP, letzte Parameter = für Kommentare
}
if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
Old_Time=New_Time[0]; // Speicherung der Barzeit
}
}
else
{
Alert("Error in copying historical times data, error =",GetLastError());
ResetLastError();
return;
}
} // Ende OnTick
Also wenn die D+ Kurve beim ADX über der D- Kurve ist, klappt es mit dem obigen Code.
Das ist der Code, bei dem das Crossing zwischen D+ und D- funktioniert: (Hierbei wird aufgrund der Bedingung in der if-Anweisung: PositionsTotal()<1, nur ein Trade eröffnet, und wie oben beschrieben, ein zweiter Trade erst dann eröffnet, wenn der erste geschlossen ist.)
//+------------------------------------------------------------------+#property copyright"Copyright 2020, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"#include<Trade\Trade.mqh> // Benötigte Library// Erstellung einer Instanz namens CTrade
CTrade trade;
// Eingaben und Array- und Variablendefinitioneninputint SL=200; // Stop Loss in Pointsinputint TP=100; // Take Profit in Pointsinputint setADX = 22; // ADX Setting for Crossing between D+ and D-inputint setPer = 14; // ADX Periode - Standard 14, größere Werte spätere Trends--> Genauerinputdouble myLotSize = 0.01; // Lotsize inputint MN = 12345; // IMMER EINE MAGIC NUMBER VERWENDEN BEI EINEM EA; NIEMALS OHNEinputstring Text = "myOwnText"; // Diesen kannst Du verwenden um den Komment in der Position anzuzeigen// für ADX-Wertdouble ArrayADX[];
// für D+-Wertdouble ArrayDpl[];
// für D- -Wertdouble ArrayDmi[];
// für unseren ADX-Indikatorint adx;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---für ADX-Indikator
adx=iADX(Symbol(),_Period,setPer);
//--- What if handle returns Invalid Handleif(adx<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
// sortiere die Preise abwärts von der aktuellen KerzeArraySetAsSeries(ArrayADX,true);
ArraySetAsSeries(ArrayDpl,true);
ArraySetAsSeries(ArrayDmi,true);
trade.SetExpertMagicNumber(MN); // Immer die Magic Number verwenden um Trades zu sortieren, den kommentar kann der Broker verändern return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Release our indicator handlesIndicatorRelease(adx);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
// Bevor wir unseren Kaufhandel eröffnen können - müssen wir den Nachfragekurs kennendouble Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Ask Price, is the price when we want to buy something, _Digits variable stores the number of digits after the decimal point// Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX DefinitionCopyBuffer(adx,0,0,3,ArrayADX); // ADX-WertCopyBuffer(adx,1,0,3,ArrayDpl); // DplusCopyBuffer(adx,2,0,3,ArrayDmi); // D-Minus// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden // Berechne den EA für für die aktuelle Kerze (ADX)double ADXWert=NormalizeDouble(ArrayADX[0],_Digits); // ADXdouble DplWert=NormalizeDouble(ArrayDpl[0],_Digits); // D+ Wert aktuelle Kerzedouble DminWert=NormalizeDouble(ArrayDmi[0],_Digits); // D- Wert aktuelle Kerze// Ende der ADX-Handelsstrategie Umsetzung bool Buy=((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] < ArrayDmi[1]));
if(IsNewBar(_Symbol,0))
{ // Anfang is NewBar//--- Keine Position und kein Kaufsignalif(PositionsTotal()<1 && Buy)
{
trade.Buy(myLotSize,_Symbol,Ask,(Ask-SL*_Point),(Ask+TP*_Point),Text); // Parameter: myLotsize = Positionsgröße, _Symbol= akt. Chartsymbol, Ask = Ask Preis, SL, TP, letzte Parameter = für Kommentare
}
} // Ende is NewBar
} // Ende on Tick// Ab hier Funktionen einfügen// Neue Barbool IsNewBar(string symbol,ENUM_TIMEFRAMES timeframe)
{
//---- liefert die Zeit des aktuellen Balkens.datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));
datetime m_TOld=0;
//---Neuer Balkenif(TNew!=m_TOld && TNew)
{
m_TOld=TNew;
//--- Es gibt eine neue Bar!return(true);
Print("Neue Kerze!");
}
//--- noch keine neuen Balken!return(false);
}
//Ende neue Bar
Wie kann ich das mit dem Crossing zwischen D+ und D- lösen?
Ich wäre für Ratschläge sehr dankbar.
Besten Dank vorab für Eure Hilfe, langsam verzweifele ich ein wenig ;)
So ich hab das Problem lösen können. Falls jemand an der Lösung interessiert ist, so sieht die bei mir jetzt aus. (Verbesserungsvorschläge
sind jederzeit gern gesehen ;) )
//+------------------------------------------------------------------+#include<Trade\Trade.mqh> // Benötigte Library// Erstellung einer Instanz namens CTrade
CTrade trade;
// Eingaben und Array- und Variablendefinitioneninputint SL=300; // Stop Loss in Pointsinputint TP=50; // Take Profit in Pointsinputint setADX = 22; // ADX Setting for Crossing between D+ and D-inputint setPer = 14; // ADX Periode - Standard 14, größere Werte spätere Trends--> Genauerinputdouble myLotSize = 0.1; // Lotsize inputint MN = 12345; // IMMER EINE MAGIC NUMBER VERWENDEN BEI EINEM EA; NIEMALS OHNEinputstring Text = "myOwnText"; // Diesen kannst Du verwenden um den Komment in der Position anzuzeigen// für ADX-Wertdouble ArrayADX[];
// für D+-Wertdouble ArrayDpl[];
// für D- -Wertdouble ArrayDmi[];
// für unseren ADX-Indikatorint adx;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---für ADX-Indikator
adx=iADX(Symbol(),_Period,setPer);
//--- What if handle returns Invalid Handleif(adx<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
// sortiere die Preise abwärts von der aktuellen KerzeArraySetAsSeries(ArrayADX,true);
ArraySetAsSeries(ArrayDpl,true);
ArraySetAsSeries(ArrayDmi,true);
trade.SetExpertMagicNumber(MN); // Immer die Magic Number verwenden um Trades zu sortieren, den kommentar kann der Broker verändern return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Release our indicator handlesIndicatorRelease(adx);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
// Bevor wir unseren Kaufhandel eröffnen können - müssen wir den Nachfragepreis kennendouble Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Ask Price, is the price when we want to buy something, _Digits variable stores the number of digits after the decimal point// Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX DefinitionCopyBuffer(adx,0,0,3,ArrayADX); // ADX-WertCopyBuffer(adx,1,0,3,ArrayDpl); // DplusCopyBuffer(adx,2,0,3,ArrayDmi); // D-Minus// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden // Berechne den EA für für die aktuelle Kerze (ADX)double ADXWert=NormalizeDouble(ArrayADX[0],_Digits); // ADXdouble DplWert=NormalizeDouble(ArrayDpl[0],_Digits); // D+ Wert aktuelle Kerzedouble DminWert=NormalizeDouble(ArrayDmi[0],_Digits); // D- Wert aktuelle Kerze// Ende ADX// Für neue Kerzenerkennung und Sar...MqlRates priceData[];
ArraySetAsSeries(priceData,true);
//Copy candle prices for 3 candles into arrayCopyRates(_Symbol,_Period,0,3,priceData);
// einen Zähler für die Kerze erstellenstaticint candlecounter;
// Datums-Zeit-Variable für den letzten Zeitstempel erstellenstaticdatetime timestamplastcheck;
// Datumszeit-Variable für die aktuelle Kerze erstellendatetime timestampcurrentcandle;
// Zeitstempel für aktuelle Kerze im Array lesen
timestampcurrentcandle=priceData[0].time;
// Buy Handelsbedingung - ADX, Crossing....SAR folgt...bool Buy=((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] < ArrayDmi[1]));
// wenn sich der aktuelle Zeitstempel vom letzten Mal unterscheidetif ((timestampcurrentcandle!=timestamplastcheck) && (Buy))
{ // Anfang if timestamp// aktuellen Zeitstempel für das nächste Mal merken
timestamplastcheck=timestampcurrentcandle;
// 1 zum Kerzenzähler hinzufügen
candlecounter=candlecounter+1;
// Chart Ausgabe// Comment("Counted candles since start:",candlecounter, "\n", "Bool Buy",Buy);
trade.Buy(myLotSize,_Symbol,Ask,(Ask-SL*_Point),(Ask+TP*_Point),Text); // Parameter: myLotsize = Positionsgröße, _Symbol= akt. Chartsymbol, Ask = Ask Preis, SL, TP, letzter Parameter = für Kommentare
} // Ende if timestamp
} // Ende on Tick// Ab hier Funktionen einfügen
Ja , wenn du die CTrade nutzt ,ersetze doch alles andere auch durch die Standard-Klassen.
CSymbol z.b.
Den Ask würde ich immer direkt vor trade.buy ermitteln .
Den kannst du auch weglassen CTrade ermittelt den selber. Ist aber Geschmacksache.
Da ich gerade am erlernen von MQL5 bin, meinst Du mit den weiteren Standard-Klassen das hier?
https://www.mql5.com/de/articles/481
Das kann ich natürlich einbauen, soweit ich das gesehen habe, brauche ich nur den Code in die onInit zu kopieren.
Danke für den Tipp mit dem Ask Preis, ich habe die Ermittlung jetzt direkt vor trade.Buy gesetzt. Jetzt habe ich aber leider ein neues Problem: Nach der Integration des SAR-Parabolic Indikators wird leider kein Trade eröffnet. Der Bot soll einen Trade dann eröffnen, wenn der ADX-Wert größer als der eingestellte ADX Wert ist, und wenn es ein Crossing zwischen D+ und D- gegeben hat und zu guter Letzt wenn der Punkt der Parabolic unter der Kerze erscheint.
Kann mir bitte jemand weiterhelfen? Vielleicht seht Ihr ja den Fehler....
//+------------------------------------------------------------------+#include<Trade\Trade.mqh> // Benötigte Library// Erstellung einer Instanz namens CTrade
CTrade trade;
// Eingaben und Array- und Variablendefinitioneninputint SL=300; // Stop Loss in Pointsinputint TP=50; // Take Profit in Pointsinputint setADX = 10; // ADX Setting for Crossing between D+ and D-inputint setPer = 14; // ADX Periode - Standard 14, größere Werte spätere Trends--> Genauerinputdouble myLotSize = 0.1; // Lotsize inputint MN = 12345; // IMMER EINE MAGIC NUMBER VERWENDEN BEI EINEM EA; NIEMALS OHNEinputstring Text = "myOwnText"; // Diesen kannst Du verwenden um den Komment in der Position anzuzeigen// für ADX-Wertdouble ArrayADX[];
// für D+-Wertdouble ArrayDpl[];
// für D- -Wertdouble ArrayDmi[];
// SAR String Array für Tradeeinstiegsbedingungstring SARsignalkaufen ="";
// Array für Preisdatendouble mySARArray[];
MqlRates priceData[];
// für unseren ADX-Indikatorint adx;
int SARDefinition;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---für ADX-Indikator
adx=iADX(Symbol(),_Period,setPer);
// Definition der Eigenschaften des RSI-Indikators
SARDefinition = iSAR (_Symbol,_Period,0.02,0.2); // SARDefinition ersetzt durch SAR//--- What if handle returns Invalid Handleif(adx<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
//--- What if handle returns Invalid Handleif(SARDefinition<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
return(-1);
}
// sortiere die Preise abwärts von der aktuellen KerzeArraySetAsSeries(ArrayADX,true);
ArraySetAsSeries(ArrayDpl,true);
ArraySetAsSeries(ArrayDmi,true);
// Sortierung der Preisdaten im Array von Kerze 0 (aktuelle Kerze) abwärtsArraySetAsSeries(priceData,true);
trade.SetExpertMagicNumber(MN); // Immer die Magic Number verwenden um Trades zu sortieren, den kommentar kann der Broker verändern return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Release our indicator handlesIndicatorRelease(adx);
IndicatorRelease(SARDefinition);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
// Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX DefinitionCopyBuffer(adx,0,0,3,ArrayADX); // ADX-WertCopyBuffer(adx,1,0,3,ArrayDpl); // DplusCopyBuffer(adx,2,0,3,ArrayDmi); // D-Minus// Für SARCopyBuffer(SARDefinition,0,0,3,mySARArray);
// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden // Berechne den EA für für die aktuelle Kerze (ADX)double ADXWert=NormalizeDouble(ArrayADX[0],_Digits); // ADXdouble DplWert=NormalizeDouble(ArrayDpl[0],_Digits); // D+ Wert aktuelle Kerzedouble DminWert=NormalizeDouble(ArrayDmi[0],_Digits); // D- Wert aktuelle Kerze// Berechnung des SAR Werts für die aktuelle Kerzedouble SARWertaktKerze = NormalizeDouble(mySARArray[0],5);
// Berechnung des SAR Werts für die vorherige Kerzedouble SARWertletzteKerze = NormalizeDouble(mySARArray[1],5);
// Ende ADX// Für neue Kerzenerkennung und Sar...// MqlRates priceData[]; // ArraySetAsSeries(priceData,true);//Copy candle prices for 3 candles into arrayCopyRates(_Symbol,_Period,0,3,priceData);
// einen Zähler für die Kerze erstellenstaticint candlecounter;
// Datums-Zeit-Variable für den letzten Zeitstempel erstellenstaticdatetime timestamplastcheck;
// Datumszeit-Variable für die aktuelle Kerze erstellendatetime timestampcurrentcandle;
// Zeitstempel für aktuelle Kerze im Array lesen
timestampcurrentcandle=priceData[0].time;
// SAR Verkaufssignal Wenn der SAR Punkt vorher über der Kerze war - wenn der SAR Punkt unter der Kerze istif ((SARWertaktKerze < priceData[0].low) && (SARWertletzteKerze > priceData[1].high))
{
SARsignalkaufen="buy";
}
/* if (SARsignalkaufen =="buy")
{
// Chart Ausgabe
// Comment ("Der SAR Wert ist: ",SARWertaktKerze, "\n", "Der SAR Wert letzte Kerze",SARWertletzteKerze);
Comment ("Kaufen",SARsignalkaufen);
}
*/// Buy Handelsbedingung - ADX, Crossing....SAR folgt...bool Buy=((ADXWert>=setADX) && (SARsignalkaufen =="buy") && (ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] < ArrayDmi[1]));
// wenn sich der aktuelle Zeitstempel vom letzten Mal unterscheidetif ((timestampcurrentcandle!=timestamplastcheck) && (Buy))
{ // Anfang if timestamp// aktuellen Zeitstempel für das nächste Mal merken
timestamplastcheck=timestampcurrentcandle;
// 1 zum Kerzenzähler hinzufügen
candlecounter=candlecounter+1;
// Chart Ausgabe// Comment("Counted candles since start:",candlecounter, "\n", "Bool Buy",Buy); // Bevor wir unseren Kaufhandel eröffnen können - müssen wir den Nachfragepreis kennendouble Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Ask Price, is the price when we want to buy something, _Digits variable stores the number of digits after the decimal point
trade.Buy(myLotSize,_Symbol,Ask,(Ask-SL*_Point),(Ask+TP*_Point),Text); // Parameter: myLotsize = Positionsgröße, _Symbol= akt. Chartsymbol, Ask = Ask Preis, SL, TP, letzter Parameter = für Kommentare
} // Ende if timestamp
} // Ende on Tick// Ab hier Funktionen einfügen
Besten Dank vorab für Eure tolle Unterstützung und viele Grüße
Kaum ein Händler dürfte nicht auf dem Markt aktiv sein, um Geld zu verdienen, obwohl ein sich gewisser Teil vielleicht auch an der Teilnahme am Handelsgeschehen selbst erfreut. Aber Freude daran vermittelt nicht nur der manuelle Handel. Die Entwicklung automatischer Handelssysteme kann genauso begeisternd sein. Die Erstellung eines...
Du hast quasi den index 0 auf den letzten wert stehen lassen.
das gleiche wäre wenn du gleich den wert 1 aus dem array nimmst
Wie meinst Du das? Wie würde der Code dann aussehen? Meinst Du das?
Damit funktioniert es nicht.
Ergänzung: Im Livetest zeigt sich, das es mit der IsNewBar Time Funktion nicht geht. Seltsam. Mit der oben geposteten Version klappt es.
Wie meinst Du das? Wie würde der Code dann aussehen? Meinst Du das?
Damit funktioniert es nicht.
Ergänzung: Im Livetest zeigt sich, das es mit der IsNewBar Time Funktion nicht geht. Seltsam. Mit der oben geposteten Version klappt es.
In deiner version nimmst du die arrays bevor du die isnew bar aufrufst, das heist, er hat schon einen wert gespeichert, der muss nicht genau bei isnewbar auftreten.
array index 0 bedeutet die aktuelle kerze, also bei isnewbar genau die jetzige, und da muss der wert gerade passen
In deiner version nimmst du die arrays bevor du die isnew bar aufrufst, das heist, er hat schon einen wert gespeichert, der muss nicht genau bei isnewbar auftreten.
array index 0 bedeutet die aktuelle kerze, also bei isnewbar genau die jetzige, und da muss der wert gerade passen
@ amando: Du hast vollkommen Recht.
Noch eine Ergänzung: Damit funktioniert es jetzt auch, sieht das für Euch okay aus? Oder was kann man daran noch optimieren?
@ amando: Du hast vollkommen Recht.
Oder was kann man daran noch optimieren?
Dreisprachige Kommentare …pfui :-)
Dreisprachige Kommentare …pfui :-)
Hallo zusammen,
bei meinem aktuellen Code wird nur dann ein Trade eröffnet, wenn der alte zuvor geschlossen wurde. Da ich aber gerne hätte, das immer dann ein Trade eröffnet wird, wenn die Signale stimmen, muss ich was an der Zeitfunktion ändern.
Dabei besteht immer noch das alte/neue Problem aus den vorherigen beschriebenen Seiten.
Interessant ist, das nur die Crossing Bedingung bei dem nachfolgenden Code ignoriert wird, die ich aktuell auskommentiert habe: ((ADXWert>=setADX) && (ArrayDpl[0] > ArrayDmi[0]) /*&& (ArrayDpl[1] < ArrayDmi[1])*/))
Also wenn die D+ Kurve beim ADX über der D- Kurve ist, klappt es mit dem obigen Code.
Das ist der Code, bei dem das Crossing zwischen D+ und D- funktioniert: (Hierbei wird aufgrund der Bedingung in der if-Anweisung: PositionsTotal()<1, nur ein Trade eröffnet, und wie oben beschrieben, ein zweiter Trade erst dann eröffnet, wenn der erste geschlossen ist.)
Wie kann ich das mit dem Crossing zwischen D+ und D- lösen?
Ich wäre für Ratschläge sehr dankbar.
Besten Dank vorab für Eure Hilfe, langsam verzweifele ich ein wenig ;)
Paul
So ich hab das Problem lösen können. Falls jemand an der Lösung interessiert ist, so sieht die bei mir jetzt aus. (Verbesserungsvorschläge sind jederzeit gern gesehen ;) )
Ja , wenn du die CTrade nutzt ,ersetze doch alles andere auch durch die Standard-Klassen.
CSymbol z.b.
Den Ask würde ich immer direkt vor trade.buy ermitteln .
Den kannst du auch weglassen CTrade ermittelt den selber. Ist aber Geschmacksache.
Ja , wenn du die CTrade nutzt ,ersetze doch alles andere auch durch die Standard-Klassen.
CSymbol z.b.
Den Ask würde ich immer direkt vor trade.buy ermitteln .
Den kannst du auch weglassen CTrade ermittelt den selber. Ist aber Geschmacksache.
Da ich gerade am erlernen von MQL5 bin, meinst Du mit den weiteren Standard-Klassen das hier?
https://www.mql5.com/de/articles/481
Das kann ich natürlich einbauen, soweit ich das gesehen habe, brauche ich nur den Code in die onInit zu kopieren.
Danke für den Tipp mit dem Ask Preis, ich habe die Ermittlung jetzt direkt vor trade.Buy gesetzt. Jetzt habe ich aber leider ein neues Problem: Nach der Integration des SAR-Parabolic Indikators wird leider kein Trade eröffnet. Der Bot soll einen Trade dann eröffnen, wenn der ADX-Wert größer als der eingestellte ADX Wert ist, und wenn es ein Crossing zwischen D+ und D- gegeben hat und zu guter Letzt wenn der Punkt der Parabolic unter der Kerze erscheint.
Kann mir bitte jemand weiterhelfen? Vielleicht seht Ihr ja den Fehler....
Besten Dank vorab für Eure tolle Unterstützung und viele Grüße
Paul
Da ich gerade am erlernen von MQL5 bin, meinst Du mit den weiteren Standard-Klassen das hier?
https://www.mql5.com/de/articles/481
Ja genau, der Vorteil ist, wenn du die Klassen nutzt, kannst Du dich voll auf die Logik der Trades konzentrieren.
Ich sehe oft wie sich Anfänger mühselig mit einer Trade Eröffnung herumärgern.Tage.. monatelang.... aber gar nicht das eigentliche Lernen.
Die Klassen machen vieles sehr einfach. Später kannst Du auch mal dahinter schauen was da wirklich passiert.