Pon "Me gusta" y sigue las noticias
Deje un enlace a él, ¡qué los demás también lo valoren!
Evalúe su trabajo en el terminal MetaTrader 5
- Visualizaciones:
- 296
- Ranking:
- Publicado:
-
¿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

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.

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.

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.

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.