Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 1046

 

Código estándar 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);
  }

No voy a pegar todo el código, ya que el siguiente paso son los cálculos, la pregunta está relacionada con la inicialización

Cómo hacer que el valor de"InpMAPeriod" cambie cuando cambia el marco temporal.

Por ejemplo: en M15 -"InpMAPeriod"

En M30 -"InpMAPeriod2".

No soy programador, por favor, ayuda.

 

Estoy desconcertado - o mis ojos mienten, o me estoy perdiendo algo


Aquí está la fórmula de cálculo (no tienes que entrar en todo, presta atención a las condiciones de salida de la impresión y al cálculo dentro de return() - código sobre fondo amarillo)

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

... En este paso, todos los valores se devuelven correctamente en el rango de 1 a -1


Pero cuando estos valores se imprimen desde el buffer - el rango se rompe (en el buffer el rango ya es de 100 a -100)

Este es el ciclo propiamente dicho

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


Dentro del retardador, no hay suma, sólo multiplicación por 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;
     };
   
  }


¿Cuál es el problema?

 
Alexandr Sokolov:

Estoy desconcertado - o mis ojos mienten o me estoy perdiendo algo

¿Cuál es el problema?

No entendí el código en absoluto.

*100
intente cambiar a 100.0
 
Vitaly Muzichenko:

No estoy en absoluto familiarizado con el código.

intente reemplazar con 100.0

Lo intenté, pero no funcionó.

 
ukrop1203:
Hola, me sale un error de objetos fallidos después de completar un test de ekspert, y creo absolutamente todos los objetos, según tengo entendido, en la pila, es decir, sin new. Por favor, explique esta pregunta.

Intento número 2, por favor responda a la pregunta.

 
ukrop1203:

Intento número 2, por favor responda a la pregunta.

Los milagros no ocurren, si dice que se ha filtrado, significa que lo has dejado en algún lugar del montón y te has olvidado de él. Búscalo. Como alternativa, en el constructor inserte

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

y debajo del depurador, coge un punto.

 
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 NO SE HA CERRADO el pedido por orden inverso primer ticket=2, segundo ticket=3, error=3

2018.01.02 08:01:30 Primera orden selected=true, tipo de orden=1, precio de la orden=1,351920

2018.01.02 08:01:30 Segunda orden selected=true, tipo de orden=0, precio de la orden=1,351590


No cerrar dos órdenes de contador, por favor explique.

 

¿Por qué 2 funciones sobrecargadas de dibujo de líneas verticales son aprobadas por el compilador (primera función - selección de color, segunda - color y ventana) y se pueden utilizar ambas, pero cuando añado la tercera, con selección de color, ventana y estilo - jura y obliga a que todas las funciones sean del tercer tipo?


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:

¿Por qué 2 funciones sobrecargadas de dibujo de líneas verticales son aprobadas por el compilador (primera función - selección de color, segunda - color y ventana) y se pueden utilizar ambas, pero cuando añado la tercera, con selección de color, ventana y estilo - jura y obliga a que todas las funciones sean del tercer tipo?


Los valores por defecto niegan la presencia del parámetro de entrada. Considera que no existe. Y ver si el compilador puede seleccionar la función correcta.

 
ukrop1203:

No cierra dos contraórdenes, por favor explique.

En teoría tu código debería funcionar, podría estar equivocado, pero no todos los brokers permiten hacer esto, prueba en Metakvotes-demo para comprobarlo, allí definitivamente funcionó