Jump to content
Tom Next - Daytrading Community

Projekt: Entwicklung Community-EA


Wir bauen ein TomNext EA für Metatrader  

60 members have voted

  1. 1. Besteht Interesse zusammen ein EA zu bauen für Metatrader??



Recommended Posts

@Mythos

 

Kapitälchen mit oder ohne "_"?

 

Eine Linie beibehalten, Konventionen waren am Anfang des Thread , muss und will sich KB gerne dran halten : Ganz klar also ohne "_" .

 

MA bringe ich morgen in Ordnung, Übergabe Filtermode wie von Dir eingerichtet ist cool . :doubleup:

 

Was steht noch zum Coden aus ... ?

 

Backtest und Optimieren : Wollen wir diese Datenquelle gemeinsam nutzen ?

 

Bald gehts los .........Wohohohooolf , wo bissu denn ? :Howdy:

 

KB

Link to comment
Share on other sites

Der Parameter bei iMA ist kein String. MODE_EMA ist eine vordefinierte Konstante und eigentlich ein integer

 

:wub:

 

Dann mal schnell in Ordnung bringen :

 

1.) Parameter (in der V0.5 inkl TP) :

 

//+-----------------------------------------------------------------------------------------------+
                                      //                                 Version 0.5  KB was here|
extern int TP_Digits_Long  =     50;   // Profitziel für den LongTrade                            |
extern int TP_Digits_Short =     50;   // Profitziel für den LongTrade                            |
                                      //                                                         |
extern string MAParameterCoding = "SMA = 0 , EMA = 1 , SMMA = 2 , LWMA = 3"   ;//                 |
extern bool FilterMAMode   =      1;   // Für MA-Filter "Exponentiell" ausgewählt                 |
                                      //                                                         |
//+-----------------------------------------------------------------------------------------------+

 

2.) Check in der Init :

 

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
 {
//----

//+-----------------------------------------------------------------------------------------------+
                                      //                                 Version 0.5  KB was here|
                                      //                                                         |
if (FilterMAMode < 0 || FilterMAMode > 3 )      {// Fehler in der Eingabe                         |
 Print ("Falscher Input MA , bitte zwischen 0 und 3 wählen & nicht ",FilterMAMode); deinit() ;}//|
                                      //                                                         |
//+-----------------------------------------------------------------------------------------------+

//----
  return(0);
 }

 

3.) Integration in die Funktion "iMA" wie schon gepostet :

 

//------------------------------------------------------------------------------------------------+
//                                                                       Version 0.5   KB was here|
// übergeordneter Trend erkannt durch Abstand von 2 MAs, dient als Filter für die Einstiege.      |
// returns one out of FLAT, LONG, SHORT                                                           |
//                                                                                                |
// verwendete Parameter:                                                                          |
// TF_MA = 240 , FS_MA_Schnell = 3 , FS_MA_Slow = 6   ;// 4 Std TF , MA 12Std und 1 Tag           |
// MinFilterGap = 0.0025                         // Distanz zwischen den beiden MA                |
int calcFilterSignal() {                         //                                               |
 double abstand;                                //                                               |
 double ma_Schnell = iMA (Symbol() , TF_MA , FS_MA_Schnell , 0 , FilterMAMode ,PRICE_CLOSE ,0);//|
 double ma_Slow    = iMA (Symbol() , TF_MA , FS_MA_Slow    , 0 , FilterMAMode ,PRICE_CLOSE ,0);//|
 abstand = ma_Schnell - ma_Slow;                // "+" ist Long , "-" ist Short                  |
 double min_gap= MinFilterGapTicks*MarketInfo(Symbol(),MODE_TICKSIZE); //                        |
 // Signal ist "Rauschen"                                                                        |
 if (MathAbs(abstand) < min_gap)                //                                               | 
   return(FLAT);                                //                                               |
 //  Eindeutiges Signal                                                                          |
 if (abstand > 0)                               //                                               | 
   return (LONG);                               //                                               |
 else                                           //                                               |
   return (SHORT);                              //                                               |
}                                                //                                               |
//------------------------------------------------------------------------------------------------+

 

KB

 

PS.: Das ganz SchnickelSchnackel ("Version 0.5. .....") braucht es eigentlich nicht und sollte im Com-EA bitte nicht erscheinen, ist

ausschliesslich um schneller suchen/finden/editieren zu können

  • Upvote 1
