Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 1046

 

Le code standard de Mashka

#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);
  }

Je ne colle pas tout le code, puisque l'étape suivante est le calcul, la question porte sur l'initialisation.

Comment faire en sorte que la valeur de"InpMAPeriod" change lorsque la période de temps change.

Par exemple : à M15 -"InpMAPeriod"(Période d'entrée)

En M30 -"InpMAPeriod2".

Je ne suis pas un programmeur, aidez-moi s'il vous plaît.

 

Je suis perplexe - soit mes yeux mentent, soit il me manque quelque chose.


Voici la formule de calcul (il n'est pas nécessaire de tout détailler, faites attention aux conditions de sortie de l'impression et au calcul à l'intérieur de return() - code sur fond jaune)

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));
  }

... À cette étape, toutes les valeurs sont correctement retournées dans la plage de 1 à -1.


Mais lorsque ces valeurs sont imprimées à partir du tampon, l'intervalle est rompu (dans le tampon, l'intervalle est déjà de 100 à -100).

Voici le cycle lui-même

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]);
     };


Dans le ralentisseur, il n'y a pas d'addition, seulement une multiplication par 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;
     };
   
  }


Quel est le problème ?

 
Alexandr Sokolov:

Je suis perplexe - soit mes yeux mentent, soit il me manque quelque chose.

Quel est le problème ?

Je n'ai pas du tout compris le code.

*100
essayez de passer à 100.0
 
Vitaly Muzichenko:

Je ne connais pas du tout le code.

essayez de remplacer par 100.0

J'ai essayé, ça n'a pas marché.

 
ukrop1203:
Bonjour, je reçois une erreur concernant les objets non réussis après avoir effectué un test d'ekspert, et je crée absolument tous les objets, d'après ce que je comprends, dans la pile, c'est-à-dire sans new. Veuillez expliquer cette question.

Tentative numéro 2, veuillez répondre à la question.

 
ukrop1203:

Tentative numéro 2, veuillez répondre à la question.

Les miracles n'arrivent pas, si le document dit qu'il a fui, cela signifie que vous l'avez laissé quelque part dans la pile et que vous l'avez oublié. Cherchez-le. Alternativement, dans le constructeur, insérer

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

et sous le débogueur, attrape une tache.

 
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 first ticket=2, second ticket=3, error=3

2018.01.02 08:01:30 Premier ordre sélectionné=true, type d'ordre=1, prix de l'ordre=1.351920

2018.01.02 08:01:30 Second ordre sélectionné=true, type d'ordre=0, prix de l'ordre=1.351590


Ne pas fermer deux contre-ordres, veuillez expliquer.

 

Pourquoi 2 fonctions surchargées de dessin de lignes verticales sont approuvées par le compilateur (première fonction - sélection de la couleur, deuxième - couleur et fenêtre) et vous pouvez les utiliser toutes les deux, mais quand j'en ajoute une troisième, avec sélection de la couleur, de la fenêtre et du style - il jure et force toutes les fonctions à être du troisième type ?


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:

Pourquoi 2 fonctions surchargées de dessin de lignes verticales sont approuvées par le compilateur (première fonction - sélection de la couleur, deuxième - couleur et fenêtre) et vous pouvez les utiliser toutes les deux, mais quand j'en ajoute une troisième, avec sélection de la couleur, de la fenêtre et du style - il jure et force toutes les fonctions à être du troisième type ?


Les valeurs par défaut annulent la présence du paramètre d'entrée. Considérez qu'elle n'existe pas. Et voyez si le compilateur peut sélectionner la bonne fonction.

 
ukrop1203:

Il ne ferme pas deux contre-ordres, veuillez expliquer.

En théorie, votre code devrait fonctionner, je peux me tromper, mais tous les courtiers ne permettent pas de faire cela, essayez sur Metakvotes-demo pour vérifier, cela a bien fonctionné là-bas.

Raison: