Cree su propia extensión de MetaTrader (dll) - página 14

 

¡Hola Mladen!

Cuando intento obtener el valor del buffer[0] el valor es algo así como Buffer: 2147483647

Así que creo que esto no es correcto... Debería haber un valor algo así como: 1,23584

ya que hice una prueba y puse: buffer = Rates[10].close;

¿Alguna idea?

Muchas gracias y adiós, AT

 
at120:
¡Hola Mladen!

Cuando intento obtener el valor del buffer[0] el valor es algo así como Buffer: 2147483647

Así que creo que esto no es correcto... Debería haber un valor algo así como 1,23584

ya que hice una prueba y puse: buffer = Rates[10].close;

¿Alguna idea?

Muchas gracias y adiós, AT

Ese valor es lo que se conoce como EMPTY_VALUE

Desde el lado de mql revisa si todo está bien con tu declaración de buffer y asignación de valores. También comprueba cómo estás manejando los elementos del buffer (array) desde el lado de C++

 

¡Hola Mladen!

He probado algo en la llamada a la DLL y también con los buffers, PERO sin ningún resultado positivo...

Intenté poner el valor del buffer en el código C++ a 1, buffer[]=1; No hay cambio...

Adjunto la DLL (por favor, renómbrala de .zip a .dll), a la que llamo con el siguiente código MQL4

Gracias por cualquier aporte/sugerencia...

Adiós, AT

sma_rec.dll.zip

#property indicator_separate_window

#property indicator_buffers 1 // one indicator line to be plotted

#property indicator_color1 Red // plot colour is red - change via GUI

#import "sma_rec.dll"

void updateBuffer(MqlRates &rates[], double& buffer[], int bars, int indicator_counted, int period, double& internal_calcs[2] );

#import

extern int ma_period = 10; // default period is 10 - change via GUI

extern int ma_shift = 0; // default is no shift - change via GUI

double buffer[]; // the indicator buffer - the DLL will // write to this and it will be plotted

MqlRates Rates[];

double internal_calcs[2];

int init(){

// set up the indicator buffer

IndicatorBuffers(2);

SetIndexStyle(0, DRAW_LINE);

SetIndexShift(0, ma_shift);

SetIndexBuffer(0, buffer);

SetIndexLabel(0, "Recursive SMA");

IndicatorDigits(Digits);

return(0);

}

int start(){

ArrayCopyRates(Rates);

updateBuffer( Rates, buffer, Bars, IndicatorCounted(), ma_period, internal_calcs );

// Print("4 - close: ",Rates[0].close,"\n");

//Print("Buffer: ",buffer[0],"\n");

return(0);

}
Archivos adjuntos:
 
at120:
¡Hola Mladen!

He probado algo en la llamada a la DLL y también con los buffers, PERO sin ningún resultado positivo...

Intenté poner el valor del buffer en el código C++ a 1, buffer[]=1; No hay cambio...

Adjunto la DLL (por favor, renómbrala de .zip a .dll), a la que llamo con el siguiente código MQL4

Gracias por cualquier aporte/sugerencia...

Adiós, AT

sma_rec.dll.zip

#property indicator_separate_window

#property indicator_buffers 1 // one indicator line to be plotted

#property indicator_color1 Red // plot colour is red - change via GUI

#import "sma_rec.dll"

void updateBuffer(MqlRates &rates[], double& buffer[], int bars, int indicator_counted, int period, double& internal_calcs[2] );

#import

extern int ma_period = 10; // default period is 10 - change via GUI

extern int ma_shift = 0; // default is no shift - change via GUI

double buffer[]; // the indicator buffer - the DLL will // write to this and it will be plotted

MqlRates Rates[];

double internal_calcs[2];

int init(){

// set up the indicator buffer

IndicatorBuffers(2);

SetIndexStyle(0, DRAW_LINE);

SetIndexShift(0, ma_shift);

SetIndexBuffer(0, buffer);

SetIndexLabel(0, "Recursive SMA");

IndicatorDigits(Digits);

return(0);

}

int start(){

ArrayCopyRates(Rates);

updateBuffer( Rates, buffer, Bars, IndicatorCounted(), ma_period, internal_calcs );

// Print("4 - close: ",Rates[0].close,"\n");

//Print("Buffer: ",buffer[0],"\n");

return(0);

}

No puedes usar buffer[]=1; - no significa nada en mql. Tienes que usar algún índice en la parte del buffer[] (como buffer[0]=1; )

 

¡Hola Mladen!

He utilizado lo siguiente para ello en C++

