Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   Hedge EA (http://www.expert-advisor.com/forum/showthread.php?t=6634)

traderdoc 02.05.20 15:49

Jungs, dass das Backtesten mindestens im MT4 für die Katz ist, das weiss doch nun inzwischen jeder. Da kommen keine in der Realität existierenden Ergebnisse raus, nicht mal mit Sicherheit trendgebende.
Ich programmiere nun seit mehr als 13 Jahren für Kunden der unterschiedlichsten Ansprüche, jedem rate ich ab, sich nach Backtestdaten zu orientieren, mindestens sollte ein Demo-Forward-Konto laufen, besser mit kleinen Lotgrößen aber auf einem Real-Konto unter permanenter Beobachtung.
2007 dachte ich auch, oh Backtest, das ist ja ne geile Sache, da kann man ja die Variablen hin- und herschieben bis ein positives Ergebnis kommt, aber da viele Aspekte des realen Tradens dort nicht berücksichtigt werden (können), habe ich den Strategietester nur noch zum Testen der geschriebenen Programme benutzt, um den korrekten Ablauf zu kontrollieren.
Das wird auch nicht viel besser, wenn man lückenlose Tickdaten benutzt.

traderdoc

TogoTiger 02.05.20 18:27

Ja, Traderdoc, das ist mir klar. Ich wollte nur nochmals versuchen, weil MA-EA ein gutes Ergebnis mit seinem Programm hatte und ich das kaum glauben konnte. Sein EA ist letzte Woche einige Stunden auf einem Demo-Account von JFD gelaufen und hat wie erwartet nur Verluste gebracht. Nicht mal mit dem Optimieren der Parameter (hier ja nur SL und TP) kann im Backtest ein Gewinn realisiert werden. Aber selbst dann wären gefundene Parameter in der Praxis kaum erfolgreich.
Wenn eine solche Strategie Gewinne bringen würde, wären du und ich und jeder, der ein bisschen programmieren kann, schon längst Multimillionäre.

Aber eigentlich bin ich blöd, den Code von MA-EA zum Laufen zu bringen. Er guckt sich ja nicht einmal die Verbesserungsvorschläge an. Oder er kapierts nicht, obwohl ich das sehr einfach geschrieben habe. Die Doku liest er eh nicht, oder versteht sie nicht.

Ja, und damit bleib ich nun wirklich still zu diesem Thema. Keine Lust mehr.

MA-EA 02.05.20 21:50

Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mir die Vorschläge angeguckt. Sonst würde das Teil wahrscheinlich nicht so gut laufen. :rolleyes:

Was für Einstellungen hattest Du denn im Backtest?

Er läuft bei mir im ActivTrades-Demo von 7 bis 16:26. Auf allen WP, die üblicherweise einen Spread bis ungefähr 15 haben. Werd demnächst wahrscheinlich WPs mit Spreads bis ungefähr 20 testen. Um 17:27 werden alle Orders dicht gemacht, egal ob Long oder Short, egal ob mit Gewinn oder nicht.

Das Gerät muss ständig Long und Short im selben WP gleichzeitig sein. Wird die Order einer Richtung geschlossen (meistens weil sie den eingestellten Gewinn erreicht hat) wird in die selbe Richtung gleich die nächste Order geöffnet (so soll es jedenfalls sein :rolleyes:. Klappt aber nicht durchgehend und ich hab keine Ahnung, warum. ). Lots der jeweiligen Richtung werden mit dem einstellbaren Wert addiert, wenn er eine Gewinn-Order schließt.

Auch wenn das ganze Prinzip wohl nicht so überzeugend klingt, wär ich dankbar, wenn Ihr den Code mal durchschauen und sagen könntet, ob er gut und richtig ist. Vor allem weiß ich nicht, ob das bei OrderSend mit dem Prüfen klappt, ob der EA schon Orders offen hat.

Noch nicht getestet:
Code:

/*=============================================================================================================
// N O T I Z E N  U N D  I N F O S
//=============================================================================================================


In dieser Vers. 2 wird möglichst nur mit
Close_All_After_ bool gearbeitet.
Ansonsten wird versucht, hier keine
anderen bools zu benutzen.

Ob der EA Orders offen hat,
wird nicht mehr in extra for-Schleife
raus gefunden, sondern in den OrderSend-
Funktionen/Bedingungen.
RT wird entfernt. Falls EA rund
um die Uhr arbeiten soll,
werden einfach Start- und Endzeit
auf 0:00 Uhr eingestellt.


//-------------------------------------------------------------------------------------------------------------



//-------------------------------------------------------------------------------------------------------------


Öffnen der Orders dauert allgemein etwas lange.

Lag vielleicht an Dist? Mit SL und TP getestet.
Auch mit SL und TP dauert das Öffnen neuer Orders
teilweise sehr lange.


//-------------------------------------------------------------------------------------------------------------



//=============================================================================================================
// P R O P E R T Y
//============================================================================================================*/
// #property strict
// #property strict sorgt anscheinend dafür, dass Kommentare im Konfig-Fenster im MT4 sichtbar sind.

#property copyright"LoSh_AlwInv_Dist_LP_v2.mq4"
#property copyright"daniel-rudloff@web.de"
//=============================================================================================================
// B E S C H R E I B U N G
//=============================================================================================================
extern string TOY="true = on / yes";
extern string FON="false = off / no";
//=============================================================================================================
// E I N S T E L L U N G E N
//=============================================================================================================

//-----------------------------------------------------------------------------------------------------------*/

extern string OPORTY="Open Order Types";
input bool open_Buy=true;
input bool open_Sell=true;

//-----------------------------------------------------------------------------------------------------------*/

extern string MN="Magic Numbers";
extern int Buy_MN=2;
extern int Sell_MN=4;

//-----------------------------------------------------------------------------------------------------------*/

extern string OOO1="Open Orders";
extern string OOO2="from/till";
extern string OOO3="(Server Time)";

extern int Open_From_Hour=7;
extern int Open_From_Min=0;

extern int Open_Till_Hour=17;
extern int Open_Till_Min=26;

//-----------------------------------------------------------------------------------------------------------*/

extern string CAOTOC1="Close all Orders after";
extern string CAOTOC2="(Server Time)";

extern bool Close_all_Orders_after=true;

extern int Close_after_Hour=17;
extern int Close_after_Min=27;

//-----------------------------------------------------------------------------------------------------------*/

extern int Slippage=99999999;

//-----------------------------------------------------------------------------------------------------------*/

extern double LotsBuy=0.01;
extern double LotsSel=0.01;

extern string esLPOCP1="Lots Buy/Lots Sell";
extern string esLPOCP2="+ LotsPlus";
extern string esLPOCP3="if Order close";
extern string esLPOCP4="with Profit";

extern double LotsPlus=0.01;

//-----------------------------------------------------------------------------------------------------------*/

extern int SL=1600; // 1600 testen

//-----------------------------------------------------------------------------------------------------------*/

extern int TP=1800; // Zum Testen 1800

//-----------------------------------------------------------------------------------------------------------*/

extern string esIITCBSMS1="if IsTradeContexBusy()";
extern string esIITCBSMS2="sleep Milli Seconds";

extern int Sl_MS=10;

//-----------------------------------------------------------------------------------------------------------*/

extern string DOPtAB1="Distance to";
extern string DOPtAB2="Order Open Price";
extern string DOPtAB3="close Win-Order";

extern int Dist = 50; // Zum Testen 50

//-----------------------------------------------------------------------------------------------------------*/


//=============================================================================================================
// I N I T / D E I N I T
//=============================================================================================================
int OnInit(){
  return(0);}
void OnDeinit(const int reason){
  return;}
//=============================================================================================================
// E A  F U N K T I O N E N  S T A R T
//=============================================================================================================int
int start(){
//=============================================================================================================
// L O T S ?
//=============================================================================================================


double Min_L=MarketInfo(Symbol(),MODE_MINLOT);
double Max_L=MarketInfo(Symbol(),MODE_MAXLOT);

if(LotsBuy<Min_L)LotsBuy=Min_L;
if(LotsSel<Min_L)LotsSel=Min_L;

if(LotsBuy==Max_L || LotsSel==Max_L)LotsPlus=0.0;


//=============================================================================================================
// S T O P  L O S S
//=============================================================================================================


//SL auf 0 stellen, wenn oben <1,
//um irgendwelche Missverständnisse zu vermeiden.
if(SL<1){
  double Buy_SL=0.0;
  double Sel_SL=0.0;}

  else{
    Buy_SL=NormalizeDouble(Ask-SL*_Point,_Digits);
    Sel_SL=NormalizeDouble(Bid+SL*_Point,_Digits);}

//SL genauso groß wie Minstoplevels machen, wenn er kleiner ist:
double MSL=MarketInfo(Symbol(),MODE_STOPLEVEL);
if(Buy_SL<MSL)Buy_SL=MSL;
if(Sel_SL<MSL)Sel_SL=MSL;


//=============================================================================================================
// T A K E  P R O F I T
//=============================================================================================================


//TP auf 0 stellen, wenn oben <1,
//um irgendwelche Missverständnisse zu vermeiden.
if(TP<1){
  double Buy_TP=0.0;
  double Sel_TP=0.0;}

  else{
    Buy_TP=NormalizeDouble(Ask+TP*_Point,_Digits);
    Sel_TP=NormalizeDouble(Bid-TP*_Point,_Digits);}


//=============================================================================================================
// C L O S E  D I S T A N C E  B E R E C H N U N G
//=============================================================================================================


double CLbuy_D = NormalizeDouble( Bid - Dist *_Point,_Digits);

double CLsel_D = NormalizeDouble( Ask + Dist *_Point,_Digits);


//=============================================================================================================
// O P E N  O R D E R S
//=============================================================================================================


if(Hour()>=Open_From_Hour&&Minute()>=Open_From_Min&&Hour()<=Open_Till_Hour&&Minute()<=Open_Till_Min){




  if( open_Buy==true ){
 
    for(int i=OrdersTotal()-1;i>=0;i--)
   
      if(OrderSelect(i,SELECT_BY_POS))
     
        if(OrderType()==OP_BUY&&OrderMagicNumber()==Buy_MN&&OrderSymbol()==Symbol())Print( "buy" , i );


        else if(IsTradeAllowed())OrderSend(Symbol(),OP_BUY,LotsBuy,Ask,Slippage,Buy_SL,Buy_TP,NULL,Buy_MN,NULL,Blue);

        if(IsTradeContextBusy())Sleep(Sl_MS);}




  if( open_Sell==true ){

    for(int j=OrdersTotal()-1;j>=0;j--)

      if(OrderSelect(j,SELECT_BY_POS))

        if(OrderType()==OP_SELL&&OrderMagicNumber()==Sell_MN&&OrderSymbol()==Symbol())Print( "sell" , i );

     
        else if(IsTradeAllowed())OrderSend(Symbol(),OP_SELL,LotsSel,Bid,Slippage,Sel_SL,Sel_TP,NULL,Sell_MN,NULL,Blue);

        if(IsTradeContextBusy())Sleep(Sl_MS);}

}


//=============================================================================================================
// C L O S E  O R D E R S
//=============================================================================================================


for(int k=OrdersTotal()-1;k>=0;k--){
  if(OrderSelect(k,SELECT_BY_POS)){
    if(OrderType()==OP_BUY&&OrderMagicNumber()==Buy_MN&&OrderSymbol()==Symbol()){
     
      if( ( CLbuy_D > OrderOpenPrice() ) ||(Close_all_Orders_after==true&&Hour()>=Close_after_Hour&&Minute()>=Close_after_Min) ){
     
        if(IsTradeAllowed())OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Red);
         
        if(IsTradeContextBusy())Sleep(Sl_MS);
         
        LotsBuy = OrderLots() + LotsPlus;

} } } }




for(int l=OrdersTotal()-1;l>=0;l--){
  if(OrderSelect(l,SELECT_BY_POS)){
    if(OrderType()==OP_SELL&&OrderMagicNumber()==Sell_MN&&OrderSymbol()==Symbol()){
     
      if( ( CLsel_D < OrderOpenPrice() ) ||(Close_all_Orders_after==true&&Hour()>=Close_after_Hour&&Minute()>=Close_after_Min) ){

        if(IsTradeAllowed())OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
       
        if(IsTradeContextBusy())Sleep(Sl_MS);
       
        LotsSel = OrderLots() + LotsPlus;

} } } }


//=============================================================================================================
// E A  F U N K T I O N E N  B E E N D E N
//=============================================================================================================

return(NULL);} //


