Mt4 Fin de soporte. - página 27

 
Реter Konow:
Lineal, no lineal... ¿Estás hablando de nuevo de la ópera en la programación?

de ninguna manera.

 
Реter Konow:

BIEN. Su solución sólo funciona con las garrapatas. El mío tiene un temporizador. ¿Crees que mi método de sincronización con las apariciones de la barra tiene un inconveniente. De acuerdo. Que sea así. Añadiré una comprobación de la llegada de una cotización antes de establecer una nueva bandera de barra. Añadiré otro parámetro a la función: un símbolo. El usuario elegirá el símbolo por el que quiere recibir el nuevo evento de barra y lo enviará a la función. La función comprobará la hora de la última cita de este símbolo. A continuación, compararemos la hora de la aparición formal del bar y la hora de la cotización y fijaremos la bandera del evento.

Acabo de empezar a estudiar este tema, pero no veo ninguna dificultad.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Soporte para el fin de Mt4.

Artyom Trishkin, 2017.09.10 22:27

Sé cómo conseguir cotizaciones :)

En un programa multidivisa - en un temporizador en un bucle en los símbolos de la derecha. Y la apertura de una nueva barra (física, no virtual -errónea- como en tu caso) se controla con la hora de la última cotización y comparando esa hora con la del símbolo de barra cero.

Por otro lado, usted está haciendo al azar - un bar virtual que puede no existir. No los tienes el fin de semana, pero supuestamente los tienes, es lo más sencillo de poner como ejemplo.

Y, como ves, eres el único que no lo haría así. Los demás lo hacemos de forma correcta y fiable. Pero eso, por supuesto, es sólo asunto suyo.

Quería contarte cómo hacerlo bien y mostrar la gran diferencia en la simplicidad de escribir en OOP y los complicados giros en estilo procedimental a la hora de resolver la misma tarea.

Pero probablemente sabes más y no lo necesitas. No me atrevo a parecer que sé algo más. Lo siento.


 
Galina Bobro:

No hay problema. Cobertura para ahorrar la comparación de las operaciones de cadena, bueno, si el cliente es un maniático y va a operar en todos los caracteres simultáneamente.

Pero parece que no hay ningún lugar donde guardar las operaciones y la memoria - todo es mínimo

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

//+------------------------------------------------------------------+

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

//+------------------------------------------------------------------+

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


Parece ser el código estructuralmente más sensato hasta ahora. Hay una comprobación de un nuevo símbolo y un tf, no comprueba todo, sino sólo lo que necesita, no hay operaciones redundantes, lo que significa que debería funcionar bastante rápido.

Saludos cordiales.

P.D. la única pequeña cosa que se podría añadir aquí es combinar las matrices st_time y st_id en una estructura, ya que están interrelacionadas, esto reduciría el número de operaciones de incremento de matrices en el código.

 
Artyom Trishkin:

Tenía el objetivo de que su código de estilo procedimental acabara funcionando en un bucle como éste:

 ENUM_TIMEFRAMES array_timeframes[]=
      {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
      };
   int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
   for(int i=0; i<total; i++){
      string symbol_name=SymbolName(i,true);
      for(int j=0; j<total_tf; j++){
         if(IsNewBar(symbol_name,array_timeframes[j])){
            Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
            }
         }
      }


algo así (código para MQL5):

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }

void OnTick()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="") 
  {
   static const ENUM_TIMEFRAMES TF[22]=
     {
      PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym=0;
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      while(TF[curtf]!=tf) curtf++;
      return (newbar[n_cur*22+curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
   for(int j=0,j1=0; j<total; j++,j1+=22)
      for(int i=0;i<22;i++)
        {
         long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
         if(acb[j1+i]<CurBars) // пришел новый бар
           {
            //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]=true;
           }
         else
           {
            newbar[j1+i]=false;
            if(i==1) for(;i<22;i++) newbar[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }

Pero lo diré de nuevo: soy partidario de la OOP.
Sólo un ejemplo realmente desafortunado para mostrar lo que no se puede hacer en la programación procedimental.

 
Andrey Kisselyov:
No se trata de llamar a una función en un EA, se trata de escribir interfaces universales (handlers).

tienes 1000s de tareas para escribir robots; de hecho, cada uno de ellos consiste en
1 función de obtener una señal para abrir
2. función de apertura de pedidos
3 función del seguimiento de pedidos
4) La función de recibir una señal para cerrar una orden.
y así sucesivamente.
Estas funciones son diferentes para cada robot, pero se repiten en 1000 proyectos. En consecuencia, puede combinar las funciones en módulos universales y, según la tarea, llamar a la adecuada.

Si tienes estas funciones, no necesitas hacer nada más. Los parámetros de entrada de la función es la interfaz. Cada complejidad adicional aumenta el número de posibles errores y aumenta el tiempo de trabajo del programador.

 
Nikolai Semko:

algo así (código para MQL5):

Pero repito: soy partidario de la OOP.
Realmente es un ejemplo desafortunado para mostrar lo que no se puede hacer en la programación procedimental.

¿Existe en principio un ejemplo de este tipo? ¿Aunque no sea el suyo? Tengo profundas dudas. A principios de la década de 2000 dejé de contar el número de líneas de código depuradas y en funcionamiento que había escrito, porque superaba el millón y dejaba de ser interesante. Y nunca me he visto en la necesidad de crear mi propia clase, aunque la variedad y la escala de mis tareas eran muy diversas. He tenido que utilizar variables de tipo procedimiento cuando era necesario paralelizar el trabajo de varias personas, pero no más. ¿Por qué?

Por cierto, ¿por qué hablas de programación procedimental como alternativa a la POO? Hay lenguajes sin POO, en principio no procedimentales (SQL), incluso hay una dirección de desarrollo de lenguajes - la programación funcional https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5:"Algunos conceptos y paradigmas son específicos de la programación funcional y son en su mayoría ajenos a la programación imperativa (incluyendo la programación orientada a objetos)", "Otra ventaja de los programas funcionales es que proporcionan amplias oportunidades para la automatización Resulta que la POO impide el paralelismo automático de los cálculos. Esto debe considerarse ahora una desventaja muy seria, la perspectiva no es para OOP.

 
Vladimir:

¿Existe, en principio, un ejemplo de ello? ¿Aunque no sea el suyo? Tengo profundas dudas.


Creo que es muy posible que no se encuentre un ejemplo así. Personalmente, creo que las principales ventajas de la POO son una programación más cómoda de grandes proyectos y un mecanismo conveniente para utilizar tus desarrollos en el futuro. Esto ya se ha dicho aquí muchas veces con razón.

 
Andrei:

Ya se ha comentado que una interfaz única no es aplicable a la programación de cualquier tarea computacional... Poner cosas bonitas en forma de interfaces es un procedimiento puramente cosmético, que sólo es aplicable al código ya preparado y que además impide el soporte y refinamiento posterior del código...

No. No se trata de "no se aplica en absoluto", sino de "no tiene sentido utilizarlos".

Las interfaces no son "un procedimiento puramente cosmético aplicable al código ya hecho".

Todo lo contrario: las interfaces son el núcleo de la arquitectura del sistema. Es donde empieza el diseño. Las interfaces no "estorban" en absoluto el apoyo y el retrabajo, sino que los ayudan delineando claramente los límites de lo permisible. Si no hay interfaces, es fácil cruzar estos límites y hacer cambios donde no estaban previstos, lo que da lugar a errores difíciles de calcular.

Cualquier sistema complejo (no sólo en programación) comienza con el desarrollo de los principios básicos de interacción entre sus partes. Pero en la programación, como la tarea inicial suele ser muy pequeña, van en dirección contraria. Primero se escriben las partes y luego se combinan en un todo, encontrándose a menudo con el hecho de que las partes no son compatibles entre sí - por cierto, esto explica el deseo de "tener acceso a todas las variables disponibles".

 

Está bien, excepto por el hecho de que la función isNewBar() no debería existir en absoluto. Es curioso que haya tanto baile en torno a algo tan trivial.

Es sólo una variable, y simplemente se compara con el tiempo de la barra; si todos los casos son exitosos, a la variable se le asigna el tiempo de la nueva barra al final. De lo contrario, sólo se asigna un intento a todos los casos.

 
Dmitry Fedoseev:

Está bien, excepto por el hecho de que la función isNewBar() no debería existir en absoluto. Es curioso que haya tanto baile en torno a algo tan trivial.

Es sólo una variable, y simplemente se compara con el tiempo de la barra; si todos los casos son exitosos, a la variable se le asigna el tiempo de la nueva barra al final. De lo contrario, sólo se asigna un intento a todos los casos.


+1

Razón de la queja: