Crea la tua estensione MetaTrader (dll) - pagina 14

 

Ciao Mladen!

Quando cerco di ottenere il valore del buffer[0] il valore è qualcosa come Buffer: 2147483647

Quindi penso che questo non sia giusto... Ci dovrebbe essere un valore qualcosa come: 1,23584

come ho fatto un test e impostato: buffer = Rates[10].close;

Qualche idea?

Grazie mille e ciao, AT

 
at120:
Ciao Mladen!

Quando cerco di ottenere il valore del buffer[0] il valore è qualcosa come Buffer: 2147483647

Quindi penso che questo non sia giusto... Ci dovrebbe essere un valore qualcosa come: 1,23584

come ho fatto un test e impostato: buffer = Rates[10].close;

Qualche idea?

Grazie mille e ciao, AT

Quel valore è ciò che è noto come EMPTY_VALUE

Dal lato mql controlla se tutto è a posto con la tua dichiarazione del buffer e l'assegnazione dei valori. Controlla anche come stai gestendo gli elementi del buffer (array) dal lato C++

 

Ciao Mladen!

Ho provato qualcosa nel chiamare la DLL e anche con i buffer, MA senza alcun risultato positivo...

Ho provato a impostare il valore del buffer nel codice C++ a 1, buffer[]=1; Nessun cambiamento...

Ho allegato la DLL (basta rinominarla da .zip a .dll), che chiamo con il seguente codice MQL4

Grazie per qualsiasi input/suggerimento...

Ciao, 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);

}
File:
 
at120:
Ciao Mladen!

Ho provato qualcosa nel chiamare la DLL e anche con i buffer, MA senza alcun risultato positivo...

Ho provato a impostare il valore del buffer nel codice C++ a 1, buffer[]=1; Nessun cambiamento...

Ho allegato la DLL (basta rinominarla da .zip a .dll), che chiamo con il seguente codice MQL4

Grazie per qualsiasi input/suggerimento...

Ciao, 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);

}

Non puoi usare buffer[]=1; - non significa nulla in mql. Devi usare qualche indice nella parte buffer[] (come buffer[0]=1; )

 

Ciao Mladen!

Ho usato il seguente in C++

buffer = 1;

Quindi questo dovrebbe funzionare normalmente...

Il codice C++ appare come sotto.

Grazie per l'aiuto!

Ciao, 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

 

Sto avendo un problema con una dll in c++ che ho creato per connettersi a un server, inviare comandi e chiudere. Sto usando le librerie boost asio C++ e ho preso un esempio dal loro sito web. Ho testato il codice come eseguibile stand alone nella console e funziona a meraviglia, ma quando l'ho convertito in una dll, è lì che sto vedendo uno strano problema di troncamento della stringa.

Solo il primo carattere della stringa sembra essere passato al server. Attualmente sto inviando una stringa di prova "get time\n", ma solo "g" viene vista quando il messaggio viene ricevuto.

L'API assomiglia a questa (la funzione completa è qui sotto):

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

Ho letto che la stringa in MQL è in realtà una struttura e ho provato la struttura MqlStr che è stata suggerita,.......

struttura MqlStr

{

int len;

char *stringa;

};

...... ma anche questo non sembra funzionare. Si blocca il server con una stringa non valida.

Quello che ha funzionato "meglio" finora è quello che ho elencato qui sotto.

Di seguito è il mio test ea che non fa altro che inviare la stessa stringa al server ogni tick.

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

#proprietà versione "1.00"

#proprietà strict

#importare "Boost.dll

int messageOrder(string message, int length);

#import

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

//| Funzione di inizializzazione esperto |

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

int OnInit()

{

//---

//---

return(INIT_SUCCEED);

}

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

//| Funzione di deinizializzazione esperto |

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

void OnDeinit(const int reason)

{

//---

}

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

//| Funzione tick esperto |

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

void OnTick()

{

//---

string message = "get time\n";

//Print("messaggio: ", messaggio, " lunghezza = ", StringLen(messaggio));

messageOrder(message, StringLen(message));

}

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

L'esportazione della dll è qui sotto. Sto creando una std::stringa dopo che il messaggio è stato ricevuto e poi invio quella stringa al server. Il problema a portata di mano è la conversione da stringa MQL a char * C ++.

Ovviamente sto facendo qualcosa di sbagliato. Qualcuno può aiutarmi con questo?

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);

client c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= messaggio; i < lunghezza; i++, p++)

//{

// msg = *p;

//}

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

std::string line = message;

c.assignMessage(line);

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

io_service.run();

}

catch (std::exception& e)

{

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

}

return 0;

}

}

 
revivalfx:
Sto avendo un problema con una DLL c++ che ho creato per connettersi a un server, inviare comandi e chiudere. Sto usando le librerie boost asio C++ e ho preso un esempio dal loro sito web. Ho testato il codice come eseguibile stand alone nella console e funziona a meraviglia, ma quando l'ho convertito in una dll, è lì che sto vedendo uno strano problema di troncamento delle stringhe.

Solo il primo carattere della stringa sembra essere passato al server. Attualmente sto inviando una stringa di prova "get time\n" ma solo "g" viene vista quando il messaggio viene ricevuto.

L'API assomiglia a questa (la funzione completa è qui sotto):

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

Ho letto che la stringa in MQL è in realtà una struttura e ho provato la struttura MqlStr che è stata suggerita,.......

struttura MqlStr

{

int len;

char *stringa;

};

...... ma anche questo non sembra funzionare. Si blocca il server con una stringa non valida.

Quello che ha funzionato "meglio" finora è quello che ho elencato qui sotto.

Di seguito è il mio test ea che non fa altro che inviare la stessa stringa al server ogni tick.

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

#proprietà versione "1.00"

#proprietà strict

#importare "Boost.dll

int messageOrder(string message, int length);

#import

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

//| Funzione di inizializzazione esperto |

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

int OnInit()

{

//---

//---

return(INIT_SUCCEED);

}

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

//| Funzione di deinizializzazione esperto |

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

void OnDeinit(const int reason)

{

//---

}

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

//| Funzione tick esperto |

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

void OnTick()

{

//---

string message = "get time\n";

//Print("messaggio: ", messaggio, " lunghezza = ", StringLen(messaggio));

messageOrder(message, StringLen(message));

}

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

L'esportazione della dll è qui sotto. Sto creando una std::stringa dopo che il messaggio è stato ricevuto e poi invio quella stringa al server. Il problema a portata di mano è la conversione da stringa MQL a char * C ++.

Ovviamente sto facendo qualcosa di sbagliato. Qualcuno può aiutarmi con questo?

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);

client c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= messaggio; i < lunghezza; i++, p++)

//{

// msg = *p;

//}

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

std::string line = message;

c.assignMessage(line);

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

io_service.run();

}

catch (std::exception& e)

{

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

}

return 0;

}

}

Come si scopre quando stavo usando la struct MqlStr stavo scompattando impropriamente.

Ora lo sto facendo:

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);

}

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

Ora sto esplorando invece una DLL C# basata su un link in un post precedente.

 

derp! Immagino che avrei potuto guardare l'esempio sotto scripts. Grazie...... Ah! Unicode.

 
revivalfx:
derp! Immagino che avrei potuto guardare l'esempio sotto scripts. disregard. Grazie...... Ah! Unicode.

Non era la lunghezza di un messaggio?

 

Ciao Revalfx,

Vuoi usare wchar_t invece di char! Ho avuto lo stesso problema ;-)

Ciao, AT

Motivazione: