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:
- 1296
- Ranking:
- Publicado:
- 2015.05.08 11:15
- Actualizado:
- 2016.11.22 07:33
-
¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa
El script encuentra y marca en el gráfico los puntos de apoyo de DeMark y muestra su dimensión.
Este script, en esencia, lleva la misma funcional que KeyFinder y apenas podrá encontrar en él diferencias externas, excepto los botones que eliminan del gráfico el script y todos los objetos creados por él.
Figura 1. Gráfico de futuros en el índice РТС con la aplicación del script KeyFinder 2.0
Si bien el aspecto externo del funcionamiento del script no ha sufrido cambios, cabe decir que el código ha sido reformado de manera sustancial.
Para el funcionamiento del script se ha fundado la clase CKeyFinder.
Fig 2. Clase CKeyFinder
Más abajo se adjunta el propio código de clase. He intentado hacer comentarios lo más precisos posibles al código, por eso, pienso que no deberían surgir problemas.
//+------------------------------------------------------------------+ //| KeyFinder.mqh | //| Trofimov Pavel | //| trofimovpp@mail.ru | //+------------------------------------------------------------------+ #property copyright "Trofimov Pavel" #property link "trofimovpp@mail.ru" //+------------------------------------------------------------------+ //| Class for KeyFinder 2.0 | //+------------------------------------------------------------------+ class CKeyFinder { private: // Variables de clase int MinDimension; //Dimensión mínima de los puntos int MaxBars; //Cantidad de barras procesadas protected: // Método de clase para uso interno // Determinar la dimensión de los puntos superiores int getHighDimension(MqlRates &tmpRates[],int tmp_i,int tmp_iCod); // Determinar la dimensión de los puntos inferiores int getLowDimension(MqlRates &tmpRates[],int tmp_i,int tmp_iCod); public: // Constructor de clase CKeyFinder(); // Deconstructor de clase ~CKeyFinder(); // Método-propiedad - obtener dimensión int GetMinDimension(); // Método-propiedad - establecer dimensión void SetMinDimension(int temp_Val); // Método-propiedad - obtener la cantidad de barras para procesar int GetMaxBars(); // Método-propiedad - establecer la cantidad de barras para procesar void SetMaxBars(int temp_Val); // Método - encontrar puntos de apoyo superiores void FindUpKeyPoints(int temp_iCod,MqlRates &temp_rates[]); // Método - encontrar puntos de apoyo inferiores void FindLowKeyPoints(int temp_iCod,MqlRates &temp_rates[]); // Limpiar el gráfico de objetos del script. int CleanChart(); }; //+------------------------------------------------------------------+ //| Determinar la dimensión del punto superior | //+------------------------------------------------------------------+ int CKeyFinder::getHighDimension(MqlRates &tmpRates[],int tmp_i,int tmp_iCod)// Al método se transmiten matrices de datos del tipo MqlRates, el número de la barra procesada en la matriz y el índice máximo de la matriz { int k=1; while((tmpRates[tmp_i].high>tmpRates[tmp_i+k].high) && (tmpRates[tmp_i].high>tmpRates[tmp_i-k].high) && ((tmp_i+k)<(tmp_iCod)) && ((tmp_i-k)>0)) k++; if(((tmp_i+k)==tmp_iCod) || ((tmp_i-k)==0)) k=-1; return(k); }; //+------------------------------------------------------------------+ //| Determinar la dimensión del punto inferior | //+------------------------------------------------------------------+ int CKeyFinder::getLowDimension(MqlRates &tmpRates[],int tmp_i,int tmp_iCod)// Al método se transmiten matrices de datos del tipo MqlRates, el número de la barra procesada en la matriz y el índice máximo de la matriz { int k=1; while((tmpRates[tmp_i].low<tmpRates[tmp_i+k].low) && (tmpRates[tmp_i].low<tmpRates[tmp_i-k].low) && ((tmp_i+k)<(tmp_iCod)) && ((tmp_i-k)>0)) k++; if(((tmp_i+k)==tmp_iCod) || ((tmp_i-k)==0)) k=-1; return(k); }; //+------------------------------------------------------------------+ //| Method GetMinDimension | //+------------------------------------------------------------------+ int CKeyFinder::GetMinDimension(){return(MinDimension);}; //+------------------------------------------------------------------+ //| Method SetMinDimension | //+------------------------------------------------------------------+ void CKeyFinder::SetMinDimension(int temp_Val) { if(temp_Val>1) MinDimension=temp_Val; else { MessageBox("Se ha indicado una dimensión demasiado pequeña."+"\n"+"Se usará la dimensión por defecto - 5","¡Atención!",MB_OK+MB_ICONWARNING); MinDimension=5; }; }; //+------------------------------------------------------------------+ //| Method GetMaxBars | //+------------------------------------------------------------------+ int CKeyFinder::GetMaxBars() {return(MaxBars);}; //+------------------------------------------------------------------+ //| Method SetMaxBars | //+------------------------------------------------------------------+ void CKeyFinder::SetMaxBars(int temp_Val) { //comprobar la accesibilidad de la historia para la cantidad de barras establecida int SMaxBars=Bars(Symbol(),0); if(SMaxBars<temp_Val) { temp_Val=SMaxBars;//establecemos tantas barras como haya disponibles MessageBox("Se ha establecido un parámetro MaxBars demasiado alto."+"\n"+"Para los cálculos se usará "+IntegerToString(temp_Val)+" barras.","¡Atención!",MB_OK+MB_ICONWARNING); }; //comprobando que la cantidad de barras no sea demasiado pequeña if(temp_Val<(2*MinDimension)) { MessageBox("Se ha establecido una cantidad de barras demasiado baja."+"\n"+"Se usará la cantidad por defecto - 300","¡Atención!",MB_OK+MB_ICONWARNING); temp_Val=300; }; MaxBars=temp_Val; }; //+------------------------------------------------------------------+ //| Method FindKeyPoints - Buscar puntos clave superiores | //+------------------------------------------------------------------+ void CKeyFinder::FindUpKeyPoints(int temp_iCod,MqlRates &temp_rates[])// Al método se transmite el índice del elemento máximo de la matriz MqlRates y la propia matriz { int HD=1; //inicializamos la dimensión de los puntos for(int i=temp_iCod-MinDimension; i>(MinDimension-1); i--)//ciclo de barras a partir de la última - MinDimension hasta la cero + MinDimension { HD=getHighDimension(temp_rates,i,temp_iCod);//obtenemos la dimensión de los puntos if((HD>=MinDimension) || (HD==-1)) {//creamos una marca si entra dentro de la condición MinDimension string Ob_Name="KF_Label"+IntegerToString(i); if(HD!=-1) { ObjectCreate(0,Ob_Name,OBJ_TEXT,0,temp_rates[i].time,temp_rates[i].high); ObjectSetInteger(0,Ob_Name,OBJPROP_ANCHOR,0,ANCHOR_LOWER); ObjectSetString(0,Ob_Name,OBJPROP_TEXT,0,IntegerToString(HD)); ObjectSetInteger(0,Ob_Name,OBJPROP_COLOR,clrRed); } else { //Si no podemos determinar la dimensión, marcamos con una bolita ObjectCreate(0,Ob_Name,OBJ_ARROW,0,temp_rates[i].time,temp_rates[i].high); ObjectSetInteger(0,Ob_Name,OBJPROP_ARROWCODE,0,159); ObjectSetInteger(0,Ob_Name,OBJPROP_ANCHOR,0,ANCHOR_BOTTOM); ObjectSetInteger(0,Ob_Name,OBJPROP_COLOR,clrRed); }; }; }; }; //+------------------------------------------------------------------+ //| Method FindLowKeyPoints - Buscar puntos claves inferiores | //+------------------------------------------------------------------+ void CKeyFinder::FindLowKeyPoints(int temp_iCod,MqlRates &temp_rates[])// Al método se transmite el índice del elemento máximo de la matriz MqlRates y la propia matriz { int LD=1;//inicializamos la dimensión de los puntos bool iCreate; for(int i=temp_iCod-MinDimension; i>(MinDimension-1); i--)//ciclo de barras a partir de la última - MinDimension hasta la cero + MinDimension { LD=getLowDimension(temp_rates,i,temp_iCod); if((LD>=MinDimension) || (LD==-1)) { string Ob_Name="KF_Label"+IntegerToString(i)+"_1";//Nos protegemos contra barras donde low y high puedan ser puntos clave if(LD!=-1) { iCreate=ObjectCreate(0,Ob_Name,OBJ_TEXT,0,temp_rates[i].time,temp_rates[i].low); if(iCreate) { ObjectSetInteger(0,Ob_Name,OBJPROP_ANCHOR,0,ANCHOR_UPPER); ObjectSetString(0,Ob_Name,OBJPROP_TEXT,0,IntegerToString(LD)); ObjectSetInteger(0,Ob_Name,OBJPROP_COLOR,clrGreen); } else Comment("No puedo crear objeto"); } else { iCreate=ObjectCreate(0,Ob_Name,OBJ_ARROW,0,temp_rates[i].time,temp_rates[i].low); if(iCreate) { ObjectSetInteger(0,Ob_Name,OBJPROP_ARROWCODE,0,159); ObjectSetInteger(0,Ob_Name,OBJPROP_ANCHOR,0,ANCHOR_TOP); ObjectSetInteger(0,Ob_Name,OBJPROP_COLOR,clrGreen); } else Comment("No puedo crear objeto"); }; }; }; }; //+------------------------------------------------------------------+ //| Method CleanChart - limpiar el gráfico de objetos | //+------------------------------------------------------------------+ int CKeyFinder::CleanChart(void) { string Label="KF_Label"; int obj_total=ObjectsTotal(0,0,-1),n=0; for(int obj=obj_total-1; obj>=0; obj--) //La limpieza de objetos creados por el script se realiza según la máscara del nombre { string objname=ObjectName(0,obj,0,-1); if(StringFind(objname,Label)>=0) ObjectDelete(0,objname); n++; } return(n); } //+------------------------------------------------------------------+ //| Constructor de clase | //+------------------------------------------------------------------+ CKeyFinder::CKeyFinder(){}; //+------------------------------------------------------------------+ //| Deconstructor de clase | //+------------------------------------------------------------------+ CKeyFinder::~CKeyFinder(){}; //+---------------------------------------------------------------------+
Después de que la parte principal del código haya sido pasada a clase, el código del propio script se ha hecho muy compacto.
//+------------------------------------------------------------------+ //| KeyFinder2.mq5 | //| Trofimov Pavel | //| trofimovpp@mail.ru | //+------------------------------------------------------------------+ #property copyright "Trofimov Pavel" #property link "trofimovpp@mail.ru" #property version "2.00" #property description "¡Atención! ¡Este algoritmo se usa en los cálculos del ciclo!" #property description "¡Se recomienda encarecidamente indicar el procesamiento de no más de 1000 barras!" #property script_show_inputs //--- input parameters input int MinDimesion=5; //Dimensión mínima de puntos input int MaxBars=300; //Cantidad de barras procesadas #include "KeyFinder.mqh" #include <ChartObjects\ChartObjectsTxtControls.mqh> //+------------------------------------------------------------------+ //| Script variables | //+------------------------------------------------------------------+ CKeyFinder m_keyfinder; //Anunciamos la variable de clase СKeyFinder CChartObjectButton m_button_close; //Anunciamos la variable de clase CChartObjectButton //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //-Inicialización de variables MqlRates rates_array[]; string Com="\n\n\n"; int iCod=CopyRates(Symbol(),Period(),0,MaxBars,rates_array);//cantidad de elementos de la matriz MqlRates que se ha logrado copiar int sy=10;//posición de los botones if(ChartGetInteger(0,CHART_SHOW_OHLC)) sy+=16; //-Establecer los parámetros necesarios para el funcionamiento de la claseЗ m_keyfinder.SetMaxBars(MaxBars); m_keyfinder.SetMinDimension(MinDimesion); m_keyfinder.CleanChart();//Limpiar el gráfico de objetos al realizarse una nueva aplicación iCod=iCod-1;//Índice del elemento máximo en la matriz rates_array[] Com+="Funcionando...¡Espere!"; //-Crear un botón y sus propiedades m_button_close.Create(0,"ButtonClose",0,10,sy,100,20); m_button_close.Description("Close Script"); m_button_close.Color(Blue); m_button_close.FontSize(8); Comment(Com); //-Procesar las barras usando los métodos de la clase CKeyFinder if(iCod>0) { m_keyfinder.FindUpKeyPoints(iCod,rates_array);//Buscar los puntos clave superiores Com+="\nProcesados los puntos superiores.\n"; Comment(Com); m_keyfinder.FindLowKeyPoints(iCod,rates_array);//Buscar los puntos clave inferiores Comment("\n\n\nProcesamiento finalizado"); } else Comment("\n\n\n¡¡¡No hay barras que procesar!!!"); m_button_close.State(false); //-Damos cierre al script antes de pulsar el botón while(!(m_button_close.State())) { //--- redraw chart ChartRedraw(); Sleep(250); }; //-Limpiamos el gráfico pulsando el botón m_keyfinder.CleanChart(); Comment(""); } //+------------------------------------------------------------------+
Y al final, para evitar la aparición de preguntas, les mostraré una serie de enlaces y explicaciones útiles.
- Cómo cargar el código directamente desde el editor MetaEditor
- Para usar el script en MetaTrader 4 es necesario renombrar el archivo KeyFinder2.mq5 en otro archivo con la extensión mq4 y recompilarlo en el editor MetaEditor. El archivo KeyFinder.mqh, que contiene el código de clase, debe encontrarse en una misma carpeta (MQL5\Scripts, por ejemplo) con el archivo del propio script.
Espero sus observaciones, comentarios y propuestas. ¡Que comercien ustedes bien!
Traducción del ruso realizada por MetaQuotes Ltd
Artículo original: https://www.mql5.com/ru/code/12439
![KeyLevels](https://c.mql5.com/i/code/indicator.png)
Indicador de los niveles de precio de cifras redondas: 00, 20, 50, 80.
![KeyFinder](https://c.mql5.com/i/code/script.png)
El script encuentra y marca en el gráfico los puntos de apoyo de DeMark y muestra su dimensión.
![Back to the Future](https://c.mql5.com/i/code/expert.png)
Análisis fundamental conforme a reguladores.
![Oscilador de tendencia](https://c.mql5.com/i/code/indicator.png)
Oscilador de tendencia que usa el filtro de Hodrick-Prescott.