MA-EA 03.05.20 07:54

Liste der Anhänge anzeigen (Anzahl: 1)
Moin.

Funktioniert das so mit Order prüfen und öffnen? Oder müssen OrderSelect und Order Infos holen extra { } haben? :confused:
Code:

if(Hour()>=Open_From_Hour&&Minute()>=Open_From_Min&&Hour()<=Open_Till_Hour&&Minute()<=Open_Till_Min){



  if( open_Buy==true ){
 
    for(int i=OrdersTotal()-1;i>=0;i--){
   
      if( (OrderSelect(i,SELECT_BY_POS)==false) || (OrderSelect(i,SELECT_BY_POS)==true && OrderSymbol()==Symbol() && OrderMagicNumber()!=Buy_MN) ){
     
        if(IsTradeAllowed())OrderSend(Symbol(),OP_BUY,LotsBuy,Ask,Slippage,Buy_SL,Buy_TP,NULL,Buy_MN,NULL,Blue);

        if(IsTradeContextBusy())Sleep(Sl_MS);

} } }



  if( open_Sell==true ){

    for(int j=OrdersTotal()-1;j>=0;j--){
   
      if( (OrderSelect(j,SELECT_BY_POS)==false) || (OrderSelect(j,SELECT_BY_POS)==true && OrderSymbol()==Symbol() && OrderMagicNumber()!=Sell_MN) ){

        if(IsTradeAllowed())OrderSend(Symbol(),OP_SELL,LotsSel,Bid,Slippage,Sel_SL,Sel_TP,NULL,Sell_MN,NULL,Blue);

        if(IsTradeContextBusy())Sleep(Sl_MS);
       
} } }

}


MA-EA 05.05.20 20:47

Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.

Im Anhang eine Version, die die wichtigsten Sachen printen soll.

In den letzten 2 Tagen hat der EA nur Verluste gemacht. Ich glaube, ich weiß warum und hätte mir das eigentlich auch vorher denken können. :rolleyes:Weil mit immer mehr Lots auch immer mehr Spread-Kosten entstehen. Nach kurzer Zeit reichen auch mehrere Gewinn-Orders nicht mehr, um die wieder zu bekommen. Pro 0.01 Lot entstehen bis zu 15 Pips Spread. Ab ca. 0.04 Lot bekommt man natürlich mit 40 Pips Gewinn den Spread nicht mehr rein. :(

Also muss man sozusagen Spread mal Lots rechnen, um raus zu finden, wie viel Gewinn das Ding pro Order mindestens machen muss. Dazu sollen natürlich noch ein paar Pips Gewinn auf dem Konto bleiben.

Meine Frage lautet jetzt eigentlich nur: An welcher Stelle macht man diese Berechnung? In den globalen Variablen wird festgelegt, mit wie viel Gewinn er die jeweilige Order dicht machen soll.
Code:

extern string esDOPtAB1="Distance to";
extern string esDOPtAB2="Order Open Price";
extern string esDOPtAB3="close Win-Order";

extern int Dist = 40;

Mit dem Dist Wert berechnet er dann noch vor OrderSend(), wann die Order geschlossen werden soll:
Code:

double CLbuy_D = NormalizeDouble( Bid - Dist *_Point,_Digits);

double CLsel_D = NormalizeDouble( Ask + Dist *_Point,_Digits);

Code:

if( ( CLbuy_D > OrderOpenPrice() ) ... Close Buy

if( ( CLsel_D < OrderOpenPrice() ) ... Close Sell

Wenn die Order mit Gewinn geschlossen wurde, werden die Lots der jeweiligen Richtung erhöht:
Code:

...

LotsBuy = OrderLots() + LotsPlus;

...

LotsSel = OrderLots() + LotsPlus;

 ...

Ich weiß nicht so recht, wann man sozusagen den Dist-Wert mit den Lots "multiplizieren" sollte. Ich meine, kommen die sich vielleicht irgendwo in die Quere und die Berechnung schlägt fehl, weil er ja immer wieder den ganzen Code durchläuft? Oder ist das egal, ob er das oben gleich nach der Dist-Berechung oder bei OrderClose, nachdem die Lots erhöht wurden, berechnet? :confused:

MA-EA 06.05.20 06:34

Liste der Anhänge anzeigen (Anzahl: 1)
So müsste es ja eigentlich funktionieren...
Code:

//        Close-Buy-Distance anpassen
//        LotsBuy mal hundert:
          double LBuy_Mh = LotsBuy * 100.0;
          Print( "-LotsBuy x 100.0=",LBuy_Mh );
         
//        Ergebnis mal Dist(GV)
          double LBuyMh_Dist = LBuy_Mh * Dist;
          Print( "-LotsBuyMh x Dist=",LBuyMh_Dist , "-Old Buy Dist=",Dist );
         
//        Neuer Dist-Wert durch 100
          Dist = LBuyMh_Dist / 100.0;
          Print( "-New Buy Dist=",Dist );

Code:

//        Close-Sel-Distance anpassen
//        LotsSel mal hundert:
          double LSel_Mh = LotsSel * 100.0;
          Print( "-LotsSel x 100.0=",LSel_Mh );
         
//        Ergebnis mal Dist(GV)
          double LSelMh_Dist = LSel_Mh * Dist;
          Print( "-LotsSelMh x Dist=",LSelMh_Dist , "-Old Sel Dist=",Dist );
         
//        Neuer Dist-Wert durch 100
          Dist = LSelMh_Dist / 100.0;
          Print( "-New Sel Dist=",Dist );


TogoTiger 06.05.20 06:48

Hast noch nicht bemerkt, dass du mit 0.04 Lots auch mehr Gewinn machst als mit 0.01 Lots. Es liegt nicht an deiner Vermutung. Deine Strategie funktioniert nicht.
Wenn du jetzt einfach versuchst, deine Verluste, ob durch Spreads oder verlorene Trades verursacht, mit dem nächsten Trade auszugleichen, nennt sich das Martingale Strategie. Die kann durchaus eine Weile funktionieren, endet aber immer mit dem Totalverlust.
Mit so einfachen Strategien kannst du lange rumprobieren.
Ich geb dir einen Tip:
Du musst verschiedene Indikatoren auswerten und so mehr Gewinn- als Verlusttrades erreichen. Ich habe erst Erfolg gehabt, als ich verschiedene Indikatoren zudem in verschiedenen Zeiteinheiten ausgewertet habe.
z.B. einen Trendindikator in 1H oder 1W und TRSI oder MACD oder sowas in kleinerer Zeiteinheit, und dann nur in der Richtung des Trends Trades eröffnen. Für sehr kurzfristige Trades, die du ja haben willst, mussst zudem nicht nur den absoluten Wert deines Indikators berücksichtigen. Wichtig ist, ob er steigt oder fällt.
Aber sowas zu programmieren liegt wohl weit ausserhalb deiner Fähigkeiten.

MA-EA 06.05.20 09:02

Liste der Anhänge anzeigen (Anzahl: 1)
Hab schon etliche EAs mit etlichen Indikatoren versucht. CCI, Stochastic, WPR, RVI, RSI, Ichimoku, Moving Averages... :D

Hab eben die Print-Version versucht. Als er keine neue Orders geöffnet hat, obwohl er eigentlich müsste, kam im Journal überhaupt nix! Kein einziger neuer Eintrag! Als ob er überhaupt nicht arbeiten würde. :confused: Also muss das Problem beim MT4 oder bei ActivTrades liegen...

Abgesehn davon ergibt die neue Dist immer 0! Entweder funktioniert das nicht so, wie ichs mir vorgestellt habe, oder irgendwo ist nen Rechenfehler drin. :confused: Aber wie ich irgendwo schon mal sagte, bin ich Alles Andere als nen Mathe-Ass... Unter Experten steht aber auch nicht, ob und was er rechnet.

Dann scheint er noch ununterbrochen alle Orders zu zählen, ausser wenn er doch mal Welche öffnet oder schließt.
Code:

//        Close-Buy-Distance anpassen
//        LotsBuy mal hundert:
          double LBuy_Mh = LotsBuy * 100.0;
          Print( "-LotsBuy x 100.0=",LBuy_Mh );
         
//        Ergebnis mal Dist(GV)
          double LBuyMh_Dist = LBuy_Mh * Dist;
          Print( "-LotsBuyMh x Dist=",LBuyMh_Dist , "-Old Buy Dist=",Dist );
         
//        Neuer Dist-Wert durch 100
          Dist = LBuyMh_Dist / 100.0;
          Print( "-New Buy Dist=",Dist );

Code:

//        Close-Sel-Distance anpassen
//        LotsSel mal hundert:
          double LSel_Mh = LotsSel * 100.0;
          Print( "-LotsSel x 100.0=",LSel_Mh );
         
//        Ergebnis mal Dist(GV)
          double LSelMh_Dist = LSel_Mh * Dist;
          Print( "-LotsSelMh x Dist=",LSelMh_Dist , "-Old Sel Dist=",Dist );
         
//        Neuer Dist-Wert durch 100
          Dist = LSelMh_Dist / 100.0;
          Print( "-New Sel Dist=",Dist );


TogoTiger 06.05.20 14:34

Nochmals: überleg dir gut, was du wann machen musst und fange Fehler ab.

z.B. was soll
if(IsTradeContextBusy()) Sleep(Sl_MS);
nach SendOrder?
wenn du das schon abfragst, gehört das vor SendOrder und zwar so:
while (IsTradeContextBusy()) Sleep(Sl_MS);

Und dann wertest du immer noch nicht aus, ob SendOrder korrekt abgelaufen ist.
Sogar der Compiler meldet dir, dass du das auswerten sollst. Warum wohl?

Aber genau habe ich deinen Code nicht analysiert. Das tu ich mir nun wirklich nicht nochmals an.

traderdoc 06.05.20 15:39

Der @MA-EA ist leider sehr beratungsresistent.

traderdoc


Alle Zeitangaben in WEZ +2. Es ist jetzt 14:43 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum