🚀 بهترین برنامه نویس و طراح ربات معامله گر فارکس و سفارش ربات و اکسپرت معامله گر متاتریدر به زبان MQL4 و MQL5 | متااکسپرت

شمارش معاملات باز در Expert Advisor

شمارش معاملات باز در Expert Advisor

طراحی یک اکسپرت ادوایزر (Expert Advisor) موفق که قادر به خودکارسازی استراتژی‌های معاملاتی در پلتفرم متاتریدر (MetaTrader) باشد، مستلزم درک عمیقی از جنبه‌های فنی پلتفرم و منطق مدیریت معاملات است. در قلب هر استر‍اتژی هوشمند، توانایی شمارش معاملات باز (Counting Open Trades) و اتخاذ تصمیمات مبتنی بر وضعیت فعلی بازار و پرتفوی قرار دارد. این فرآیند، که در نگاه اول ساده به نظر می‌رسد، در واقع یکی از پایه‌ای‌ترین و در عین حال حیاتی‌ترین بخش‌های توسعه یک ربات معاملاتی قابل اعتماد و پایدار است. شمارش دقیق معاملات باز، تنها محدود به دانستن تعداد کلی پوزیشن‌ها (Positions) نیست، بلکه شامل فیلتر کردن و گروه‌بندی آن‌ها بر اساس معیارهای مختلف مانند نماد، نوع معامله، شناسه اختصاصی و زمان باز شدن است. این قابلیت، سنگ بنای پیاده‌سازی منطق‌های شرطی پیشرفته، مدیریت ریسک (Risk Management) چندلایه، کنترل حجم معاملات، و جلوگیری از باز شدن معاملات اضافی در شرایط نامطلوب می‌باشد.

عدم توجه کافی به مکانیسم صحیح شمارش معاملات، می‌تواند منجر به اشتباهات فاجعه‌باری شود. یک اکسپرت ممکن است به جای یک معامله، ده‌ها معامله همزمان بر روی یک نماد باز کند، یا قادر به تشخیص موقعیت‌های خود برای مدیریت آن‌ها (مثل حرکت حد ضرر به نقطه سر به سر یا بستن بخشی از معامله) نباشد. چنین مشکلاتی نه تنها سود بالقوه را از بین می‌برد، بلکه می‌تواند حساب معاملاتی را در معرض ریسک‌های غیرمنتظره و بزرگ قرار دهد. بنابراین، تسلط بر روش‌های شمارش معاملات باز، تنها یک مهارت برنامه‌نویسی نیست، بلکه یک ضرورت برای هر توسعه‌دهنده‌ای است که قصد دارد سیستم‌های معاملاتی اتوماتیک با قابلیت اطمینان بالا ایجاد کند. این مقاله به صورت عمیق و کاربردی به بررسی این مفهوم کلیدی، تفاوت‌های آن در MQL4 و MQL5، روش‌های پیاده‌سازی، اشتباهات متداول و سناریوهای کاربردی می‌پردازد.

درک ساختار داده‌ای معاملات در متاتریدر

پیش از پرداختن به روش‌های شمارش، لازم است ساختار و تفاوت‌های بنیادین بین دو پلتفرم متاتریدر ۴ و ۵ درک شود. این تفاوت‌ها مستقیماً بر روی توابع و منطق مورد نیاز برای شمارش معاملات تأثیر می‌گذارند. در MQL4 مفهوم اصلی، Order Ticket است. هر درخواست معاملاتی، چه باز شده باشد و چه در حال انتظار، به عنوان یک «آردر» شناخته می‌شود. زمانی که یک معامله واقعی باز می‌شود، همچنان یک آردر در نظر گرفته می‌شود که وضعیت آن به «باز» تغییر کرده است. بنابراین، در MT4 برای بررسی معاملات باز، باید بین آردرهای در حال انتظار (pending orders) و آردرهای باز شده (market orders که اکنون positions هستند) تمایز قائل شد.