Link to comment
Share on other sites

Hier meine inkrementellen Änderungen, habe diese mit #0.6 gekennzeichnet:

 

1. Doku der Änderungen für den ChangeLog

// #0.6 Der Wolf 02.01.2012
// - calcInitStopDiff implementiert
// - calcNewTrailingStop implementiert
// - chandelierExit implementiert
// - handleOpenOrders: Abfrage auf StopLoss
// - checkAndHandleSignals open sell: stop + entry anstelle stop - entry

 

2. externe Paramter

//---- Trailing Stop Parameters abschaltbar
extern bool TrailStopChandelier = true;
extern bool TrailStopParabolicSAR = false;  
//---- ChandelierExit Parameter
extern int chandelierExitATRPeriod = 9;           //Standard: 9
extern double chandelierExitATRMultiplier = 3.0;  //Standard: 3.0
extern int chandelierExitRange = 7;               //Standard: 7
//ParabolicSAR Parameter
extern double parabolicSARStep = 0.02;            //Standard: 0.02
extern double parabolicSARMaximum = 0.2;          //Standard: 0.2

 

3. Funktion calcInitStopDiff

//-----------------------------------------------------------------
// Chandelier als InitStop 
// returns the distance of the initStop or 0 if there is no initStop
double calcInitStopDiff(int orderType) {
 double initStopDiff=0.0;
 
 double chandelierExitValue0=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 double chandelierExitValue1=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 
 int shiftATR = 0;                        //shift für ATR in initerner ChandelierExit Berechnung
 int shiftChandelierExit = 0;             //shift für ChandelierExit

 //ChandelierExit Buffer 0 - Blue - Support
 chandelierExitValue0 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,0,shiftChandelierExit); 
 //ChandelierExit Buffer 1 - Red  - Resistance  
 chandelierExitValue1 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,1,shiftChandelierExit); 

 if ((chandelierExitValue0==EMPTY_VALUE && chandelierExitValue1!=EMPTY_VALUE) || (chandelierExitValue0!=EMPTY_VALUE && chandelierExitValue1==EMPTY_VALUE)) {
   //o.k.  
   if (orderType == OP_BUY && chandelierExitValue0 != EMPTY_VALUE ) {
     initStopDiff = Ask - chandelierExitValue0;
     //Print("calcInitStopDiff buy | chandelier_exit="+chandelierExitValue0+"|Ask="+Ask+"|StopDiff="+initStopDiff);    
   }      
   else if (orderType == OP_SELL && chandelierExitValue1 != EMPTY_VALUE ) {
     initStopDiff = chandelierExitValue1 - Bid;
     //Print("calcInitStopDiff sell | chandelierExit="+chandelierExitValue1+"|Bid="+Bid+"|StopDiff="+initStopDiff);
   } 
 } else  { 
   //Print("calcInitStopDiff: einer der ChandelierExitBuffer muß EMPTY_VALUE zurückliefern: Rückgabe Buffer0 = "+ chandelierExitValue0 + " | Rückgabe Buffer1 = " + chandelierExitValue1);
   initStopDiff = 0.0; //kein initial Stop ermittelbar 
 }  
 
 //Print("calcInitStopDiff: return("+initStopDiff+")");
 return(initStopDiff);
}

 

4. Funktion calcNewTrailingStop

