Expert Advisors: Diff_TF_MA_EA

 

Diff_TF_MA_EA:

Ein Expert Advisor, der auf dem Indikator Diff_TF_MA basiert.


Autor: Scriptor

 

An einigen Stellen hat er den Code zerschnitten.

//+------------------------------------------------------------------+
//| Gibt den Namen Zeitrahmen zurück|
//+------------------------------------------------------------------+
string NameTimeframe(int timeframe=PERIOD_CURRENT)
  {
   if(timeframe==PERIOD_CURRENT) timeframe=Period();
   switch(timeframe)
     {
      case 1      : return "M1";
      case 2      : return "M2";
      case 3      : return "M3";
      case 4      : return "M4";
      case 5      : return "M5";
      case 6      : return "M6";
      case 10     : return "M10";
      case 12     : return "M12";
      case 15     : return "M15";
      case 20     : return "M20";
      case 30     : return "M30";
      case 16385  : return "H1";
      case 16386  : return "H2";
      case 16387  : return "H3";
      case 16388  : return "H4";
      case 16390  : return "H6";
      case 16392  : return "H8";
      case 16396  : return "H12";
      case 16408  : return "D1";
      case 32769  : return "W1";
      case 49153  : return "MN1";
      default     : return (string)(int)Period();
     }
  }
Versuchen Sie dies
string NameTimeframe( const ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT )
{
  return(StringSubstr(EnumToString(timeframe == PERIOD_CURRENT ? Period() : timeframe), 7));
}
 
//+------------------------------------------------------------------+
//|| Füllt Positions-Ticket-Arrays|
//+------------------------------------------------------------------+
void FillingListTickets(void)
  {
   list_tickets_buy.Clear();
   list_tickets_sell.Clear();
   total_volume_buy=0;
   total_volume_sell=0;
//---
   int total=PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket=PositionGetTicket(i);
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      if(PositionGetInteger(POSITION_MAGIC)!=InpMagic)   continue;
      if(PositionGetString(POSITION_SYMBOL)!=symb)       continue;
      double volume=PositionGetDouble(POSITION_VOLUME);
      if(type==POSITION_TYPE_BUY)
        {
         list_tickets_buy.Add(ticket);
         total_volume_buy+=volume;
        }
      else if(type==POSITION_TYPE_SELL)
        {
         list_tickets_sell.Add(ticket);
         total_volume_sell+=volume;
        }
     }
  }

Keine Überprüfung von PositionGetTicket.

"else if" kann einfach "else" sein.

Typ wird nicht nach continue genommen.

 

Es gibt keine schwebenden Aufträge im Expert Advisor, deshalb ist diese Bedingung nur für POSITION_TYPE_BUY korrekt.

double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());

Diese Bedingung ist nur für POSITION_TYPE_BUY korrekt.

 
fxsaber:

Es gibt keine ausstehenden Aufträge im Expert Advisor, so dass eine solche

Diese Bedingung ist nur für POSITION_TYPE_BUY korrekt.

Warum?

