
مقدمه
همه فکر میکنند اکسپرتی که ورودیهایش مطابق با هیستوری تنظیم شدهاند، در همان بار اول (و ترجیحاً) در مدت زمان کمی، قرار است به ما سود بدهد و سود بدهد… بهطور غیرمستقیم تاییدههایی دربارهی این فرضیه، بعد از آنکه رقابتهای قهرمانی ترید در سال ۲۰۰۶ را تماشا کردم، به گوش من رسیدند. وقتی این رقابت آغاز شد، اکسپرتهای سوددده بسیاری نسبت به قبل در رقابت حاضر بودند، اما بعداً مشخص شد برخی از آنها اصلاً به درد رقابت نمیخورند. فکر میکنم دلیلش این باشد که بیشتر آن اکسپرتهایی که به خط پایان نرسیدند، فقط مطابق با هیستوری تنظیم شده بودند.
ایدهی بررسی این فرضیه در عمل، در انجمن روسی این وبسایت، در بخش سیستمهای ایدهآل برای ترید خودکار، متولد شد. ایدهی اصلی این است که بهینهسازی یک اکسپرت را یک بار در روز، انجام دهیم و سپس نتایج بدستآمده از بهینهسازی را تحلیل کرده و آنها را در متغیرهای اکسپرت ثبت کنیم.
برای اجرای این ایده، تصمیم گرفتیم از اکسپرت آماده، یعنی MACD Sample، در نرمافزار متاتریدر ۴ استفاده کنیم و تابع بهینهسازی خودکار خودمان را درون آن وارد کنیم. کمی بعد، کد آن بهینهسازِ خودکار، آماده بود، و در همان انجمن در بخش بهینهساز خودکار، آپلود شد. بعد از گذشت مدتی، اولین تاییدها دربارهی این ایده در همان جا ظاهر شدند. سپس، بهینهساز ما به یک کتابخانهی mqh برای بهکارگیری بهتر، منتقل شد.
نصب بهینهساز خودکار
برای انجام این کار مراحل زیر را طی کنید:
- MACD Sample_1.mq4 را در پوشهی “expert” نرمافزار متاتریدر ۴ کپی کنید. قطعاً نرمافزار باید به اینترنت متصل باشد، و
- این پوشه، همراه با نرمافزار متاتریدر ۴ را در یک جای جدید کپی کنید.
برای راحتی کار، از اینجا به بعد، نرمافزار اصلی [متاتریدر] را “نرمافزار / Terminal” و کپی آن را “Terminal-Tester” مینامیم. با همان اکسپرتی که بهطور پیشفرض در خود نرمافزار بود، و ما کمی آن را تغییر دادیم، یعنی MACD Sample_1.mq4، در تایمفریم H1، روی EURUSD، یک تست میگیریم.
Terminal-Tester Setup
یادتان نرود حتماً MACD Sample_1.mq4 را در Terminal-Tester کامپایل کنید. ابتدا نرمافزار (Client Terminal) را باز کرده و سپس سراغ استراتژیتستر بروید. باید مطابق با تصویر زیر آن را تنظیم کنید.
بهینهسازی برای سه روز انجام خواهد شد. سه روز برای بررسی بهینهساز خودکار کاملاً خوب و کافی است. تاربخ بهینهسازی (“From”) را مطابق با این فرمول انتخاب میکنیم: تاریخ کنونی منهایِ سه روز. حین بهینهسازی، هیستوری مورد نیاز برای اَرز انتخابشده (در اینجا EURUSD) باید دانلود شود.
کسانی که بهینهسازی را برای اولین بار انجام میدهند، میتوانند توضیحات مربوط به روش انجام کار را در منوی Help نرمافزار متاتریدر ۴، بیابند: <Help – Help Topics F1 – Auto Trading – Expert Optimization – Setup>. یا اینکه میتوانند این مقاله را بخوانند: Testing of Expert Advisors in the MetaTrader 4 Client Terminal: An Outward Glance.
همانطور که در تصویر زیر نشان داده شدهاست، متغیرها را برای بهینهسازی انتخاب میکنیم.
بهینهسازی خودکار محدود به ۴ متغیر است، اما بهمنظور از دست ندادن زمان، داشتن فقط سه متغیر هم کار ما را راه میاندازد و کافیست. بعد از اینکه متغیرها انتخاب شدند، بیایید تنظیمات بهینهسازی را در فایل تنظیمات بهنام MACD Sample_1.set، ذخیره کنیم. این فایل باید در پوشهای از Terminal-Tester ذخیره شود که نام آن پوشه “tester” است. سپس پیش-بهینهسازی (pre-optimization) را اجرا کرده و زمان شروع را نیز بهیاد داشته باشید. این کار برای محاسبهی دورهی زمانیِ مورد نیاز برای بهینهسازی خودکار با پارامترهای از پیش تعیینشده، لازم است. بعد از اینکه بهینهسازی تمام شد، زمان انتظار لازم را محاسبه خواهیم کرد. سپس باید این نرمافزار را ببندیم، چراکه، درغیراینصورت، قادر نخواهیم بود آن را برنامهریزیشده اجرا کنیم.
تنظیمات اکسپرتی که در نرمافزار قرار دارد
برای انجام این کار، بیایید اکسپرت آزمایشی MACD Sample_1.mq4 را در متااِدیتور باز کرده و کارهای زیر را انجام دهیم:
– زمان شروع بهینهسازی خودکار را تعیین کنید، برای مثال، هر روز ساعت ۰۰:۰۱:
datetime SetHour = 0; // Optimization starting hour; datetime SetMinute = 1; // Optimization starting minute.
– تعداد روزها برای بهینهسازی را تعیین کنید (تعداد روزها باید برابر با تعداد روزهای تعیینشده برای پیش-بهینهسازی باشد):
int TestDay = 3;
– زمان بهینهسازی و زمان انتظار، که قبلاً محاسبه کردهایم، را در واحد دقیقه تعیین کنید. برای مثال، ۴ دقیقه:
int TimeOut = 4;
– نام اکسپرت را وارد کنید:
string NameMTS = "MACD Sample_1"; // EA's name
– نام فایل تنظیمات، همراه با تنظیمات را وارد کنید:
// Set-file name with the settings string NameFileSet = "MACD Sample_1.set";
– مسیر پوشهای که Terminal-Tester نصبشده درون آن است را وارد کنید، برای مثال:
// Path to the tester string PuthTester = "D:\Program Files\Forex Best Trade Station";
– اولویت فیلترینگ را مشخص کنید:
// Sorting by Maximal profit int Gross_Profit = 1; // Sorting by Maximal profit factor int Profit_Factor = 2; // Sorting by Maximal expected payoff int Expected_Payoff = 3;
– نام متغیرها را جهت بهینهسازی بنویسید:
string Per1 = "FastEMA"; string Per2 = "SlowEMA"; string Per3 = "SignalSMA"; string Per4 = "";
– فایل پیوستشدهی auto_optimization.mqh را در پوشهی “include” کپی کنید؛
– فایل کتابخانه (library file) را در اکسپرت وارد کنید:
//--- Including the auto optimizer's library #include <auto_optimization.mqh>
– فقط این باقی میماند که کد زیر را در ابتدای تابع start() اکسپرت خودتان کپی کنید. MACD Sample_1.mq4 این بخش را در خود دارد (نیازی به این کار نیست).
// Not to be launched at testing and optimizing if(!IsTesting() && !IsOptimization()) { // Compare the current hour with that preset for launching if(TimeHour(TimeLocal()) == SetHour) { // Protection against restarting if(!StartTest) { // Compare the minute range to the minute // preset for launching if(TimeMinute(TimeLocal()) > SetMinute - 1) { // the range is necessary, in case that for some reasons // no new tick is available for a long time if(TimeMinute(TimeLocal()) < SetMinute + 1) { // Flag of tester launching StartTest = true; TimeStart = TimeLocal(); Tester(TestDay, NameMTS, NameFileSet, PuthTester, TimeOut, Gross_Profit, Profit_Factor, Expected_Payoff, Per1, Per2, Per3, Per4); } } } } } FastEMA = GlobalVariableGet(Per1); SlowEMA = GlobalVariableGet(Per2); SignalSMA = GlobalVariableGet(Per3); TrailingStop = GlobalVariableGet(Per4); // If the tester launching is flagged if(StartTest) { // If more time has elapsed the launching than it was set // to be the test waiting time if(TimeLocal() - TimeStart > TimeOut*60) { // Zeroize the flag StartTest = false; } }
کار همین بود. بعد از اینکه بهینهساز خودکار، مجدد کامپایل شد، میتوانید آن را اجرا کنید. اما شاید فقط بتوانید آن را برای همان اَرز و تایمفریمی استفاده کنید که پیش-بهینهسازی برای آنها انجام شدهاست. در اینجا میشود: EURUSD در تایمفریم H1. برای بررسی بهینهساز خودکار، میتوانید کدی که در پایین آورده شدهاست را در تابع int init() وارد کرده، آنگاه بهینهساز خودکار هنگام شروع به کار اکسپرت، [با آن] اجرا خواهد شد.
Tester(TestDay,NameMTS,NameFileSet,PuthTester,TimeOut, Gross_Profit,Profit_Factor, Expected_Payoff, Per1,Per2,Per3,Per4);
بهینهساز خودکار چگونه کار میکند؟
بهینهساز خودکار برمبنای استفاده از Terminal-Tester جهت بهینهسازی پارامترهای اکسپرتی که روی نمودار Terminal اجرا شدهاست، کار میکند. برای انجام این کار، برنامه، فایلی را به Terminal-Tester میفرستد که شامل پارامترهای بهینهسازی میشود (optimise.ini) و Terminal-Tester را در حالت بهینه اجرا میکند. سپس، نتایج بدستآمده از “FileReport……..htm” را در Terminal کپی میکند و بهترین مقادیر نتایج بدستآمده را فیلتر میکند.
جزئیات بیشتر دربارهی چگونگی عملکرد بهینهساز خودکار
در زمان از پیش تعیینشده، برای مثال، ۰۰:۰۱، بهینهساز خودکار باید اجرا شود. متغیرها نیز باید با مقادیر پُر شوند.
// Path to the terminal string PuthTerminal = TerminalPath() + "\experts\files"; // Name of the ini file for the tester string FileOptim = "optimise.ini"; string FileOptim1 = "\optimise.ini"; // Calculation of the starting date datetime DayStart = TimeLocal()-86400*TestDay; // Optimization starting date string DateStart = TimeToStr(DayStart,TIME_DATE); // Optimization ending date string DateStop = TimeToStr(TimeLocal(),TIME_DATE); // Tester report file name string FileReport = "FileReport_" + Symbol() + "_" + DateStop + ".htm"; string FileReport1 = "\FileReport_" + Symbol() + "_" + DateStop + ".htm"; // Limitation for the minimum amount of trades per day double MinTr = TestDay - 2; // Limitation for maximal amount of trades per day double MaxTr = (60 / Period()*TestDay) + 2; // The amount of attempts to copy the report file int KvoPptk = 10; // The amount of lines for sorting int StepRes = 12;
آنگاه پارامترهای فایل ini در آرایه رشتهای نوشته میشوند:
// Prepare the ini file for optimization ArrayOpttim[0] = ";optimise strategy tester"; // Enable/Disable Expert Advisors ArrayOpttim[1] = "ExpertsEnable = false"; // Name of the EA file ArrayOpttim[2] = "TestExpert=" + NameMTS; // Name of the file containing parameters ArrayOpttim[3] = "TestExpertParameters=" + NameFileSet; // Symbol ArrayOpttim[4] = "TestSymbol=" + Symbol(); // Timeframe ArrayOpttim[5] = "TestPeriod=" + Period(); // Modeling mode ArrayOpttim[6] = "TestModel=" + 0; // Recalculate ArrayOpttim[7] = "TestRecalculate=false"; // Optimization ArrayOpttim[8] = "TestOptimization=true"; // Use date ArrayOpttim[9] = "TestDateEnable=true"; // From ArrayOpttim[10] = "TestFromDate=" + DateStart; // To ArrayOpttim[11] = "TestToDate=" + DateStop; // Report file name ArrayOpttim[12] = "TestReport=" + FileReport; // Rewrite the report file ArrayOpttim[13] = "TestReplaceReport=true"; // Shut down the terminal upon completion ArrayOpttim[14] = "TestShutdownTerminal=true";
پارامترهای بهینهسازی از آرایه (array) درون فایل ini ثبت میشوند. میتوانید در بخش Help نرمافزار متاتریدر ۴، دربارهی اینکه چگونه فایلهای ini ایجاد میشوند، مطالعه داشته باشید. <Help – Help Topics F1 – Tools – Configuration at Startup>.
// Write data into the ini file // Find out about the array size OptimArraySize = ArraySize(ArrayOpttim); // Open a file to write opttim = FileOpen(FileOptim, FILE_CSV|FILE_WRITE, 0x7F); if(opttim > 0) { for(int i = 0; i < OptimArraySize; i++) { // from the array into the variable ini = ArrayOpttim[i]; // from the variable into the file FileWrite(opttim, ini); } // close the file FileClose(opttim); } else { Print("Failed writing data into the ini file. Error No ", GetLastError()); return(0); }
بعد از اینکه پارامترها در فایل ini ذخیره شدند، shell32.dll موجود در standard Windows delivery، متصل شده و تابع ShellExecuteA اجرا میشود.
#import "shell32.dll" //Connect a dll (provided with Windows) int ShellExecuteA(int hwnd,string Operation,string File,string Parameters,string Directory,int ShowCmd); #import
فایلی که حاوی پارامترها است، به پوشهی Terminal Tester فرستاده خواهد شد.
// copy the ini file into the tester folder copyini = ShellExecuteA(0,"Open","xcopy", "\"" + PuthTerminal + FileOptim1 + "\" \"" + PuthTester + "\" /y", "", ۳); // wait until the file is copied Sleep(1200); if(copyini < 0) { Print("Failed copying ini file"); return(0); }
آنگاه تستر اجرا شده و شروع به بهینهسازی متغیرهای از پیش تعریفشده، میکند. اکسپرت حین بهینهسازی، در وضعیت ساکن (توقف) قرار دارد.
// Start Tester start = ShellExecuteA(0, "Open", "terminal.exe", FileOptim, PuthTester, 3); if(start < 0) { Print("Failed starting Tester"); return(0); } Comment("Wait until optimization is complete"); // wait until optimization is complete Sleep(60000*TimeOut);
بعد از اینکه بهینهسازی کامل شد، تستر بهطور خودکار نتایج را در فایل گزارش ثبت میکند. این فایل به پوشهای کپی میشود که نرمافزار درون آن است.
for(Pptk = 0; Pptk < KvoPptk; Pptk++) { //Start a cycle attempting to compy the resport file Comment("Attempt # " + Pptk + " to copy the report file"); ShellExecuteA(0, "Open", "xcopy", "\"" + PuthTester + FileReport1 + "\" \"" + PuthTerminal + "\" /y", "", 3); // wait until the file is copied Sleep(1200); // Try to open the report file file = FileOpen(FileReport, FILE_READ, 0x7F); if(file < 0) { // if it fails to open, wait some more and try again Sleep(60000); } else break; } if(file < 0) { Print("Failed copying the report file"); return(0); }
آنگاه دادههای فایل گزارش، در آرایه رشتهای جهت پردازشهای بیشتر، جای میگیرند.
// Read from file into the array // Cycle, until the file ends while(FileIsEnding(file) == false) { // Read a string from the report file FileLine = FileReadString(file); // Find the necessary string and set the reference point there index = StringFind(FileLine, "title", 20); if(index > 0) { // Increase the array in size ArrayResize(ArrayStrg, NumStr + 1); // Record the strings from the file in the array ArrayStrg[NumStr] = FileLine; NumStr++; } } // Close the file FileClose(file); // Delete the file in order not to produce too many copies FileDelete(FileReport); // Set the array size by the amount of data read from the file ArrayResize(ArrayData, NumStr);
آنگاه مقادیر مورد نیاز در آرایه، انتخاب میشوند:
for(text = 0; text < NumStr; text++) { select = ArrayStrg[text]; //------------------------------------------------------------------------- // Reporting text processing (These are apples and oranges) | //------------------------------------------------------------------------- // Position Pass ClStep=StringFind(select, "; \">",20)+4; // Find the end of position ClStepRazm = StringFind(select, "td>", ClStep); // Read the value CycleStep = StringSubstr(select, ClStep, ClStepRazm - ClStep); // Position Profit // Find the beginning of the position GrProf = StringFind(select, "", ClStepRazm); // Find the end of position GrProfRazm = StringFind(select, "td>", GrProf); // Read value GrossProfit = StringSubstr(select, GrProf+4, GrProfRazm - (GrProf + 4)); // Position Total Trades // Find the beginning of position TotTrad = StringFind(select, "", GrProfRazm); // Find the end of position TotTradRazm = StringFind(select, "td>", TotTrad); // Read the value TotalTrades = StringSubstr(select, TotTrad+4, TotTradRazm - (TotTrad + 4)); // Position Profitability // Find the beginning of position ProfFact = StringFind(select, "", TotTradRazm); // Find the end of position ProfFactRazm = StringFind(select, "td>", ProfFact); // Read the value ProfitFactor = StringSubstr(select, ProfFact + 4, ProfFactRazm - (ProfFact + 4)); // Position Expected Payoff // Find the beginning of position ExpPay = StringFind(select, "", ProfFactRazm); // Find the dn of position ExpPayRazm=StringFind(select, "td>", ExpPay); // Read the value ExpectedPayoff = StringSubstr(select, ExpPay+4, ExpPayRazm - (ExpPay + 4)); // Variables' positions starting with the second one // Find the beginning of position P1 = StringFind(select, Per1, 20); // Find the end of position P1k = StringFind(select, ";", P1); // Read the Variable Perem1 = StringSubstr(select, P1 + StringLen(Per1) + 1, P1k - (P1 + 1 + StringLen(Per1))); // Find the beginning of position P2 = StringFind(select, Per2, 20); // Find the end of position P2k = StringFind(select, ";", P2); // Read the Variable Perem2 = StringSubstr(select, P2 + StringLen(Per2) + 1, P2k - (P2 + 1 + StringLen(Per2))); // Find the beginning of position P3 = StringFind(select, Per3, 20); // Find the end of position P3k = StringFind(select, ";", P3); // Read the Variable Perem3 = StringSubstr(select, P3 + StringLen(Per3) + 1, P3k - (P3 + 1 + StringLen(Per3))); // Find the beginning of position P4 = StringFind(select, Per4, 20); // Find the end of position P4k = StringFind(select, ";", P4); // Read the Variable Perem4 = StringSubstr(select, P4 + StringLen(Per4) + 1, P4k - (P4 + 1 + StringLen(Per4))); Comment("The obtained results are being analyzed");
بعد از آن، نتایح بدستآمده، قبل از اینکه بهشکل عددی در بیایند، فیلتر میشوند، و حداقل و حداکثر مقدار معاملات مشخص میشوند. صفر در مقدار Profit_Factor، جای خودش را بهخاطر مرتبسازی صحیح و پس از آن غربالگری، به ۱۰۰۰ میدهد.
// Transform into number format TotalTradesTransit = StrToDouble(TotalTrades); GrossProfitTransit = StrToDouble(GrossProfit); ExpectedPayoffTran = StrToDouble(ExpectedPayoff); nodubl = true; if(MinTr < TotalTradesTransit && MaxTr > TotalTradesTransit) { // Filter by the amount of trades PrFactDouble = StrToDouble(ProfitFactor); // Replace 0 in the Profit_Factor for proper analysis if(PrFactDouble == 0) { PrFactDouble = 1000; }
سپس مقادیر بررسی میشوند تا تکراری در میان آنها نباشد و آنگاه فیلتر میشوند.
// Filter data having identical values for(Dubl = 0; Dubl <= ResizeArayNew; Dubl++) { // Start the loop searching for identical values if(GrossProfitTransit == ArrayData[Dubl][1]) { // check whether the results for maximal profit coincide if(TotalTradesTransit == ArrayData[Dubl][2]) { // check whether the results for the amount of trades coincide if(PrFactDouble == ArrayData[Dubl][3]) { // check whether the results for Profit Factor coincide if(ExpectedPayoffTran == ArrayData[Dubl][4]) { // check whether the results for expected payoff coincide nodubl=false; // If everything coincides, flag it as coincided } } } } }
بعد از آن، مقادیری که برای مرتبسازی آماده شدهاند، در آرایه نوشته میشوند.
// Write the filtered data in the array if(nodubl) { ArrayData[text][1] = GrossProfitTransit; ArrayData[text][2] = TotalTradesTransit; ArrayData[text][3] = PrFactDouble; ArrayData[text][4] = ExpectedPayoffTran; ArrayData[text][5] = StrToDouble(Perem1); ArrayData[text][6] = StrToDouble(Perem2); ArrayData[text][7] = StrToDouble(Perem3); ArrayData[text][8] = StrToDouble(Perem4); ResizeArayNew++; }
آنگاه دادهها را به ترتیب اولویتی که از پیش تعیین شدهاست، آنالیز میکنند. آنالیز به این شکل انجام میشود:
- حلقه اجرا میشود، و در گام اول (first pass)، مقادیر بر اساس اولین پارامتر مرتب میشوند، برای مثال، بر اساس حداکثر سود؛ چند تا از بهترین مقادیر انتخاب شدهاند (۱۲، بهطور پیشفرض)، و بقیه حذف میشوند؛
- در گام دوم، مقادیر بر اساس پارامتر دوم، مرتب میشوند، برای مثال، بر اساس Profit Factor؛ برخی از بهترین مقادیر انتخاب میشوند، نیمی از آنها بعد از اولین مرتبسازی، و بقیه حذف میشوند.
- و در گام سوم، مرتبسازی آخر بر اساس پارامتر سوم انجام میشود، برای مثال، بر اساس بازپرداخت مورد انتظار؛ نیمی از مقادیر بعد از مرتبسازی دوم اخذ میشوند و بقیه حذف میگردند.
// Analyzer // Analyzing principle is the sequential checking of maximal // values according to the predefined filtering priority ArrayResize(ArrayTrans, ResizeArayNew - 1); for(int PrioStep = 1; PrioStep < 4; PrioStep++) { for(PrCycle = 0; PrCycle < ResizeArayNew; PrCycle++) { Sort = ArrayData[PrCycle][0]; Prior1 = ArrayData[PrCycle][1]; transit = ArrayData[PrCycle][2]; Prior2 = ArrayData[PrCycle][3]; Prior3 = ArrayData[PrCycle][4]; transit1 = ArrayData[PrCycle][5]; transit2 = ArrayData[PrCycle][6]; transit3 = ArrayData[PrCycle][7]; transit4 = ArrayData[PrCycle][8]; if(PrioStep == 1) { //Prepare for the 1st sorting if(Gross_Profit ==1) { SortTrans = Prior1; } if(Profit_Factor == 1) { SortTrans = Prior2; } if(Expected_Payoff == 1) { SortTrans = Prior3; } } if(PrioStep == 2) { // Restore if(Gross_Profit ==1) { Prior1 = Sort; } if(Profit_Factor == 1) { Prior2 = Sort; } if(Expected_Payoff == 1) { Prior3 = Sort; } //Prepare for the 2nd sorting if(Gross_Profit == 2) { SortTrans = Prior1; } if(Profit_Factor == 2) { SortTrans = Prior2; } if(Expected_Payoff == 2) { SortTrans = Prior3; } } if(PrioStep == 3) { // Restore if(Gross_Profit == 2) { Prior1 = Sort; } if(Profit_Factor == 2) { Prior2 = Sort; } if(Expected_Payoff == 2) { Prior3 = Sort; } //Prepare for the 3rd sorting if(Gross_Profit ==3) { SortTrans = Prior1; } if(Profit_Factor == 3) { SortTrans = Prior2; } if(Expected_Payoff == 3) { SortTrans = Prior3; } } ArrayTrans[PrCycle][0] = SortTrans; ArrayTrans[PrCycle][1] = Prior1; ArrayTrans[PrCycle][2] = transit; ArrayTrans[PrCycle][3] = Prior2; ArrayTrans[PrCycle][4] = Prior3; ArrayTrans[PrCycle][5] = transit1; ArrayTrans[PrCycle][6] = transit2; ArrayTrans[PrCycle][7] = transit3; ArrayTrans[PrCycle][8] = transit4; } ArraySort(ArrayTrans,StepRes, 0, MODE_DESCEND); // Sort the array ArrayResize(ArrayTrans, StepRes); // Cut off the unnecessary things for(int CopyAr = 0; CopyAr < StepRes; CopyAr++) { ArrayData[CopyAr][0] = ArrayTrans[CopyAr][0]; ArrayData[CopyAr][1] = ArrayTrans[CopyAr][1]; ArrayData[CopyAr][2] = ArrayTrans[CopyAr][2]; ArrayData[CopyAr][3] = ArrayTrans[CopyAr][3]; ArrayData[CopyAr][4] = ArrayTrans[CopyAr][4]; // Per1 Variable 1 ArrayData[CopyAr][5] = ArrayTrans[CopyAr][5]; // Per2 Variable 2 ArrayData[CopyAr][6] = ArrayTrans[CopyAr][6]; // Per3 Variable 3 ArrayData[CopyAr][7] = ArrayTrans[CopyAr][7]; // Per4 Variable 4 ArrayData[CopyAr][8] = ArrayTrans[CopyAr][8]; } StepRes = StepRes / 2; }
مقادیری که به این سبک فیلتر شدهاند، در متغیرهای جهانی نوشته میشوند. مقادیر متغیرهای جهانی در اکسپرت ما جایگزین میگردند.
// Write the obtained results in variables double Peremen1 = ArrayTrans[0][5]; double Peremen2 = ArrayTrans[0][6]; double Peremen3 = ArrayTrans[0][7]; double Peremen4 = ArrayTrans[0][8]; // If the variable name is specified, write the result in // global variables if(Per1 != "") { GlobalVariableSet(Per1, Peremen1); } if(Per2 != "") { GlobalVariableSet(Per2,Peremen2); } if(Per3 != "") { GlobalVariableSet(Per3,Peremen3); } if(Per4 != "") { GlobalVariableSet(Per4,Peremen4); } Comment(Per1, " ", Peremen1, " | ", Per2, " ", Peremen2, " | ", Per3, " ", Peremen3, " | ", Per4, " ", Peremen4); Print(Per1, " ", Peremen1, " | ", Per2, " ", Peremen2, " | ", Per3, " ", Peremen3," | ",Per4," ",Peremen4); } // Function ends. That's all, automated optimization is complete.
نتایج عملکرد بهینهساز خودکار
نتایج عملکرد بهینهساز خودکار را میتوانید با استفاده از پیامهایی که در گوشهی سمت چپ، بالای نمودار، ظاهر میشوند، مشاهده کنید. تصویر زیر مثالی از این موضوع است:
زمان مرجع تکمیل بهینهسازی[۱].
تحلیل مقادیر بدستآمده بعد از بهینهسازی.
مقادیر نتیجهیِ متغیرها[۲].
اگر نتایج بهینهسازی در پیام ظاهر شد، بدان معناست که بهینهسازی تمام شدهاست و دادهها دریافت شدهاند.
برای اینکه بتوانیم بهصورت جداگانه، کار بهینهساز خودکار را ارزیابی کنیم، ممکن است بگویید تمام فایلهایی را که حاوی دادههای متوسط هستند و حین فرآیند کاری ذخیره شدهاند را، باید بررسی کنیم. تستر، دادهها را در فایلی با نام “FileReport_EURUSD_2007.03. 12.htm” ذخیره میکند، که در آن نماد (symbol) و دادهها در نام فایل، مطابق با نماد انتخابشده و تاریخ کنونی بهینهسازی، جایگزین میشوند. این فایل را میتوانید در پوشهی Terminal-Tester پیدا کنید. این فایلها همراه با گزارشها بهطور خودکار پاک نمیشوند، بنابراین فرد میتواند از آنها برای بررسی تغییرات پارامترها استفاده کند.
فایل بعدی، FileTest1.csv، بعد از اینکه مقادیر فیلتر شدند و مقدار معاملات مشخص شد، و کپیها حذف شدند، ذخیره میشود. مسیر ذخیرهی این فایل: D:\Program Files\terminal_folder_name\experts\files
سپس مقادیری که پس از هر مرحله غربالگری بدست میآید، درون FileTest2.csv ذخیره میشوند. این فایل هم در همان پوشهی قبلی ذخیره میشود.
جدول بالا نشان میدهد که چگونه مقادیر بدستآمده فیلتر شدهاند. ترتیب فیلترینگ بهطور پیشفرض اینگونه تعیین شدهاست: ۱- Gross_Profit، ۲- Profit_Factor، ۳- Expected_Payoff.
کد بهینهساز خودکار حاوی کامنتهایی با جزئیات است، و در صورت نیاز میتوانید بهترین پارامترهای متغیر را انتخاب کنید. برای مثال، قصد دارید اکسپرت خود را برای یک بازهی زمانی غیر از روزهای اخیر بهینهسازی کنید، یا میخواهید مقدار معاملات را در دورهی بهینهسازی، کاهش/افزایش دهید. برای انجام این کار میبایستی مستقیماً متغیرهای مربوطه را در auto_optimization.mqh تغییر دهید.
// Limitation of minimal amount of trades per day double MinTr = TestDay - 2; // Limitation on maximal amount of trades per day double MaxTr = (60 / Period()*TestDay) + 2; // The amount of attempts to copy the report file int KvoPptk = 10; // The amount of strings to be sorted int StepRes = 12;
نتیجهگیری
این مقاله قصد نداشت به تازهکارها اِلمانهای بهینهسازی را آموزش دهد. بنابراین، پیشنهاد میشود قبل از اینکه سراغ بهینهسازی خودکار بروید، حتماً بهینهسازی معمولی را یاد بگیرید. بهتر این است، از بهینهساز خودکار زمانی استفاده کنید که، متغیرهای پایه، که روی اکسپرت شما در زمانهای مختلف، تاثیرات مختلفی میگذارند را، انتخاب کرده باشید. بهعبارت دیگر، بهتر است از این بهینهساز خودکار برای مطابقت دادن پارامترهای متغیرها، با تغییراتی که روی عملکرد اکسپرت شما، بسته به نوسانات بازار، بیش از دیگر پارامترها در متغیرهای دیگر، تاثیر میگذارند، استفاده کنید.
علاوه بر اینها، بهتر این است که دورهی بهینهسازی را خیلی طولانی درنظر نگیرید. فرض کنید اکسپرت، ۶ الی ۱۲ ساعت هر روز، بهینهسازی شود، آنگاه این سوال پیش میآید: پس کی ترید کنیم؟ بهعبارت دیگر، بهینهسازی به خودی خود، نیاز نیست. پیشنهاد میشود تناوب بهینهسازی (منظور، تناوب اجرای بهینهساز است) را با درنظر گرفتن تایمفریمی که روی آن اکسپرت قرار است ترید کند، تعیین کنید. این یعنی اینکه ضروری است درنظر داشته باشیم که دادههای هیستوری هنگامیکه Tester-Terminal شروع به کار میکند، بهنوعی پمپاژ میشوند و ممکن است بروکر دادههای هیستوری مورد نیاز برای یک بازهی زمانی خاص را در اختیار نداشته باشد. برای تایید فرضیهای که در ابتدای این مقاله به آن اشاره شد، نیاز دارید ۲۴ ساعت اتصال اینترنت قوی، پایدار و بدون قطعی داشته باشید.
برنامههای بهینهسازی خودکاری که توسعه داده شدند، در فایلهای پیوستشده موجود هستتند: auto_optimization.mqh – خود کتابخانه، MACD Sample_1.mq4 – که نسخهی کمی تغییردادهشدهی اکسپرتی است که در نرمافزار متاتریدر ۴ موجود است.
این مقاله دارای فایل پیوست است.
[۱]) Optimization Completeness Reference Time
[۲]) Resulting Values of Variables
۲۲ مورد نظر
best ed pills
reasons for ed drugs and medications ed symptoms
online drugstore ed clinic cheap drugs online
cost of cialis at walmart cialis brand cialis 20mg
cialis lilly 20mg purchasing cialis in the usa cialis name brnd
ivermectin stromectol sheep drench ivermectin ivermectin cost uk
prednisone 20 mg prices average cost of generic prednisone online order prednisone
stromectol amazon ivermectin scabies treatment ivermectin for scabies
propecia sale finasteride proscar generic finasteride for sale
ivermectin gel ivermectin buy australia ivermectin discovery
what is stromectol used for ivermectin mechanism of action ivermectin dose cats
natural remedies for ed non prescription ed drugs male ed pills
purchase propecia no prescription finasteride proscar finasteride 1 mg
ivermectin scabies treatment ۱% ivermectin is ivermectin
trusted online canadian pharmacy reviews canada rx drugs online highest rated canadian pharmacies
best ed pills online best medication for ed erectile dysfunction drugs
stromectol 12 mg tablets stromectol buy stromectol online
stromectol price usa stromectol 3 mg tablets price stromectol 3 mg tablets price
buy clomid buy clomid 50mg online where to buy cheap clomid online
buy clomid 50mg buy clomid 50mg online buy clomid 50mg online
tadalafil 10mg price cialis generic tadalafil 20mg india
sildenafil 100 mg viagra where to buy viagra tablets for men