در مقابل، MQL5 این مفاهیم را به صورت مجزا تعریف کرده است. در این پلتفرم، Position به معامله‌ای اشاره دارد که در حال حاضر در بازار باز است و Order به درخواست‌های در حال انتظار (مانند Limit یا Stop) اختصاص دارد. این جداسازی مفهومی، باعث شفافیت بیشتر و ساده‌تر شدن برخی از عملیات‌ها می‌شود. برای شمارش معاملات باز در MQL5، ما مستقیماً با پوزیشن‌ها (Positions) سروکار داریم و نیازی به فیلتر کردن آردرها از نظر وضعیت نیست. این تفاوت بنیادی نیازمند استفاده از مجموعه توابع کاملاً متفاوتی در دو محیط برنامه‌نویسی است. در MQL4 از توابعی مانند OrdersTotal() و OrderSelect() استفاده می‌شود، در حالی که در MQL5 توابع PositionsTotal() و PositionGetTicket() نقش اصلی را ایفا می‌کنند.

یک مفهوم مشترک و بسیار مهم در هر دو پلتفرم، Magic Number است. این یک عدد صحیح و شناسه‌ای منحصر به فرد است که توسط برنامه‌نویس به هر معامله‌ای که اکسپرت باز می‌کند، اختصاص داده می‌شود. هدف اصلی آن، ایجاد تمایز بین معاملات باز شده توسط اکسپرت‌های مختلف یا حتی توسط استراتژی‌های مختلف درون یک اکسپرت است. هنگام شمارش معاملات، می‌توانیم فقط آن دسته از معاملاتی را در نظر بگیریم که Magic Number مطابق با عدد تعریف شده در اکسپرت ما را دارند. این امر مانع از تداخل اکسپرت‌ها و مدیریت ناخواسته معاملات دیگر می‌شود و امکان کار همزمان چندین ربات بر روی یک حساب را فراهم می‌آورد.

روش‌های بنیادین شمارش معاملات باز در MQL4

در MQL4، شمارش معاملات باز نیازمند پیمایش (Iteration) بین همه آردرهای موجود و بررسی شرایط هر یک است. تابع OrdersTotal() تعداد کل آردرها (شامل معاملات باز و در حال انتظار) را برمی‌گرداند. سپس با استفاده از یک حلقه، هر آردر به کمک OrderSelect() انتخاب شده و ویژگی‌های آن بررسی می‌شود. برای تشخیص اینکه آیا این آردر یک معامله باز است یا خیر، باید دو شرط اصلی را چک کرد: اول اینکه نوع آردر (OrderType()) باید یکی از انواع معاملات باز بازار باشد (یعنی OP_BUY یا OP_SELL). دوم اینکه نماد آردر (OrderSymbol()) باید با نماد جاری نمودار (یا نماد مورد نظر ما) مطابقت داشته باشد. این پایه‌ای‌ترین شکل شمارش است.

اما شمارش مؤثر اغلب نیازمند فیلترهای پیشرفته‌تر است. فیلتر بر اساس Magic Number حیاتی است. پس از انتخاب هر آردر، مقدار OrderMagicNumber() با عدد جادویی تعریف شده در اکسپرت مقایسه می‌شود. فقط در صورت تطابق، این معامله متعلق به اکسپرت ما محسوب می‌شود. این مکانیسم به ما اجازه می‌دهد تا در محیطی که چندین اکسپرت فعال هستند، فقط معاملات مربوط به خود را مدیریت کنیم. یک نمونه شبه‌کد (Pseudocode) برای شمارش معاملات باز یک اکسپرت خاص بر روی نماد جاری در MQL4 به صورت زیر است:

تعریف متغیر count = 0
تعریف متغیر myMagic = 123456

برای i از 0 تا OrdersTotal()-1:
    اگر OrderSelect(i, SELECT_BY_POS):
        اگر OrderSymbol() == Symbol() و (OrderType() == OP_BUY یا OrderType() == OP_SELL) و OrderMagicNumber() == myMagic:
            count = count + 1

این شبه‌کد، هسته اصلی بیشتر توابع شمارش در MQL4 را تشکیل می‌دهد. با گسترش این منطق، می‌توانیم معاملات خرید و فروش را به طور جداگانه شمارش کنیم، یا حجم کل معاملات باز (OrderLots()) را جمع‌آوری کنیم که برای محاسبه ریسک کلی پرتفوی بسیار مفید است.

