Mira cómo descargar robots gratis
¡Búscanos en Twitter!
Pon "Me gusta" y sigue las noticias
¿Es interesante este script?
Deje un enlace a él, ¡qué los demás también lo valoren!
¿Le ha gustado el script?
Evalúe su trabajo en el terminal MetaTrader 5
Asesores Expertos

Download all ticks of a symbol's history - Asesor Experto para MetaTrader 5

Visualizaciones:
296
Ranking:
(5)
Publicado:
pull all ticks.mq5 (13.54 KB) ver
MQL5 Freelance ¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa

Este código de asesor experto escaneará la vigilancia de mercado del broker del usuario y extraerá símbolos para los que descargará todos los ticks disponibles , o ticks hasta una fecha.

Puede ayudarle a descargar todo el historial de símbolos para su backtest , o crear un gráfico personalizado a partir de esos ticks.

Los terminales almacenarán en caché los ticks en la carpeta de datos, así que asegúrese de que dispone de espacio suficiente en el disco duro.

Para facilitar la descarga de los símbolos necesitamos primero un gestor de descargas.

La estructura CDownloadManager contiene toda la información que necesitaremos retener.

struct CDownloadManager
  {
   bool              m_started,m_finished;
   string            m_symbols[],m_current;
   int               m_index;

  • El estado de la descarga (iniciada/terminada)
  • la lista de los símbolos a escanear
  • el símbolo actual
  • y el índice del símbolo que se está escaneando

También necesitaremos leer y escribir en el disco duro y como estamos trabajando con símbolos creamos 2 funciones rápidas para escribir y leer cadenas desde ficheros binarios.

La función guardar cadena en fichero :

void writeStringToFile(int f,string thestring)
  {
/guardar cadena de símbolos
   char sysave[];
   int charstotal=StringToCharArray(thestring,sysave,0,StringLen(thestring),CP_ACP);
   FileWriteInteger(f,charstotal,INT_VALUE);
   for(int i=0;i<charstotal;i++)
     {
      FileWriteInteger(f,sysave[i],CHAR_VALUE);
     }
  }

Recibe :

  • el manejador de fichero f, de un fichero abierto para escritura y las banderas binarias FILE_WRITE|FILE_BIN
  • la cadena a escribir en el fichero

Escribe una longitud entera de cuántos caracteres hay en la cadena y luego almacena cada carácter en la cadena.

La función cargar cadena desde archivo:

string readStringFromFile(int f)
  {
   string result="";
//cargar cadena de símbolos
   char syload[];
   int charstotal=(int)FileReadInteger(f,INT_VALUE);
   if(charstotal>0)
     {
      ArrayResize(syload,charstotal,0);
      for(int i=0;i<charstotal;i++)
        {
         syload[i]=(char)FileReadInteger(f,CHAR_VALUE);
        }
      result=CharArrayToString(syload,0,charstotal,CP_ACP);
     }
   return(result);
  }

Recibe

  • el manejador de fichero f de un fichero abierto para lectura como binario , flags FILE_READ|FILE_BIN

Procede a leer cada carácter en una matriz de caracteres y luego crea una cadena a partir de esa matriz de caracteres que se devuelve como resultado de la carga como cadena.

Volvamos a la estructura CDownloadManager . Necesitamos una forma de inicializar el gestor y llenarlo desde el market watch:

   //+------------------------------------------------------------------+
   //| coger símbolos de la vigilancia del mercado|
   //+------------------------------------------------------------------+
   void              grab_symbols()
     {
      //! solo desde el mw !
      int s=SymbolsTotal(true);
      ArrayResize(m_symbols,s,0);
      for(int i=0;i<ArraySize(m_symbols);i++)
        {
         m_symbols[i]=SymbolName(i,true);
        }
     }

Bastante sencillo :

  • preguntar cuantos símbolos hay en el market watch (activos)
  • redimensionar nuestro array m_symbols para recibirlos
  • bucle en el total de símbolos y solicitar el nombre del símbolo

También somos responsables de gestionar la descarga de los datos de los símbolos por lo que necesitaremos una función que sea esencialmente el gestor:

   //+------------------------------------------------------------------+
   //| Gestionar el proceso de descarga de símbolos|
   //+------------------------------------------------------------------+
   void              manage(string folder,string filename)
     {
      //esencialmente esto inicia o navega al siguiente símbolo
      //si se establece
      if(ArraySize(m_symbols)>0)
        {
         //si no se inicia
         if(!m_started)
           {
            m_started=true;
            //ir al primer símbolo
            m_current=m_symbols[0];
            m_index=1;
            save(folder,filename);
            if(_Symbol!=m_current)
              {
               ChartSetSymbolPeriod(ChartID(),m_current,_Period);
              }
            else
              {
               ENUM_TIMEFRAMES new_period=PERIOD_M1;
               for(int p=0;p<ArraySize(TFS);p++)
                 {
                  if(_Period!=TFS[p])
                    {
                     new_period=TFS[p];
                     break;
                    }
                 }
               ChartSetSymbolPeriod(ChartID(),m_current,new_period);
              }
            return;
           }
         //si se inicia
         else
           {
            m_index++;
            if(m_index<=ArraySize(m_symbols))
              {
               m_current=m_symbols[m_index-1];
               save(folder,filename);
               if(_Symbol!=m_current)
                 {
                  ChartSetSymbolPeriod(ChartID(),m_current,_Period);
                 }
               return;
              }
            else
              {
               m_finished=true;
               FileDelete(folder+"\\"+filename);
               Print("Finished");
               ExpertRemove();
               return;
              }
           }
        }
      else
        {
         Print("Please grab symbols first");
        }
      //si el conjunto termina aquí
     }

Como funciona el sistema :

  • Se abre el gráfico , necesitamos 1 gráfico , y se activa un temporizador.
  • Ese temporizador se ejecuta , cancelamos el temporizador
  • Comprobamos si es una nueva descarga o una descarga continua.
  • Si es una nueva descarga, la configuramos tomando todos los símbolos.
  • Si es una descarga continua, descargamos los datos del símbolo actual.

Esta es la parte del código que realiza la descarga en el temporizador:

//+------------------------------------------------------------------+
//|Temporizador|
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- si está sincronizado
   if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1)
     {
      EventKillTimer();
      //--- carga el sistema aquí
      if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE))
        {
         //--- sistema cargado por lo que estamos escaneando un símbolo aquí
         Comment("System loaded and we are processing "+MANAGER.m_current);
         //--- carga de ticks

         //--- encuentra primero el tick más antiguo disponible en el broker
         int attempts=0;
         int ping=-1;
         datetime cursor=flatten(TimeTradeServer());
         long cursorMSC=((long)cursor)*1000;
         long jump=2592000000;//60*60*24*30*1000;

         MqlTick receiver[];
         long oldest=LONG_MAX;
         Comment("PleaseWait");
         while(attempts<5)
           {
            ping=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,cursorMSC,1);
            if(ping==1)
              {
               if(receiver[0].time_msc==oldest)
                 {
                  attempts++;
                 }
               else
                 {
                  attempts=0;
                 }
               if(receiver[0].time_msc<oldest)
                 {
                  oldest=receiver[0].time_msc;
                 }
               cursorMSC-=jump;
               if(limitDate&&receiver[0].time<=oldestLimit)
                 {
                  break;
                 }
              }
            else
              {
               attempts++;
              }

            Sleep(44);
            Comment("Oldest Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nAttempts("+IntegerToString(attempts)+")\nPlease wait for response...");
           }
         //--- en este punto tenemos el tick más antiguo
         //--- empezar a pedir ticks del más antiguo al más reciente
         if(oldest!=LONG_MAX)
           {
            ArrayFree(receiver);
            datetime newest_tick=0;
            //--- recibe la hora del último tick para este símbolo almacenado en symbol_time
            datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
            while(newest_tick<most_recent_candle)
              {
               //--- solicitar un nuevo lote comenzando desde la hora más antigua con el límite de ticks especificado
               int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets);
               if(pulled>0)
                 {
                  //--- si sacamos un nuevo lote actualizamos nuestros tiempos descargados
                  newest_tick=receiver[pulled-1].time;
                  oldest=receiver[pulled-1].time_msc;
                  ArrayFree(receiver);
                 }
               //--- timeout server requests , alteralo si quieres
               Sleep(44);
               Comment("Pulled up to "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" so far");
              }
           }
         else
           {
            Alert("Please close the terminal \n head over to the ticks folder \n and delete the empty folders");
            ExpertRemove();
           }
         //--- actualizar el gestor y seguir adelante
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
      else
        {
         //--- tome los símbolos de vigilancia del mercado para iniciar la descarga
         Comment("Grabbing MW and starting");
         MANAGER.grab_symbols();
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
     }
  }


Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/code/56324