Der Aufruf dieser Funktion ist an zwei Stellen im Code vorhanden:

   //--- Eröffnung von Positionen durch Signale
      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }
      if(open_short)
        {
         if(num_b>0) CloseBuy();
         if(num_s==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_SELL,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_SELL,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_SELL);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_SELL,ll))
              {
               if(trade.Sell(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

Wenn also nur der Programmierer, der diesen Code geschrieben hat, dummerweise den falschen Ordertyp an die Funktion sendet, dann ja, dann gibt es einen Fehler. Im Fall dieses Codes wird es keinen Fehler geben.

 
Artyom Trishkin:

Warum?

Der Aufruf dieser Funktion befindet sich an zwei Stellen im Code:

Wenn also nur der Programmierer, der diesen Code geschrieben hat, dummerweise den falschen Auftragstyp an die Funktion sendet, dann wird es einen Fehler geben. Im Falle dieses Codes wird es keinen Fehler geben.

Denn es kann eine andere Sichtweise auf das KB geben

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

MT4 oder MT5. Was sind die Vor- und Nachteile?

Renat Fatkhullin, 2018.01.31 14:28

  1. 4300 Programme und 870 Experten inklusive, im Quellcode, wissend genug , um zu lernen und eigene Ideen zu entwickeln

Es wird nicht behauptet, dass es in diesem speziellen Fall einen Fehler gibt. Aber Funktionen wandern von einem Code zum anderen. Ein potenzieller Fehler in einer migrierenden Funktion ist wie eine hängende Pistole an der Wand.

Man kann ihn natürlich durch die Finger gleiten lassen. Aber ich sehe hier, dass es besser ist, Sie zu warnen.

 
fxsaber:

Weil es eine andere Perspektive auf den QB geben kann


Es wird nicht behauptet, dass es in diesem speziellen Fall einen Fehler gibt. Aber Funktionen wandern von einem Code zum anderen. Ein potenzieller Fehler in einer migrierenden Funktion ist wie eine hängende Pistole an der Wand.

Man kann ihn natürlich durch die Finger gleiten lassen. Aber ich sehe hier, dass es besser ist, zu warnen.

Sie haben Recht, Warnung ist richtig.
Der Autor wollte wahrscheinlich unnötige Prüfungen entfernen - in manchen Fällen ist Vielseitigkeit unnötig. Sie müssen durch die Aufzählung von ENUM_ORDER_TYPE verwirrt worden sein. Wenn es ENUM_POSITION_TYPE gäbe, würde es keine Fragen geben.

Genauso wenig wie Ihr Vorschlag, Text zu kürzen. Ist switch nicht schneller?

 
Artyom Trishkin:

Der Autor wollte wahrscheinlich unnötige Prüfungen entfernen - in manchen Fällen ist Universalität unnötig. Hier müssen Sie durch die Aufzählung ENUM_ORDER_TYPE verwirrt worden sein. Wenn ENUM_POSITION_TYPE vorhanden wäre, gäbe es keine Fragen.

Hier hätten Sie die Funktion selbst und ihre Aufrufe korrigieren müssen. Der Autor hat das seit MT4 nicht mehr so richtig realisiert.

Genauso wie Ihr Vorschlag, den Text zu kürzen. Ist switch nicht schneller?

Solche Switch-Konstruktionen sind genau das, was man nicht machen sollte. Was die Geschwindigkeit angeht, so braucht man sie für diese Funktion überhaupt nicht. Aber das Beispiel ist wirklich sehr anschaulich. Es wird zumindest von Interesse sein.

 
fxsaber:

Die Funktion selbst und ihre Aufrufe hätten hier korrigiert werden müssen. Der Autor hat dies seit MT4 nicht mehr zu Ende gedacht.

Aber solche Switch-Konstruktionen sind genau das, was nicht gemacht werden sollte. Was die Geschwindigkeit angeht, so braucht diese Funktion diese überhaupt nicht. Aber das Beispiel ist wirklich sehr anschaulich. Interessant wird es auf jeden Fall sein.

Interessant. Und was ist Ihrer Meinung nach falsch am Ansatz der Standardberechnung des Mindestabstands für das Setzen von Stop-Orders?

//+------------------------------------------------------------------+
//| Gibt den korrekten StopLoss relativ zum StopLevel zurück |
//+------------------------------------------------------------------+
double CorrectStopLoss(const ENUM_ORDER_TYPE order_type,const int stop_loss)
  {
   if(stop_loss==0) return 0;
   double pt=symbol_info.Point();
   double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());
   int lv=StopLevel(),dg=symbol_info.Digits();
   return
   (order_type==ORDER_TYPE_BUY ?
    NormalizeDouble(fmin(price-lv*pt,price-stop_loss*pt),dg) :
    NormalizeDouble(fmax(price+lv*pt,price+stop_loss*pt),dg)
    );
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Gibt den berechneten StopLevel zurück|
//+------------------------------------------------------------------+
int StopLevel(void)
  {
   int sp=symbol_info.Spread();
   int lv=symbol_info.StopsLevel();
   return(lv==0 ? sp*size_spread : lv);
  }
//+------------------------------------------------------------------+

Ich kann hier keine Fehler erkennen. Erklären Sie das. Und was ist der Unterschied zwischen der Berechnung des Mindestabstandes bei MT4 und MT5?

 

Es gibt tatsächlich mehr Fehler im Code. Zum Beispiel ist es gut gezeigt, dass die Verwendung von CSymbolInfo nur um des SB-Stils willen böse ist.

Das Schließen von Positionen über eine zuvor gesammelte Liste von Tickets ist böse. Dies ist ein sehr häufiger Fehler.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Fehler, Bugs, Fragen

fxsaber, 2018.01.23 09:39 Uhr.

Das ist die falsche Logik. Nach einem fehlgeschlagenen und erfolgreichen OrderSend sollte die aktuelle Handelsumgebung komplett neu eingelesen werden. Diese Regel sollte immer gelten.

Zu den Returncodes. Ich analysiere sie in meinen Expert Advisors in keiner Weise. Meiner Meinung nach sollte die Handelslogik nicht von ihnen abhängen.

 
Artyom Trishkin:

Interessant. Was ist Ihrer Meinung nach falsch an dem Ansatz der Standardberechnung des Mindestabstands von Stop-Aufträgen?

Ich kann hier keine Fehler erkennen. Erklären Sie das. Und was ist der Unterschied zwischen der Berechnung des Mindestabstandes bei MT4 und MT5?

Der Fehler liegt in der Enum-Eingabe und dem Aufruf, nicht im Mindestabstand. Aber auch dieser wird falsch berechnet, denn

Forum zum Thema Trading, automatisierte Handelssysteme und Testen von Handelsstrategien.

Expert Advisors: Diff_TF_MA_EA

fxsaber, 2018.02.01 21:38

Es ist gut gezeigt, dass die Verwendung von CSymbolInfo nur um des SB-Stils willen böse ist.