bool CalendarCountryById( const long country_id, // identificador del país MqlCalendarCountry& country // descripción del país );CalendarEventById — obtener la descripción de un evento según el identificador.
bool CalendarEventById( const long event_id, // identificador del evento MqlCalendarEvent& event // descripción del evento );CalendarValueById — obtener la descripción de un valor según el identificador.
bool CalendarValueById( const long value_id, // identificador del valor MqlCalendarValue& value // descripción del valor );CalendarEventByCountry — obtener la matriz de noticias disponibles del país.
bool CalendarEventByCountry( string country_code, // código del país MqlCalendarEvent& events[] // matriz de eventos );CalendarEventByCurrency — obtener la matriz de noticias disponibles sobre la divisa en la que influyen.
bool CalendarEventByCurrency( string currency, // divisa MqlCalendarEvent& events[] // matriz de eventos );CalendarValueHistoryByEvent — obtener la matriz de valores en el periodo indicado según el identificador de evento.
bool CalendarValueHistoryByEvent( ulong event_id, // indicador de evento MqlCalendarValue& values[], // matriz de valores datetime datetime_from, // fecha inicial datetime datetime_to=0 // fecha final );CalendarValueHistory — obtener la matriz de valores de todos los eventos en el periodo indicado con filtrado según el país y/o divisa.
bool CalendarValueHistory( MqlCalendarValue& values[], // matriz de valores datetime datetime_from, // comienzo del periodo datetime datetime_to=0, // final del periodo string country_code=NULL, // código del país string currency=NULL // divisa );CalendarValueLastByEvent — obtener la matriz de los últimos valores de un evento según el identificador. Esta función permite solicitar solo aquellos valores que han cambiado desde el momento de la última solicitud. Para ello, se usa su parámetro in/out "change_id".
bool CalendarValueHistory( ulong event_id, // identificador del evento ulong& change_id, // identificador del último cambio del calendario MqlCalendarValue& values[] // matriz de valores );CalendarValueLast — obtener la matriz de los últimos valores de todos los eventos con filtrado según el país y/o divisa. Esta función permite solicitar solo aquellos valores que han cambiado desde el momento de la última solicitud. De forma análoga a CalendarValueLastByEvent, para la solicitud se usa la propiedad "change_id".
bool CalendarValueHistory( ulong event_id, // identificador del evento ulong& change_id, // identificador del último cambio del calendario MqlCalendarValue& values[], // matriz de valores string country_code=NULL, // código del país string currency=NULL // divisa );
struct MqlCalendarCountry { ulong id; // identificador del país ISO 3166-1 string name; // nombre de texto del país string code; // nombre en código del país ISO 3166-1 alpha-2 string currency; // código de la divisa del país string currency_symbol; // símbolo/señal de la divisa del país string url_name; // nombre del país utilizado en la URL en el sitio web mql5.com };MqlCalendarEvent — descripción del evento.
struct MqlCalendarEvent { ulong id; // identificador del evento ENUM_CALENDAR_EVENT_TYPE type; // tipo del evento ENUM_CALENDAR_EVENT_SECTOR sector; // sector con el que se relaciona el evento ENUM_CALENDAR_EVENT_FREQUENCY frequency; // periodicidad de publicación del evento ENUM_CALENDAR_EVENT_TIMEMODE time_mode; // modo de publicación del evento por tiempo ulong country_id; // indicador del país ENUM_CALENDAR_EVENT_UNIT unit; // unidad de medición del valor del evento ENUM_CALENDAR_EVENT_IMPORTANCE importance; // importancia del evento ENUM_CALENDAR_EVENT_MULTIPLIER multiplier; // multiplicador del valor del evento uint digits; // número de decimales tras la coma en el valor del evento string source_url; // URL de la fuente string event_code; // código del evento string name; // nombre de texto del evento en el lenguaje del terminal };MqlCalendarValue — descripción del valor del evento.
struct MqlCalendarValue { ulong id; // identificador del valor ulong event_id; // identificador del evento datetime time; // hora y fecha del evento datetime period; // periodo de informe del evento int revision; // revisión del indicador publicado con respecto al periodo de informe long actual_value; // valor actual del evento long prev_value; // valor anterior del evento long revised_prev_value; // valor anterior revisado del evento long forecast_value; // valor pronosticado del evento ENUM_CALENDAR_EVENT_IMPACRT impact_type; // influencia potencial en el curso de la divisa };
enum ENUM_CALENDAR_EVENT_FREQUENCY { CALENDAR_FREQUENCY_NONE =0, // no se usa CALENDAR_FREQUENCY_WEEK =1, // semana CALENDAR_FREQUENCY_MONTH =2, // mes CALENDAR_FREQUENCY_QUARTER =3, // trimestre CALENDAR_FREQUENCY_YEAR =4, // año CALENDAR_FREQUENCY_DAY =5, // día }; enum ENUM_CALENDAR_EVENT_TYPE { CALENDAR_TYPE_EVENT =0, // evento(reunión, discurso, etc.) CALENDAR_TYPE_INDICATOR =1, // indicador CALENDAR_TYPE_HOLIDAY =2, // fiesta }; enum ENUM_CALENDAR_EVENT_SECTOR { CALENDAR_SECTOR_NONE =0, // no CALENDAR_SECTOR_MARKET =1, // mercado CALENDAR_SECTOR_GDP =2, // PIB CALENDAR_SECTOR_JOBS =3, // trabajo CALENDAR_SECTOR_PRICES =4, // precios CALENDAR_SECTOR_MONEY =5, // dinero CALENDAR_SECTOR_TRADE =6, // comercio CALENDAR_SECTOR_GOVERNMENT =7, // gobierno CALENDAR_SECTOR_BUSINESS =8, // negocios CALENDAR_SECTOR_CONSUMER =9, // consumidor CALENDAR_SECTOR_HOUSING =10, // vivienda CALENDAR_SECTOR_TAXES =11, // impuestos CALENDAR_SECTOR_HOLIDAYS =12, // fiestas }; enum ENUM_CALENDAR_EVENT_IMPORTANCE { CALENDAR_IMPORTANCE_NONE =0, // no CALENDAR_IMPORTANCE_LOW =1, // baja CALENDAR_IMPORTANCE_MODERATE =2, // media CALENDAR_IMPORTANCE_HIGH =3, // alta }; enum ENUM_CALENDAR_EVENT_UNIT { CALENDAR_UNIT_NONE =0, // no CALENDAR_UNIT_PERCENT =1, // porcentajes CALENDAR_UNIT_CURRENCY =2, // divisa nacional CALENDAR_UNIT_HOUR =3, // número de horas CALENDAR_UNIT_JOB =4, // número de puestos laborales CALENDAR_UNIT_RIG =5, // número de plataformas petroleras CALENDAR_UNIT_USD =6, // dólares USA CALENDAR_UNIT_PEOPLE =7, // número de personas CALENDAR_UNIT_MORTGAGE =8, // número de créditos hipotecarios CALENDAR_UNIT_VOTE =9, // número de votos CALENDAR_UNIT_BARREL =10, // número de barriles CALENDAR_UNIT_CUBICFEET =11, // volumen pies cúbicos CALENDAR_UNIT_POSITION =12, // número de puestos laborales CALENDAR_UNIT_BUILDING =13 // número de construcciones }; enum ENUM_CALENDAR_EVENT_MULTIPLIER { CALENDAR_MULTIPLIER_NONE =0, // no CALENDAR_MULTIPLIER_THOUSANDS =1, // miles CALENDAR_MULTIPLIER_MILLIONS =2, // millones CALENDAR_MULTIPLIER_BILLIONS =3, // miles de millones CALENDAR_MULTIPLIER_TRILLIONS =4, // billones }; enum ENUM_CALENDAR_EVENT_IMPACRT { CALENDAR_IMPACT_NA =0, // desconocido CALENDAR_IMPACT_POSITIVE =1, // positivo CALENDAR_IMPACT_NEGATIVE =2, // negativo }; enum ENUM_CALENDAR_EVENT_TIMEMODE { CALENDAR_TIMEMODE_DATETIME =0, // la fuente publica la hora exacta CALENDAR_TIMEMODE_DATE =1, // el evento ocupa el día completo CALENDAR_TIMEMODE_NOTIME =2, // la fuente no publica la hora del evento CALENDAR_TIMEMODE_TENTATIVE =3, // la fuente no publica la hora del evento de antemano, solo el día, la hora se concreta al darse el evento };
ERR_CALENDAR_MORE_DATA =5400, // la matriz es pequeña para el resultado completo (se han dado los valores que han cabido en la matriz) ERR_CALENDAR_TIMEOUT =5401, // se ha superado el límite de tiempo de espera para la solicitud de datos del calendario ERR_CALENDAR_NO_DATA =5402, // no se han detectado datos
bool CharArrayToStruct( void& struct_object, // estructura const uchar& char_array[], // matriz uint start_pos=0 // posición inicial en la matriz );StructToCharArray - Copia una estructura POD en una matriz de tipo uchar.
bool StructToCharArray( const void& struct_object, // estructura uchar& char_array[], // matriz uint start_pos=0 // posición inicial en la matriz );
ushort MathSwap(ushort value); uint MathSwap(uint value); ulong MathSwap(ulong value);
bool StringReserve( string& string_var, // cadena uint new_capacity // tamaño del búfer para guardar la cadena );StringSetLength — establece para una cadena la longitud indicada en símbolos.
bool StringSetLength( string& string_var, // cadena uint new_length // nueva longitud de la cadena );
bool ArrayRemove( void& array[], // matriz de cualquier tipo uint start, // desde qué índice comenzamos a eliminar uint count=WHOLE_ARRAY // número de elementos );ArrayInsert — Inserta en la matriz-receptor el número indicado de elementos, comenzando por el índice establecido.
bool ArrayInsert( void& dst_array[], // matriz-receptor const void& src_array[], // matriz-fuente uint dst_start, // índice en la matriz-receptor para la inserción uint src_start=0, // índice en la matriz-fuente para el copiado uint count=WHOLE_ARRAY // número de elementos insertados );ArrayReverse — Invierte en la matriz el número indicado de elementos, comenzando por el índice indicado.
bool ArrayReverse( void& array[], // matriz de cualquier tipo uint start=0, // desde qué índice comenzamos a invertir la matriz uint count=WHOLE_ARRAY // número de elementos );
int CustomBookAdd( const string symbol, // nombre del símbolo const MqlBookInfo& books[] // matriz con las descripciones de los elementos de la profundidad de mercado uint count=WHOLE_ARRAY // número de elementos que se usarán );
bool CustomSymbolCreate( const string symbol_name, // nombre del símbolo personalizado const string symbol_path="", // nombre del grupo en el que se creará el símbolo const string symbol_origin=NULL // nombre del símbolo sobre cuya base se creará el símbolo personalizado );Nombre del símbolo desde el que se copiarán las propiedades del símbolo personalizado creado, se indica en el parámetro "symbol_origin".
Añadida la traducción de la interfaz al croata.
Documentación actualizada.
#import "TestLib.dll" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { int x=41; TestClass::Inc(x); Print(x); }El código C# de la función Inc de la clase TestClass tiene el aspecto siguiente:
public class TestClass { public static void Inc(ref int x) { x++; } }Como resultado de la ejecución, el script retornará el valor 42.
struct MqlTick
{
datetime time; // Hora de la última actualización de precios
double bid; // Precio Bid actual
double ask; // Precio Ask actual
double last; // Precio actual de la última transacción (Last)
ulong volume; // Volumen para el precio Last actual
long time_msc; // Hora de la última actualización de precios en milisegundos
uint flags; // Banderas de los ticks
double volume_real; // Volumen para el precio Last actual con precisión aumentada
};
struct MqlBookInfo { ENUM_BOOK_TYPE type; // tipo de solicitud de la enumeración ENUM_BOOK_TYPE double price; // precio long volume; // volumen double volume_real; // volumen con precisión aumentada };
//+------------------------------------------------------------------+ //| Default packing | //+------------------------------------------------------------------+ struct A { char a; int b; }; //+------------------------------------------------------------------+ //| Specified packing | //+------------------------------------------------------------------+ struct B pack(4) { char a; int b; }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { Print("sizeof(A)=",sizeof(A)); Print("sizeof(B)=",sizeof(B)); } //+------------------------------------------------------------------+Conclusión:
sizeof(A)=5 sizeof(B)=8Podrá encontrar información más detallada sobre la alineación de estructuras en MSDN.
enum Main { PRICE_CLOSE_, PRICE_OPEN_ }; input Main Inp=PRICE_CLOSE; //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void OnStart() { }El compilador mostrará la advertencia:
class X { }; void f(int) { } template<typename T> void a(T*) { new T(2); } // antes, en este lugar el compilador daba error template<typename T> void a() { f(0); } void OnInit() { a<X>(); }
Documentación actualizada.
Ha sido actualizada la documentación.
Actualización de la documentación.
datetime iTime( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
double iOpen( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
double iHigh( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
double iLow( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
double iClose( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
long iVolume( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
int iBars( string symbol, // símbolo ENUM_TIMEFRAMES timeframe // periodo );
int iBarShift( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo datetime time, // hora y fecha bool exact=false // modo );
int iLowest( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int type, // identificador de la serie temporal int count, // número de elementos int start // índice );
int iHighest( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int type, // identificador de la serie temporal int count, // número de elementos int start // índice );
long iRealVolume( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
long iTickVolume( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
long iSpread( string symbol, // símbolo ENUM_TIMEFRAMES timeframe, // periodo int shift // desplazamiento );
void TesterHideIndicators( bool hide // bandera );
Actualización de la documentación.
Correciones de crash logs.
MetaTrader 5 build 1745 es la última versión de la plataforma comercial que da soporte a Microsoft Windows XP/2003/Vista.
Hace unos meses, ya anunciamos que las antiguas versiones de los sistemas operativos dejarían de tener soporte.
Windows 2003, Windows Vista y sobre todo Microsoft Windows XP son ya
muy antiguos. Microsoft dejó de dar soporte a Windows XP hace 3 años,
puesto que, debido a sus limitaciones técnicas, este sistema no permite
implementar al cien por cien las posibilidades potenciales del equipo.
MetaTrader 5 build 1745, así como las versiones de la plataforma
anteriormente publicadas, continuarán funcionando en los sistemas
operativos indicados, pero ya no recibirán ninguna actualización.
Asimismo, en los sistemas operativos mencionados tampoco se iniciarán
los instaladores.
La versión mínima para trabajar con
MetaTrader 5 será Windows 7, pero le recomendamos encarecidamente
utilizar las versiones de 64 bits de Windows 10.
La nueva versión de la plataforma no dará soporte a los terminales de escritorio y móviles de las versiones antiguas:
Para dar soporte a los nuevos proyectos compartidos se ha modificado el
protocolo de trabajo con el repositorio online MQL5 Storage. Por
desgracia, después de actualizar a la nueva versión de la plataforma,
usted deberá extraer (check-out) de nuevo todos los datos del
repositorio. Los propios datos que se guardan en él no se tocarán ni
perderán.
Antes de actualizar a la nueva versión de la
plataforma, le recomendamos enviar todos los cambios locales al
repositorio (ejecutar Commit).
Añadida la posibilidad de crear instrumentos financieros sintéticos, es decir, instrumentos basados en uno o más de los disponibles. Solo tiene que especificar la fórmula para el cálculo de las cotizaciones y la plataforma generará los ticks del instrumento sintético en tiempo real, y también creará su historia de minutos.
Cómo sucede esto
Por ejemplo, usted puede crear un instrumento que muestre el índice del dólar (USDX). Su fórmula tendrá el aspecto siguiente:
50.14348112 * pow(ask(EURUSD),-0.576) * pow(USDJPY,0.136) * pow(ask(GBPUSD),-0.119) * pow(USDCAD,0.091) * pow(USDSEK,0.042) * pow(USDCHF,0.036)
Nota: en la fórmula original del índice del dólar se usan las
parejas USDEUR y USDGBP. Puesto que en la plataforma solo hay parejas de
divisas inversas, en la fórmula del instrumento sintético para ellas se
usa la potencia negativa y el precio Ask en lugar de Bid.
La
plataforma calculará en tiempo real el precio del nuevo instrumento
basándose en las cotizaciones de los otros seis instrumentos,
proporcionados por su bróker. En la Observación del mercado y en el
gráfico, podrá ver cómo cambiar su precio:
int CustomTicksAdd( const string symbol, // nombre del símbolo const MqlTick& ticks[] // matriz con los datos de ticks que se deben aplicar al instrumento personalizado );La función CustomTicksAdd permite retransmitir los ticks como si llegaran del servidor del bróker. Los datos se registran directamente en la base de ticks, y luego se envían a la ventana "Observación del mercado". Y ya desde ella, el terminal guarda los ticks en su base. Si se transmite un gran volumen de datos en una llamada, la función cambia su comportamiento para ahorrar recursos. Si se transmiten más de 256 ticks, los datos se dividen en dos partes. La primera parte (la más grande) se registra directamente en la base de ticks (como hace CustomTicksReplace). La segunda parte, compuesta de los últimos 128 ticks, se transmite a la ventana de "Observación de mercado" y, después de ello, se guarda en la base del terminal.
En el MetaEditor han aparecido los proyectos completos. Así, desarrollar programas es mucho más cómodo.
Ahora como proyecto no actúa el principal archivo MQ5 del programa. El
proyecto es un archivo "MQPROJ" aparte, en el que se guardan los ajustes
del programa, los parámetros de compilación y la información sobre
todos los archivos utilizados. El acceso a los ajustes principales del
proyecto se organiza a través de una ventana de diálogo aparte, ya no
hay necesidad de indicarlos en el código fuente con la ayuda de
#property.
Para trabajar más cómodamente con el proyecto, ahora existe una
pestaña aparte en el Navegador. En esta se representan por categorías
todos los archivos utilizados: de inclusión, de recursos, de encabezado,
etc. Además, los archivos se añaden al navegador del proyecto de forma
automática. Por ejemplo, si usted incluye un nuevo archivo MQH en el
código, se mostrará automáticamente en el apartado "Dependencies" del
navegador.
Hemos previsto directamente la posibilidad de
trabajar con nuevos proyectos en el repositorio online MQL5 Storage.
Ahora resulta mucho más cómodo desarrollar grandes proyectos junto a
otros miembros de MQL5.community.
Para trabajar en dichos proyectos compartidos, se ha añadido el nuevo apartado Shared Projects. El proyecto creado en este apartado se envía directamente al repositorio: usted podrá conceder derechos a otros miembros y proceder al desarrollo conjunto rápidamente.
Al compilar el proyecto en Shared Project, el archivo ejecutable EX5 se copia automáticamente en el catálogo local Experts, Indicators o Scripts, dependiendo del tipo de programa. Usted podrá iniciar directamente el programa en el gráfico, sin copiar los archivos manualmente cada vez.
Cambios en el trabajo con el repositorio MQL5 Storage
Para implementar la posibilidad de trabajar con proyectos compartidos, se ha rehecho por completo el protocolo de trabajo con el repositorio MQL5 Storage. Por desgracia, después de actualizar a la nueva versión de la plataforma, usted deberá extraer (check-out) de nuevo todos los datos del repositorio. Los propios datos que se guardan en él no se tocarán ni perderán.
El comando "Extraer datos del repositorio" (Checkout from Storage) ahora no está disponible. Para extraer datos de utilizan los comandos "Activar MQL5 Storage" y "Obtener archivos del repositorio":
Nuevos proyectos: ejemplo de creación y detalles del funcionamiento
En el MetaEditor ahora existe un nuevo elemento: el proyecto propiamente dicho. Se trata de un archivo con la expansión mqproj, en el que se guardan las propiedades generales del programa, así como información sobre todos los archivos utilizados. Ahora es posible gestionar cómodamente las propiedades del programa en una ventana de diálogo propia del MetaEditor, sin tener que modificarlas manualmente en el código fuente (directivas #property).
Si usted ya dispone de desarrollos, el método más sencillo de probar los nuevos proyectos es usar el comando "Nuevo proyecto a partir de un Archivo fuente".
En el mismo catálogo que se encuentra el archivo fuente, se creará un archivo de proyecto homónimo con la expansión mqproj. Al proyecto se añadirán de forma automática las propiedades principales del programa, indicadas como #property en el archivo fuente: el nombre, el copyright, la versión, el enlace al desarrollador y la descripción.
En las propiedades de los proyectos han aparecido dos nuevas opciones para compilar programas MQL5:
Para trabajar con un proyecto se ha diseñado la pestaña aparte "Proyecto", en la ventana "Navegador". En esta pestaña se muestran cómodamente todos los archivos usados en el proyecto. Al generar el proyecto a partir de un archivo fuente, se añaden automáticamente al apartado "Dependencies" todos los archivos de inclusión utilizados (indicados con la ayuda de la directiva #include en el archivo MQ5 principal y en todos los archivos incluidos en él).
Al añadir nuevos archivos de inclusión al código fuente, dichos archivos también aparecerán en el Navegador del proyecto. En el apartado Headers se añadirán los archivos de encabezado utilizados, y en el apartado Resources, las imágenes, sonidos y otros programas MQL5 incluidos en el proyecto en forma de recursos. En el apartado Sources se muestran los archivos MQ5 con el código fuente. Al apartado Settings and files podemos añadir otros archivos, por ejemplo, los ajustes para la simulación y las plantillas para los gráficos.
Para añadir los archivos existentes al proyecto y eliminar archivos del mismo, use los comandos del menú contextual. Preste mucha atención al eliminar archivos: usted puede quitar un archivo del proyecto (suprimir la vinculación) o eliminarlo completamente del disco duro:
Crear un nuevo proyecto es igual de fácil que crear un programa MQL5 normal. Pulse "Nuevo proyecto" y, ya en el Wizard de MQL5 en el modo normal, elija el tipo de programa a crear, indicando también sus propiedades (nombre, manejador de eventos, etc).
Para obtener un archivo ejecutable EX5, usted podrá abrir el proyecto y ejecutar el comando de compilación (F7) o, como antes, abrir el archivo MQ5 principal del programa y compilarlo.
Proyectos compartidos en MQL5 Storage: detalles del funcionamiento
Para trabajar con proyectos compartidos, se ha diseñado el apartado Shared Projects. Si usted aún no ha activado el repositorio, ejecute en el menú contextual de esta carpeta el comando Activate MQL5 Storage. El MetaEditor comprobará de inmediato si hay datos guardados en su repositorio, y también si hay disponible para usted algún proyecto compartido. Los datos disponibles se extraerán instantáneamente del repositorio y luego serán cargados en la computadora (Checkout). Los proyectos compartidos disponibles se mostrarán en el apartado Shared Project, para obtenerlos, pulse "Extraer archivos del repositorio" en el menú contextual.
Para crear un nuevo proyecto compartido, elija la carpeta Shared Projects y pulse "Nuevo proyecto":
A continuación, siga los pasos estándar del Wizard MQL5: indique el tipo, el nombre y las propiedades del futuro programa. Elija para los proyectos compartidos nombres claros y comprensibles, para que los demás miembros puedan distinguirlos fácilmente. En los nombres solo se permiten letras latinas, no están permitidos los espacios en blanco.
Una vez creado, el proyecto se añadirá automáticamente al repositorio MQL5 Storage. Los archivos utilizados de la biblioteca estándar no son añadidos al repositorio, podrá añadirlos manualmente en caso necesario.
Para permitir trabajar en el proyecto a los otros integrantes, abra las propiedades del mismo. Aquí podrá conceder derechos a usuarios concretos (indicando el login de MQL5.community), y también establecer los parámetros generales del trabajo cooperativo:
Para trabajar con mayor comodidad, al compilar un proyecto
compartido, el archivo ejecutable final (EX5) se copia de forma
automática en la carpeta Experts, Indicators o Scripts, dependiendo del
tipo de programa. De esta forma, usted podrá iniciar directamente el
programa en el terminal, sin copiarlo manualmente al catálogo necesario.
Proyectos públicos en MQL5 Storage: participación en los desarrollos
Como ya hemos mencionado anteriormente, cada proyecto compartido en MQL5 Storage dispone de ajustes de privacidad: el proyecto puede ser privado o estár abierto para otros usuarios. Ahora todos los proyectos en los que se puede participar libremente se representan en la pestaña aparte "Proyectos públicos".
Cualquier usuario puede encontrar un proyecto interesante y participar en su desarrollo. Basta con pulsar "Unirse", y después recibir el proyecto desde el repositorio.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- archivo de la plantilla en forma de matriz binaria unsigned char my_template[]= { 0xFF,0xFE,0x3C, ... ,0x00 // la matriz de datos ha sido acortada en el ejemplo }; //--- guardamos y aplicamos la plantilla if(FileSave("my_template.tpl",my_template)) { Print("Custom template saved in \\MQL5\\Files"); if(ChartApplyTemplate(0,"\\Files\\my_template.tpl")) Print("Custom template applied to the current chart"); else Print("Failed to apply custom template"); } else Print("Failed to save custom template"); }
Función | Acción |
---|---|
CustomSymbolCreate | Crea un símbolo personalizado con el nombre indicado en el grupo indicado |
CustomSymbolDelete | Elimina el símbolo personalizado con el nombre indicado |
CustomSymbolSetInteger | Establece para el símbolo personalizado el valor de propiedad de tipo de número entero |
CustomSymbolSetDouble | Establece para el símbolo personalizado el valor de propiedad de tipo real |
CustomSymbolSetString | Establece para el símbolo personalizado el valor de propiedad de tipo string |
CustomSymbolSetMarginRate | Establece para el símbolo personalizado los coeficientes del margen de carga dependiendo del tipo y la dirección de la orden |
CustomSymbolSetSessionQuote | Establece la hora de comienzo y finalización de la sesión de cotizaciones indicada para los símbolos y el día de la semana indicados |
CustomSymbolSetSessionTrade | Establece la hora de comienzo y finalización de la sesión de comercial indicada para los símbolos y el día de la semana indicados |
CustomRatesDelete | Elimina todas las barras en el intervalo temporal indicado de la historia de precios del instrumento personalizado |
CustomRatesReplace | Sustituye totalmente la historia de precios del instrumento personalizado en el intervalo temporal indicado, con los datos de la matriz del tipo MqlRates |
CustomRatesUpdate | Añade a la historia del instrumento personalizado las barras ausentes y sustituye las existentes con datos de la matriz del tipo MqlRates |
CustomTicksAdd | Añade a la historia de precios del instrumento personalizado los datos de la matriz del tipo MqlTick. El símbolo personalizado debe ser elegido en la ventana de MarketWatch (Observación del mercado) |
CustomTicksDelete | Elimina todos los ticks en el intervalo temporal indicado de la historia de precios del instrumento personalizado |
CustomTicksReplace | Sustituye totalmente la historia de precios del instrumento personalizado en el intervalo temporal indicado, con los datos de la matriz del tipo MqlTick |
La biblioteca se ubica en el catálogo de trabajo del terminal en la carpeta Include\Generic.
bool ArraySwap( void& array1[], // primera matriz void& array2[] // segunda matriz );La función adopta matrices dinámicas de idéntico tipo e idénticas dimensiones. Para las matrices multidimensionales, deberá coincidir el número de elementos en todas las dimensiones, excepto la primera.
union LongDouble { long long_value; double double_value; };A diferencia de la estructura, los diferentes miembros de una unión se relacionan con una misma zona de la memoria. En este ejemplo se ha declarado la unión LongDouble, en la que el valor del tipo long y el valor del tipo double comparten la misma zona de la memoria. Es importante comprender que no es posible hacer que la unión guarde al mismo tiempo valores de tipo entero long y reales double (como sucedía en la estructura), puesto que las variables long_value y double_value se solapan (en la memoria) una sobre otra. Sin embargo, un programa MQL5 puede en cualquier momento procesar la información que se contiene en esta unión como un valor entero (long) o como uno real (double). Por consiguiente, la unión permite obtener dos (o más) variantes de representación de una misma secuencia de datos.
union LongDouble { long long_value; double double_value; }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- LongDouble lb; //--- obtenemos el número no válido -nan(ind) y lo mostramos lb.double_value=MathArcsin(2.0); printf("1. double=%f integer=%I64X",lb.double_value,lb.long_value); //--- valor mayor normalizado (DBL_MAX) lb.long_value=0x7FEFFFFFFFFFFFFF; printf("2. double=%.16e integer=%I64X",lb.double_value,lb.long_value); //--- menor positivo normalizado (DBL_MIN) lb.long_value=0x0010000000000000; printf("3. double=%.16e integer=%.16I64X",lb.double_value,lb.long_value); } /* Resultado de la ejecución 1. double=-nan(ind) integer=FFF8000000000000 2. double=1.7976931348623157e+308 integer=7FEFFFFFFFFFFFFF 3. double=2.2250738585072014e-308 integer=0010000000000000 */
class Foo { int value; public: string Description(void){return IntegerToString(value);}; //--- constructor por defecto Foo(void){value=-1;}; //--- constructor con parámetros Foo(int v){value=v;}; }; //+------------------------------------------------------------------+ //| estructura que contiene el objeto del tipo Foo | //+------------------------------------------------------------------+ struct MyStruct { string s; Foo foo; }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- MyStruct a,b; Foo an_foo(5); a.s="test"; a.foo=an_foo; Print("a.s=",a.s," a.foo.Description()=",a.foo.Description()); Print("b.s=",b.s," b.foo.Description()=",b.foo.Description()); //--- Print("b=a"); b=a; //--- Print("a.s=",a.s," a.foo.Description()=",a.foo.Description()); Print("b.s=",b.s," b.foo.Description()=",b.foo.Description()); /* Resultado de la ejecución; a.s=test a.foo.Description()=5 b.s= b.foo.Description()=-1 b=a a.s=test a.foo.Description()=5 b.s=test b.foo.Description()=5 */ }En el operador implícito se realiza el copiado por miembros de los objetos.
ENUM_POSITION_REASON | ENUM_DEAL_REASON | ENUM_ORDER_REASON | Descripción de las causas |
---|---|---|---|
POSITION_REASON_CLIENT | DEAL_REASON_CLIENT | ORDER_REASON_CLIENT | La operación se ha ejecutado como resultado de la activación de una orden colocada desde el terminal de escritorio |
POSITION_REASON_MOBILE | DEAL_REASON_MOBILE | ORDER_REASON_MOBILE | La operación se ha ejecutado como resultado de una orden colocada desde el terminal móvil |
POSITION_REASON_WEB | DEAL_REASON_WEB | ORDER_REASON_WEB | La operación se ha ejecutado como resultado de la activación de una orden colocada desde la plataforma web |
POSITION_REASON_EXPERT | DEAL_REASON_EXPERT | ORDER_REASON_EXPERT | La operación se ha ejecutado como resultado de la activación de una orden colocada desde un programa MQL5: un asesor o script |
- | DEAL_REASON_SL | ORDER_REASON_SL | La operación se ha ejecutado como resultado de la activación de un Stop Loss |
- | DEAL_REASON_TP | ORDER_REASON_TP | La operación se ha ejecutado como resultado de la activación de un Take Profit |
- | DEAL_REASON_SO | ORDER_REASON_SO | La operación se ha ejecutado como resultado del evento Stop Out |
- | DEAL_REASON_ROLLOVER | - | La transacción se ha ejecutado a causa del traslado de una posición |
- | DEAL_REASON_VMARGIN | - | La transacción se ha ejecutado después de abonarse/retirarse el margen de variación |
- | DEAL_REASON_SPLIT | - | La transacción se ha ejecutado a causa del fraccionamiento (reducción del precio) de una acción u otro activo que tenía una posición abierta en el momento del anuncio del fraccionamiento |
Actualización de la documentación.
//+------------------------------------------------------------------+ //| Función de plantilla | //+------------------------------------------------------------------+ template<typename T1,typename T2> string Assign(T1 &var1,T2 var2) { var1=(T1)var2; return(__FUNCSIG__); } //+------------------------------------------------------------------+ //| Sobrecarga especial para el caso bool+string | //+------------------------------------------------------------------+ string Assign(bool &var1,string var2) { var1=(StringCompare(var2,"true",false) || StringToInteger(var2)!=0); return(__FUNCSIG__); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { int i; bool b; Print(Assign(i,"test")); Print(Assign(b,"test")); }Como resultado de la ejecución de este código, veremos que para la pareja int+string se ha usado la función de plantilla Assign(), y en la segunda llamada bool+string ya se ha usado la función sobrecargada.
string Assign<int,string>(int&,string) string Assign(bool&,string)
template<typename T> T Func() { return (T)0; } void OnInit() { Func<double>(); // especialización explícita de la función de plantilla }De esta forma, la especialización tiene lugar no a través de los parámetros de llamada, sino mediante la indicación directa de los tipos.
Actualización de la documentación.
Actualización de la documentación.
#resource ruta_al_archivo_del_recurso as tipo_de_variable_de_recurso nombre_de_la_variable_de_recurso
#resource "data.bin" as int ExtData[] // declaración de matriz de tipo numérico que contiene los datos del archivo data.bin #resource "data.bin" as MqlRates ExtData[] // declaración de matriz de estructuras sencillas que contiene los datos del archivo data.bin #resource "data.txt" as string ExtCode // declaración de línea que contiene los datos del archivo data.txt #resource "data.txt" as string ExtCode[] // declaración de matriz de línea que contiene los datos del archivo data.txt #resource "image.bmp" as bitmap ExtBitmap[] // declaración de matriz unidimensional que contiene el ráster del archivo BMP, tamaño de la matriz = height * width #resource "image.bmp" as bitmap ExtBitmap2[][] // declaración de matriz bidimensional que contiene el ráster del archivo BMP, tamaño de la matriz [height][width]
Actualización de la documentación.
string str; ... if(str) // surgirá el error de compilación "Cannot convert type 'string' to 'bool'" (en los anteriores builds no sucedía así) Print("str is true");Debemos escribir una condición explícita:
string str; ... //--- comprueba si la línea de caracteres ha sido inicializada if(str!=NULL) Print("str is true"); o //--- comprueba si el valor de la línea de caracteres es "true" if(StringCompare(str,"true",false)) Print("str is true"); o //--- comprueba si la línea de caracteres es un número y es distinto de cero if((int)str!=0) Print("str is true");
Correciones de crash logs.
void ArrayPrint( const void& array[], // matriz mostrada uint digits=_Digits, // número de decimales tras la coma const string separator=NULL, // separador entre los valores de los campos de la estructura ulong start=0, // índice del primer elemento mostrado ulong count=WHOLE_ARRAY, // número de elementos mostrados ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN );ArrayPrint no muestra en el diario todos los campos de la matriz de estructuras, los campos-matrices y los campos-punteros de los objetos se omiten. Para mostrar todos los campos de esta estructura será necesaria una función propia de muestra masiva con el fotmato deseado.
//--- muestra los valores de las 10 últimas barras MqlRates rates[]; if(CopyRates(_Symbol,_Period,1,10,rates)) { ArrayPrint(rates); Print("Comprobando\n[time]\t[open]\t[high]\t[low]\t[close]\t[tick_volume]\t[spread]\t[real_volume]"); for(int i=0;i<10;i++) { PrintFormat("[%d]\t%s\t%G\t%G\t%G\t%G\t%G\t%G\t%I64d\t",i, TimeToString(rates[i].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS), rates[i].open,rates[i].high,rates[i].low,rates[i].close, rates[i].tick_volume,rates[i].spread,rates[i].real_volume); } } else PrintFormat("CopyRates failed, error code=%d",GetLastError()); //--- ejemplo de muestra /* [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.11930 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 Comprobando [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.1193 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 */
void OnStart() { int arr[]; //--- cuánta memoria se ha usado al inicio Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- cuánta memoria se ha usado para la matriz con el tamaño 1, pero con reserva ArrayResize(arr,1,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- tras aumentar la matriz, el tamaño utilizado de la memoria no ha aumentado a cuenta de la reserva ArrayResize(arr,1024*512,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- tras disminuir la matriz, el tamaño de la memoria tampoco cambiará ArrayResize(arr,1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- la memoria no utilizada por la matriz queda libre gracias a la eliminación de la reserva ArrayResize(arr,1,-1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); }
#include <Graphics/Graphic.mqh> double Func1(double x) { return MathPow(x,2); } double Func2(double x) { return MathPow(x,3); } double Func3(double x) { return MathPow(x,4); } void OnStart() { GraphPlot(Func1,Func2,Func3,-2,2,0.05,CURVE_LINES); }Resultado:
#include <Math/Stat/Binomial.mqh> #include <Graphics/Graphic.mqh> void OnStart(void) { double vars[101]; double results[101]; const int N=2000; //--- MathSequence(0,N,20,vars); MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results); ArrayPrint(results,4); GraphPlot(results); //--- }Resultado:
Documentación actualizada.
Añadidas descripciones emergentes para los botones Buy, Sell y Close en los cuadros de diálogo comerciales. Las descripciones aclararán qué activos precisamente se comprarán o venderán al realizar esta o aquella operación, ayudando así a los tráders principiantes a comprender la esencia del proceso comercial.
Asimismo, se ha incluido en la biblioteca una versión MQL5 de la biblioteca de análisis numérico ALGLIB.
Posibilidades de la biblioteca
Cómo usarlo
los archivos de la biblioteca ALGLIB se ubican en el catálogo \MQL5\Include\Math\Alglib. Para usar las funciones, incluya el archivo principal de la biblioteca en su programa:
En la biblioteca estándar se han incluido funciones para trabajar con estadística matemática. Ahora en MQL5 están disponibles las posibilidades del lenguaje R, uno de las mejores herramientas de procesamiento y análisis estadístico de datos.
Posibilidades de la biblioteca
La biblioteca estadística contiene funciones para el cálculo de las características estadísticas de los datos, así como funciones para trabajar con distribuciones estadísticas:
Cómo usarlo
los archivos de la biblioteca estadística se ubican en el catálogo \MQL5\Include\Math\Stat. Para usarla, incluya el archivo con las funciones necesarias en su programa, por ejemplo:
#include <Math\Stat\Binomal.mqh> #include <Math\Stat\Cauchy.mqh>
Puede leer una descripción detallada de las funciones de la biblioteca en el artículo Distribuciones Estadísticas en MQL5: tomando lo mejor de R.
Se ha incluido en la biblioteca estándar una versión MQL5 de la biblioteca Fuzzy, en la que se han implementado los sistemas de inferencia de lógica difusa Mamdani y Sugeno.
Posibilidades de la biblioteca
Cómo usarlo
Los archivos de la biblioteca Fuzzy se encuentran en el catálogo \MQL5\Include\Math\Fuzzy. Para usarla, incluya el archivo con las funciones necesarias en su programa, por ejemplo:
#include <Math\Fuzzy\mamdanifuzzysystem.mqh> #include <Math\Fuzzy\sugenofuzzysystem.mqh>
Podrá encontrar una descripción detallada de la biblioteca en Code Base: Fuzzy - biblioteca para trabajar con lógica difusa
long FileLoad( const string filename, // [in] nombre del archivo void &buffer[], // [out] matriz para la lectura uint common_flag=0 // [in] 0 - búsqueda de un archivo en la carpeta Files del terminal, FILE_COMMON - en la carpeta común de los terminales ); bool FileSave( const string filename, // [in] nombre del archivo const void &buffer[], // [in] matriz para el almacenamiento uint common_flag=0 // [in] 0 - creación de un archivo en la carpeta Files del terminal, FILE_COMMON - en la carpeta común de los terminales );Ejemplo de cómo grabar una matriz de ticks y leerla enseguida:
//--- parámetros de entrada input int ticks_to_save=1000; // número de ticks //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { string filename=_Symbol+"_ticks.bin"; MqlTick ticks[]; //--- int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save); if(copied!=-1) { PrintFormat(" CopyTicks(%s) copied %d ticks",_Symbol,copied); //--- si la historia de ticks está sicronizada, el código de error será igual a cero if(!GetLastError()==0) PrintFormat("%s: Ticks are not synchronized. Error=",_Symbol,copied,_LastError); //--- escribimos los ticks en el archivo if(!FileSave(filename,ticks,FILE_COMMON)) PrintFormat("FileSave() failed, error=%d",GetLastError()); } else PrintFormat("Failed CopyTicks(%s), Error=",_Symbol,GetLastError()); //--- ahora leemos estos ticks de vuelta desde el archivo ArrayFree(ticks); long count=FileLoad(filename,ticks,FILE_COMMON); if(count!=-1) { Print("Time\tBid\tAsk\tLast\tVolume\tms\tflags"); for(int i=0;i<count;i++) { PrintFormat("%s.%03I64u:\t%G\t%G\t%G\t%I64u\t0x%04x", TimeToString(ticks[i].time,TIME_DATE|TIME_SECONDS),ticks[i].time_msc%1000, ticks[i].bid,ticks[i].ask,ticks[i].last,ticks[i].volume,ticks[i].flags); } } }
//--- velas iguales, pintadas de un mismo color #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- solo se indica un color, por eso todas las velas serán solo de un color #property indicator_color1 clrGreenSi indicamos dos colores, los contornos se dibujarán con el primer color, y el cuerpo con el segundo.
//--- el color de las velas se diferencia del color de las sombras #property indicator_label1 "Two color candles" #property indicator_type1 DRAW_CANDLES //--- las sombras y el contorno de las velas en color verde, el cuerpo, en color blanco #property indicator_color1 clrGreen,clrWhiteSi se indican tres colores, el contorno de la vela se dibujará con el primer color, y el color de la vela alcista y bajista se establecerá con el segundo y el tercer color.
//--- el color de las velas se diferencia del color de las sombras #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- las sombras y el contorno de las velas en color verde, el cuerpo de la vela alcista, en color blanco, el cuerpo de la vela bajista, de color rojo #property indicator_color1 clrGreen,clrWhite,clrRedDe esta forma, con la ayuda del estilo DRAW_CANDLES se pueden crear variantes personalizadas propias del color de las velas. Asimismo, todos los colores pueden cambiarse de forma dinámica durante el proceso del trabajo con la ayuda de la función PlotIndexSetInteger(índice_de_la_construcción_DRAW_CANDLES, PLOT_LINE_COLOR, número_del_modificador, color) , donde el número_del_modificador puede tener los valores siguientes:
//--- establecemos el color del contorno y las sombras PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrBlue); //--- establecemos el color del cuerpo para la vela alcista PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrGreen); //--- establecemos el color del cuerpo para la vela bajista PlotIndexSetInteger(0,PLOT_LINE_COLOR,2,clrRed);
Se ha actualizado la documentación.
class CFoo final { //--- cuerpo de la clase }; class CBar : public CFoo { //--- cuerpo de la clase };Al intentar heredar de una clase con el modificador final, como se muestra en el ejemplo de más arriba, el compilador dará error:
class CFoo { void virtual func(int x) const { } };A continuación, el método se redefine en la clase heredada:
class CBar : public CFoo { void func(short x) { } };Pero por error, el tipo de argumento cambia de int a short. De hecho, en este caso ya tiene lugar no la redefinición, sino la sobrecarga del método. Actuando de acuerdo con el algoritmo de definición de la función sobrecargada, en ciertas situaciones el compilador puede elegir el método definido en la clase básica, en lugar del método redefinido.
class CBar : public CFoo { void func(short x) override { } };Si durante la redefinición se cambia la signatura del método, el compilador no podrá encontrar en la clase padre un método con la misma signatura y dará un error de compilación:
class CFoo { void virtual func(int x) final { } }; class CBar : public CFoo { void func(int) { } };Al intentar redefinir un método con el modificador final, como se muestra en el ejemplo de más arriba, el compilador dará error:
Se ha actualizado la documentación.
class CFoo { }; class CBar { }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { void *vptr[2]; vptr[0]=new CFoo(); vptr[1]=new CBar(); //--- for(int i=0;i<ArraySize(vptr);i++) { if(dynamic_cast<CFoo *>(vptr[i])!=NULL) Print("CFoo * object at index ",i); if(dynamic_cast<CBar *>(vptr[i])!=NULL) Print("CBar * object at index ",i); } CFoo *fptr=vptr[1]; // dará error de transformación de los punteros, vptr[1] no es un objeto de CFoo } //+------------------------------------------------------------------+
string text="Hello"; ushort symb=text[0]; // retornará el código del símbolo 'H'
Se ha actualizado la documentación.