buffer = 1;

Así que esto debería funcionar normalmente...

El código C++ se ve como abajo.

¡Gracias por la ayuda!

Adiós, AT

#include

#include "stdafx.h"

#include

#define WIN32_LEAN_AND_MEAN

#define MT4_EXPFUNC __declspec(dllexport)

//+------------------------------------------------------------------+

//| MT4 HISTORY DATA STRUCT |

//+------------------------------------------------------------------+

#pragma pack(push,1)

struct RateInfo

{

__int64 ctm;

double open;

double low;

double high;

double close;

unsigned __int64 vol_tick;

int spread;

unsigned __int64 vol_real;

};

#pragma pack(pop)

struct MqlStr

{

int len;

char *string;

};

MT4_EXPFUNC void __stdcall updateBuffer(const RateInfo* Rates, double buffer[],int Bars, int IndicatorCounted, int ma_period, double internal_calcs[2] )

{

//---

if(Rates==NULL)

{

printf("updateBuffer: NULL array\n");

}

//---

if(Rates != NULL)

{

printf("updateBuffer: something is in array\n");

}

//---

if(buffer==NULL)

{

printf("updateBuffer: NULL array\n");

}

//---

if(Bars<0)

{

printf("updateBuffer: wrong Bars number (%d)\n", Bars);

}

//---

if(ma_period<0)

{

printf("updateBuffer: wrong MA Period (%d)\n", ma_period);

}

//---

if(ma_period==10)

{

printf("updateBuffer: 10 MA Period (%d)\n", ma_period);

}

// buffer = 1;

//buffer = ( buffer - internal_calcs[0] ) + ( Rates.close/ma_period ); // calculate new SMA value//

// check if the DLL is being called for the very first time

if ( IndicatorCounted == 0 )

{

buffer[0] = Rates[0].close;

buffer[1] = ( Rates[0].close + Rates[1].close ) / 2.0;

for( int ii = 2 ; ii < ma_period ; ii++ )

{

buffer = ( ( buffer * ii ) / (ii+1) ) + ( Rates.close/(ii+1) );

}

for( int ii = ma_period ; ii < Bars - 1 ; ii++ )

{

buffer = ( buffer - (Rates.close/ma_period) ) + ( Rates.close/ma_period );

}

internal_calcs[0] = (Rates.close/ma_period);

internal_calcs[1] = Bars - 1; // how many indicator values calculated so far

}

if ( IndicatorCounted > 0 && (Bars - 1) > internal_calcs[1] ) // evaluates to TRUE if there is a new bar

{

buffer = ( buffer - internal_calcs[0] ) + ( Rates.close/ma_period ); // calculate new SMA value

internal_calcs[0] = (Rates.close/ma_period); // update // internal_calcs with new value for next SMA calc.

internal_calcs[1] = Bars - 1; // update how many indicator values calculated so far

} // end of ( IndicatorCounted > 0 && (Bars - 1) > internal_calcs[1]) if // statement

} // end of main function call

 

Estoy teniendo un problema con una dll de c++ que he creado para conectarse a un servidor, enviar comandos y cerrar. Estoy usando las bibliotecas boost asio C++ y tomé un ejemplo de su sitio web. Probé el código como un ejecutable independiente en la consola y funciona a las mil maravillas, pero cuando lo convertí en una dll, ahí es donde estoy viendo un extraño problema de truncamiento de la cadena.

Sólo el primer carácter de la cadena parece pasar al servidor. Actualmente estoy enviando una cadena de prueba "get time\n" pero sólo se ve "g" cuando se recibe el mensaje.

La API se ve así (la función completa está abajo):

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

He leído que la cadena en MQL es en realidad una estructura y he probado la estructura MqlStr que se sugirió,.......

struct MqlStr

{

int len;

char *cadena;

};

...... pero eso tampoco parece funcionar. Se cuelga el servidor con una cadena inválida.

Lo que ha funcionado "mejor" hasta ahora es lo que he enumerado a continuación.

Abajo está mi ea de prueba que no hace nada más que enviar la misma cadena al servidor en cada tick.

---------------

#property version "1.00"

#property strict

#importar "Boost.dll";

int mensajeOrden(cadena mensaje, int longitud);

#importar

//+------------------------------------------------------------------+

//| Función de inicialización experta ||.

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEED);

}

//+------------------------------------------------------------------+

//| Función de desinicialización experta ||.

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| Función de tick experto ||

//+------------------------------------------------------------------+

void OnTick()

