问题
I have an arrayobject class and I am saving the information when a new record is created or deleted. And then loading the data back when the ea initialises
I an unsure how to create a multi array from the object to save/load file
main.mql4
#include <CTrade.mqh>
CArrayObj* listOfTrades=NULL;
int OnInit()
{
//initialise listOfTrades and load saved data from file
listOfTrades = new CArrayObj;
}
void OnDeinit(const int reason)
{
if(CheckPointer(listOfTrades)==POINTER_DYNAMIC)
delete(listOfTrades);
}
void OnTick(){ checkTPHit(listOfTrades); }
signal.mql4
void Trigger()
{
//Create Order
int newTicket=NewOrder(symbol, order, LotSize, price, takeprofit2, stoploss, comment, 5000);
if(newTicket>0)
{
for(int i=listOfTrades.Total()-1;i>=0;i--){
CTrade *trade=listOfTrades.At(i);
if(!trade.isTicketExist())
{listOfTrades.Delete(i);continue;}
}
listOfTrades.Add(new CTrade(ticket,entry, tp1, tp2, tp3, sl));
listOfTrades.saveToFile;
listOfTrades.printTrades;
}
}
CTrade.mql4
#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>
class CTrade : public CObject
{
private:
string file = "CTrade.csv"
public:
int m_ticketId;
double m_entry, m_tp1, m_tp2, m_tp3, m_sl;
CTrade(const int ticket, entry, tp1, tp2, tp3, sl){
m_ticketId=ticket;
m_oop=entry;
m_tp1=tp1;
m_tp2=tp2;
m_tp3=tp3;
m_sl=sl;
}
bool isTicketExist(){
if(OrderSelect(m_ticketId,SELECT_BY_TICKET))
return(OrderCloseTime()==0);
else return(false);//or GetLastError()!=4108
}
saveToFile (){
//save data to file everytime add/delete, to load when the ea is initilaized again
//create multidimensional array and get its size to save to file from objects
//save to file
int handle=FileOpen(file,FILE_READ|FILE_WRITE|FILE_BIN|FILE_COMMON);
if(handle!=INVALID_HANDLE)
{
//--- write array data to the end of the file
FileSeek(handle,0,SEEK_END);
FileWriteArray(handle,arr,0,arraySize);
//--- close the file
FileClose(handle);
}
else
Print("Failed to open the file, error ",GetLastError());
}
loadData () {
// load data on the ea's initilization
}
printTrades(){
//method to print to terminal while in testing phase
CArrayObj* _listOfTrades
for(int i=_listOfTrades.Total()-1;i>=0;i--)
{
CTrade* trade=_listOfTrades.At(i);
// action with CTrade object
printf(trade.m_ticketId);
}
}
};
回答1:
I use JAson.mqh
lib for saving data to json - it is simpler. I use json.mqh (prev. messages on SOF if needed, or download from http://lordy.co.nf) for deserialization because the first lib has a bug when parsing arrays (or maybe fixed already, dont know).
If you need a deserialization example, please ask for link in comment
#include <JAson.mqh> //https://www.mql5.com/en/code/13663
class CTrade : public CObject{
//...
public:
static void jsonList(CArrayObj* list, CJAVal &js)
{
for(int i=0;i<list.Total();i++)
{
CTrade *trade=list.At(i);
js["array"].Add(trade.json());
}
}
CJAVal json()const
{
CJAVal result;
result["ticketId"]=(string)m_ticketId;
result["entry"]=DoubleToString(m_entry,_Digits);
result["tp1"]=DoubleToString(m_tp1,_Digits);
result["tp2"]=DoubleToString(m_tp2,_Digits);
result["tp3"]=DoubleToString(m_tp3,_Digits);
result["sl"]=DoubleToString(m_sl,_Digits);
return result;
}
};
void save(CArrayObj* list)
{
int handle=FileOpen(generateFileName(InpMagicNumber,_Symbol),FILE_WRITE);
if(handle==INVALID_HANDLE){Print(__LINE__,__FILE__," error# ",_LastError);return;}
FileWriteString(handle,CTrade::jsonList(list).Serialize());
FileClose(handle);
}
来源:https://stackoverflow.com/questions/62234536/mql4-save-object-to-array-then-to-file