مبانی اکسپرت نویسی در NTL+ | IFCM ایران
IFC Markets کارگزار CFD آنلاین

مبانی اکسپرت نویسی در NTL+

معرفی

این مقاله برای برنامه نویسانی است که قصد دارند اولین اکسپرت شان را در NTL+ بنویسند. این مقاله تعدادی از ویژگی های ایجاد اکسپرت ها را دربرمی گیرد که دانستن شان به دوری از بسیاری از اشتباهات کمک خواهد کرد و از اتلاف وقت در نوشتن اکسپرت جلوگیری و اشکالات اسکریپت را برطرف می کند (اسکریپت در زبان برنامه نویسی NTL+ اشاره به سه نوع برنامه دارد: اکسپرت ها، شاخص ها و برنامه های سودمند).


ایجاد یک اکسپرت

برای ایجاد یک اکسپرت جدید، ابتدا به پنجرۀ "ناوبری" (Navigator) بروید، سپس روی پوشۀ برنامه های مشاور (Advisors) راست-کلیک کنید و از فهرست زمینه، عملکرد "ایجاد" (Create) را انتخاب نمایید. در اینجا از شما خواسته می شود تا اسمی را برای اکسپرت جدید درج کنید. لطفاً توجه داشته باشید که اسم اکسپرت باید منطبق با استانداردهای نامگذاری در OS Windows باشد یعنی یک اسم نمی تواند شامل علائمی نظیر * | \ : " < > ? / گردد.


بعد از آنکه فایل اکسپرت جدید ایجاد شد، اولین قالب را با 3 عملکرد Initialize() ، Run() ، DeInitialize() مشاهده خواهید کرد. هرکدام از این عملکردها در زمان های مشخصی از عمر اکسپرت اجرا می شوند. بنابراین، برنامه نویس نیازی ندارد که آنها را فرابخواند چراکه روند خودکار است.


بلافاصله پس از شروع اکسپرت، عملکرد Initialize() اجرا می شود که برای مقدار دهی اولیه در نظر گرفته شده است. لازم به ذکر است که عملیات معاملاتی نباید در عملکرد Initialize() اجرا شوند چراکه مقادیر پارامترهای معاملاتی (نظیر قیمت های Ask و Bid، اطلاعات حساب، اطلاعات مربوط به دستورها و پوزیشن های معاملاتی) در زمان اجرای Initialize() تعیین نمی شوند.


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


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


آماده کردن یک الگوریتم و نوشتن یک کد اکسپرت

توسعۀ یک الگوریتم که اکسپرت معاملاتی تان را اجرا کند، اولین مرحله است. این الگوریتم باید ساختاری شفاف و توضیحاتی با جزئیات کامل داشته باشد که اشکالزدایی، ویرایش و بهینه سازی بیشتر را آسان تر نماید.


تعیین معیارهای معاملاتی برای بازکردن پوزیشن های خرید یا فروش، اینکه تحت چه شرایطی پوزیشن های معاملاتی بسته شوند و اینکه تعداد پوزیشن های معاملاتی باز چطور کنترل یا محدود خواهند شد، ضروری است. اگر اکسپرت تان قرار است دستورهای در حال انتظار (pending order) شامل دستورهای OCO و دستورهای فعال سازی را اجرا کند باید ابتدا به امکان حذف یا ویرایش دستورهایی که تاکنون برقرار شده اند توجه کنید.


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


به دخالت های دستی خودتان در عملکرد یک اکسپرت توجه داشته باشید، چه می شود اگر اکسپرت یک معامله را باز کند و شما آن را در ترمینال تجاری ببندید؟ به این موضوع توجه داشته باشید که آیا اکسپرت می تواند وارد هرگونه وضعیت غیر برنامه ریزی شده ای شود که منجر به از کار افتادن اکسپرت گردد.


شما برای دستیابی به یک عملکرد مناسب باید وضعیت معاملات باز و دستورهای واقع شده را در کوچکترین علائم تحلیل کنید. Deals.Total و Orders.Total مشخصه هایی هستند که برای تعداد پوزیشن های معاملاتی باز و دستورهای واقع شده استفاده می شوند و روش های Orders.Select() و Deals.Select() برای انتخاب یک پوزیشن یا یک دستور بکار می روند.