روش‌های بنیادین شمارش معاملات باز در MQL5

رویکرد MQL5 به دلیل تفاوت ساختاری، مستقیم‌تر است. تابع PositionsTotal() تعداد کل پوزیشن‌های باز در حساب را برمی‌گرداند (صرف نظر از نماد یا Magic Number). مشابه MQL4، یک حلقه برای پیمایش بین این پوزیشن‌ها ایجاد می‌کنیم. اما به جای OrderSelect()، از PositionGetTicket(i) برای دریافت شناسه (Ticket) پوزیشن و سپس PositionGetSymbol(i) یا توابع مشابه برای استخراج اطلاعات آن استفاده می‌کنیم. در MQL5، هر پوزیشن از ابتدا متعلق به یک نماد خاص است و نوع آن (POSITION_TYPE_BUY یا POSITION_TYPE_SELL) مشخص است. همچنین، ویژگی Magic Number با استفاده از PositionGetInteger(POSITION_MAGIC) قابل دسترسی است.

شفافیت این مدل باعث می‌شود کد کم‌تر در معرض خطا باشد. شبه‌کد معادل برای شمارش معاملات باز یک اکسپرت خاص بر روی نماد جاری در MQL5 به صورت زیر است:

تعریف متغیر count = 0
تعریف متغیر myMagic = 123456

برای i از 0 تا PositionsTotal()-1:
    شناسه = PositionGetTicket(i)
    اگر شناسه > 0:
        اگر PositionGetString(POSITION_SYMBOL) == _Symbol و PositionGetInteger(POSITION_MAGIC) == myMagic:
            count = count + 1

همانطور که مشاهده می‌شود، نیازی به بررسی نوع برای تشخیص معامله باز از معامله در حال انتظار نیست، چرا که PositionsTotal() فقط شامل معاملات باز است. این امر منطق شرطی را ساده‌تر می‌کند.

فیلترهای پیشرفته و سناریوهای کاربردی شمارش

یک اکسپرت حرفه‌ای، تنها به شمارش کلی معاملات اکتفا نمی‌کند. بلکه بر اساس نیاز استراتژی، از فیلترهای ترکیبی مختلفی برای درک دقیق‌تر وضعیت بازار استفاده می‌کند. این فیلترها پایه مدیریت معاملات (Trade Management) هوشمند را تشکیل می‌دهند.

شمارش بر اساس نماد (Symbol)

حتی اگر اکسپرت بر روی یک نمودار خاص اجرا شود، ممکن است بخواهیم وضعیت معاملات را در نمادهای دیگر نیز بررسی کنیم. این برای استراتژی‌های مبتنی بر همبستگی (Correlation) یا مدیریت پرتفوی چندنماده ضروری است. در این حالت، به جای مقایسه با Symbol() یا _Symbol، نام نماد مورد نظر را مستقیماً در شرط وارد می‌کنیم. این امکان بررسی شرایطی مانند «اگر در نماد EURUSD معامله بازی ندارم، مجاز به باز کردن معامله در نماد GBPUSD باشم» را فراهم می‌آورد.

شمارش بر اساس نوع معامله (Type)

جدا کردن تعداد معاملات خرید از فروش می‌تواند برای استراتژی‌های جهت‌گیر (Directional) یا تشخیص حالت‌های خنثی (Flat) حیاتی باشد. مثلاً ممکن است استراتژی اجازه دهد حداکثر دو معامله خرید همزمان فعال باشد، اما اگر معامله فروش جدیدی سیگنال شود، بسته شود. یا در یک استراتژی هج (Hedge)، تعداد خرید و فروش‌ها برای تشخیص اندازه هج مورد محاسبه قرار گیرد. این شمارش با افزودن شرط OrderType() == OP_BUY یا PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY در حلقه پیمایش انجام می‌پذیرد.

شمارش بر اساس Magic Number (چند استراتژی)

این قدرتمندترین فیلتر برای طراحی اکسپرت‌های چند استراتژی (Multi-Strategy) است. فرض کنید یک اکسپرت داریم که سه استراتژی مستقل را بر روی یک جفت ارز اجرا می‌کند. به هر استراتژی یک Magic Number منحصر به فرد اختصاص می‌دهیم (مثلاً ۱۰۰۱، ۱۰۰۲، ۱۰۰۳). اکنون می‌توانیم به راحتی معاملات هر استراتژی را جداگانه شمارش و مدیریت کنیم. این کار باعث می‌شود تنظیمات هر استراتژی (مانند حجم معامله، توقف ضرر، حد سود) کاملاً مستقل از دیگری اعمال شود. همچنین، امکان غیرفعال کردن موقت یک استراتژی بدون تأثیر بر استراتژی‌های دیگر وجود خواهد داشت. در این سناریو، شمارش معاملات برای هر Magic Number به صورت جداگانه انجام می‌شود و تصمیم‌گیری‌های شرطی بر اساس آن اعداد خاص صورت می‌گیرد.

شمارش بر اساس زمان (Time)

گاهی اوقات لازم است معاملات باز شده در یک بازه زمانی خاص (مثلاً در طول روز جاری، یا در طول آخرین ساعت) را شمارش کنیم. این برای محدود کردن فرکانس معاملات (مثلاً حداکثر ۵ معامله در روز) یا اجرای استراتژی‌های وابسته به زمان مفید است. در این حالت، زمان باز شدن معامله (OrderOpenTime() در MQL4 یا PositionGetInteger(POSITION_TIME) در MQL5) با زمان فعلی مقایسه می‌شود. تنها معاملاتی که زمان باز شدن آن‌ها در بازه مورد نظر قرار دارد، در شمارش لحاظ می‌شوند. پیاده‌سازی این فیلتر نیازمند کار با توابع زمانی در MQL است.

تأثیر شمارش معاملات بر مدیریت سرمایه و ریسک

شمارش معاملات باز، جزئی جدایی‌ناپذیر از یک سیستم مدیریت ریسک (Risk Management) قوی است. بدون دانستن تعداد و حجم معاملات فعال، محاسبه ریسک مواجهه (Exposure) حساب غیرممکن است. یک قاعده رایج در مدیریت سرمایه، محدود کردن حداکثر تعداد معاملات همزمان یا حداکثر حجم کلی در باز است. برای مثال، یک اکسپرت ممکن است این قانون را داشته باشد: «هیچگاه بیش از ۳ معامله باز در کل حساب وجود نداشته باشد» یا «حجم کل معاملات باز بر روی جفت ارز X از ۵ لات تجاوز نکند». پیاده‌سازی چنین قوانینی مستلزم شمارش دقیق و لحظه‌ای معاملات است.

محاسبه ریسک بر اساس درصد حساب نیز به شمارش وابسته است. فرض کنید حداکثر ریسک مجاز در هر معامله ۲٪ از موجودی حساب باشد. اکسپرت قبل از باز کردن هر معامله جدید، باید کل ریسک موجود از معاملات باز فعلی را محاسبه کند. این محاسبه نیازمند دانستن تعداد معاملات باز، حجم هر کدام، و فاصله قیمت فعلی تا حد ضرر آن‌ها است. اگر ریسک تجمعی از یک آستانه مشخص (مثلاً ۵٪) بیشتر شده باشد، اکسپرت باید از باز کردن معامله جدید خودداری کند، حتی اگر سیگنال معاملاتی صادر شده باشد. این سطح از مدیریت ریسک پویا، بدون توانایی شمارش و تجزیه‌وتحلیل معاملات باز، غیرقابل دستیابی است.

علاوه بر این، شمارش معاملات برای استراتژی‌های مارتینگل یا پیرامیدسازی (Pyramiding) که در آن‌ها با افزایش تعداد معاملات باز، حجم معامله جدید تغییر می‌کند، ضروری است. در این استراتژی‌ها، شمارش دقیق تعیین می‌کند که معامله جدید در کدام مرحله از دنباله قرار دارد و حجم آن باید چقدر باشد.

اشتباهات رایج برنامه‌نویسان در شمارش معاملات

بسیاری از خطاها و رفتارهای غیرمنتظره در اکسپرت‌ها ریشه در اشتباهات ظریف در منطق شمارش معاملات دارد. یکی از رایج‌ترین این اشتباهات، عدم ریست (Reset) صحیح شمارنده‌ها در هر تیک جدید است. متغیر شمارنده باید در ابتدای هر بار اجرای تابع OnTick() یا بلوک محاسباتی اصلی، به صفر بازنشانی شود و سپس با پیمایش مجدد معاملات، مقداردهی گردد. اگر این کار انجام نشود، مقدار از تیک قبلی باقی می‌ماند و منجر به شمارش اشتباه می‌شود.

اشتباه دیگر، استفاده نادرست از OrdersTotal() در MQL4 بدون فیلتر کردن نوع معامله است. همانطور که گفته شد، این تابع هم معاملات باز و هم آردرهای در حال انتظار را برمی‌گرداند. اگر برنامه‌نویس تنها این تابع را چک کند، ممکن است فکر کند یک معامله باز وجود دارد در حالی که آن آردر، یک دستور معلق است. این می‌تواند باعث شود اکسپرت از باز کردن معامله جدید خودداری کند، در حالی که در واقع ظرفیت خالی وجود دارد.

نادیده گرفتن Magic Number نیز یک خطای فاحش است. اگر اکسپرت بدون بررسی Magic Number اقدام به بستن یا مدیریت معاملات کند، ممکن است معاملات باز شده توسط اکسپرت‌های دیگر، اسکریپت‌ها، یا حتی معاملات دستی کاربر را دستکاری کند. این رفتار کاملاً غیرقابل قبول و خطرناک است.

در MQL5، یک اشتباه رایج، فرض بر این است که ایندکس (i) در حلقه for، همان شناسه (Ticket) پوزیشن است. در حالی که ایندکس فقط شماره موقعیت در لیست داخلی است و شناسه واقعی باید با PositionGetTicket(i) دریافت شود. استفاده مستقیم از i در توابع PositionGet... باعث خطا می‌شود.

همچنین، برخی برنامه‌نویسان برای بهینه‌سازی، شمارش معاملات را تنها در شرایط خاصی انجام می‌دهند، اما وضعیت معاملات می‌تواند توسط عوامل خارجی (مانند بستن دستی توسط کاربر یا رسیدن به حد سود/ضرر) تغییر کند. بنابراین، بهتر است شمارش در هر تیک یا حداقل قبل از هر تصمیم مهم معاملاتی مجدداً انجام شود تا از سنکرون بودن اطلاعات با واقعیت اطمینان حاصل گردد.

بهینه‌سازی عملکرد اکسپرت در شمارش معاملات

پیمایش کل لیست معاملات در هر تیک (که می‌تواند ده‌ها یا صدها بار در ثانیه رخ دهد) می‌تواند از نظر محاسباتی پرهزینه باشد، به ویژه اگر حساب دارای تعداد زیادی معامله باز باشد. برای اکسپرت‌های با فرکانس بالا (HFT) یا اکسپرت‌هایی که روی چندین نمودار همزمان اجرا می‌شوند، این موضوع می‌تواند باعث کندی سیستم شود. راه‌های متعددی برای بهینه‌سازی این فرآیند وجود دارد.

اولین و ساده‌ترین روش، محدود کردن دفعات شمارش است. به جای شمارش در هر تیک، می‌توان این کار را فقط در ابتدای یک کندل جدید (بر اساس NewBar())، یا هر چند ثانیه یکبار (با استفاده از GetTickCount()) انجام داد. البته این روش باید با دقت انجام شود تا از دست دادن رویدادهای مهم (مانند پر شدن یک دستور معلق) را به همراه نداشته باشد.

