Biblioteca/Include/data.mqh

491 lines
44 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:43:34 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| data.mqh |
//| Rafael Morgado Silva |
//| |
//+------------------------------------------------------------------+
#property copyright "Rafael Morgado Silva"
class DataArray
{
public:
MqlDateTime today;
int positions;
double closesymbolref,equity,balance,floatprofit,invested,volbuy,volsell,profitbuy,profitsell,effbuy,effsell;
DataArray(void)
{
positions=0;
closesymbolref=0;
equity=0;
balance=0;
floatprofit=0;
invested=0;
volbuy=0;
volsell=0;
profitbuy=0;
profitsell=0;
effbuy=0;
effsell=0;
}
};
class DataAquisition
{
string StructToString(MqlDateTime &today)
{
return(IntegerToString(today.year)+"-"+IntegerToString(today.mon)+"-"+IntegerToString(today.day)+" "+
IntegerToString(today.hour)+":"+IntegerToString(today.min)+":"+IntegerToString(today.sec));
}
// string FormatDouble(double number,int digits=2)
// {
// string numberstr=DoubleToString(number,digits);
// int pos=StringFind(numberstr,".");
// if (pos>=0) StringSetCharacter(numberstr,StringFind(numberstr,"."),StringGetCharacter(",",0));
// return(numberstr);
// }
double calc_volumes(bool type)
{
MqlDateTime thisday;
TimeLocal(thisday);
thisday.hour=0;
thisday.min=0;
thisday.sec=0;
datetime today=StructToTime(thisday);
HistorySelect(today,TimeLocal());
int total=HistoryDealsTotal();
double varday=0;
for (int i=0;i<total;i++)
{
ulong ticket=HistoryDealGetTicket(i);
bool enable=false;
string psymbol=HistoryDealGetString(ticket,DEAL_SYMBOL);//PositionGetString(POSITION_SYMBOL);
double tick_value=1;
double tick_size=1;
if(SymbolInfoInteger(psymbol,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_EXCH_FUTURES)//BMF
{
tick_value=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_VALUE);
tick_size=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
}
else
{
tick_value=1;
tick_size=1;
}
if (ticket!=0)
{
if(((HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL)&&type)||((HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY)&&(!type)))
varday+=MathRound(100*HistoryDealGetDouble(ticket,DEAL_VOLUME)*HistoryDealGetDouble(ticket,DEAL_PRICE)*tick_value/tick_size)/100.0;
}
}
return(varday);
}
double calc_profit(bool type)
{
MqlDateTime thisday;
TimeLocal(thisday);
thisday.hour=0;
thisday.min=0;
thisday.sec=0;
datetime today=StructToTime(thisday);
HistorySelect(today,TimeLocal());
int total=HistoryDealsTotal();
double varday=0;
for (int i=0;i<total;i++)
{
ulong ticket=HistoryDealGetTicket(i);
bool enable=false;
string psymbol=HistoryDealGetString(ticket,DEAL_SYMBOL);//PositionGetString(POSITION_SYMBOL);
double tick_value=1;
double tick_size=1;
if(SymbolInfoInteger(psymbol,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_EXCH_FUTURES)//BMF
{
tick_value=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_VALUE);
tick_size=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
}
else
{
tick_value=1;
tick_size=1;
}
if (ticket!=0)
{
if(((HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL)&&type)||((HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY)&&(!type)))
varday+=HistoryDealGetDouble(ticket,DEAL_PROFIT);
}
}
return(varday);
}
public:
MyTimer timer;
string SymbolRef;
string DataFname;
DataArray ReportData[];
DataAquisition(void){SymbolRef="IBOV";DataFname="-data.csv";}
void Save(string myname="")
{
//MqlDateTime today;
//TimeLocal(today);
if (timer.UpdateTime(true))
{
int dataoutput=FileOpen(myname+DataFname,FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8);//arquivo de coleta de dados (saldo, nativos, investido, giro, etc)
FileSeek(dataoutput,0,SEEK_END);
MqlRates symbolref[];
CopyRates(SymbolRef,PERIOD_D1,0,1,symbolref);
int positions=PositionsTotal();
double invested=0;
for (int i=0;i<positions;i++)
{
if (PositionGetSymbol(i)!="")
invested+=PositionGetDouble(POSITION_PRICE_CURRENT)*PositionGetDouble(POSITION_VOLUME);
}
double volbuy=calc_volumes(false);
double volsell=calc_volumes(true);
double profitbuy=calc_profit(true);
double profitsell=calc_profit(false);
double effbuy=((volsell!=0)?(100.0*profitbuy/volsell):0);
double effsell=((volbuy!=0)?(100.0*profitsell/volbuy):0);
FileWrite(dataoutput,
TimeLocal(),//StructToString(today),
DoubleToString(symbolref[0].close,0),
DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY)),
DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE)),
DoubleToString(AccountInfoDouble(ACCOUNT_PROFIT)),
IntegerToString(positions),
DoubleToString(invested),
DoubleToString(volbuy),
DoubleToString(volsell),
DoubleToString(profitbuy),
DoubleToString(profitsell),
DoubleToString(effbuy),
DoubleToString(effsell));
//timer.LastUpdate=timer.Periodicidade*(datetime)floor(TimeLocal()/timer.Periodicidade);
timer.SetLastUpdate();
FileClose(dataoutput);
}
}
void SaveToArray()
{
if (timer.UpdateTime(true))
{
int size=ArraySize(ReportData);
ArrayResize(ReportData,size+1,10000);
TimeLocal(ReportData[size].today);
MqlRates symbolref[];
CopyRates(SymbolRef,PERIOD_D1,0,1,symbolref);
ReportData[size].closesymbolref=symbolref[0].close;
ReportData[size].positions=PositionsTotal();
ReportData[size].invested=0;
for (int i=0;i<ReportData[size].positions;i++)
{
if (PositionGetSymbol(i)!="")
ReportData[size].invested+=PositionGetDouble(POSITION_PRICE_CURRENT)*PositionGetDouble(POSITION_VOLUME);
}
ReportData[size].volbuy=calc_volumes(false);
ReportData[size].volsell=calc_volumes(true);
ReportData[size].profitbuy=calc_profit(true);
ReportData[size].profitsell=calc_profit(false);
ReportData[size].effbuy=((ReportData[size].volsell!=0)?(100.0*ReportData[size].profitbuy/ReportData[size].volsell):0);
ReportData[size].effsell=((ReportData[size].volbuy!=0)?(100.0*ReportData[size].profitsell/ReportData[size].volbuy):0);
ReportData[size].equity=AccountInfoDouble(ACCOUNT_EQUITY);
ReportData[size].balance=AccountInfoDouble(ACCOUNT_BALANCE);
ReportData[size].floatprofit=AccountInfoDouble(ACCOUNT_PROFIT);
//timer.LastUpdate=timer.Periodicidade*(datetime)floor(TimeLocal()/timer.Periodicidade);
timer.SetLastUpdate();
}
}
void SaveProcessedData(string myname)
{
MqlDateTime today;
int dataoutput;
if(MQLInfoInteger(MQL_TESTER))
{
dataoutput=FileOpen(myname,FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);//Tester, arquivo de report
FileWrite(dataoutput,"Date",SymbolRef,"Equity","Balance","Profit","Positions","Invested",
"VolBuy","VolSell","ProfitBuy","ProfitSell","EffBuy","EffSell");
}
else
dataoutput=FileOpen(myname,FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8);//Online arquivo report diario
int size=ArraySize(ReportData);
FileSeek(dataoutput,0,SEEK_END);
TimeLocal(today);
double eqtyref=1,eqty=1,bal=1;
for (int i=0;i<size;i++)
{
if (i!=0) eqtyref*=ReportData[i].closesymbolref/ReportData[i-1].closesymbolref;
if (i!=0) eqty*=ReportData[i].equity/ReportData[i-1].equity;
if (i!=0) bal*=ReportData[i].balance/ReportData[i-1].balance;
FileWrite(dataoutput,
StructToString(ReportData[i].today),
// DoubleToString((ReportData[0].closesymbolref!=0)?100*(ReportData[i].closesymbolref/ReportData[0].closesymbolref-1):0),
// DoubleToString((ReportData[0].equity!=0)?100*(ReportData[i].equity/ReportData[0].equity-1):0),
// DoubleToString((ReportData[0].balance!=0)?100*(ReportData[i].balance/ReportData[0].balance-1):0),
DoubleToString(100*(eqtyref-1)),
DoubleToString(100*(eqty-1)),
DoubleToString(100*(bal-1)),
DoubleToString((ReportData[i].invested!=0)?100*(ReportData[i].floatprofit/ReportData[i].invested):0),
IntegerToString(ReportData[i].positions),
//((StringCompare(EAName,"Fermi")==0)?
((!EqtyPlot)?DoubleToString(100*(ReportData[i].invested/ReportData[0].invested-1))://Somente para o Fermi, online
DoubleToString(100*ReportData[i].invested/ReportData[((MGMTType==MMTAccount)?i:0)].equity)),
DoubleToString(100*ReportData[i].volbuy/ReportData[((MGMTType==MMTAccount)?i:0)].equity),
DoubleToString(100*ReportData[i].volsell/ReportData[((MGMTType==MMTAccount)?i:0)].equity),
DoubleToString(100*ReportData[i].profitbuy/ReportData[((MGMTType==MMTAccount)?i:0)].equity),
DoubleToString(100*ReportData[i].profitsell/ReportData[((MGMTType==MMTAccount)?i:0)].equity),
DoubleToString(ReportData[i].effbuy),
DoubleToString(ReportData[i].effsell));
}
FileClose(dataoutput);
}
void SaveSymbol()
{
int dataoutput=FileOpen("reportsymbolref.tex",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
FileWrite(dataoutput,SymbolRef);
FileClose(dataoutput);
}
void SaveTable1a(int yearini,int yearend,double &yearlyrets[],double &yearlyvols[])
{
int size=ArraySize(ReportData);
int dataoutput=FileOpen("reporttable1a.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
ArrayResize(yearlyrets,yearend-yearini+1);
ArrayFill(yearlyrets,0,ArraySize(yearlyrets),0);
ArrayResize(yearlyvols,yearend-yearini+1);
ArrayFill(yearlyvols,0,ArraySize(yearlyrets),0);
for (int year=yearini;year<=yearend;year++)
for (int i=0;i<size;i++)
if (ReportData[i].today.year==year)
{
if (i!=0) yearlyrets[year-yearini]+=(ReportData[0].equity!=0)?(100*(ReportData[i].equity-ReportData[i-1].equity)/ReportData[((MGMTType==MMTAccount)?(i-1):0)].equity):0;
yearlyvols[year-yearini]+=ReportData[i].volbuy+ReportData[i].volsell;
}
FileWrite(dataoutput,"Year","Return");
for (int year=yearini;year<=yearend;year++)
FileWrite(dataoutput,year,"\\cellcolor{"+((yearlyrets[year-yearini]>0)?"cyan":"pink")+"}"+DoubleToString(yearlyrets[year-yearini],2)+"\\%");
FileClose(dataoutput);
}
void SaveTable1b(int yearini,int yearend,double &yearlyrets[],double &yearlyvols[])
{
int dataoutput=FileOpen("reporttable1b.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
double avg=0,sigma=0,sharpe=0,posyears=0,negyears=0,avgvol=0;
double count=0;
for (int year=yearini;year<=yearend;year++)
{
avg+=yearlyrets[year-yearini];
sigma+=yearlyrets[year-yearini]*yearlyrets[year-yearini];
if (yearlyrets[year-yearini]>0)posyears++;
else negyears++;
avgvol+=yearlyvols[year-yearini];
count++;
}
avg/=(double)count;
sigma=((count>1)?sqrt((sigma-count*avg*avg)/(count-1)):sqrt((sigma-count*avg*avg)/count));//desvio padr<EFBFBD>o da amostra
sharpe=avg/sigma;
posyears/=(double)count;
negyears/=(double)count;
avgvol/=(double)count;
//avgvol=(ReportData[0].equity!=0)?100*(avgvol/ReportData[0].equity):0;
avgvol=avgvol/(double)1000;
FileWrite(dataoutput,"Avg",DoubleToString(avg,2)+"\\%");
FileWrite(dataoutput,"Ann avg",DoubleToString(avg,2)+"\\%");
FileWrite(dataoutput,"Ann \\sigma",DoubleToString(sigma,2)+"\\%");
FileWrite(dataoutput,"Sharpe",DoubleToString(sharpe,2));
FileWrite(dataoutput,"Pos years",DoubleToString(100*posyears,2)+"\\%");
FileWrite(dataoutput,"Neg years",DoubleToString(100*negyears,2)+"\\%");
FileWrite(dataoutput,"Avg volume",DoubleToString(avgvol,2)+"k");
FileClose(dataoutput);
}
void SaveTable2a(int yearini,int yearend,double &monthlyrets[],double &monthlyvols[])
{
int dataoutput=FileOpen("reporttable2a.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
int nyears=yearend-yearini+1;
int size=ArraySize(ReportData);
ArrayResize(monthlyrets,12*nyears);
ArrayFill(monthlyrets,0,12*nyears,0);
ArrayResize(monthlyvols,12*nyears);
ArrayFill(monthlyvols,0,12*nyears,0);
for (int month=1;month<=12;month++)
for (int year=yearini;year<=yearend;year++)
for (int i=0;i<size;i++)
if ((ReportData[i].today.year==year)&&(ReportData[i].today.mon==month))
{
if (i!=0) monthlyrets[month-1+12*(year-yearini)]+=(ReportData[0].equity!=0)?(100*(ReportData[i].equity-ReportData[i-1].equity)/ReportData[((MGMTType==MMTAccount)?(i-1):0)].equity):0;
monthlyvols[month-1+12*(year-yearini)]+=ReportData[i].volbuy+ReportData[i].volsell;
}
for (int year=yearini;year<=yearend;year++)
FileWriteString(dataoutput,";"+IntegerToString(year));
FileWriteString(dataoutput," \n");
for (int month=1;month<=12;month++)
{
FileWriteString(dataoutput,IntegerToString(month));
for (int year=yearini;year<=yearend;year++)
FileWriteString(dataoutput,";"+"\\cellcolor{"+((monthlyrets[month-1+12*(year-yearini)]>0)?"cyan":"pink")+"}"+DoubleToString(monthlyrets[month-1+12*(year-yearini)],2)+"\\%");
FileWriteString(dataoutput," \n");
}
FileClose(dataoutput);
}
void SaveTable2b(int yearini,int yearend,double &monthlyrets[],double &monthlyvols[])
{
int dataoutput=FileOpen("reporttable2b.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
double avg=0,sigma=0,sharpe=0,posyears=0,negyears=0,avgvol=0;
double count=0;
for (int month=1;month<=12;month++)
for (int year=yearini;year<=yearend;year++)
{
avg+=monthlyrets[month-1+12*(year-yearini)];
sigma+=monthlyrets[month-1+12*(year-yearini)]*monthlyrets[month-1+12*(year-yearini)];
if (monthlyrets[month-1+12*(year-yearini)]>0)posyears++;
else negyears++;
avgvol+=monthlyvols[month-1+12*(year-yearini)];
count++;
}
avg/=(double)count;
sigma=((count>1)?sqrt((sigma-count*avg*avg)/(count-1)):sqrt((sigma-count*avg*avg)/count));//desvio padr<EFBFBD>o da amostra
sharpe=(pow(avg/100+1,12)-1)/(sqrt(12)*sigma/100);
posyears/=(double)count;
negyears/=(double)count;
avgvol/=(double)count;
// avgvol=(ReportData[0].equity!=0)?100*(avgvol/ReportData[0].equity):0;
avgvol=avgvol/(double)1000;
FileWrite(dataoutput,"Avg",DoubleToString(avg,2)+"\\%");
FileWrite(dataoutput,"Ann avg",DoubleToString(100*(pow(avg/100+1,12)-1),2)+"\\%");
FileWrite(dataoutput,"Ann \\sigma",DoubleToString(sqrt(12)*sigma,2)+"\\%");
FileWrite(dataoutput,"Sharpe",DoubleToString(sharpe,2));
FileWrite(dataoutput,"Pos months",DoubleToString(100*posyears,2)+"\\%");
FileWrite(dataoutput,"Neg months",DoubleToString(100*negyears,2)+"\\%");
FileWrite(dataoutput,"Avg volume",DoubleToString(avgvol,2)+"k");
FileClose(dataoutput);
}
void SaveTable3()
{
int size=ArraySize(ReportData);
int dataoutput=FileOpen("reporttable3a.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
double avg=0,sigma=0,sharpe=0,posyears=0,negyears=0,avgvol=0;
double count=0;
double avgbprofit=0,avgsprofit=0,buyeff=0,selleff=0,avgprofit=0,avgeff=0;
for (int i=1;i<size;i++)
{
double returns=(ReportData[0].equity!=0)?(100*(ReportData[i].equity-ReportData[i-1].equity)/ReportData[((MGMTType==MMTAccount)?(i-1):0)].equity):0;
avg+=returns;
sigma+=returns*returns;
if (returns>0) posyears++;
else if (returns<0) negyears++;
avgvol+=ReportData[i].volbuy+ReportData[i].volsell;
count++;
avgbprofit+=ReportData[i].profitbuy;
avgsprofit+=ReportData[i].profitsell;
buyeff+=ReportData[i].effbuy;
selleff+=ReportData[i].effsell;
}
avg/=(double)count;
sigma=((count>1)?sqrt((sigma-count*avg*avg)/(count-1)):sqrt((sigma-count*avg*avg)/count));//desvio padr<EFBFBD>o da amostra
sharpe=(pow(avg/100+1,252)-1)/(sqrt(252)*sigma/100);
posyears/=(double)count;
negyears/=(double)count;
avgvol/=(double)count;
avgbprofit/=(double)count;
avgsprofit/=(double)count;
buyeff/=(double)count;
selleff/=(double)count;
avgprofit=avgbprofit+avgsprofit;
avgeff=(avgvol!=0)?(100*avgprofit/avgvol):0;
//avgvol=(ReportData[0].equity!=0)?100*(avgvol/ReportData[0].equity):0;
avgvol=avgvol/(double)1000;
FileWrite(dataoutput,"Avg",DoubleToString(avg,2)+"\\%");
FileWrite(dataoutput,"Ann avg",DoubleToString(100*(pow(avg/100+1,252)-1),2)+"\\%");
FileWrite(dataoutput,"Ann \\sigma",DoubleToString(sqrt(252)*sigma,2)+"\\%");
FileWrite(dataoutput,"Sharpe",DoubleToString(sharpe,2));
FileWrite(dataoutput,"Pos days",DoubleToString(100*posyears,2)+"\\%");
FileWrite(dataoutput,"Neg days",DoubleToString(100*negyears,2)+"\\%");
FileWrite(dataoutput,"Avg volume",DoubleToString(avgvol,2)+"k");
FileClose(dataoutput);
dataoutput=FileOpen("reporttable3b.csv",FILE_WRITE|FILE_COMMON|FILE_CSV|FILE_ANSI,';',CP_UTF8);
//avgbprofit=(ReportData[0].equity!=0)?100*(avgbprofit/ReportData[0].equity):0;
//avgsprofit=(ReportData[0].equity!=0)?100*(avgsprofit/ReportData[0].equity):0;
//avgprofit=(ReportData[0].equity!=0)?100*(avgprofit/ReportData[0].equity):0;
FileWrite(dataoutput,"Avg buy profit",DoubleToString(avgbprofit,2)+"");
FileWrite(dataoutput,"Avg sell profit",DoubleToString(avgsprofit,2)+"");
FileWrite(dataoutput,"Buy efficiency",DoubleToString(buyeff,2)+"\\%");
FileWrite(dataoutput,"Sell efficiency",DoubleToString(selleff,2)+"\\%");
FileWrite(dataoutput,"Avg profit",DoubleToString(avgprofit,2)+"");
FileWrite(dataoutput,"Avg efficiency",DoubleToString(avgeff,2)+"\\%");
FileClose(dataoutput);
}
void ArrayToFile(string myname="")
{
int size=ArraySize(ReportData);
MqlDateTime tini=ReportData[0].today,tend=ReportData[size-1].today;
double yearlyrets[],yearlyvols[];
double monthlyrets[],monthlyvols[];
SaveProcessedData(myname+DataFname);
SaveSymbol();
SaveTable1a(tini.year,tend.year,yearlyrets,yearlyvols);
SaveTable1b(tini.year,tend.year,yearlyrets,yearlyvols);
SaveTable2a(tini.year,tend.year,monthlyrets,monthlyvols);
SaveTable2b(tini.year,tend.year,monthlyrets,monthlyvols);
SaveTable3();
}
void FileToFile(string myname="")//rotina usada exclusivamente no report di<EFBFBD>rio
{
int datainput=FileOpen(myname+DataFname,FILE_READ|FILE_CSV|FILE_ANSI,';',CP_UTF8);//report di<EFBFBD>rio, diretorio de dados
int i=0;
ArrayResize(ReportData,0,10000);
MyPrint("Processing "+myname+DataFname);
while(!FileIsEnding(datainput))
{
if (i==0)//Header
{
FileReadDatetime(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
FileReadNumber(datainput);
}
else
{
ArrayResize(ReportData,i,10000);
TimeToStruct(FileReadDatetime(datainput),ReportData[i-1].today);
ReportData[i-1].closesymbolref=FileReadNumber(datainput);
ReportData[i-1].equity=FileReadNumber(datainput);
ReportData[i-1].balance=FileReadNumber(datainput);
ReportData[i-1].floatprofit=FileReadNumber(datainput);
ReportData[i-1].positions=(int)FileReadNumber(datainput);
ReportData[i-1].invested=FileReadNumber(datainput);
ReportData[i-1].volbuy=FileReadNumber(datainput);
ReportData[i-1].volsell=FileReadNumber(datainput);
ReportData[i-1].profitbuy=FileReadNumber(datainput);
ReportData[i-1].profitsell=FileReadNumber(datainput);
ReportData[i-1].effbuy=FileReadNumber(datainput);
ReportData[i-1].effsell=FileReadNumber(datainput);
//Print(i," ",ReportData[i].closesymbolref," ",ReportData[i].equity);
}
i++;
}
FileClose(datainput);
SaveProcessedData(myname+"-dailyreport.csv");
}
};