#property strict #include "Telegram\Telegram.mqh" // MQL5 (MetaQuotes Language 5) is a high-level language designed for developing technical indicators, trading robots and utility applications, which automate financial trading. MQL5 is an object-oriented language that is based on the concepts of the popular C++ programming language. // // The code you've posted is an import statement in MQL5, which allows you to use external functions from DLL (Dynamic-Link Library) files. In this case, the function `ShellExecuteW` from the `shell32.dll` library is being imported. // // Here's a breakdown of the function: // // - `int ShellExecuteW(int hWnd, string Verb, string File, string Parameter, string Path, int ShowCmd);` // // This function is used to perform an operation on a specified file. The operation to be performed is specified by the `Verb` parameter and it can be any action that the system associates with the file type. // // - `hWnd`: A handle to the parent window used for displaying a UI or error messages. // - `Verb`: The operation to be performed. This is typically a string like "open", "edit", etc. // - `File`: The path of the file on which the operation is to be performed. // - `Parameter`: The parameters to be passed to the application opening the file. // - `Path`: The default directory. // - `ShowCmd`: Whether the application window will be shown when the application is opened. This can be one of several values, like SW_SHOW or SW_HIDE. // // The function returns an integer value. If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the error. // #import "shell32.dll" int ShellExecuteW(int hWnd, string Verb, string File, string Parameter, string Path, int ShowCmd); #import input string TokenFile="Galileu-token.txt"; input string MyName="Galileu Rafael";//Nome do bot no telegram input double Capital=100000;//Capital disponibilizado na conta input string Ref1="";//Referência 1 para os gráficos input string Ref2="";//Referência 2 para os gráficos input double TxB3=0.023;//Taxas da B3 (%) input double TxCorretagem=0;//Taxa de corretagem (%) int ThisMinute=0; int ThisDay=0; string AuxFileName="AccountMonitor.aux"; int AuxDay=0; bool Shell(string file, string parameters="",string directory="") { int r=ShellExecuteW(0, "open", file, parameters, directory, 0); if (r > 32) return(true); Alert("Shell failed: ",r); return(false); } //+------------------------------------------------------------------+ //| CMyBot | //+------------------------------------------------------------------+ // This is a class definition in MQL5 language for a bot that interacts with users through a chat interface. The bot can process different commands and respond accordingly. Here's a brief overview of the class: // // - The class `CMyBot` inherits from the `CCustomBot` class. // - It has two public methods: `SendResult()` and `ProcessMessages()`. // - `SendResult()` is used to generate charts, sleep for a certain period, and send messages and documents to certain users. // - `ProcessMessages()` is used to process incoming messages from users. It checks if the message is from a certain user and if it contains certain commands. Depending on the command, it responds with a message or generates and sends a document. // // The bot can process the following commands: // - `/start`: Sends a welcome message and prompts the user to type `/report` for a detailed report. // - `/help`: Sends a list of all available commands. // - `/report`: Generates charts and sends a detailed report. // - `/aggregate`: Generates aggregated results and sends a report. // - `/profit`: Sends a result message. // - `/file`: Generates aggregated data and sends it. // // The bot uses the `Shell()` function to execute scripts for generating charts, and the `Sleep()` function to pause execution for a certain period. It also uses the `SendMessage()` and `SendDocument()` functions to send messages and documents to users. // class CMyBot: public CCustomBot { public: void SendResult(string result) { Print(MyName+": gerando gráficos"); Calc_aggregate(); Shell("AccountMonitor.gp","",TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\"); Shell("AccountMonitor2.gp","",TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\"); Sleep(20000); long ids[4]={6610010541,329475658,6425802004,5970645071}; //long ids[1]={6610010541}; for(int i=0; i=10) FileWrite(fileout,data, ref1,(1+multiplicador_ref1)*(1+refd1)-1, ref2,(1+multiplicador_ref2)*(1+refd2)-1, (1+multiplicador_eqty)*(1+profitrel+balrel)-1, (1+multiplicador_saldo)*(1+balrel)-1);*/ } double ThisCapital=Capital; if (balrel!=0) ThisCapital=100*(profitbuy+profitsell)/balrel; multiplicador_ref1=(1+multiplicador_ref1)*(1+refd1/100)-1; multiplicador_ref2=(1+multiplicador_ref2)*(1+refd2/100)-1; multiplicador_eqty=(1+multiplicador_eqty)*(1+(((voltotal==0)&&(invested0!=0))? (profitrel/invested0): (profitrel/100))+balrel/100-(volbuy+volsell)*(TxB3+TxCorretagem)/(100*ThisCapital))-1; //no caso do fermi, isso tem que ser recalculado. se for o primeiro dia do mês, com o rebalanço não //para detectar rebalanceamento: balrel não é zero (rebalanceamento com venda). No caso de rebalanceamento só compra //(reajuste de capital por ex.) o valor de Capital será alterado aqui e no robô. voltotal não será zero, mesmo balrel sendo. //Se for um reajuste de compra, a variação no dia será a variação no lucro flutuante/novo saldo (profitrel) //o melhor teste para detectar rebalanceamento é ter voltotal diferente de zero. O cálculo da variação vai ser profitrel+balrel //se voltotal for zero, e invested não for zero, se trata de uma carteira e a variação no dia vai ser a (variação no flutuante)/(investido no início do dia) //(profitrel*Capital/100)/(invested0*Capital/100)=profitrel/invested0 // //para tirar as taxas, subtrair de eqty e saldo (volbuy+volsell)*(TxB3+TxCorretagem)/Capital multiplicador_saldo=(1+multiplicador_saldo)*(1+balrel/100-(volbuy+volsell)*(TxB3+TxCorretagem)/(100*ThisCapital))-1; string str_data[]; StringSplit(data,StringGetCharacter(" ",0),str_data); StringAdd(str_data[0]," 00:00:00"); FileWrite(fileout,str_data[0], ref1,100*multiplicador_ref1, ref2,100*multiplicador_ref2, 100*multiplicador_eqty, 100*multiplicador_saldo); FileClose(fileout); } FileClose(filein); } } multiplicador_eqty=0; multiplicador_saldo=0; multiplicador_ref1=0; multiplicador_ref2=0; if (FileIsExist("AccountMonitor-aggregate2.csv")) FileDelete("AccountMonitor-aggregate2.csv"); datetime tmptime=StructToTime(thistime)-30*24*3600; Print("Calculando o resultado agregado mensal a partir de " ,TimeToString(tmptime,TIME_DATE)," até ",TimeToString(StructToTime(thistime),TIME_DATE)); for (int i=0;i<=30;i++)//até 31 dias corridos { filein=FileOpen("AccountMonitor-"+TimeToString(tmptime,TIME_DATE)+".csv",FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,';',CP_UTF8); tmptime+=24*3600; if (filein!=INVALID_HANDLE) { //Print("Calculando " ,TimeToString(tmptime,TIME_DATE)); fileout=FileOpen("AccountMonitor-aggregate2.csv",FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8); if (fileout!=INVALID_HANDLE) { FileSeek(filein,0,SEEK_SET); FileSeek(fileout,0,SEEK_END); string data,ref1,ref2; int positions; double equity,balance,invested,profit, profitbuy=0,effbuy,volbuy=0, profitsell=0,effsell,volsell=0, profittotal,efftotal,voltotal=0, refd1=0,refd2=0, profitrel=0,balrel=0,invested0=0; int filecnt=0; while(!FileIsEnding(filein)) { data=FileReadString(filein); equity=FileReadNumber(filein); balance=FileReadNumber(filein); positions=(int)FileReadNumber(filein); invested=FileReadNumber(filein); profit=FileReadNumber(filein); profitbuy=FileReadNumber(filein); effbuy=FileReadNumber(filein); volbuy=FileReadNumber(filein); profitsell=FileReadNumber(filein); effsell=FileReadNumber(filein); volsell=FileReadNumber(filein); profittotal=FileReadNumber(filein); efftotal=FileReadNumber(filein); voltotal=FileReadNumber(filein); ref1=FileReadString(filein); refd1=FileReadNumber(filein); ref2=FileReadString(filein); refd2=FileReadNumber(filein); profitrel=FileReadNumber(filein); balrel=FileReadNumber(filein); if (filecnt==0) invested0=invested; filecnt++; } double ThisCapital=Capital; if (balrel!=0) ThisCapital=100*(profitbuy+profitsell)/balrel; multiplicador_ref1=(1+multiplicador_ref1)*(1+refd1/100)-1; multiplicador_ref2=(1+multiplicador_ref2)*(1+refd2/100)-1; multiplicador_eqty=(1+multiplicador_eqty)*(1+(((voltotal==0)&&(invested0!=0))? (profitrel/invested0): (profitrel/100))+balrel/100-(volbuy+volsell)*(TxB3+TxCorretagem)/(100*ThisCapital))-1; multiplicador_saldo=(1+multiplicador_saldo)*(1+balrel/100-(volbuy+volsell)*(TxB3+TxCorretagem)/(100*ThisCapital))-1; string str_data[]; StringSplit(data,StringGetCharacter(" ",0),str_data); StringAdd(str_data[0]," 00:00:00"); FileWrite(fileout,str_data[0], ref1,100*multiplicador_ref1, ref2,100*multiplicador_ref2, 100*multiplicador_eqty, 100*multiplicador_saldo); FileClose(fileout); } FileClose(filein); } } } void OnDeinit(const int reason) { EventKillTimer(); } int OnInit() { EventSetTimer(15); int tokenfile=FileOpen(TokenFile,FILE_READ|FILE_SHARE_READ|FILE_TXT); if (tokenfile!=INVALID_HANDLE) { ThisBot.Init(FileReadString(tokenfile));//Token FileClose(tokenfile); } return(INIT_SUCCEEDED); } string StructToString(MqlDateTime &today) { return(IntegerToString(today.year)+"-"+IntegerToString(today.mon)+"-"+IntegerToString(today.day)+" "+ IntegerToString(today.hour)+":"+IntegerToString(today.min)+":"+IntegerToString(today.sec)); } // The MQL5 code provided is a function that is called every time a timer event occurs. The function is used to monitor the performance of a trading account and write the results to a file. // // Here's a brief breakdown of what the function does: // // 1. It retrieves the current local time and converts it to a structured format. // // 2. It retrieves various account information such as equity, balance, number of open positions, and profit. // // 3. It calculates the total amount invested in open positions. // // 4. It calculates the volume and profit of buy and sell trades. // // 5. It retrieves the daily price change of two reference assets. // // 6. If it's a weekday and the time is after 9 AM, it writes the profit, balance, and invested amount to a file. // // 7. It reads the profit, balance, and invested amount from the file and calculates the market value change for the day. // // 8. It generates a string containing all the calculated information and displays it on the chart. // // 9. It updates the bot with the calculated information. // // 10. If it's a weekday and the time is between 9 AM and 6 PM, it writes all the calculated information to a CSV file. // // 11. If it's a weekday and the time is after 6:30 PM, it sends the calculated information to the bot. // // This function is useful for traders who want to monitor their trading performance in real-time and have a record of their daily trading activity. // void OnTimer() { datetime thistime=TimeLocal(); MqlDateTime strtime; TimeToStruct(thistime,strtime); { double equity=AccountInfoDouble(ACCOUNT_EQUITY);//+10*MathRand()/(double)32767; double balance=AccountInfoDouble(ACCOUNT_BALANCE); double positions=(double)PositionsTotal(); double profit=AccountInfoDouble(ACCOUNT_PROFIT); double invested=0; for (int i=0;i=9)) { if (FileIsExist(AuxFileName)) { MqlDateTime fdata; TimeToStruct((datetime)FileGetInteger(AuxFileName,FILE_MODIFY_DATE),fdata); if (fdata.day!=strtime.day) { int auxfile=FileOpen(AuxFileName,FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8); if (auxfile!=INVALID_HANDLE) { //FileWrite(auxfile,equity,balance,invested); FileWrite(auxfile,100*profit/Capital,100*balance/Capital,100*invested/Capital); FileClose(auxfile); } } } else { int auxfile=FileOpen(AuxFileName,FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8); if (auxfile!=INVALID_HANDLE) { FileWrite(auxfile,100*profit/Capital,100*balance/Capital,100*invested/Capital); FileClose(auxfile); } } AuxDay=strtime.day; } double profit0=0,balance0=1,invested0=1; int fileaux=FileOpen(AuxFileName,FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,';',CP_UTF8); if (fileaux!=INVALID_HANDLE) { FileSeek(fileaux,0,SEEK_SET); profit0=FileReadNumber(fileaux); balance0=FileReadNumber(fileaux); invested0=FileReadNumber(fileaux); FileClose(fileaux); } StringAdd(result,StringFormat("Variação no valor de mercado no dia (com taxas): %.2f%%\n", ((((volbuy+volsell)==0)&&(invested0!=0))?(100*(100*profit/Capital-profit0)/invested0):(100*profit/Capital-profit0+100*(profitbuy+profitsell)/Capital-(TxB3+TxCorretagem)*(volbuy+volsell)/Capital)) )); StringAdd(result,StringFormat("Lucro realizado no dia: %.2f \t\t %.2f%%\nEficiência: %.2f%%\nVolume: %.2f \t\t %.2f%%\n",profitbuy+profitsell,100*(profitbuy+profitsell)/Capital,(((volbuy+volsell)!=0)?(100.0*2*(profitbuy+profitsell)/(volbuy+volsell)):0),(volbuy+volsell),100*(volbuy+volsell)/Capital)); StringAdd(result,StringFormat("Posições: %.0f\nTotal investido: %.2f \t\t %.2f%%\nLucro flutuante: %.2f \t\t %.2f%%\n",positions,invested,100*invested/Capital,profit,100*profit/Capital)); StringAdd(result,StringFormat("Taxas da B3: %.2f\n",TxB3*(volbuy+volsell)/100)); StringAdd(result,StringFormat("Taxas de corretagem: %.2f\n",TxCorretagem*(volbuy+volsell)/100)); StringAdd(result,"Variação do "+Ref1+" no dia: "+StringFormat(" %.2f%%\n",ref1)); StringAdd(result,"Variação do "+Ref2+" no dia: "+StringFormat(" %.2f%%\n",ref2)); Comment(result); ThisBot.Update(result); if ((strtime.day_of_week!=SATURDAY)&&(strtime.day_of_week!=SUNDAY)) if ((strtime.min!=ThisMinute)&& (strtime.hour>=9)&& (strtime.hour<=18)) { int fileout=FileOpen("AccountMonitor-"+TimeToString(thistime,TIME_DATE)+".csv",FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI,';',CP_UTF8); if (fileout!=INVALID_HANDLE) { FileSeek(fileout,0,SEEK_END); FileWrite(fileout, StructToString(strtime), equity, balance, positions, 100*invested/Capital, 100*profit/Capital, profitbuy, effbuy, volbuy, profitsell, effsell, volsell, profitbuy+profitsell, (((volbuy+volsell)!=0)?(100.0*2.0*(profitbuy+profitsell)/(volbuy+volsell)):0), 100*(volbuy+volsell)/Capital, Ref1,ref1,Ref2,ref2, 100*profit/Capital-profit0,//100*profit/invested0-profit0*Capital/invested0;$20*Capital/columnhead(5) 100*(profitbuy+profitsell)/Capital ); FileClose(fileout); } ThisMinute=strtime.min; } if ((strtime.day_of_week!=SATURDAY)&&(strtime.day_of_week!=SUNDAY)) if ((strtime.day!=ThisDay)&& (((strtime.hour==18)&&(strtime.min>=30))||(strtime.hour>18)) ) { ThisBot.SendResult(result); ThisDay=strtime.day; } } }