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:
- 1961
- Ranking:
- Publicado:
- 2014.01.14 12:35
- 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
Habilidades y propósito principal
EasyXML es un analizador de XML simple pero potente que puede leer y analizar XML de tres fuentes diferentes:
- URL
- Entrada archivo
- Entrada de string
Está escrito completamente en MQL5 nativo y se basa en la Windows nativo "wininet.dll" solamente para buscar documentos XML desde una dirección URL.
EasyXML leerá XML como XHTML con la profundidad del nodo (casi) infinito, mientras que está tratando de analizar el documento que esté bien formado. Sin embargo, no se valida el XML contra un DTD o una hoja de estilos XSLT.
MQL5 Integration
La clase nodo del EasyXML heredadas del nativo MQL5 CObject y los nodos se almacenan en CArrayObj.
Cuando van los nodos del árbol DOM pueden ser manipulados fácilmente mediante los métodos públicos de EasyXML, así como las funciones nativas de MQL5 para recuperar datos y almacenar datos del DOM.
Archivo Caché del URL y Depuración
Puesto que uno no siempre puede confiar en tiempos activos Feed RSS, EasyXML puede guardar un archivo de caché XML de la alimentación, una vez que lo ha cargado desde una dirección URL con éxito por primera vez. El usuario entonces puede utilizar el archivo de caché en lugar de la alimentación en vivo para el análisis, en el caso de que la alimentación deba estar caida por alguna razón.
Puesto que los documentos XML y XHTML tienden a ser erróneos, EasyXML tiene una opción de depuración. Mientras que no puede reparar un XML roto, seguramente ayudará a detectar dónde está el error. Si se activa imprimirá información detallada de los nodos analizados.
Además, los errores que se producen siempre son rastreados e impresos, a pesar del hecho, si la depuración está activada o desactivada.
Uso básico
Sólo incluye la clase base en los scripts y está configurado y listo para funcionar:
//+------------------------------------------------------------------+ //| Incluye | //+------------------------------------------------------------------+ #include <EasyXML\EasyXml.mqh>
En primer lugar, en su escritura, crear una instancia de la clase EasyXML. Luego establecer depuración o archivo de caché y llamar a uno de los métodos disponibles para cargar el XML y empezar a analizar:
//+------------------------------------------------------------------+ //| Función inicio del script de programa | //+------------------------------------------------------------------+ void OnStart() { // Crear instancia de la clase CEasyXml CEasyXml EasyXmlDocument; // Depuración opcional EasyXmlDocument.setDebugging(true); // Ajuste del cache del ficheo URL EasyXmlDocument.setUrlCacheFile("forexcalendar.xml"); // Método 1: Cargar XML desde URL if(EasyXmlDocument.loadXmlFromUrl("http://www.forexfactory.com/ffcal_week_this.xml")) { readRecursive(EasyXmlDocument.getDocumentRoot()); } // Borrar DOM EasyXmlDocument.Clear(); // Método 2: Cargar XML desde el string if(EasyXmlDocument.loadXmlFromString("<root><child attr='value'>content</child><sibling>siblingcontent</sibling></root>")) { readRecursive(EasyXmlDocument.getDocumentRoot()); } // Borrar DOM EasyXmlDocument.Clear(); // Método 3: Cargar XML desde un fichero if(EasyXmlDocument.loadXmlFromFile("forexcalendar.xml")) { readRecursive(EasyXmlDocument.getDocumentRoot()); } }
Se muestran para propósitos de demostración de los tres métodos. Normalmente no necesitará todas ellos a la vez, aunque es posible despejar el árbol DOM en medio y empezar a analizar sobre el otra vez, incluso de otra fuente. Usa el comando Clear() para borrar el árbol DOM analizado. setDebugging() y setUrlCacheFile() son opcionales y no tienen que ser llamados si no son necesarios.
EasyXmlDocument.getDocumentRoot() siempre devuelve el nodo raíz del árbol DOM. Todos los nodos incluyendo el nodo raíz son del tipo CEasyXmlNode, que se deriva del CObject MQL5 (como se mencionó anteriormente). Pueden utilizarse a partir de ahora todos los métodos de EasyXml, así como de CArrayObj y CObject al lado de caminar el árbol DOM analizado.
El ejemplo siguiente muestra la implementación de readRecursive(), la función global que se llama en el último ejemplo de código:
//+------------------------------------------------------------------+ //| leer xml recurrente | //+------------------------------------------------------------------+ int readRecursive(CEasyXmlNode *ActualNode,int iNodeLevel=0) { // Output vars string sSpace; string sOutput; // Salida de sangría para facilitar la lectura StringInit(sSpace,iNodeLevel*4,StringGetCharacter(" ",0)); // Concatenar cadena de salida sOutput += sSpace + IntegerToString(iNodeLevel) + " - Node Name: '" + ActualNode.getName() + "'"; sOutput += (ActualNode.getValue()) ? " Value: '" + ActualNode.getValue() + "'" : ""; // Iterate through AttributeNodes for(int i=0; i<ActualNode.Attributes().Total(); i++) { CEasyXmlAttribute *Attribute=ActualNode.Attributes().At(i); sOutput+=" || Attribute "+IntegerToString(i+1)+": '"+Attribute.getName()+"' Value: '"+Attribute.getValue()+"'"; } Print(sOutput); // Iterate through child nodes for(int j=0; j<ActualNode.Children().Total(); j++) { CEasyXmlNode *ChildNode=ActualNode.Children().At(j); readRecursive(ChildNode,iNodeLevel+1); } return(0); }
La lectura recursiva de documentos XML tiene grandes ventajas sobre lectura en línea, aunque puede que no sea conveniente para todas las necesidades. Llamando a Attributes() en un nodo obtendrá todos los atributos analizados mientras Children() conseguirá los nodos hijo que se almacenan en el nodo actual. Ambos métodos devuelven un CArrayObj que contiene los elementos. Llamando Total() sobre esos objetos pueden utilizarse en un bucle for() para iterar sobre los elementos. getNombre() y getValue() devolverán contenido verdadero almacenado en el nodo.
Por supuesto es posible iterar sobre nodos inline así:
//+------------------------------------------------------------------+ //| Función de inicio del string de programa | //+------------------------------------------------------------------+ void OnStart() { // Crear un objeto de la clase CEasyXml CEasyXml EasyXmlDocument; // Set debugging EasyXmlDocument.setDebugging(false); // Ejemplo: yendo por el árbol DOM inline if(EasyXmlDocument.loadXmlFromUrl("http://www.forexfactory.com/ffcal_week_this.xml")) { CEasyXmlNode *RootNode=EasyXmlDocument.getDocumentRoot(); //recorrer nodo raíz for(int i=0; i<RootNode.Children().Total(); i++) { CEasyXmlNode *ChildNode=RootNode.Children().At(i); Print(IntegerToString(i)+" "+ChildNode.getName()); //recorrer los nodos hijo for(int j=0; j<ChildNode.Children().Total(); j++) { CEasyXmlNode *SubNode=ChildNode.Children().At(j); Print(IntegerToString(i)+"-"+IntegerToString(j)+" "+SubNode.getName()+" | "+SubNode.getValue()); } } } }
Iteración funciona igual que el ejemplo recurrente, salvo que debe establecerse un bucle for() separado para que cada nivel de nodo sea leído.
Además también es posible caminar el DOM paso a paso y manipular elementos solos si es necesario:
//+------------------------------------------------------------------+ //| Función de incio del script de programa | //+------------------------------------------------------------------+ void OnStart() { // Crear un objeto de la clase CEasyXml CEasyXml EasyXmlDocument; // Set debugging EasyXmlDocument.setDebugging(true); // Example 2: Yendo por el paso del árbol DOM a paso if(EasyXmlDocument.loadXmlFromString("<root><child attr='value'>content</child><sibling>siblingcontent</sibling></root>")) { CEasyXmlNode *Node=EasyXmlDocument.getDocumentRoot(); Print(Node.getName()); CEasyXmlNode *ChildNode=Node.FirstChild(); Print(ChildNode.getName()); // Siempre verifique que los punteros válidos si pisan lateralmente de forma manual. while(CheckPointer(ChildNode.Next())!=POINTER_INVALID) { ChildNode=ChildNode.Next(); Print(ChildNode.getName()); } CEasyXmlNode *ParentNode=ChildNode.Parent(); Print(ParentNode.getName()); // Volver a la raíz: ParentNode y Nodo son dos descripciones diferentes del mismo objeto Print("Comparison of object descriptors: ParentNode == Node ? ",ParentNode==Node); } }
Todos los métodos disponibles de EasyXML así como el nativo MQL5 iteración/Getter/Setter de CObject y CArrayObj vienen en el juego.
Tenga en cuenta, sin embargo, que algunas de esas funciones no se preocupan por acceder a memoria válida y devolver NULL, si no lo logran.
En el último ejemplo invocando el nodo relacionado con ChildNode.Next() - sin comprobar validez de puntero - implicaría una falla grave de puntero malo (= acceso mala memoria), que bloqueará definitivamente el script. Así que si tienes la necesidad de paso o manipular manualmente el árbol DOM, cuida la validez del puntero, mientras se refiere a los métodos de la clase CObject y CArrayObj.
Captadores de nodo más importantes
Método | Propósito | Return |
---|---|---|
Chilrden() | Obtener todos los hijos del nodo | CArrayObj - containing CEasyXmlNodes |
Attributes() | Obtener todos los atributos attributes del nodo | CArrayObj - containing CEasyXmlAttributes |
Parent() | Obtener el nodo padre | CEasyXmlNode (CObject) |
LastChild() | Obtener el último nodo hijo | CEasyXmlNode (CObject) |
FirstChild() | Obtener el primer nodo hijo | CEasyXmlNode (CObject) |
getName() | Obtener el nombre del nodo | string |
getValue() | Obtener el valor del nodo (contiene texto) | string |
getAttribute(string pName) | Obtener Atributos del nombre especificado | string |
Next() (Inherited from CObject) | Obtener el siguiente nodo relacionado | CEasyXmlNode (CObject) || NULL |
Prev() (Inherited from CObject) | Obtener el nodo hermano anterior | CEasyXmlNode (CObject) || NULL |
El Nodo más fundamental
Método | Propósito | Return |
---|---|---|
createChild(CEasyXmlNode *pChildNode) | crear un nuevo nodo hijo | CEasyXmlNode (CObject) - the new child node |
createSibling(CEasyXmlNode *pSiblingNode) | crear nuevo nodo relacionado | CEasyXmlNode (CObject) - the new sibling node |
setName(string pName) | ajustar nombre de nodo | void |
setValue(string pValue) | ajustar valor de nodo (contiene texto) | void |
setAttribute(string pName,string pValue) | ajustar atributo del nuevo nodo | void |
Atributos getters/setters
Los Objetos de atributo implementan el mismo get/setName(), get/SetValue() métodos para almacenar y recuperar datos como los objetos de nodo.
Descargo de responsabilidad
Este fragmento de código está bajo desarrollo activo y, como con todo software, no pretende estar libre de errores u otros defectos. Utilice EasyXml bajo su propio riesgo y prueba antes de implementar esta librería en cualquier trading EA en vivo. Si usted tiene algún problema o tiene preguntas relacionadas con el uso, por favor no dude en contactarme.
Créditos
La integración del wininet.dll utilizado para buscar contenido URL utiliza WININET_TEST por entero. Aunque esta librería es construida sobre si misma, único análisis de sistema, el Analizador XML escrito por yu-sha fue una fuente de gran aprendizaje para lidiar con las operaciones de string de MQL5.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/code/1998

Este indicador es una pequeña modificación del clásico indicador de Fractales. Usted puede elegir el número o las barras izquierda/derecha para tener una nueva parte superior o inferior así como un parámetro de desplazamiento.

Variante del clásico Indicador Awesome. Calcula la tasa de variación suavizada de dos medias exponenciales.

El código está diseñado para ser una simple referencia de cómo crear paneles movibles (arrastre) y rellenarlo con la información.

Un indicador de fuerza de tendencia con ocho estados.