{

//---

string message = "get time\n";

//Print("mensaje: ", mensaje, " longitud = ", StringLen(mensaje));

messageOrder(mensaje, StringLen(mensaje));

}

//+------------------------------------------------------------------+

La exportación de la dll está abajo. Estoy creando un std::string después de recibir el mensaje y luego enviar esa cadena al servidor. El problema en cuestión es la cadena MQL a C++ char * conversión.

Obviamente estoy haciendo algo mal. ¿Puede alguien ayudar con esto?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

try

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

cliente c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= mensaje; i < longitud; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

std::string línea = mensaje;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100"));

io_service.run();

}

catch (std::exception& e)

{

std::cerr << "Excepción: " << e.what() << "\n";

}

return 0;

}

}

 
revivalfx:
Estoy teniendo un problema con una dll de c++ que he creado para conectarse a un servidor, enviar comandos y cerrar. Estoy usando las bibliotecas boost asio C++ y tomé un ejemplo de su sitio web. Probé el código como un ejecutable independiente en la consola y funciona a las mil maravillas, pero cuando lo convertí en una dll, ahí es donde estoy viendo un extraño problema de truncamiento de cadenas.

Sólo el primer carácter de la cadena parece pasar al servidor. Actualmente estoy enviando una cadena de prueba "get time\n" pero sólo se ve "g" cuando se recibe el mensaje.

La API se ve así (la función completa está abajo):

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

He leído que la cadena en MQL es en realidad una estructura y he probado la estructura MqlStr que se sugirió,.......

struct MqlStr

{

int len;

char *cadena;

};

...... pero eso tampoco parece funcionar. Se cuelga el servidor con una cadena inválida.

Lo que ha funcionado "mejor" hasta ahora es lo que he enumerado a continuación.

Abajo está mi ea de prueba que no hace nada más que enviar la misma cadena al servidor en cada tick.

---------------

#property version "1.00"

#property strict

#importar "Boost.dll";

int mensajeOrden(cadena mensaje, int longitud);

#importar

//+------------------------------------------------------------------+

//| Función de inicialización experta ||.

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEED);

}

//+------------------------------------------------------------------+

//| Función de desinicialización experta ||.

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| Función de tick experto ||

//+------------------------------------------------------------------+

void OnTick()

{

//---

string message = "get time\n";

//Print("mensaje: ", mensaje, " longitud = ", StringLen(mensaje));

messageOrder(mensaje, StringLen(mensaje));

}

//+------------------------------------------------------------------+

La exportación de la dll está abajo. Estoy creando un std::string después de recibir el mensaje y luego enviar esa cadena al servidor. El problema en cuestión es la cadena MQL a C++ char * conversión.

Obviamente estoy haciendo algo mal. ¿Puede alguien ayudar con esto?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

try

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

cliente c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= mensaje; i < longitud; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

std::string línea = mensaje;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100"));

io_service.run();

}

catch (std::exception& e)

{

std::cerr << "Excepción: " << e.what() << "\n";

}

return 0;

}

}

Resulta que cuando usaba la estructura MqlStr la desempaquetaba incorrectamente.

Ahora lo estoy haciendo:

struct MqlStr

{

int len;

char *string;

};

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(MqlStr * message, int length)

/// MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

std::string line;

try

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

client c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= message; i < length; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

line = message[0].string;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100")));

io_service.run();

}

catch (std::exception& e)

{

std::cerr << "Exception: " << e.what() << "\n";

}

//return line.length();

return strlen(message[0].string);

//return message[0].len;

}

}

[/CODE]

I return the length of the MqlStr string and it is always 1. So it is doing exactly the same as the implementation above.

Here's the MQL code.

[CODE]

#property version "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

//+------------------------------------------------------------------+

//| Expert initialization function |

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| Expert deinitialization function |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| Expert tick function |

//+------------------------------------------------------------------+

void OnTick()

{

//--- int len = 0;

string message = "get time\n";

//Print("message: ", message, " length = ", StringLen(message));

len = messageOrder(message, StringLen(message)); Print("len ", len);

}

//+------------------------------------------------------------------+

Ahora estoy explorando una DLL de C# en su lugar basado en un enlace en un post anterior.

 

¡derp! Supongo que podría haber mirado el ejemplo en scripts. Gracias...... Ah! Unicode.

 
revivalfx:
¡derp! Supongo que podría haber mirado el ejemplo en scripts. Gracias...... Ah! Unicode.

¿No era un mensaje muy largo?

 

Hola revalfx,

¡Debes usar wchar_t en lugar de char! Yo tuve el mismo problema ;-)

Adiós, AT