روش دیگر، ذخیره‌سازی نتایج شمارش در متغیرهای سراسری (Global Variables) یا متغیرهای استاتیک (Static Variables) است. هنگامی که یک معامله باز یا بسته می‌شود، یک رویداد (OnTrade() در MQL5 یا OnTradeTransaction() و بررسی دستی در MQL4) رخ می‌دهد. می‌توان در این رویدادها، شمارنده‌ها را به‌روزرسانی کرد. بدین ترتیب، در تیک‌های عادی، به جای پیمایش کامل، فقط مقدار از پیش محاسبه‌شده خوانده می‌شود که بسیار سریع‌تر است. این روش نیازمند مدیریت دقیق حالت‌ها و اطمینان از همگام‌سازی کامل رویدادهای معاملاتی با متغیرهای ذخیره‌شده است.

همچنین، می‌توان حلقه پیمایش را به محض یافتن شرط مورد نظر شکست (Break). مثلاً اگر تنها نیاز به دانستن این داریم که «آیا حداقل یک معامله باز با Magic Number مشخص وجود دارد؟»، به محض یافتن اولین معامله، می‌توانیم حلقه را متوقف کنیم و از بررسی بقیه معاملات صرف‌نظر کنیم. این کار باعث صرفه‌جویی در زمان در حساب‌های با معاملات زیاد می‌شود.

استفاده از ساختارهای داده‌ای مانند آرایه‌ها برای نگهداری شناسه (Ticket) معاملات متعلق به اکسپرت نیز یک روش پیشرفته است. با به‌روزرسانی این لیست در رویدادهای معاملاتی، دسترسی سریع‌تری به معاملات خود خواهیم داشت.

نکات پیشرفته برای اکسپرت‌های چند استراتژی

طراحی یک اکسپرت که بتواند چندین استراتژی را به صورت موازی و مستقل اجرا کند، اوج هنر برنامه‌نویسی اکسپرت ادوایزر (Expert Advisor) است. در چنین سیستمی، شمارش معاملات نقش مرکزی ایفا می‌کند. هر استراتژی باید بتواند وضعیت معاملات خود را بدون تداخل با دیگران، رصد کند. کلید این کار، همانطور که پیش‌تر اشاره شد، اختصاص Magic Number منحصر به فرد به هر استراتژی است. اما فراتر از آن، باید ساختار کد به گونه‌ای طراحی شود که هر استراتژی ماژولار و مستقل باشد.

یک رویکرد خوب، ایجاد یک کلاس یا ساختار (struct) برای هر استراتژی است که درون آن، پارامترهای اختصاصی (شامل Magic Number، تنظیمات حجم، پارامترهای اندیکاتور و …) و توابع عضو (مانند تابع بررسی سیگنال، تابع مدیریت ریسک و تابع شمارش معاملات آن استراتژی) تعریف شده باشد. تابع شمارش درون این کلاس، تنها معاملاتی را می‌شمارد که Magic Number آن برابر با مقدار اختصاص داده شده به کلاس باشد. بدین ترتیب، هر استراتژی به طور کامل از جزئیات استراتژی‌های دیگر جدا می‌شود.

در سطح اکسپرت اصلی، یک آرایه یا لیست از این استراتژی‌ها نگهداری می‌شود. در تیک اصلی، یک حلقه روی تمام استراتژی‌ها اجرا می‌شود و برای هر کدام، ابتدا وضعیت معاملات باز آن شمارش و تحلیل می‌شود، سپس بر اساس آن، تصمیم به باز کردن، بستن یا مدیریت معاملات گرفته می‌شود. این معماری همچنین امکان تخصیص منابع (مثلاً حداکثر تعداد معاملات کل بین استراتژی‌ها) را فراهم می‌کند. برای مثال، اکسپرت می‌تواند یک محدودیت سراسری ۱۰ معامله داشته باشد و بین ۴ استراتژی به صورت عادلانه یا بر اساس اولویت توزیع کند.

همچنین، در اکسپرت‌های چند استراتژی، ممکن است نیاز به شمارش معاملات بر اساس گروه‌های Magic Number باشد. به عنوان مثال، دو استراتژی مختلف ممکن است برای معاملات کوتاه‌مدت و بلندمدت بر روی یک نماد طراحی شده باشند. در این صورت، می‌توان یک محدوده اعداد جادویی برای هر گروه در نظر گرفت (مثلاً ۲۰۰۰-۲۰۹۹ برای استراتژی کوتاه‌مدت و ۳۰۰۰-۳۰۹۹ برای بلندمدت). تابع شمارش می‌تواند با بررسی اینکه Magic Number در کدام بازه قرار دارد، معاملات را گروه‌بندی کند.

مثال‌های مفهومی و شبه‌کد جامع

برای درک بهتر نحوه ادغام شمارش معاملات در منطق یک اکسپرت، به چند سناریوی مفهومی و شبه‌کد آن‌ها می‌پردازیم. این مثال‌ها بدون در نظر گرفتن جزئیات پیاده‌سازی کامل یک زبان خاص، منطق کلی را نمایش می‌دهند.

سناریوی ۱: محدود کردن حداکثر معاملات همزمان بر روی یک نماد.

تعریف myMagic = 5555
تعریف maxTrades = 2

تابع شمارش معاملات فعال روی نماد جاری():
    count = 0
    برای هر معامله باز در حساب:
        اگر معامله.نماد == نماد جاری و معامله.Magic == myMagic:
            count = count + 1
    برگرداندن count

در تیک اصلی:
    currentCount = شمارش معاملات فعال روی نماد جاری()
    اگر سیگنال خرید صادر شده و currentCount < maxTrades:
        باز کردن معامله خرید با حجم استاندارد و Magic = myMagic

سناریوی ۲: مدیریت ریسک تجمعی.

تعریف myMagic = 7777
تعریف maxTotalRiskPercent = 5.0 // حداکثر ریسک کل ۵٪

تابع محاسبه ریسک تجمعی():
    totalRisk = 0.0
    برای هر معامله باز در حساب:
        اگر معامله.Magic == myMagic:
            حجم = معامله.حجم
            فاصله تا استاپ = قدرمطلق(معامله.قیمت باز - معامله.استاپ لاس)
            ارزش هر پیپ = (مقدار پولی تغییر با یک پیپ)
            ریسک این معامله = فاصله تا استاپ * ارزش هر پیپ
            totalRisk = totalRisk + ریسک این معامله
    برگرداندن (totalRisk / موجودی حساب) * 100

در تیک اصلی:
    ریسک جاری = محاسبه ریسک تجمعی()
    اگر سیگنال فروش صادر شده و ریسک جاری < maxTotalRiskPercent:
        باز کردن معامله فروش

سناریوی ۳: اکسپرت دو استراتژی با Magic Number های مختلف.

تعریف magicStrategyA = 1001
تعریف magicStrategyB = 2001
تعریف maxTradesPerStrategy = 3

تابع شمارش بر اساس Magic(magicNumber):
    count = 0
    برای هر معامله باز در حساب:
        اگر معامله.Magic == magicNumber:
            count = count + 1
    برگرداندن count

در تیک اصلی:
    countA = شمارش بر اساس Magic(magicStrategyA)
    countB = شمارش بر اساس Magic(magicStrategyB)

    // استراتژی A (مثلاً بر اساس شکست RSI)
    اگر شرایط استراتژی A برقرار و countA < maxTradesPerStrategy:
        باز کردن معامله با magicStrategyA

    // استراتژی B (مثلاً بر اساس میانگین متحرک)
    اگر شرایط استراتژی B برقرار و countB < maxTradesPerStrategy:
        باز کردن معامله با magicStrategyB

این شبه‌کدها نشان می‌دهند که چگونه شمارش معاملات باز، به یک جزء فعال و تصمیم‌ساز در جریان کار اکسپرت تبدیل می‌شود. پیاده‌سازی دقیق این منطق در MQL4 یا MQL5 مستلزم آگاهی از توابع خاص پلتفرم، مدیریت صحیح خطاها، و در نظر گرفتن موارد خاص (مانند حالت هج در حساب‌های مختلف) است. با این حال، درک مفهومی این اصول، پایه‌ای مستحکم برای خلق اکسپرت‌های پیچیده، ایمن و سودآور فراهم می‌کند.

دیدگاه‌ها (0)

  • نظرات نامربوط به محتوا تأیید نخواهند شد.
  • لطفاً از افزودن نظرات تکراری خودداری کنید.
  • نظرات مربوط به دوره‌ها فقط برای خریداران محصول است.

*
*