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

 
Vitaly Muzichenko #:


Esta es la mejor manera de hacerlo.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
{
  int H=100;
  double b, a;
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  }
  else if (rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) { 
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
  // записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
 
JRandomTrader un buffer circular, recordando la posición actual del primer elemento?

¡Qué idea tan brillante! ¿A quién se le ocurrió y cuál es su aplicación práctica? Dudo que se utilice exclusivamente para los gráficos de ventanas deslizantes...

 
Mihail Matkovskij #:

¡Qué idea tan brillante! ¿A quién se le ocurrió y cuál es su aplicación práctica? Dudo que se utilice exclusivamente para los gráficos de ventanas deslizantes...

Es cierto, no es descabellado saber cuántos datos puedes retroceder. Porque este búfer circular se "pisa los talones", debido a su limitada longitud...

 
Mihail Matkovskij #:
Esta es la mejor manera de hacerlo.

Lo he comprobado, sí es una buena solución - me lo quedo.

Pero todavía me gustaría comprobar siArrayCopy funciona

---

Decidí hacerlo así, porque no es agradable arrancar el gráfico:

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_label1  "Bid"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_label2  "Ask"

double Buffer1[];
double Buffer2[];
int H;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
{
  SetIndexBuffer(0,Buffer1);
  ArraySetAsSeries(Buffer1,true);
  SetIndexBuffer(1,Buffer2);
  ArraySetAsSeries(Buffer2,true);
  ArrayInitialize(Buffer1,EMPTY_VALUE);
  ArrayInitialize(Buffer2,EMPTY_VALUE);
  IndicatorSetInteger(INDICATOR_DIGITS,Digits());
  IndicatorSetString(INDICATOR_SHORTNAME,"Tick:");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
{
  H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  double b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  double a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  } else if(rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) {
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
// записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // идентификатор события
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam  // параметр события типа string
                 )
{
  if(id==CHARTEVENT_CHART_CHANGE) {
    H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
    int B=Bars(Symbol(),0);
    for(int j=H; j<B; j++) {
      Buffer1[j]=EMPTY_VALUE;
      Buffer2[j]=EMPTY_VALUE;
    }
  }
}
//+------------------------------------------------------------------+
 
JRandomTrader un buffer de anillo que recuerda la posición actual del primer elemento?

En el ejemplo de Vitali, puedes utilizar esta idea. Pero no hay forma de evitar el bucle (que es fundamental para ello). En cualquier caso, tenemos que transferir los datos del buffer del anillo al buffer del indicador utilizando el bucle o la función ArrayCopy. ¿Y qué cambiará?

 
Mihail Matkovskij #:

¡Qué idea tan brillante! ¿A quién se le ocurrió y cuál es su aplicación práctica? Dudo que se utilice exclusivamente para los gráficos de ventanas deslizantes...

A quién se le ocurrió - no hay fin a la vista, creo que se ha reinventado muchas veces, la idea es bastante obvia.

Yo, por ejemplo, lo utilizo para calcular la media móvil de datos que no se almacenan en el historial, sino que sólo tienen un valor instantáneo.

Se ha utilizado en la transmisión de datos desde tiempos inmemoriales.

 
Mihail Matkovskij #:

En el ejemplo de Vitali, puedes utilizar esta idea. Pero no hay forma de evitar el bucle (que es fundamental para ello). En cualquier caso, tenemos que transferir los datos del buffer del anillo al buffer del indicador utilizando el bucle o la función ArrayCopy. ¿Y qué sería diferente?

Que un nuevo valor puede ser insertado e inmediatamente copiado desde el lugar deseado. El ciclo de copia se mantiene, pero no hay ciclo de desplazamiento.

 
Vitaly Muzichenko #:

Lo he comprobado, sí es una buena solución - me lo quedo.

Pero todavía me gustaría comprobar cómo funcionaArrayCopy.

Con ArrayCopy, sólo puedes transferir datos desde otro array. Pero no puedes desplazarlos. Puedes utilizar un buffer de anillo y desplazar los datos desde él... Pero cómo puede hacerlo conArrayCopy si tiene un movimiento circular... No lo entiendo. Y, en principio, no hace falta entenderlo. El desplazamiento habitual mediante un bucle no es tan crítico en términos de velocidad. Al menos, yo no conozco ninguna más rápida. ¿Qué puede ser más rápido, sólo el ensamblador? De todos modos, déjalo como está. Funcionará.

 
JRandomTrader #:

Que un nuevo valor pueda ser insertado y copiado inmediatamente desde el lugar correcto. El ciclo de copia se mantiene, pero no hay ciclo de desplazamiento.

Pongamos un ejemplo, sería en el

El código para la actualización es

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2022.02.13
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
 
Mihail Matkovskij #:

Con ArrayCopy, sólo puedes transferir datos desde otro array. Pero no es posible desplazarlos. Puedes utilizar un buffer circular y transferir datos desde él... Pero cómo hacerlo conArrayCopy si tiene un movimiento circular... No lo entiendo. Y, en principio, no hace falta entenderlo. El desplazamiento habitual mediante un bucle no es tan crítico en términos de velocidad. Al menos, yo no conozco ninguna más rápida. ¿Qué puede ser más rápido, el ensamblador? De todos modos, déjalo como está. Funcionará.

Ahora mismo el código funciona, pero la velocidad es cuestionable debido al bucle.

¿Qué va a ser?

Quiero probar algunas cocinas para la capacidad de arbitraje, el indicador dibujará la diferencia de valores, se ejecuta en un temporizador una vez cada 100ms. Los retrasos en la ejecución del código son críticos para esta situación.