Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 1046

 

Mashkas Standard-Code

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//--- indicator parameters
input int            InpMAPeriod=13;        // Period
input int            InpMAShift=0;          // Shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMA;  // Method
//--- indicator buffer
double ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
   int    draw_begin=InpMAPeriod-1;
//--- indicator short name
   switch(InpMAMethod)
     {
      case MODE_SMA  : short_name="SMA(";                break;
      case MODE_EMA  : short_name="EMA(";  draw_begin=0; break;
      case MODE_SMMA : short_name="SMMA(";               break;
      case MODE_LWMA : short_name="LWMA(";               break;
      default :        return(INIT_FAILED);
     }
   IndicatorShortName(short_name+string(InpMAPeriod)+")");
   IndicatorDigits(Digits);
//--- check for input
   if(InpMAPeriod<2)
      return(INIT_FAILED);
//--- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexShift(0,InpMAShift);
   SetIndexDrawBegin(0,draw_begin);
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtLineBuffer);
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|  Moving Average                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- check for bars count
   if(rates_total<InpMAPeriod-1 || InpMAPeriod<2)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtLineBuffer,false);
   ArraySetAsSeries(close,false);
//--- first calculation or number of bars was changed
   if(prev_calculated==0)
      ArrayInitialize(ExtLineBuffer,0);
//--- calculation
   switch(InpMAMethod)
     {
      case MODE_EMA:  CalculateEMA(rates_total,prev_calculated,close);        break;
      case MODE_LWMA: CalculateLWMA(rates_total,prev_calculated,close);       break;
      case MODE_SMMA: CalculateSmoothedMA(rates_total,prev_calculated,close); break;
      case MODE_SMA:  CalculateSimpleMA(rates_total,prev_calculated,close);   break;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Ich füge nicht den gesamten Code ein, da der nächste Schritt Berechnungen sind, die Frage bezieht sich auf die Initialisierung

Wie lässt sich der Wert"InpMAPeriod" ändern, wenn sich der Zeitrahmen ändert?

Zum Beispiel: bei M15 -"InpMAPeriod"

Bei M30 -"InpMAPeriod2".

Ich bin kein Programmierer, bitte helfen Sie mir.

 

Ich bin verblüfft - entweder lügen meine Augen, oder ich übersehe etwas.


Hier ist die Berechnungsformel (Sie müssen nicht auf alles eingehen, achten Sie auf die Druckausgabebedingungen und die Berechnung innerhalb von return() - Code auf gelbem Hintergrund)

double Phase_Value_2(int index, double point, int period)
  {
   
   double muving = 0, flat = 0, up = EMPTY_VALUE, down = EMPTY_VALUE;
   int limit = index + (period > 1 ? period : 1);
   for(int i = index; i < limit; i++)
     {
      if(High[i] <= High[i+1] && Low[i] >= Low[i+1])
        {
         flat += High[i] - Low[i];
        }
      else if(MathMax(High[i],High[i+1]) - MathMin(Low[i],Low[i+1]) < High[i] - Low[i] + High[i+1] - Low[i+1])
        {
         muving += High[i] - Low[i];
        }
      else
        {
         up     = (High[i] > High[i+1] ? High[i] - High[i+1] : 0);
         down   = (Low[i] < Low[i+1] ? Low[i+1] - Low[i] : 0);
         muving += up + down;
         up     = MathMin(High[i],High[i+1]);
         down   = MathMax(Low[i],Low[i+1]);
         flat   += up - down;
        };
     };
   
   muving = (muving == 0 ? 1 * point : muving);
   flat   = (flat == 0 ? 1 * point : flat);
   if(flat <= muving && flat / muving > 1) Print("index ",(string)index," ",(string)flat," / ",(string)muving," = ",(string)(flat/muving));
  //-----------------------------------------------------------------
   return(muving < flat ? (1 - (muving / flat)) * (-1) : 1 - (flat / muving));
  }

... In diesem Schritt werden alle Werte korrekt im Bereich von 1 bis -1 zurückgegeben.


Wenn diese Werte jedoch aus dem Puffer gedruckt werden, wird der Bereich unterbrochen (im Puffer ist der Bereich bereits 100 bis -100).

Hier ist der Zyklus selbst

for(int i = limit_slowing; i >= 0; i--)
     {
      if(p_slowing > 1) {Slowing(i,(int)p_slowing,p_method,P);}
      else              {P[i] = Phase_Value_2(i,_Point,(int)p_period) * 100;}; if(P[i] > 100 || P[i] < -100) Print("index ",(string)i,", value ",(string)P[i]);
     };


Innerhalb des Retarders finden keine Additionen statt, sondern nur Multiplikationen mit 100

void Slowing(int index, int slowing, ENUM_MA_METHOD method, double &Bufer[])
  {
   
   double value = 0, c = 2 / (double)(slowing+1); int limit, period = slowing, sum_period = 0;
   
   if(method == MODE_SMA)
     {
      limit = index + slowing;
      for(int i = index; i < limit; i++) value += Inhibitor[i];
      Bufer[index] = (value / (double)slowing) * 100;
     }
   
   else if(method == MODE_EMA)
     {
      if(Bufer[index+1] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = (value / (double)slowing) * 100; return;
        };
      Bufer[index] = (c * Inhibitor[index] + (1-c) * (Bufer[index+1]/100)) * 100;
     }
   
   else if(method == MODE_SMMA)
     {
      if(Bufer[index+1] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = (value / (double)slowing) * 100; return;
        };
      if(Bufer[index+1] != EMPTY_VALUE && Bufer[index+2] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = ((value - (Bufer[index+1]/100) + Inhibitor[index]) / (double)slowing) * 100; return;
        };
      value = (Bufer[index+1]/100) * (double)slowing;
      Bufer[index] = ((value - (Bufer[index+1]/100) + Inhibitor[index]) / (double)slowing) * 100;
     }
   
   else
     {
      limit = index + slowing;
      for(int i = index; i < limit; i++)
        {
         value += Inhibitor[i] * (double)period;
         sum_period += period; period--;
        };
      Bufer[index] = value / (double)sum_period * 100;
     };
   
  }


Wo liegt das Problem?

 
Alexandr Sokolov:

Ich bin verwirrt - entweder lügen meine Augen oder ich übersehe etwas

Wo liegt das Problem?

Ich habe den Code überhaupt nicht verstanden.

*100
Versuchen Sie, auf 100,0 zu wechseln.
 
Vitaly Muzichenko:

Ich bin mit dem Code überhaupt nicht vertraut.

Versuchen Sie, durch 100,0 zu ersetzen.

Ausprobiert, hat nicht geklappt.

 
ukrop1203:
Hallo, ich erhalte eine Fehlermeldung über erfolglose Objekte, nachdem ich einen ekspert-Test abgeschlossen habe, und ich erzeuge absolut alle Objekte, soweit ich verstehe, im Stapel, d.h. ohne new. Bitte erläutern Sie diese Frage.

Versuch Nummer 2, bitte beantworten Sie die Frage.

 
ukrop1203:

Versuch Nummer 2, bitte beantworten Sie die Frage.

Es geschehen keine Wunder. Wenn es heißt, dass es durchgesickert ist, bedeutet das, dass Sie es irgendwo auf dem Stapel liegen gelassen und vergessen haben. Suchen Sie danach. Alternativ können Sie in den Konstruktor einfügen

if (CheckPointer(&this)==POINTER_DYNAMIC) DebugBreak();

und unter dem Debugger, fangen Sie einen Punkt.

 
bool CloseByBu(OpenModel& open_model) { 
   bool closed_by_bu = False;
   if (OrderSelect(open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES) && OrderType() <= 1) {
      closed_by_bu = OrderCloseBy(open_model.bu_ticket, open_model.ticket);   
      if (!closed_by_bu) {         
         PrintMessageInLog(StringFormat("DIDN'T CLOSE order by opposite order first ticket=%i, second ticket=%i, error=%i", 
			   		 open_model.ticket, open_model.bu_ticket, GetLastError()));         
         PrintMessageInLog(StringFormat("First order selected=%s, order type=%i, order price=%f", 
                           		string(OrderSelect(open_model.ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));
         PrintMessageInLog(StringFormat("Second order selected=%s, order type=%i, order price=%f", 
                           		string(OrderSelect(open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));                                       
      }
   }   
   return closed_by_bu;
}

2018.01.02 08:01:30 DIDN'T CLOSE order by opposite order erstes Ticket=2, zweites Ticket=3, error=3

2018.01.02 08:01:30 Erster Auftrag selected=true, Auftragsart=1, Auftragspreis=1.351920

2018.01.02 08:01:30 Zweiter Auftrag selected=true, Auftragsart=0, Auftragspreis=1.351590


Bitte erläutern Sie, warum Sie zwei Gegenaufträge nicht abschließen.

 

Warum werden 2 überladene Funktionen zum Zeichnen vertikaler Linien vom Compiler zugelassen (erste Funktion - Farbauswahl, zweite - Farbe und Fenster) und man kann beide verwenden, aber wenn ich eine dritte Funktion mit Farb-, Fenster- und Stilauswahl hinzufüge, flucht er und zwingt alle Funktionen, vom dritten Typ zu sein?


void VLine(int window=0) {
 
  
 string nm="VLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, Red);
  ObjectSet(nm, OBJPROP_STYLE, 0);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}


void VLine(color cl, int window=0) {
 
  
 string nm="VLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, cl);
  ObjectSet(nm, OBJPROP_STYLE, 0);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}




void VLine(color cl, int window=0, int style=0) {
 
 
 string nm="STOPLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, cl);
  ObjectSet(nm, OBJPROP_STYLE, style);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
  • www.mql5.com
При создании графического объекта функцией ObjectCreate() необходимо указать тип создаваемого объекта, который может принимать одно из значений перечисления ENUM_OBJECT. Дальнейшие уточнения свойств созданного объекта возможно с помощью функций по работе с графическими объектами.
 
Viatcheslav Pashkov:

Warum werden 2 überladene Funktionen zum Zeichnen vertikaler Linien vom Compiler zugelassen (erste Funktion - Farbauswahl, zweite - Farbe und Fenster) und man kann beide verwenden, aber wenn ich eine dritte Funktion mit Farb-, Fenster- und Stilauswahl hinzufüge, flucht er und zwingt alle Funktionen, vom dritten Typ zu sein?


Die Standardwerte negieren das Vorhandensein des Eingabeparameters. Bedenken Sie, dass sie nicht existiert. Und schauen Sie, ob der Compiler die richtige Funktion auswählen kann.

 
ukrop1203:

Zwei Gegenaufträge werden nicht geschlossen, bitte erklären Sie das.

Theoretisch sollte Ihr Code funktionieren, ich könnte mich irren, aber nicht alle Broker erlauben dies, versuchen Sie es auf Metakvotes-demo zu überprüfen, es hat dort definitiv funktioniert