//+------------------------------------------------------------------+ //| BuddyIlanOptimizer.mq5 | //| Copyright 2018, BPASoftware Thai Co. Ltd | //| https://www.mql5.com/en/market/product/28759 | //+------------------------------------------------------------------+ /* * https://docs.microsoft.com/fr-fr/windows/desktop/api/shellapi/nf-shellapi-shellexecutea : * * 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 failure. The return value * is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. * It is not a true HINSTANCE, however. It can be cast only to an int and compared to * either 32 or the following error codes below. */ #import "shell32.dll" int ShellExecuteW(int hwnd,string Operation,string File,string Parameters,string Directory,int ShowCmd); #import #include input string sOptimiser=""; // --------------- Optimiser Settings //Здесь задаем пути к другому терминалу (к копии). input string sTerminalTesterPath="C:\Program Files\Alpari MT5 1"; input string sTerminalTesterDataPath="C:\Users\Пользователь\AppData\Roaming\MetaQuotes\Terminal\E0D00B1F6450CA08FAC85F562DAADA76"; input int InpTesterPeriod=45; // Tester Period (days) input string sBuddyIlan=""; // --------------- Buddy Ilan Settings input int TakeProfit = 40.0; // Take Profit (Point) input int Stoploss = 1000.0; // Stop Loss (Point) string gVarStop,gVarSL,gVarTP,gVarSTOFilter,gVarSTOTimeFrameFilter; string str; int BetterSL = 0.0; int BetterTP = 0.0; double BetterProfit=0.0; double BetterDD=0.0; bool BetterSTOFilter; bool BetterSTOTimeFrameFilter; enum OptimisationType { _SL,_TP,_STO }; bool bOptimisationDone=false; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ void DisplayNodesSL(CEasyXmlNode *Node) { for(int i=0; iBetterProfit || (profit==BetterProfit && slBetterProfit || (profit==BetterProfit && tpBetterProfit) // On ne tient pas compte du DD ici { BetterProfit=profit; BetterSTOFilter=(res[10]=="true")?true:false; BetterSTOTimeFrameFilter=(res[11]=="true")?true:false; } } } if(Node.getName()=="Table") str=""; } } } //+------------------------------------------------------------------+ bool CopyAndMoveCommonIni() { string PathIniFile= sTerminalTesterDataPath+"\\config\\common.ini"; string PathTester = TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\Optimiser\\"; int ret=ShellExecuteW(0,"Open","xcopy","\""+PathIniFile+"\" \""+PathTester+"\" /y","",0); // wait until the file is copied Sleep(2500); if(ret<32) { Print("Failed copying ini file"); return false; } // We are working now in the sand box, we can use usual MT5 File commands string IniFileName="Optimiser\\common.ini"; string CopyTo="Optimiser\\optimise.ini"; return FileMove( IniFileName, 0, CopyTo, 0 ); //return true; } //+------------------------------------------------------------------+ bool CreateAndCopyParametersFile(bool SL,bool TP,int SLValue,int TPValue) { // MQL5\Profiles\Tester int filehandle=FileOpen("Optimiser\\bollinger.set",FILE_WRITE|FILE_TXT); if(filehandle!=INVALID_HANDLE) { FileWrite(filehandle, "_EA_IDENTIFIER=Buddy Ilan\n", "_EA_MAGIC_NUMBER=1111||0||1||10||N\n", StringFormat("TakeProfit=%d||30||10||70||%s\n",(TPValue==0)?30:TPValue,(TP==true)?"Y":"N"), StringFormat("Stoploss=%d||500||250||1500||%s\n",(SLValue==0)?1000:SLValue,(SL==true)?"Y":"N")); FileClose(filehandle); } else { Print("Invalid handle of FileOpen (bollinger.set), error number: ",GetLastError()); return false; } Sleep(1500); string PathTester=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\Optimiser\\bollinger.set"; string PathProfile=sTerminalTesterDataPath+"\\MQL5\\Profiles\\Tester\\"; //PrintFormat( "[%s]", PathTester ); //PrintFormat( "-> [%s]", PathProfile ); // copy the ini file into the tester folder int ret=ShellExecuteW(0,"Open","xcopy","\""+PathTester+"\" \""+PathProfile+"\" /y","",0); // wait until the file is copied Sleep(5000); if(ret<32) { Print("Failed copying parameters file"); return false; } return true; } //+------------------------------------------------------------------+ bool StartOptimizer() { // Suppression local FileDelete("Optimiser\\BuddyIlanReport.xml"); // Suppression dans Instance Optimiser string PathReport=sTerminalTesterDataPath+"\\MQL5\\Files\\Reports\\BuddyIlanReport.xml"; ShellExecuteW(0,"Open","cmd.exe"," /C del "+PathReport,"",0); Sleep(2500); int start=ShellExecuteW(0,"Open",sTerminalTesterPath+"\\terminal64.exe","/config:"+TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\Optimiser\\optimise.ini","",0); if(start<32) { Print("Failed starting Tester"); return false; } Sleep(15000); return true; } //+------------------------------------------------------------------+ bool CopyReport() { int nTry=0; while(nTry++<500) // Timeout : 2 heures { string PathReport = sTerminalTesterDataPath + "\\MQL5\\Files\\Reports\\BuddyIlanReport.xml"; string PathTarget = TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\Optimiser\\"; int ret=ShellExecuteW(0,"Open","xcopy","\""+PathReport+"\" \""+PathTarget+"\" /y","",0); if(ret<32) { PrintFormat("Waiting generation report (%d) ...",nTry); Sleep(15000); } else { if(FileIsExist("Optimiser\\BuddyIlanReport.xml")==true) { PrintFormat("Report found (ret=%d) ...",ret); Sleep(2500); return true; } else { PrintFormat("Waiting report (%d) ...",nTry); Sleep(15000); } } } return false; } //+------------------------------------------------------------------+ bool LoadResults(OptimisationType eType) { /* * Réinitialistion variable */ BetterProfit=0.0; /* * Lecture des résultats */ CEasyXml EasyXmlDocument; EasyXmlDocument.setDebugging(false); // MQL5/Files/Reports/ if(EasyXmlDocument.loadXmlFromFullPathFile("Optimiser\\BuddyIlanReport.xml")==true) { str=""; CEasyXmlNode *RootNode=EasyXmlDocument.getDocumentRoot(); for(int j=0; j SL=%d (Profit=%.2lf)",BetterSL,BetterProfit); break; case _TP : DisplayNodesTP(cNode); PrintFormat("-> TP=%d (Profit=%.2lf DD=%lf)",BetterTP,BetterProfit,BetterDD); break; case _STO : DisplayNodesSTO(cNode); PrintFormat("-> STOFilter=%s STOTimeFrameFilter=%s (Profit=%.2lf)",(BetterSTOFilter==true)?"true":"false",(BetterSTOTimeFrameFilter==true)?"true":"false",BetterProfit); break; } break; } } } } else PrintFormat("Error found"); return true; } //+------------------------------------------------------------------+ bool AddTesterStanza() { int filehandle=FileOpen("Optimiser\\Optimise.ini",FILE_READ|FILE_WRITE|FILE_TXT); Print("File stanza: ", filehandle); if(filehandle!=INVALID_HANDLE) { FileSeek(filehandle,0,SEEK_END); FileWrite(filehandle,"[Tester]\n", "Expert=Project_N_1\\Project_N_1\n", "ExpertParameters=bollinger.set\n", "Symbol="+_Symbol+"\n", "Period=M15\n", "Login=\n", "Model=4\n", "ExecutionMode=0\n", "Optimization=2\n", "OptimizationCriterion=0\n", "FromDate="+TimeToString(TimeGMT()-InpTesterPeriod*86400,TIME_DATE)+"\n", "ToDate="+TimeToString(TimeGMT(),TIME_DATE)+"\n", "ForwardMode=0\n", "Report=MQL5\\Files\\Reports\\BuddyIlanReport\n", "ReplaceReport=1\n", "ShutdownTerminal=1\n", "Deposit=10000\n", "Currency=EURUSD\n", "Leverage=1:100\n", "UseLocal=1\n", "UseRemote=0\n", "UseCloud=0\n", "Visual=1\n"); FileClose(filehandle); Print("Stanza success"); } else { Print("FileOpen, error ",GetLastError()); return false; } return true; } //+------------------------------------------------------------------+