در برنامهنویسی اکسپرت (MQL5)، تنها دیدن گزارش نهایی بکتست برای ارزیابی عملکرد یک ربات معاملهگر کافی نیست. یک توسعهدهنده حرفهای باید بتواند به دادههای آماری دقیق در حین اجرا دسترسی داشته باشد و آنها را درون کد فراخوانی کند. این قابلیت به شما اجازه میدهد تا «معیار بهینهسازی» (Optimization Criterion) اختصاصی خود را بسازید و ربات را دقیقاً بر اساس اهداف استراتژیک خود (مثل کمترین افت سرمایه یا بیشترین پایداری) تنظیم کنید.
در این مقاله تخصصی، تابع قدرتمند TesterStatistics را کالبدشکافی کرده و تمام شناسههای آماری آن را در قالب جداول کاربردی بررسی میکنیم. در پایان نیز با دو مثال عملی، نحوه ساخت سیستم امتیازدهی هوشمند در تابع OnTester را آموزش خواهیم داد.
تابع TesterStatistics() کلید دسترسی برنامهنویس به نتایج محاسباتی استراتژی تستر است. این تابع در انتهای هر پاس از تست اجرا میشود و میتواند مقادیر حیاتی مثل سود خالص، دراودان (Drawdown)، فاکتور سود و نسبت شارپ را به برنامه برگرداند.
اهمیت این تابع زمانی دوچندان میشود که بخواهید از تابع OnTester استفاده کنید. با ترکیب این دو ابزار، شما دیگر محدود به معیارهای پیشفرض متاتریدر (مثل Balance Max) نیستید. بلکه میتوانید الگوریتمهای پیشرفته مدیریت سرمایه را مستقیماً در فرایند بهینهسازی (Optimization) دخیل کنید تا بهترین تنظیمات ربات، نه صرفاً بر اساس سود، بلکه بر اساس کیفیت معاملات انتخاب شوند.
برای راحتی کار شما، تمامی آمارهای ضروری را در ۵ دستهبندی اصلی تفکیک کردهایم. با استفاده از این جداول میتوانید به سرعت تشخیص دهید هر شناسه (ID) چه کاری انجام میدهد و چه مقداری برای آن مطلوب است.

این گروه، پایه و اساس ارزیابی مالی استراتژی است و نشان میدهد آیا ربات در پایان دوره تست، توانایی خلق ثروت را داشته است یا خیر.
| شناسه (ID) در کد | توضیح و کاربرد | مقدار مطلوب / تفسیر |
|---|---|---|
| STAT_INITIAL_DEPOSIT | سرمایه اولیه حساب در شروع تست. | ثابت است. |
| STAT_PROFIT | سود خالص نهایی (مجموع سودها و ضررها). | مثبت بودن (هرچه بیشتر بهتر). |
| STAT_GROSS_PROFIT | سود ناخالص (فقط مجموع معاملات سودده). | جهت محاسبه نسبتها استفاده میشود. |
| STAT_GROSS_LOSS | ضرر ناخالص (فقط مجموع معاملات ضررده). | باید کنترل شده باشد. |
| STAT_EXPECTED_PAYOFF | امید ریاضی (میانگین سود در هر معامله). | مثبت باشد. اگر منفی باشد، استراتژی در بلندمدت بازنده است. |
این بخش حیاتیترین قسمت برای مدیریت سرمایه و بقای حساب است. توجه کنید که در کدنویسی سیستمهای مدیریت ریسک حرفهای، همواره Equity (دارایی شناور) معیار دقیقتری نسبت به Balance (موجودی بسته شده) است.
| شناسه (ID) در کد | توضیح و کاربرد | مقدار مطلوب / تفسیر |
|---|---|---|
| STAT_EQUITY_DDREL_PERCENT | مهمترین معیار ریسک. بیشترین درصد افت Equity در کل تست. |
|
| STAT_EQUITY_DD | مقدار دلاری بیشترین افت Equity. | بسته به سرمایه اولیه، باید قابل تحمل باشد. |
| STAT_BALANCE_DDREL_PERCENT | بیشترین درصد افت Balance. | اهمیت کمتری نسبت به Equity دارد (چون معاملات باز را نمیبیند). |
| STAT_MIN_MARGINLEVEL | حداقل سطح مارجین. برای استراتژیهای پرریسک حیاتی است. |
|
این نسبتها «کیفیت» و پایداری سودآوری را میسنجند و به ما میگویند آیا سود به دست آمده حاصل شانس بوده یا نتیجهی یک سیستم معاملاتی قوی.
| شناسه (ID) در کد | توضیح و کاربرد | مقدار مطلوب / تفسیر |
|---|---|---|
| STAT_PROFIT_FACTOR | فاکتور سود (نسبت سود ناخالص به ضرر ناخالص). |
|
| STAT_RECOVERY_FACTOR | فاکتور بازیابی (سود خالص تقسیم بر دراودان). قدرت جبران ضرر. |
|
| STAT_SHARPE_RATIO | نسبت شارپ. ثبات سوددهی نسبت به ریسک. |
|
برای درک رفتار استراتژی و اطمینان از اعتبار آماری نتایج (Statistical Significance) استفاده از این بخش ضروری است. یک استراتژی با ۵ معامله قابل اعتماد نیست، حتی اگر سود بالایی داشته باشد.
| شناسه (ID) در کد | توضیح و کاربرد | مقدار مطلوب / تفسیر |
|---|---|---|
| STAT_TRADES | تعداد کل معاملات کامل. | حداقل ۵۰ معامله برای اعتبار آماری لازم است. |
| STAT_MAX_PROFITTRADE | بزرگترین سود در یک تک معامله. | نباید اختلاف فاحشی با میانگین سود داشته باشد (شانسی نباشد). |
| STAT_MAX_LOSSTRADE | بزرگترین ضرر در یک تک معامله. | باید با حد ضرر (SL) همخوانی داشته باشد. |
| STAT_CONLOSSMAX | بیشترین مبلغ ضرر متوالی. (بدترین سناریوی ممکن). | باید متناسب با تحمل ریسک سرمایه باشد. |
| STAT_MAX_CONLOSSES | تعداد معاملات ضررده متوالی. | جهت آمادگی روانی تریدر مهم است. |
| شناسه (ID) در کد | توضیح و کاربرد |
|---|---|
| STAT_CUSTOM_ONTESTER | مقداری که شما از تابع OnTester برمیگردانید. این عدد مبنای بهینهسازی “Custom Max” در متاتریدر میشود. |
| STAT_COMPLEX_CRITERION | معیار پیچیده داخلی متاتریدر. ترکیبی از سود و کیفیت است اما معمولاً برنامهنویسان ترجیح میدهند معیار خودشان را بسازند. |
در این بخش، دو مثال کاربردی و کاملاً متفاوت برای نحوه استفاده از آمارهای بالا در تابع OnTester آورده شده است. عددی که این تابع برمیگرداند، «امتیاز نهایی» آن پاس از بهینهسازی است و الگوریتم ژنتیک متاتریدر تلاش میکند تا این عدد را به حداکثر (Maximize) برساند. برای فعالیت حرفهای، باید زبان این بازار را یاد بگیرید. در ادامه مهمترین اصطلاحات را که در متون رقبا نیز به آنها اشاره شده بود، با دقت بیشتری تشریح میکنیم.
در این روش، هدف ما یافتن تنظیماتی است که سودآوری با ثبات و ریسک کنترلشده داشته باشند. ما نتایج را بر اساس ترکیبی از فاکتور سود و نسبت شارپ امتیازدهی میکنیم و هر نتیجهای که ریسک بالایی داشته باشد را فیلتر (حذف) میکنیم.
double OnTester()
{
// 1. دریافت آمارهای مورد نیاز
double profitFactor = TesterStatistics(STAT_PROFIT_FACTOR);
double sharpeRatio = TesterStatistics(STAT_SHARPE_RATIO);
double equityDD = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
double trades = TesterStatistics(STAT_TRADES);
// 2. فیلتر کردن نتایج غیرقابل قبول (نتایج صفر میشوند)
if(trades < 50) return 0; // تعداد معاملات کم فاقد اعتبار است
if(profitFactor < 1.5) return 0; // فاکتور سود پایین رد میشود
if(equityDD > 20.0) return 0; // دراودان بالای 20% رد میشود
// 3. فرمول امتیازدهی
// امتیاز بر اساس ترکیب فاکتور سود و نسبت شارپ محاسبه میشود
double score = profitFactor * sharpeRatio;
return score;
}
در استراتژیهای شبکهای (Grid) یا مارتینگل، مهمترین فاکتور بقا و دوری از کال مارجین شدن است. بنابراین ما از سطح مارجین (Margin Level) به عنوان فاکتور اصلی ضریب اطمینان استفاده میکنیم.
double OnTester()
{
// 1. دریافت آمارها
double netProfit = TesterStatistics(STAT_PROFIT);
double minMargin = TesterStatistics(STAT_MIN_MARGINLEVEL);
double equityDD = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
double maxLoss = TesterStatistics(STAT_MAX_LOSSTRADE); // بزرگترین ضرر تکی
// 2. فیلترهای امنیتی سختگیرانه
if(netProfit <= 0) return 0; // زیاندهها حذف شوند
if(minMargin < 500) return 0; // اگر مارجین لول زیر 500% رفت، خطرناک است (امتیاز 0)
if(equityDD > 30.0) return 0; // دراودان بالای 30% برای مارتینگل خطرناک است
// 3. فرمول امتیازدهی
// پایه امتیاز سود است، اما با ضریب ایمنی مارجین تعدیل میشود
double score = netProfit;
// پاداش برای مارجین لول بالا (امنیت بیشتر = امتیاز بیشتر)
score = score * (minMargin / 1000.0);
// جریمه سنگین برای ریسک دراودان
score = score * (100.0 - equityDD) / 100.0;
return score;
}
پس از آنکه معیار سفارشی را در اکسپرتتان نوشتید، از طریق استراتژی تستر معیار Custom max را انتخاب کنید و بهینه سازی را انجام دهید.

در این مقاله دیدیم که بهینهسازی یک ربات معاملهگر، بسیار فراتر از نگاه کردن به سود نهایی است. با استفاده از تابع OnTester و درک عمیق آمارهایی مثل دراودان، نسبت شارپ و فاکتور سود، شما ابزاری قدرتمند برای ساخت اکسپرتهای پایدار و قابل اعتماد در اختیار دارید. اکنون میتوانید معیارهای هوشمندانهای تعریف کنید که ربات شما را در شرایط مختلف بازار مقاومتر کند.
نکته مهم: بهینه سازی اکسپرت با استراتژی تستر زمانی مفید خواهد بود که استراتژیای که نوشتید پتانسیل سودآوری داشته باشید و شما باید ابتدا باید نوشتن اکسپرتهای سودده را یاد بگیرید و سپس بهینه سازی کنید.
در دوره جامع اکسپرت نویسی با هوش مصنوعی، انواع استراتژیهای پرایساکشن، ایچیموکو و انواع اندیکاتورهای خوب را یاد میگیرید. و در این دوره علاوه بر استراتژیهای خوب انواع روش مدیریت سرمایه و روشهایی مثل مارتینگل، هجینگ و زون ریکاوری و … که کمک میکنه به سوددهی نیز یاد خواهید گرفت.
برای شروع میتوانید فصل اول که دوره مقدماتی اکسپرتنویسی است را به صورت رایگان از سایت دریافت کنید.
دراودان بالانس (Balance) فقط وقتی ضرر ثبت شود تغییر میکند، اما دراودان اکوئیتی (Equity) ضرر معاملات باز را هم لحظهبهلحظه حساب میکند. برای سنجش واقعی ریسک ربات، همیشه باید به Equity Drawdown نگاه کنید، چون ممکن است حساب در ضرر سنگین باشد اما چون معامله بسته نشده، بالانس تغییری نکرده باشد.
نسبت شارپ فقط به سود نگاه نمیکند، بلکه نوسانات سود را هم میسنجد. اگر سود شما نوسان زیادی داشته باشد یا ریسک بالایی برای کسب سود کم تحمل کرده باشید، این عدد منفی یا نزدیک به صفر میشود. نسبت شارپ زیر ۱ معمولاً نشانه خوبی نیست.
باید از تابع OnTester استفاده کنید. در این تابع شرط بگذارید که اگر STAT_EQUITY_DDREL_PERCENT بیشتر از ۲۰ بود، تابع مقدار صفر را برگرداند. این کار باعث میشود متاتریدر آن تنظیمات را در بهینهسازی نادیده بگیرد.
در حالت ایدهآل، فاکتور سود بالای ۲ عالی است. اما اگر استراتژی شما اسکالپ با تعداد معاملات بالاست، فاکتور سود ۱.۵ هم قابل قبول است. فاکتور سود زیر ۱ یعنی استراتژی ضررده است.
خیر، تاثیر آن بسیار ناچیز است. این تابع فقط یکبار در انتهای هر پاس اجرا میشود و محاسبات سنگینی ندارد. پس نگران کند شدن بهینهسازی نباشید.
اگر رباتی در یک سال فقط ۱۰ معامله کرده و سود خوبی داده، ممکن است کاملاً شانسی باشد. اما اگر همان سود را با ۱۰۰ یا ۲۰۰ معامله به دست آورده باشد، یعنی استراتژی ثبات دارد. معمولاً زیر ۵۰ معامله از نظر آماری قابل اعتماد نیست.
وقتی شما تابع OnTester را در کد اکسپرت خود مینویسید، باید در تنظیمات Strategy Tester گزینه Optimization Criterion را روی Custom max قرار دهید. این کار به متاتریدر میگوید که به جای سود یا بالانس، عددی که شما محاسبه کردهاید را معیار بهتر بودن قرار دهد.