double calcNewTrailingStop(double curStop,int orderType) {

 double trailStopChandelier=0.0;
 double trailStopParabolic=0.0;
 
 double chandelierExitValue0=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 double chandelierExitValue1=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 
 int shiftATR = 0;                        //shift für ATR in initerner ChandelierExit Berechnung
 int shiftChandelierExit = 0;             //shift für ChandelierExit
 int shiftParabilicSAR = 0;               //shift für ParabolicSAR         

 //--- ChandelierExit
 if (TrailStopChandelier) {
   //ChandelierExit Buffer 0 - Blue - Support
   chandelierExitValue0 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,0,shiftChandelierExit); 
   //ChandelierExit Buffer 1 - Red  - Resistance  
   chandelierExitValue1 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,1,shiftChandelierExit); 

   if ((chandelierExitValue0==EMPTY_VALUE && chandelierExitValue1!=EMPTY_VALUE) || (chandelierExitValue0!=EMPTY_VALUE && chandelierExitValue1==EMPTY_VALUE)) {
     //o.k.  
     if (orderType == OP_BUY && chandelierExitValue0 != EMPTY_VALUE ) 
       trailStopChandelier = chandelierExitValue0;
     else if (orderType == OP_SELL && chandelierExitValue1 != EMPTY_VALUE ) {
       trailStopChandelier = chandelierExitValue1;
     } 
   } else {
     //Print("calcNewTrailingStop: einer der ChandelierExitBuffer muß EMPTY_VALUE zurückliefern: Rückgabe Buffer0 = "+ chandelierExitValue0 + " | Rückgabe Buffer1 = " + chandelierExitValue1);
     trailStopChandelier = 0.0;
   }
 }
 
 //--- ParabolicSAR
 if (TrailStopParabolicSAR) {
   trailStopParabolic = iSAR(NULL,0,parabolicSARStep,parabolicSARMaximum,shiftParabilicSAR);  
   //Print("calcNewTrailingStop buy | trailStopParabolic="+trailStopParabolic);   
 }
 
 //--- Fallunterscheidung ChandelierExit / ParabolicSAR
 if ( orderType == OP_BUY ) 
   return(MathMax(trailStopChandelier,  trailStopParabolic));
 else if ( orderType == OP_SELL && trailStopChandelier > 0.0 && trailStopParabolic > 0.0)
   return(MathMin(trailStopChandelier,  trailStopParabolic));
 else if ( orderType == OP_SELL && (trailStopChandelier == 0.0 || trailStopParabolic == 0.0) )
   return(trailStopChandelier +  trailStopParabolic);
 else
   return (0.0);
}

 

5. Funktion chandelierExit

//+------------------------------------------------------------------------------+
//| chandelierExit                                                               |
//| @param chandelierExitRange: range of periods for HH/LL backwards             |
//| @param shiftATR: shift of ATR                                                |
//| @param chandelierExitATRPeriod: AverageTrueRange ATR Period                  |
//| @param chandelierExitATRMultiplier: Multiplier for ATR                       |
//| @param chandelierExitBuffer: Buffer 0 - Blue - Suppor                        |
//|                              Buffer 1 - Red  - Resistance                    |
//| @param shiftChandelierExit: shift, relative to the current bar               |
//| @return Double Value for Support/Resistance, EMPTY_VALUE for opposite Buffer |
//+------------------------------------------------------------------------------+
double chandelierExit(int chandelierExitRange, int shiftATR, int chandelierExitATRPeriod, double chandelierExitATRMultiplier, int chandelierExitBuffer, int shiftChandelierExit) {
 if(chandelierExitBuffer >= 0 && chandelierExitBuffer <= 1)
   return(iCustom(NULL, 0, "ChandelierExit",chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,chandelierExitBuffer,shiftChandelierExit));
 else {
   Print("Fehler: Aufruf mit ungültigem Parameter für Buffer, erlaubt ist 0 oder 1, übergeben wurde "+chandelierExitBuffer);
   return(EMPTY_VALUE); 
 } 
}

 

6. Ergänzung der Funktion handleOpenOrders um Abfrage auf StopLoss

void handleOpenOrders() {
...
  if(NormalizeDouble(stop - OrderStopLoss(),Digits) != 0) 
     //#0.6 Der Wolf 02.01.2012 Anfang
     if ((OrderType() == OP_BUY && stop > 0.0 && stop > OrderStopLoss())
      || (OrderType() == OP_SELL && stop > 0.0 && stop < OrderStopLoss()) )
     //#0.6 Der Wolf 02.01.2012 Ende
        tbModifyOrder(OrderTicket(),OrderOpenPrice(),stop,OrderTakeProfit(), OrderExpiration());
 }  
}

 

7. Fehlerbereinigung in checkAndHandleSignals im Abschnitt "open sell:" stop + entry anstelle stop - entry

void checkAndHandleSignals()
...
//---- open sell
  if(filterSignal + entrySignal == 2*SHORT && 
     (calculateCurrentOrders() == 0 || calcOpenDirection() == SHORT || HedgeAllowed)) {
     entry= Bid;
     stop=calcInitStopDiff(OP_SELL);
      lots= calcLots(stop);
     if(stop > 0) {
       //#0.6 Der Wolf 02.01.2012 Anfang
       stop = entry + stop;
       //#0.6 Der Wolf 02.01.2012 Ende
     } else
       stop= 0;
     tp=calcTPDiff(OP_SELL);
     if(tp > 0)
       tp= entry + tp;
     else
       tp= 0;
     res = tbSendOrder(Symbol(),OP_SELL,lots,entry,3,stop,tp,"sell",MAGICNR, 0);
  }

 

 

