کامران کیانلو
کامران کیانلو
خواندن ۳ دقیقه·۲ سال پیش

میشه داخل یک اکسپرت MQL5 یک اندیکاتور DRAW کرد؟

امروز تقریبا چند ساعت درگیر این موضوع بودم که چرا وقتی می خوام داخل یک اکسپرت MQL5 یک اندیکاتور Draw کنم بهم خطای Array Out Of Range میده.

جالبیش اینجا بود که همین کد رو تو خود فایل اندیکاتور وقتی اجرا می کردم بدون مشکل بود ولی وقتی تنظیم می کردم که اندیکاتور رو تو فایل اکسپرت من Draw کنه خطای Array Out of range میداد.

باهاش یه 3 ساعتی ور رفتم تا چیزای خوبی دستگیرم شد و در نهایت راه حل مشکل رو پیدا کردم.

در بابت ++C و مصائب کار با آرایه داینامیک

خب MQL5 عملا از روی ++C ساخته شده و توی ++C (که یادش بخیر دوران دانشگاه کار می کردیم) یادمه که خیلی درباره مقدار دهی به آرایه های داینامیک بحث بود که حتما باید برای ریختن دیتا تو آرایه داینامیک با آدرسش تو حافظه کار می کردیم. یادمه قبل آرایه علامت & می ذاشتیم و سیستم خودش میرفت آدرس آرایه رو توی هارد پیدا می کرد و باهاش کار می کرد.

این داستان واقعا تو نگاه اول پیچیده بود و دو سه روزی باید خوب حالت های مختلف رو تست می کردی تا کاملا میشد درک کرد که چطور با آرایه داینامیک میشه تو ++C کار کرد.

حالا این چیزی که من فهمیدم اینه (یافته هام تا اینجاست - آپدیت شد تو همین پست میذارم)، توی MQL5 اومدن برای راحتی کار گفتن آقا جان، شما از آرایه که می خوای استفاده کنی کلا بیا و از همون اول استاتیک تعریفش کن یا اگر داینامیک تعریفش کردی اشکالی نداره که، با تابع ArrayResize اونو استاتیکش کن.

اینطوری کلا کاربر رو از درگیری های کار با آرایه داینامیک فارغ کردن و فقط یک جا لازمه که از آرایه Dynamic استفاده بشه و اون هم برای زمانیه که می خوایم یک اندیکاتور خودمون بسازیم. روالش هم اینطوری گفته انجام بدیم که :

  1. اول آرایه داینامیک بساز
  2. بعد با تابع SetIndexBuffer به من معرفیش کن که به عنوان بافر می خوای استفاده اش کنی
  3. بعدم که دیگه ولش کن غمت نباشه خودم حافظه اش رو مدیریت می کنم. تو فقط توش دیتا بریز امااا یه نکته مهم داره که من هم سر همین گیره بودم این 3 ساعت رو

تابع SetIndexBuffer همونطور که توی داکیومنت اصلی MQL5 هم اومده برای ساخت اندیکاتور ها استفاده میشه نه چیزی دیگه - درواقع ادیکتاتور رو به آرایه ما Bind می کنه.

حالا ما وقتی میایم و توی OnCalculate که مخصوص ساخت اندیکاتور هاست با آرایه داینامیک کار می کنیم هیچ مشکلی وجود نداره اما وقتی توی OnTick یا اصلا توی OnInit با آرایه داینامیک کار می کنیم بهمون خطای Array Out Of Range میده.

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


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

خیلی ساده و خلاصه میشه اینطوری پیش رفت

  • اندیکاتور مورد نظر خودمون رو خیلی خوشگل مشگلا به عنوان یک فایل اندیکاتور جدا بسازیم
  • تو قدم بعدی تو اکسپرت از طریق تابع ChartIndicatorAdd اندیکاتور مورد نظر خودمون رو به اکسپرت اضافه می کنیم. خیلی تمیز و شیک و مجلسی


الان در حال یادگیری MQL5 - کنجکاوی هام درباره برنامه نویسی رو اینجا می نویسم.
شاید از این پست‌ها خوشتان بیاید