همچنین لازم است به به بهبود کار اکسپرت پس از بستن و باز کردن ترمینال توجه شود: حتی اگر به همان وضعیتی برگردد که پیش از بستن ترمینال داشت. شرایطی را در نظر داشته باشید که در آنها بین بستن و بازکردن مجدد ترمینال برخی از معاملات می توانند توسط توقف ضرر (S/L) یا کسب سود (T/P) از پیش تنظیم شده بسته شوند و دستورهایی که می توانند فعال شوند که شامل بازشدن پوزیشن های معاملاتی جدید خواهند بود.


باید اقدامات لازم در زمان وقوع ایرادات و وضعیت های استاندارد را پیش بینی کنید. به عنوان مثال، کافی نبودن موجودی حساب برای باز کردن پوزیشن های معاملاتی یا تلاش برای ثبت دستورهایی که بسیار به قیمت جاری بازار نزدیک هستند.


از طریق شیء "حساب" (Account) و مشخصاتش می توان به وضعیت حساب دسترسی پیدا کرد. بطور مثال، از مشخصۀ Account.Balance برای دسترسی به موجودی کنونی حساب استفاده می شود و از مشخصۀ Account.MarginFree برای دسترسی به میزان مارجین آزاد استفاده می شود.


int Run() { // initialize a variable "volume" – the volume set in base currency int volume = 10000; if(Account.MarginFree < volume/Account.Leverage) return -1; }

توجه داشته باشید که خط return -1 ، اجرای این عامل، به اجبار اکسپرت را متوقف می کند.


کار با تاریخچۀ قیمت ها

استفاده از رشته های زمانی به شما اجازه می دهد تا به منظور تحلیل یک وضعیت معین بازار در گذشته، تاریخچۀ قیمت ها روی نمادهای جاری را دریافت کنید. رشته های زمانی نمایانگر یک گروه از آرایه ها است: Open[] - باز شدن میلۀ قیمت ها، Close[] - بسته شدن میلۀ قیمت ها، High[] بالاترین میلۀ قیمت ها، Low[] - پایین ترین میلۀ قیمت ها، Time[] - زمان باز شدن میله و Volume[] - کوچکترین حجم میله (تعداد حجم ها در هر میله). تمامی رشته های زمانی در ارتباط با نمودار نماد هستند که در آن اکسپرت در حال اجرا شدن است و چهارچوب زمانی جاری. رشته های زمانی، شاخص گذاری وارونه دارند: عنصر آخر (آخر در شرایط زمان) یک 0 index دارد و اولین عنصر - شاخصی دارد برابر با Bars.Total(Chart.Symbol,Chart.Interval)-1.


هرگاه لازم نیست که از دیگر سمبل ها، اطلاعاتی کسب شود، باید از شیء "میله ها" (Bars) استفادده کنید. روش هایش از قبیل Open()، High()، Low() ، Close() ، Volume() ، Time() همانند روش های رشته های زمانی مرتبط هستند. تنها تفاوت در این است که شما باید نماد، اندازۀ میله (فواصل، چهارچوب زمانی) و تعداد میله ای که می خواهید مقادیر را برایش دریافت کنید را تعیین نمایید. پیش از اجرای یک اسکریپت، باید تمامی نمادهایی که اسکریپت باید با آنها کار کند را ثبت کنید. برای این منظور، ابتدا پنجرۀ "قیمت های جاری" (MarketWatch) را باز کنید، سپس روی یک کادر خالی راست-کلیک کنید و از فهرست زمینه گزینۀ "ثبت" (Subscribe) را انتخاب کنید. سپس روی نماد دلخواه تان کلیک و "OK" را بزنید.


شما در اکسپرت ها ممکن است نیاز پیدا کنید که زمان باز شدن یک میلۀ جدید یا زمان تکمیل ایجاد یک میلۀ قبلی را تعیین کنید. برای این منظور می توانید از آرایۀ جهانی "حجم" () استفاده نمایید. مقدار Volume[0] توسط یک در هر کوچکترین نوسان (تیک) افزایش پیدا می کند و پس از اولین کوچکترین نوسان (تیک) در یک میلۀ جدید به 1 مجدداً برمی گردد. بنابراین، برای تعیین لحظۀ باز شدن یک میلۀ جدید، می توان از ساختار زیر استفاده کرد:


int Run() { if(Volume[0]==1) { // Some code to run whe opening a new bar. } }

کار Run() می تواند با استفاده از عملگر return برای تمام مقادیر Volume[0] به غیر از 1، به راحتی تمام شود:


int Run() { if(Volume[0]>1) return (0); // Some code to run whe opening a new bar. }

روش جایگزین دیگر، تحلیل میلۀ زمان باز شدن است البته به شرطی که زمان برای دو حداقل نوسان آخر مطابقت داشته باشد، شما می توانید با استفاده از عملگر return(0) از این عملکرد خارج شوید. در زمان ایجاد یک میلۀ جدید، مقادیر متفاوتی برای Time[0] روی حداقل نوسان های (تیک) جاری و قبلی دریافت می کنیم - همین رویداد است که به معنای باز شدن یک میلۀ جدید می باشد.


datetime lasttime=0; int Run() { if(lasttime == Time[0]) return(0); // Some code to run whe opening a new bar. lasttime = Time[0]; }

تست یک اکسپرت

Advisor Tester (سنجشگر برنامۀ مشاور) برای ارزیابی کارائی اکسپرت و بررسی عملکردش در نظر گرفته شده است. برای شروع این سنجشگر ابتدا در منوی اصلی در بالای ترمینال روی گزینۀ "نمایش" (View) کلیک کرده و سپس گزینۀ Advisor Tester (سنجشگر برنامۀ مشاور) را انتخاب کنید. در آنجا گزینه هایی برای تعویض بخش های سنجشگر در بالای پنجره اش تعبیه شده اند:


  • پارامترها - پارمترهای سنجشگر
  • نتایج - نمایش جدول اطلاعات روی پوزیشن ها
  • نمودار دارائی خالص - تغییر در موجودی حساب و دارائی خالص (بالانس و اکوتی)
  • ژورنال - فایل ژورنال

پارامترها

شما در بخش "پارامترها" (Parameters) می توانید پارامترهای زیر را که بر روند سنجش تاثیر می گذارند، مشخص کنید:


  • فهرست آبشاری Advisor (برنامۀ مشاور)
  • دکمۀ مشخصات - فراخواندن پارامترهای اکسپرت برای ویرایش. اگر اکسپرت پارامترهای مشخص شده با کلمۀ کلیدی extern (بیرونی) را ندارد، سپس این دکمه غیرفعال خواهد شد.
  • نماد - نماد برای سنجش*.
  • فاصله - فاصله (چهارچوب زمانی) برای سنجش.
  • اسپرد - انتخاب یک مقدار اسپرد. گزینۀ Current spread (اسپرد جاری) با مقدار کنونی اسپرد مرتبط است. شما همچنین می توانید هر مقدار غیرمنفی ای را در کادر Spread (اسپرد) درج نمایید.
  • روش - روش سنجش. که می تواند یکی از گزینه های Control Points (نقاط کنترل) یا Open Price Only (فقط قیمت باز شدن) باشد.در زمان انتخاب Control Points (نقاط کنترل) ، برای هر میله چهار کوچکترین نوسان بطور خودکار ایجاد می شود (ترتیبش بعداً ارائه می گردد). برای میله هایی که در آن قیمت باز شدن پایین تر از قیمت بسته شدن است، کوچکترین نوسان قیمت ها (تیک ها) با قیمت باز شدن (Open)، پایین ترین قیمت (Low)، بالاترین قیمت (High) و قیمت بسته شدن (Close) مرتبط هستند و برای میله هایی که قیمت باز شدن در آنها پایین تر از قیمت بسته شدن است ، ترتیب به این شکل است: قیمت باز شدن (Open)، بالاترین قیمت (High)، پایین ترین قیمت (Low) و قیمت بسته شدن (Close).
    img
    Для метода در روش Open Price Only (فقط قیمت باز شدن)، تمامی معامله ها فقط در قیمت های باز انجام می شوند. عناصر رشته های زمانی در شاخص صفر که در ذیل آمده اند، با یکدیگر برابرندOpen[0] = High[0] = Low[0] = Close[0]، مقادیر برای شاخص های غیر صفریِ رشته های زمانی با مقادیر مرتبط رشته های زمانی برای روش Control Points (نقاط کنترل) منطبق هستند.
  • چک باکس مخصوص Limit Dates (محدود کردن تاریخ ها) برای روشن کردن محدودیت برای تاریخ های سنجیده شده بکار برده می شود.
  • کادرهای From (از) و To (تا) که مخصوص درج تاریخ هستند برای تعیین تاریخ سنجش استفاده می شوند. مقادیر از پیش فرض شده با محدودۀ تاریخچۀ بارگذاری شده برای فاصله و نماد مشخص شده مرتبط هستند.
  • واریز وجه اولیه - واریز اولیه در ابتدای سنجش.
  • چک باکس مخصوص Enable visual mode (فعالسازی حالت تصویری) برای نمایش نموداری دارای موقعیت های باز شدن و بسته شدن مشخص شده و همچنین زمان های ثبت دستورها برای آخرین موقعیت سنجیده شده در زمانیکه سنجش در حال اجرا است بکار می رود.
  • چک باکس Enable expert logs (فعالسازی ثبت اکسپرت) برای چاپ گرفتن از عملکرد System.Print() در بخش ژورنال (Journal) کاربرد دارد.
  • دکمۀ Start/Stop (شروع/توقف) سنجش را شروع یا متوقف می کند.

علامت گذاشتن روی چک باکس های Enable visual mode (فعالسازی حالت تصویری) و Enable expert logs (فعالسازی ثبت اکسپرت) بر سرعت سنجش تاثیر می گذارد ، بنابراین توصیه می شود که فقط در مواقع ضروی آنها را علامت بگذارید.


* در حال حاضر سنجش اکسپرت های چند ارزی بطور کامل پشتیبانی می شوند. اگر نرم افزار مشاوری (advisor) که با معاملات روی چندین ارز کار می کند را سنجیدید و تاریخچۀ بارگذاری شده برای قیمت های این نمادها همخوانی نداشت، قیمت های Ask و Bid، رشته های زمانی و مقادیر بازگردانده شده توسط شیء Bars (میله ها)، می توانند صفر شود.


نتایج

بخش "نتایج" (Results) اطلاعات در مورد تمام پوزیشن های بازشده و بسته شده در خلال فرآیند سنجش را نمایش می دهد. جدولِ شامل پوزیشن های معاملاتی بسته در بالا قرار دارد که اطلاعات زیر را نشان می دهد:


  • شمارۀ # (Number #) - یک شمارۀ ترتیبی از یک پوزیشن بسته شده. #1 نشان دهندۀ اولین معاملۀ بسته است، #2 به دومین معاملۀ بسته شده اختصاص دارد و الی آخر.
  • شناسۀ معامله (Deal ID) - شناسۀ پوزیشن معاملاتی بسته شده
  • نماد (Symbol) - نمادی که پوزیشن معاملاتی روی آن باز شده است
  • حجم 1 (Volume1) - حجم پوزیشن معاملاتی در واحد ارز پایه
  • حجم 2 (Volume2) - حجم پوزیشن معاملاتی در واحد ارز مظنه
  • نرخ باز شدن (Open rate) - قیمت باز شدن
  • زمان باز شدن (Open time) - زمان باز شدن
  • توقف ضرر (Stop loss) - سطح توقف ضرر (فقط زمانیکه مشخص شود نشان داده می شود)
  • کسب سود (Take profit) - کسب سود (فقط زمانیکه مشخص شود نشان داده می شود)
  • آخرین سوآپ (Last swap) - سوآپ پوزیشن معاملاتی جاری
  • نرخ بسته شدن (Rate close) - قیمت بسته شدن
  • زمان بسته شدن (Time close) - زمان بسته شدن
  • سود (Profit) - سود پوزیشن معاملاتی
  • موجودی حساب (Balance) - موجودی حساب پس از بسته شدن پوزیشن معاملاتی*
  • دارائی خالص (Equity) - دارائی خالص پس از بسته شدن پوزیشن معاملاتی *

* این ستون ها در حالت Show extended columns (نمایش ستون های طولانی) نشان داده می شوند. این حالت را می توان از طریق فهرست زمینۀ جدول فعال کرد.


جدول پایینی پوزیشن های معاملاتی ای را نشان می دهد که در انتهای سنجش بسته نشده اند. عناوین ستون ها منطبق بر عناوین ستون های جدول "پوزیشن های معاملاتی بسته شده" (Closed Positions) هستند، به غیر از ستون های از دست رفته مرتبط با پوزیشن های معاملاتی بسته شده.


خط وضعیت که در پایین قرار دارد، اطلاعات مربوط به موجودی حساب (balance)، دارائی خالص (equity)، الزامات مارجین و مارجین آزاد را در زمان تکمیل سنجش نمایش می دهد.


نمودار دارائی خالص

این نمودار بسته به تعداد پوزیشن بسته شده، تغییر در موجودی حساب (balance) و دارائی خالص (equity) را نمایش می دهد. دو بار کلیک پشت سرهم روی نمودار، معاملۀ مرتبط در جدول "پوزیشن های معاملاتی بسته شده" (Closed positions) را نشان می دهد.


ژورنال

بخش ژورنال (Journal) متن خروجی عملکرد System.Print() استفاده در یک اکسپرت را نشان می دهد. اگر چک باکس Enable expert logs (فعالسازی ثبت اکسپرت) در بخش پارامترها (Parameters ) خاموش باشد، ژورنال فقط شامل دستورات شروع و توقف خواهد بود.


اشکالزدایی اسکریپت

به ندرت پیش می آید که اشکالزادیی اسکریپت بدون استفاده از عملکرد System.Print() انجام شود. عملکردی که اطلاعات مرتبط با بخش ژورنال (Journal ) پنجرۀ "جعبه ابزار" (Toolbox) را (یا اطلاعات مرتبط با بخش ژورنال پنجرۀ سنجشگر) نمایش می دهد. هرچند، دانستن این موضوع که چه زمانی یک اکسپرت را اجرا کرده اید می تواند کمک کننده باشد، اطلاعات نمایش داده شده نیز در فایل ثبت در فولدر username\Documents\NeTTradeX Advisors\logs هم موجود می باشند. فایل های ثبت با هر ویرایشگر متنی که فرمت txt را پشتیبانی کند باز می شوند. فایل ثبت شامل سوابقی دربرگیرندۀ یک رویداد، کد بازگشت و پیام متنی می شود.


اضافه کردن یک مقدار پردازش برای مشخصۀ System.LastError شما را قادر می سازد تا در مواقعی که اکسپرت دچار اشکال می شود، بتوانید وضعیت را مورد بررسی قرار دهید. این مشخصه کد آخر خطای مرتبط با عملیات معاملاتی را ذخیره می کند. این مشخصه یک ویژگی مهم دارد: هر عملیات معاملۀ بعدی ، مشخصه را طبق نتیجۀ کارش تغییر می دهد. بنابراین، اگر اسکریپتی دارید که برای یک معامله با یک پارامتر اشتباه درخواست می دهد و سپس یک دستور با پارامترهای صحیح برقرار می کند، مقدار صفر (هیچ خطا) در System.LastError ثبت و ذخیره می شود. در نتیجه، مقدار مشخصۀ System.LastError باید "قبل" از عملیات معاملاتی بعدی دریافت شود (که در اینجا، قرار دادن یک دستور است)، بنابراین این خطای رخ داده را در خلال روند ایجاد معامله ذخیره خواهد کرد. روش System.ErrorDescription() برای دریافت یک توصیف متنی از یک خطا بکار می رود و آن خط را با یک توصیف متنی از مشکل بازمی گرداند. تنها مقدار ورودی نمایانگر کد خطای عددی است که از طریق System.LastError دریافت شده است.


زمانیکه اشکالیزدایی آغاز شود، مشخصۀ IsStopped شیء System نیز می تواند مفید باشد. اگر اجرای برنامه در آخرین تیک (کوچکترین نوسان بازار) بیش از 7 ثانیه به طول انجامید، مقدار "صحیح" خواهد داشت. برنامه نویس با کمک این مشخصه از این مطلع می شود که اسکریپت به زودی به اجبار متوقف خواهد شد (پس از 3 ثانیه)، به این ترتیب زمانی داده می شود تا برنامه بتواند عملیات معین در ارتباط با تکمیل صحیح اسکریپت را اجرا کند.


خلاصه

در پایان لازم به ذکر است که روند ایجاد اکسپرت می تواند به دو مرحله اصلی تقسیم گردد: توسعۀ یک الگوریتم و رمزگذاری اش. هرچه اولین مرحله با دقت صورت گیرد، اجرای مرحلۀ دوم آسان تر و سریع تر خواهد بود. این مقاله موضوعات خاصی را دربارۀ ایجاد الگوریتم و راه حل های کاربردی دربر می گیرد که باعث می شود اولین برخورد شما با NTL+ و مواجه با قابلیت هایش برای نوشتن اکسپرت های معاملاتی، ساده شود.


Close support
Call to instagram Call to Telegram Call to WhatsApp Call Back