Histograma coloreado MACD Histograma coloreado MACD

El histograma de colores MACD es una versión mejorada del clásico indicador MACD (Moving Average Convergence Divergence), diseñada para ofrecer un análisis visual más claro e intuitivo del impulso del mercado. Este indicador combina las funcionalidades tradicionales del MACD con un histograma dinámico que cambia de color en función de la relación entre la línea MACD y la línea de señal, lo que permite a los operadores identificar rápidamente tendencias, puntos de inversión y momentos de indecisión en el mercado.

Multiple EA Tracking with a Magic Number Based Profit and Loss Live Dashboard in MQL5 Multiple EA Tracking with a Magic Number Based Profit and Loss Live Dashboard in MQL5

Si está ejecutando varios robots de trading simultáneamente o sólo una estrategia sofisticada, hacer un seguimiento del rendimiento de cada Asesor Experto puede ser sorprendentemente lento. MetaTrader 5 (MT5) muestra convenientemente las órdenes y posiciones en su "caja de herramientas", pero cuando numerosos robots comparten la misma cuenta, se hace más difícil saber qué EA está generando sus ganancias o pérdidas. Una sola cuenta puede tener docenas o cientos de operaciones, cada una abierta por diferentes EAs, por lo que es difícil separar los resultados de un robot de otro.

Useful #define statements Useful #define statements

Estas son algunas sentencias #define que son útiles para realizar operaciones en tu EA. Sólo tiene que asignar el nombre de sus variables al principio del archivo, y luego dejar que las otras sentencias #define hagan el trabajo. Para utilizar este archivo, añada #include <DEFINE_statements.mqh> a la primera línea de su archivo EA.

Self Optimized SMA Self Optimized SMA

El indicador traza dos líneas. La línea inferior se calcula a partir del último período de la SMA que provocó un rebote al alza. La línea superior se calcula a partir del último periodo de la SMA que provocó un rebote a la baja.