Den Indicator ChandelierExit habe ich sicherheitshalber auch noch angehängt.

 

Ich hoffe, ich habe nichts übersehen.

ChandelierExit.mq4

  • Upvote 7
Link to comment
Share on other sites

Vielen Dank für das Update :doubleup: , werd die vollständige Version 0.6 so bald wie möglich reinstellen.

 

6. Ergänzung der Funktion handleOpenOrders um Abfrage auf StopLoss

 

Da haben wir uns vermutlich falsch verstanden. Aus meiner Sicht war es geplant das in der Berechnung des neuen Trailingstops, automatisch das "nur nach oben nachziehen" inkludiert ist. Deswegen auch der aktuelle Stop als Parameter. Ich würde also diese Abfrage noch in die Trailingfunktion packen.

 

Die anderen Funktionen muss ich mir erst genau durchschauen.

Link to comment
Share on other sites

Da haben wir uns vermutlich falsch verstanden. Aus meiner Sicht war es geplant das in der Berechnung des neuen Trailingstops, automatisch das "nur nach oben nachziehen" inkludiert ist. Deswegen auch der aktuelle Stop als Parameter. Ich würde also diese Abfrage noch in die Trailingfunktion packen.

o.k. packe ich noch rein !

Link to comment
Share on other sites

:doubleup: für Deinen Post #254

 

zum BT :

 

100 Trades ist doch schon ganz OK für den allerersten Start .

 

Auffällig ist hier , dass die Gewinner eigentlich alle zwischen dem 35´gsten und 50´gsten Trade liegen, der EA aber ansonsten eher flat ist .

 

Na ja, warten wir die Vervollständigung des Codes ab und gehen besser erst dann in das Detail

 

KB

Link to comment
Share on other sites

so, erledigt

 

Funktion calcNewTrailingStop inklusive Fallunterscheidung ob TrailigStop gesetzt werden soll

//-------------------------------------------------------------
// Chandelier als InitStop + Trailing (per Parameter trailing ausschaltbar)
// Parabolic als zusätzlicher Trailing (max(chandelier,parabolic)), wobei AccStart= 0.
double calcNewTrailingStop(double curStop,int orderType) {
 double trailStop = 0.0;
 
 double trailStopChandelier=0.0;
 double trailStopParabolic=0.0;
 
 double chandelierExitValue0=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 double chandelierExitValue1=EMPTY_VALUE; //Initialisierung mit EMPTY_VALUE
 
 int shiftATR = 0;                        //shift für ATR in initerner ChandelierExit Berechnung
 int shiftChandelierExit = 0;             //shift für ChandelierExit
 int shiftParabilicSAR = 0;               //shift für ParabolicSAR         

 //--- ChandelierExit
 if (TrailStopChandelier) {
   //ChandelierExit Buffer 0 - Blue - Support
   chandelierExitValue0 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,0,shiftChandelierExit); 
   //ChandelierExit Buffer 1 - Red  - Resistance  
   chandelierExitValue1 = chandelierExit(chandelierExitRange,shiftATR,chandelierExitATRPeriod,chandelierExitATRMultiplier,1,shiftChandelierExit); 

   if ((chandelierExitValue0==EMPTY_VALUE && chandelierExitValue1!=EMPTY_VALUE) || (chandelierExitValue0!=EMPTY_VALUE && chandelierExitValue1==EMPTY_VALUE)) {
     //o.k.  
     if (orderType == OP_BUY && chandelierExitValue0 != EMPTY_VALUE ) 
       trailStopChandelier = chandelierExitValue0;
     else if (orderType == OP_SELL && chandelierExitValue1 != EMPTY_VALUE ) {
       trailStopChandelier = chandelierExitValue1;
     } 
   } else {
     Print("calcNewTrailingStop: einer der ChandelierExitBuffer muß EMPTY_VALUE zurückliefern: Rückgabe Buffer0 = "+ chandelierExitValue0 + " | Rückgabe Buffer1 = " + chandelierExitValue1);
     trailStopChandelier = 0.0;
   }
   //Print("calcNewTrailingStop | trailStopChandelier="+trailStopChandelier);   
 }
 
 //--- ParabolicSAR
 if (TrailStopParabolicSAR) {
   trailStopParabolic = iSAR(NULL,0,parabolicSARStep,parabolicSARMaximum,shiftParabilicSAR);  
   //Print("calcNewTrailingStop | trailStopParabolic="+trailStopParabolic);   
 }
 
 //--- Fallunterscheidung ChandelierExit / ParabolicSAR
 if ( orderType == OP_BUY ) 
   trailStop = MathMax(trailStopChandelier,  trailStopParabolic);
 else if ( orderType == OP_SELL && trailStopChandelier > 0.0 && trailStopParabolic > 0.0)
   trailStop = MathMin(trailStopChandelier,  trailStopParabolic);
 else if ( orderType == OP_SELL && (trailStopChandelier == 0.0 || trailStopParabolic == 0.0) )
   trailStop = trailStopChandelier +  trailStopParabolic;
 else
   trailStop = 0.0;
   
 //--- Fallunterscheidung ob TrailigStop gesetzt werden soll
 //wenn der alte Trailingstop curStop zurückgegeben wird, dann braucht keine Änderung durchgeführt werden
 //in allen anderen Fällen wurde ein neuer Trailingstop berechnet der auch per Modify geändert werden sollte 
 //Print("calcNewTrailingStop | trailStop="+trailStop);   
 if ((orderType == OP_BUY && trailStop > 0.0 && trailStop > curStop)
    || (orderType == OP_SELL && trailStop > 0.0 && trailStop < curStop) )
    return(trailStop);  //neuer TrailingStop
 else
    return(curStop);  //alter TrailingStop: d.h. keine Änderung notwendig
}

  • Upvote 6
Link to comment
Share on other sites

So, endlich die zusammengebaute Version. Ich hab das Kriterium beim Trailingstop im Fall Short noch leicht geändert:

 

(orderType == OP_SELL && trailStop > 0.0 && (curStop == 0 || trailStop < curStop))

damit wird auch getrailed wenn es keinen Init-Stoploss gibt. Im Long fall ist das sowieso der Fall.

 

Für das genaue durchschauen der Funktionen fehlt mir derzeit leider die Zeit, aber sieht sehr gut aus.

 

Hier Version 0.6:

eTomNextCommunity.mq4

 

Ich stell es hiermit auch in den Downloadbereich in der Kategorie "community-projekte", dann muss man für die aktuellste Version nicht mehr den Thread durchackern ;)

EA im Download

 

ab sofort stell ich das File dann nur noch ins Downloadmodul.

 

EDIT ganz vergessen:

was noch fehlt:

double calcLots(double stopDiff)  // Lotsizeberechnung nach abhängig von externem Parameter
bool isBreakEven(double openPrice,int orderType) // check ob BreakEven-Trigger erreicht

 

danach würde ich sagen wir schauen uns mal an (mit konkreten Chartbeispielen) was der EA tut und ob er überhaupt das tut was wir wollen.

  • Upvote 4
Link to comment
Share on other sites

damit wird auch getrailed wenn es keinen Init-Stoploss gibt.

 

Wingman ist im Zusamenhang mit dem initialStop per ChandelierExit aufgefallen, daß es Diskrepanzen zwischen den Einstiegs- bzw. Filtersignale und dem initialStop gibt.

Leider wurde die Frage von Wingman in einen eigenen Thread "Anfängerfrage ChandeleierExit" ausgelagert.

Ich sehe daher einen Abstimmbedarf für den initialStop.

 

Hier die ursprünglichen Anforderungen an den CommunityEA:

 

1. Einstiege werden per HeikenAshi-Signal generiert, dies ist in der Funktion calcEntrySignal() realisiert

2. zusätzliche Filter zum Einstieg werden durch zwei MA's in der Funktion calcFilterSignal() realisiert

3. ein initialStop soll per ChandelierExit in der Funktion calcInitStopDiff() generiert werden

 

Daraus ergeben sich voneinander unabhängige Ereignisse: wenn HA-Signal und Filter z.B. einen Down-Trend anzeigen und der ChandelierExit nicht, dann gibt es eben keinen InitalStop

 

erforderlicher Diskussionsbedarf:

Nehmen wir den ChandelierExit als zusätzlichen Filter auf ?

 

Die Alternative wäre, einen anderern initial Stop zu verwenden, was aber m.E. nicht im Sinne der Anforderungen wäre, vor allem wenn dann im trailingStop sowieso der CE wieder ins Spiel kommt.

Link to comment
Share on other sites

Ja ich glaube da gab es auch missverständnisse.

Fragen wir mal so: was macht der Chandelier? Er berechnet doch

<HH der letzten x-Bars> - ATR*Faktor

oder? Sobald das gebrochen wird dann wechsel auf short, aber immer die gleiche berechnung.

was spricht also dagegen den InitStop genau auf dieses Level zu setzen? Also der Chandelier wo er wäre, wenn er er den Trend in diese Richtung sehen würde...

 

Die Idee vom Chandelier ist ja auch

traders ѕhουƖԁ exit long positions аt еіthеr thе peak high ѕіnсе entry minus 3 ATRs

was wir hier ja machen würden.

 

Edit: als Filter würde ich ihn nicht nehmen, da er ja dem Trend-start hinterherhinkt. wir wollen aber mit dem HA den Start direkt erkennen und nutzen.

 

Ich verwende den Parabolic normal auch ein wenig anders. Mit

newStop= oldStop + (ExtremPoint-oldStop)*afFactor

also die Idee des parabolic auf eigene Werte angewendet.

Link to comment
Share on other sites

Ja ich glaube da gab es auch missverständnisse.

Fragen wir mal so: was macht der Chandelier? Er berechnet doch

<HH der letzten x-Bars> - ATR*Faktor

oder?

Er berechnet doch abhängig von der Richtung der letzten x Bars

<
HH der letzten x-Bars> - ATR*Faktor
bzw. 
LL der letzten x-Bars> + ATR*Faktor

 

Sobald das gebrochen wird, dann erfolgt der Wechsel auf die jeweils andere Seite.

Es ist also nicht immer die gleiche Berechnung, sondern abhängig davon ob der aktuelle close sich über oder unter den letzten x Bars befindet.

 

Der ChandelierExit kennt also nach meiner Ansicht nicht immer eine Berechnung sondern abhängig von der Richtung der letzten x Bars (also dem Trend) entweder einen oberen Wert oder einen unteren Wert.

 

Und wenn nun die Chandelier-Richtung nicht mit der Trendfilter-Richtung übereinstimmt, dann gibt es keinen Wert für den Chandelier (=EMPTY_VALUE)

Link to comment
Share on other sites

Der ChandelierExit kennt also nach meiner Ansicht nicht immer eine Berechnung sondern abhängig von der Richtung der letzten x Bars (also dem Trend) entweder einen oberen Wert oder einen unteren Wert.

 

naja, aus meiner Sicht implementiert der Chandelier eine Idee: "Aussteigen wenn der Kurs x*ATR unter das maximum fällt". Diese Idee liefert eine Berechnung für den Long und eine für den Short fall.

Der Chandelier inkludiert halt noch einen "geratenen" Trend und gibt nur die entsprechende Berechnung aus.

 

Da wir aber den Trend "selber raten" wäre es trotzdem in der Idee des Chandelier hier die entsprechende Berechnung für "unseren" Trend zu nehmen.

 

Gibts noch andere Meinungen dazu?

Link to comment
Share on other sites

@Chandelier

Ja, ich denke wir haben da ein kleines Missverständis. :cleanglasses:

Bin gespannt, wie das die anderen sehen ?

 

@Parabolic

Ich verwende den Parabolic normal auch ein wenig anders. Mit

newStop= oldStop + (ExtremPoint-oldStop)*afFactor

also die Idee des parabolic auf eigene Werte angewendet.

Ich habe den Parabolic bisher überhaupt nicht benutzt, nur rudimentär angetestet.

Habe den Fehler bemerkt, daß ich noch den Ordertype und den alten Stop berücksichtigen muß. Bin bereits am Testen einer geänderten Version.

Link to comment
Share on other sites

Da die Diskussion um den Chandelier eigentlich bereits in den Bereich "tut der EA was wir uns gedacht haben" fällt, hab ich noch die verbleibenden 2 Funktionen implementiert:

 

//BreakEven
extern bool BreakEvenActive      = true;
extern int  BreakEvenATRPeriod   =   13;
extern double BreakEvenATRFaktor =  1.5;

//MM
extern int    MMPercent   =   0;  //first priority, defines the relative Risk per Order
extern double MMRisk      =   0;  //second. only used if MMPercent is 0. Defines the absolute Risk per Order
extern double MMLots      = 0.1;  //third. only used if the others are 0. Defines the fixed Lotsize per Order

//-----------------------------------------------------------------
//# %Equity - es wird immer der angegebene % der Equity pro Trade risikiert
//# fixer Betrag als Risk (wenn %Equity==0)
//# fixe Lotzahl (wenn a) und b) == 0)
//returns the lotsize for this order

double calcLots(double stopDiff) {
  double lots= 0;
  double lots_step= MarketInfo(Symbol(),MODE_LOTSTEP);
  double risk= 0;
  
  if(MMPercent == 0 && MMRisk == 0) {
    lots= MMLots;
  } else {  
    if(MMPercent != 0)
      risk= AccountEquity()*MMPercent/100;
    else
      risk= MMRisk;
    
    double point_value= MarketInfo(Symbol(),MODE_TICKVALUE)/MarketInfo(Symbol(),MODE_TICKSIZE);
    lots= risk/(stopDiff*point_value);
  }
  lots= MathFloor(lots/lots_step)*lots_step;
  lots= MathMin(MarketInfo(Symbol(),MODE_MAXLOT),MathMax(MarketInfo(Symbol(),MODE_MINLOT),lots));
  return(lots);
}

//-------------------------------------------------------------
// Breakeven nach Anstieg um x*ATR

bool isBreakEven(double openPrice,int orderType) {
 if(!BreakEvenActive)
     return(false);
     
 double atr= iATR(Symbol(),Period(),BreakEvenATRPeriod,0);
 if(orderType == OP_BUY) {
   if(Bid > openPrice+atr*BreakEvenATRFaktor)
     return(true);
   else
     return(false);
 }
 if(orderType == OP_SELL) {
   if(Ask < openPrice-atr*BreakEvenATRFaktor)
     return(true);
   else
     return(false);
 }
 return(false);
}

 

Version 1.0 ist im Downloadmodul.

 

Damit wäre die erste vollständige Version des EAs implementiert. :doubleup: Ist ja schon einiges an Code und Logik zusammengekommen.

 

Die erste "Verbesserung/Logikproblem" wurde ja auch schon in Form des Chandelier als Init-Stop aufgedeckt. Ich würde sagen das behandeln wir als erstes. Also: Meinungen dazu?

 

PS: Spannender Effekt derzeit: wenn kein initSL vorhanden ist greift die Lotsberechnung auf die fixen Lots zurück. Sind diese deutlich kleiner als die durchschnittliche prozentuelle Lotsize wird aus einer positiven Performance eine deutlich negative. Die Trades wo der Chandelier noch auf der falschen Seite ist, sind also scheinbar sehr wichtig für die positive Entwicklung. mMn ein weiterer Grund warum wir ihn nicht als Filter einsetzen sollten, bzw. wenn als umgekehrten Filter: Nur einstieg wenn chandelier auf der "falschen" Seite.

 

Als kleiner Teaser: Ergebnis einer ersten Optimierung auf 1 Jahr. die Parameter die sich hier ergeben haben sind äußerst spannend und geben sicher Diskussionsbedarf für die Logik, aber dazu mehr später.

TesterGraph.gif

  • Upvote 4
Link to comment
Share on other sites

 

Die erste "Verbesserung/Logikproblem" wurde ja auch schon in Form des Chandelier als Init-Stop aufgedeckt. Ich würde sagen das behandeln wir als erstes. Also: Meinungen dazu?

 

Wie wärs denn mit einem simplen "x Bars Low/High" oder dem ATR als iniSL, einfach nur um von Beginn an einen KatastrophenSL im Markt zuhaben?

Link to comment
Share on other sites

... hab ich noch die verbleibenden 2 Funktionen implementiert:

Super, danke !

 

Damit wäre die erste vollständige Version des EAs implementiert.

Ist noch nicht ganz vollständig, habe noch einen Fehler im calcNewTrailingStop() beim Parabolic.

Werde mir gleich die Version 1.0 holen, kurz mit meiner Korrektur antesten und stelle dann die geänderte Funktion in diesen Thread rein.

Link to comment
Share on other sites

Wie wärs denn mit einem simplen "x Bars Low/High" oder dem ATR als iniSL, einfach nur um von Beginn an einen KatastrophenSL im Markt zuhaben?

 

Der Chandelier macht eigentlich eine Kombination davon. Also für Long - ATR*Faktor. Er macht es eben nur immer für eine Richtung, aber ich finde man könnte wie gesagt diese Logik einfach direkt so nehmen.

 

@Wolf: vollständig schon, von fehlerfrei hat keiner was gesagt :moveaway:

Link to comment
Share on other sites

Alles klar, hier die Fehlerbereinigung in der Funktion calcNewTrailingStop().

Fällt natürlich nur auf, wenn der externe Parameter TrailStopChandelier auf false und TrailStopParabolicSAR auf true stehen.

 

//--- ParabolicSAR
 if (TrailStopParabolicSAR) {
   trailStopParabolic = iSAR(NULL,0,ParabolicSARStep,ParabolicSARMaximum,shiftParabilicSAR);  
   if (trailStopParabolic > 0.0) {
     if ((orderType == OP_BUY && trailStopParabolic < Bid) || (OrderType()==OP_SELL && trailStopParabolic > Ask) ) {
         //o.k., ParabolicStop "passt" zur Order
     } else 
       trailStopParabolic=curStop;
   }
   //Print("calcNewTrailingStop | trailStopParabolic="+trailStopParabolic+"| curStop="+curStop+"|OrderTicket="+OrderTicket());     
 }

 

btw.

ich habe bei Indikatoren für die Shift-Parameter Variablen verwendet und diesen i.d.R. 0-Werte zugewiesen.

 

Wäre evtl. ein nächster Diskussionspunkt, ob man vielleicht generell eine (externe) Variable für (alle) Shift-Werte von Indikatoren verwendet.

Möglicherweise könnte man auch die Variable EachTickMode dazu hernehmen, also wenn EachTickMode true dann Shift-Werte = 0 ansonsten Shift-Werte = 1.

Wie seht ihr das ?

Link to comment
Share on other sites

Wäre evtl. ein nächster Diskussionspunkt, ob man vielleicht generell eine (externe) Variable für (alle) Shift-Werte von Indikatoren verwendet.

Möglicherweise könnte man auch die Variable EachTickMode dazu hernehmen, also wenn EachTickMode true dann Shift-Werte = 0 ansonsten Shift-Werte = 1.

Wie seht ihr das ?

 

Find ich gut, ich habs jetzt einfach mal dazugetan damits einheitliche Shifts gibt. Deine Änderung im Trailing ist auch drin und als Version 1.1 hochgeladen.

 

@InitStop: gibts dazu keine weiteren Meinungen? Ich würde ja ganz frech Licens Meinung als "pro meine Variante" nehmen, aber das wär dreist ;)

Da die Diskussionsbeteiligung sehr klein ist folgender Vorschlag: Wir bauen die schnell zu machende Lösung (InitStop immer auf HH-x*ATR) ein, damit wir mal weiter testen und verbessern können. Möglicherweise stellt sich dann ja noch raus das der Chandelier als Filter doch gut ist.

@Wolf: wär das für dich in Ordnung? Ich sehe nur das Risiko das bei einer Diskussion über Alternativen derzeit nur wir 2 diskutieren und wir die anderen langweilen ...

 

@cxalgo: stimmt, sieht gut aus. Eigentlich war gedacht ihn auf M15 laufen zu lassen, aber scheinbar is H1 auch nit schlecht ;) Mit den Parametern is es dann eher ein "Scalper" als Trendfolger. Aber auch spannend wie der gleiche EA mit anderen Parametern die "Taktik" ändern kann.

 

@all: Nicht wundern, ich flieg morgen 2 wochen auf Urlaub, kann dann also erst danach wieder antworten/einbauen.

Link to comment
Share on other sites

Ich würde ja ganz frech Licens Meinung als "pro meine Variante" nehmen, aber das wär dreist ;)

Ne, mach mal. :white_flag:

@all: Nicht wundern, ich flieg morgen 2 wochen auf Urlaub, kann dann also erst danach wieder antworten/einbauen.

Einen schönen Urlaub wünsch ich. Und ich geh mal davon aus, dass du einen Urlaubsort mit Internetanschluss gewählt hast!? :shades:

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...