برنامه‌نویسی ربات معامله‌گر

تبدیل استراتژی TradingView (Pine Script) به اکسپرت متاتریدر

دو مانیتور با نمودار شمعی و کد MQL و بازوی رباتیک که جریان داده را از نمودار تریدینگ‌ویو به کد اکسپرت متاتریدر می‌برد
تبدیل استراتژی تریدینگ‌ویو به اکسپرت یعنی بازنویسی منطق معاملاتی با MQL و سنجیدن آن در Strategy Tester متاتریدر.

پاسخ کوتاه: اسکریپت Pine Script تریدینگ‌ویو مستقیماً در متاتریدر اجرا نمی‌شود و هیچ مبدل خودکاری هم نتیجه‌ای دقیق و قابل‌اعتماد نمی‌دهد. راه درست این است که منطق استراتژی (شرط ورود، خروج، حد ضرر و مدیریت سرمایه) از کد Pine استخراج شود و از نو با MQL4 یا MQL5 به شکل یک اکسپرت نوشته شود؛ بعد نتیجه اکسپرت در Strategy Tester متاتریدر معامله‌به‌معامله با بک‌تست تریدینگ‌ویو مقایسه شود تا مطمئن شوید همان استراتژی را ساخته‌اید.

این راهنما برای معامله‌گرانی است که استراتژی خود را در TradingView نوشته یا پیدا کرده‌اند و می‌خواهند آن را روی حساب متاتریدر خودکار کنند. قدم‌به‌قدم می‌گوییم چه چیزی را چطور تبدیل کنید، معادل توابع رایج Pine در MQL5 چیست و کدام تفاوت‌ها باعث می‌شود نتیجه بک‌تست دو پلتفرم با هم فرق کند.

چرا اسکریپت TradingView در متاتریدر اجرا نمی‌شود؟

Pine Script زبان اختصاصی تریدینگ‌ویو است و فقط روی سرورهای همین سایت و روی نمودارهای آن اجرا می‌شود. متاتریدر ۴ با زبان MQL4 و متاتریدر ۵ با زبان MQL5 کار می‌کند و این دو زبان شبیه C++ هستند. تفاوت فقط در دستور زبان نیست؛ مدل اجرای دو پلتفرم هم فرق دارد:

  • اسکریپت Pine روی داده تاریخی برای هر کندل یک بار از اول تا آخر اجرا می‌شود و تاریخچه هر متغیر را خودش نگه می‌دارد (مثلاً close[1] یعنی قیمت بسته‌شدن کندل قبلی).
  • اکسپرت متاتریدر با هر تیک قیمت (رویداد OnTick) اجرا می‌شود و اگر بخواهید فقط روی کندل بسته‌شده تصمیم بگیرد، باید خودتان این منطق را بنویسید.
  • سفارش در تریدینگ‌ویو یک «شبیه‌سازی» روی داده نمودار است، اما در متاتریدر سفارش واقعی به بروکر فرستاده می‌شود و با اسپرد، اسلیپیج، حداقل فاصله حد ضرر و نوع حساب سروکار دارد.

به همین دلیل «تبدیل» در عمل یعنی بازنویسی آگاهانه، نه ترجمه خط‌به‌خط.

سه راه برای اجرای استراتژی تریدینگ‌ویو روی حساب متاتریدر

روش چطور کار می‌کند مزیت محدودیت
بازنویسی به اکسپرت MQL4/MQL5 منطق استراتژی در متاتریدر و روی همان حساب اجرا می‌شود مستقل از تریدینگ‌ویو، قابل بک‌تست و بهینه‌سازی در Strategy Tester، اجرا روی VPS نیاز به برنامه‌نویسی و تست تطبیق نتیجه
هشدار تریدینگ‌ویو + پل ارتباطی (Webhook) تریدینگ‌ویو هشدار می‌فرستد و یک ابزار واسط آن را به سفارش در متاتریدر تبدیل می‌کند کد Pine دست نمی‌خورد وابسته به اشتراک تریدینگ‌ویو، اینترنت و سرویس واسط؛ تأخیر و خطای ارسال؛ بک‌تست واقعی روی داده بروکر ندارید
اجرای دستی سیگنال هشدار را می‌بینید و خودتان معامله می‌کنید ساده و بدون هزینه فنی خودکار نیست و خطای انسانی و تأخیر دارد

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

مراحل تبدیل Pine Script به اکسپرت متاتریدر

۱. کد منبع و مجوز استفاده را بررسی کنید

فقط اسکریپتی را می‌شود تبدیل کرد که کد منبعش در دسترس است. اسکریپت‌های «Protected» و «Invite-only» تریدینگ‌ویو کد ندارند و فقط می‌توانید منطقشان را از توضیحات نویسنده حدس بزنید که برای ساخت ربات کافی نیست. اسکریپت‌های متن‌باز تریدینگ‌ویو به‌طور پیش‌فرض با مجوز Mozilla Public License 2.0 منتشر می‌شوند، مگر اینکه نویسنده مجوز دیگری نوشته باشد؛ اگر می‌خواهید اکسپرت را بفروشید یا منتشر کنید، شرایط مجوز را رعایت کنید و نام نویسنده اصلی را بیاورید.

۲. قواعد استراتژی را روی کاغذ بیاورید

پیش از نوشتن حتی یک خط MQL، این موارد را از کد Pine دربیاورید و فهرست کنید:

  • ورودی‌ها (inputs): دوره میانگین‌ها، سطح RSI، ضریب ATR و هر پارامتری که کاربر تغییر می‌دهد.
  • شرط ورود خرید و فروش: مثلاً «کراس میانگین سریع به بالای میانگین کند و RSI بالای ۵۰».
  • خروج: حد سود، حد ضرر، تریلینگ استاپ، خروج با سیگنال مخالف یا خروج زمانی.
  • فیلترها: ساعت معاملاتی، روزهای هفته، تایم‌فریم بالاتر، حداکثر تعداد معامله.
  • حجم معامله: لات ثابت یا درصدی از سرمایه.
  • تنظیمات strategy(): سرمایه اولیه، کمیسیون، اسلیپیج، pyramiding و process_orders_on_close؛ این‌ها نتیجه بک‌تست را مستقیم تغییر می‌دهند.

همین فهرست بعداً «مشخصات فنی» اکسپرت می‌شود و اگر تبدیل را به برنامه‌نویس می‌سپارید، مهم‌ترین چیزی است که باید به او بدهید. در مقاله چطور یک استراتژی را به ربات تبدیل کنیم؟ نوشتن قواعد معاملاتی را با جزئیات بیشتری توضیح داده‌ایم.

۳. نسخه متاتریدر را انتخاب کنید

اگر بروکر و حساب شما روی متاتریدر ۵ است، اکسپرت را با MQL5 بنویسید و اگر روی متاتریدر ۴ است، با MQL4. فایل‌های این دو نسخه جای هم کار نمی‌کنند. تفاوت‌های اصلی دو زبان، مثل مدل سفارش و دسترسی به داده اندیکاتورها، را در مقاله تفاوت MQL4 و MQL5 در ساخت اکسپرت ببینید. در متاتریدر ۵ نوع حساب هم مهم است: در حساب Netting برای هر نماد فقط یک پوزیشن خالص دارید، اما در حساب Hedging چند پوزیشن هم‌زمان باز می‌ماند.

۴. توابع Pine را با معادل MQL5 جایگزین کنید

بیشتر توابع پرکاربرد Pine معادل مستقیم یا نزدیک در MQL5 دارند. جدول زیر رایج‌ترین‌ها را نشان می‌دهد:

Pine Script معادل در MQL5 نکته
ta.sma(close, n) iMA(..., n, 0, MODE_SMA, PRICE_CLOSE) و CopyBuffer در MQL5 اول handle اندیکاتور در OnInit ساخته می‌شود
ta.ema(close, n) iMA(..., MODE_EMA, ...) مقدار چند کندل اول ممکن است به خاطر نقطه شروع محاسبه کمی فرق کند
ta.rsi(close, n) iRSI(_Symbol, _Period, n, PRICE_CLOSE) هر دو از هموارسازی وایلدر استفاده می‌کنند
ta.atr(n) iATR(_Symbol, _Period, n) در تریدینگ‌ویو ATR با RMA هموار می‌شود و اندیکاتور پیش‌فرض متاتریدر با میانگین ساده؛ برای نتیجه یکسان ATR را خودتان با RMA حساب کنید
ta.crossover(a, b) مقایسه مقدار دو کندل آخر: a[قبلی] <= b[قبلی] و a[آخر] > b[آخر] تابع آماده ندارد؛ با دو مقدار از CopyBuffer ساخته می‌شود
close[1] iClose(_Symbol, _Period, 1) شماره ۱ یعنی آخرین کندل بسته‌شده
request.security(..., "D", ...) iClose(_Symbol, PERIOD_D1, 1) یا CopyRates از کندل بسته‌شده تایم‌فریم بالا استفاده کنید تا ریپینت نداشته باشید
strategy.entry CTrade::Buy و CTrade::Sell ورود مخالف در Pine پوزیشن قبلی را می‌بندد؛ در MQL5 این کار را صریح بنویسید
strategy.exit(profit, loss) حد سود و ضرر هنگام ارسال سفارش یا CTrade::PositionModify واحد Pine «تیک» است و در MQL5 «پوینت»؛ در بروکرهای ۵ رقمی هر پیپ ۱۰ پوینت است
input.int(...) input int ... ورودی‌ها در پنجره تنظیمات اکسپرت دیده می‌شوند

برای کار با handle اندیکاتورها و CopyBuffer مقاله استفاده از iMA، iRSI و iMACD در ربات مثال‌های بیشتری دارد.

۵. منطق «کندل بسته‌شده» را بسازید

استراتژی‌های Pine به‌طور پیش‌فرض شرط را روی کندل بسته‌شده می‌سنجند و سفارش را در باز شدن کندل بعدی پر می‌کنند؛ مگر اینکه process_orders_on_close روشن باشد. اکسپرتی که بدون این ملاحظه روی هر تیک تصمیم بگیرد، وسط کندل وارد و خارج می‌شود و نتیجه‌اش هیچ شباهتی به بک‌تست تریدینگ‌ویو نخواهد داشت. راه ساده این است که اکسپرت فقط در اولین تیک هر کندل جدید شرط‌ها را روی کندل بسته‌شده قبلی بسنجد. تفاوت اجرای تیکی و زمان‌بندی‌شده را در مقاله تفاوت OnTick و OnTimer توضیح داده‌ایم.

۶. مدیریت سفارش را کامل کنید

در Pine نیازی نیست نگران شماره جادویی (Magic Number)، حداقل فاصله حد ضرر بروکر، حجم مجاز یا خطای ارسال سفارش باشید؛ در متاتریدر همه این‌ها لازم است. اکسپرت باید فقط پوزیشن‌های خودش را مدیریت کند (با Magic Number)، حجم را با حداقل و گام لات نماد گرد کند و اگر بروکر سفارش را رد کرد، خطا را ثبت کند و دوباره تلاش بی‌حساب نکند.

نمونه کد: کراس دو میانگین روی کندل بسته‌شده در MQL5

این کد معادل یک استراتژی ساده Pine است که با ta.crossover و ta.crossunder دو میانگین نمایی وارد خرید یا فروش می‌شود و با سیگنال مخالف پوزیشن را برمی‌گرداند. برای آموزش ساده شده و فرض کرده حساب از نوع Netting است:

#include <Trade/Trade.mqh>

input int    FastPeriod = 9;     // ta.ema(close, 9)
input int    SlowPeriod = 21;    // ta.ema(close, 21)
input double Lots       = 0.10;
input int    StopPoints = 300;   // stop loss, in points
input int    TakePoints = 600;   // take profit, in points

CTrade   trade;
int      fastHandle, slowHandle;
datetime lastBar = 0;

int OnInit()
{
   fastHandle = iMA(_Symbol, _Period, FastPeriod, 0, MODE_EMA, PRICE_CLOSE);
   slowHandle = iMA(_Symbol, _Period, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE);
   if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE)
      return(INIT_FAILED);
   trade.SetExpertMagicNumber(20261017);
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   IndicatorRelease(fastHandle);
   IndicatorRelease(slowHandle);
}

void OnTick()
{
   // Decide once per bar, on the bar that just closed (Pine's default behaviour).
   datetime barTime = iTime(_Symbol, _Period, 0);
   if(barTime == lastBar)
      return;
   lastBar = barTime;

   double fast[2], slow[2];   // [0] = bar 2 (older), [1] = bar 1 (last closed)
   if(CopyBuffer(fastHandle, 0, 1, 2, fast) != 2 || CopyBuffer(slowHandle, 0, 1, 2, slow) != 2)
      return;

   bool crossUp   = fast[0] <= slow[0] && fast[1] > slow[1];   // ta.crossover
   bool crossDown = fast[0] >= slow[0] && fast[1] < slow[1];   // ta.crossunder

   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   if(crossUp)
   {
      // strategy.entry reverses a short position: close it first.
      if(PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         trade.PositionClose(_Symbol);
      if(!PositionSelect(_Symbol))
         trade.Buy(Lots, _Symbol, ask,
                   NormalizeDouble(ask - StopPoints * _Point, _Digits),
                   NormalizeDouble(ask + TakePoints * _Point, _Digits));
   }
   else if(crossDown)
   {
      if(PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         trade.PositionClose(_Symbol);
      if(!PositionSelect(_Symbol))
         trade.Sell(Lots, _Symbol, bid,
                    NormalizeDouble(bid + StopPoints * _Point, _Digits),
                    NormalizeDouble(bid - TakePoints * _Point, _Digits));
   }
}

برای استفاده واقعی این موارد باید اضافه شود: بررسی حداقل فاصله حد ضرر بروکر (SYMBOL_TRADE_STOPS_LEVEL)، گرد کردن حجم با گام لات، فیلتر اسپرد، فیلتر ساعت معاملاتی و انتخاب پوزیشن‌ها بر اساس Magic Number در حساب Hedging.

تفاوت‌هایی که نتیجه بک‌تست دو پلتفرم را عوض می‌کند

حتی وقتی منطق درست تبدیل شده باشد، عدد سود و تعداد معاملات دو پلتفرم معمولاً دقیقاً یکی نمی‌شود. این‌ها رایج‌ترین دلیل‌ها هستند:

  • داده متفاوت: تریدینگ‌ویو داده منبع خودش را نشان می‌دهد و متاتریدر داده بروکر شما را؛ قیمت باز و بسته شدن کندل‌ها و حتی ساعت شروع آن‌ها (منطقه زمانی سرور بروکر) فرق دارد. کیفیت داده تاریخی هم روی نتیجه اثر مستقیم دارد.
  • اسپرد و اسلیپیج: بک‌تست تریدینگ‌ویو معمولاً روی یک قیمت واحد و بدون اسپرد واقعی است، اما متاتریدر با قیمت خرید و فروش (Bid و Ask) کار می‌کند. در استراتژی‌های اسکلپ این تفاوت می‌تواند سود را به ضرر تبدیل کند؛ جزئیاتش را در تاثیر اسپرد و اسلیپیج در بک‌تست ببینید.
  • ریپینت و نگاه به آینده: استفاده از request.security با lookahead یا استفاده از قیمت کندلِ هنوز بازِ تایم‌فریم بالاتر، بک‌تست تریدینگ‌ویو را غیرواقعی خوب نشان می‌دهد. در نسخه MQL فقط از کندل بسته‌شده استفاده کنید.
  • محاسبه اندیکاتورها: مثل ATR که در دو پلتفرم با روش هموارسازی متفاوت حساب می‌شود، یا تفاوت مقدار شروع میانگین‌ها.
  • زمان پر شدن سفارش: باز شدن کندل بعد در Pine، در برابر اولین تیک کندل جدید در متاتریدر؛ اگر process_orders_on_close روشن بوده، باید همین رفتار را عمداً در اکسپرت بسازید.
  • کمیسیون و نوع حساب: کمیسیون حساب ECN و تفاوت Netting و Hedging در بستن و برگرداندن پوزیشن.

هیچ‌کدام از این‌ها به معنی خطای تبدیل نیست؛ باید آن‌ها را بشناسید و جدا کنید. در مقاله چرا نتایج بک‌تست واقعی نیستند این موضوع را عمیق‌تر بررسی کرده‌ایم.

چک‌لیست تطبیق نتیجه تریدینگ‌ویو و متاتریدر

  1. یک نماد و یک بازه زمانی مشخص انتخاب کنید (مثلاً EURUSD در تایم‌فریم یک‌ساعته برای شش ماه).
  2. در تریدینگ‌ویو فهرست معاملات (List of Trades) را خروجی بگیرید.
  3. اکسپرت را در Strategy Tester متاتریدر با مدل «Every tick based on real ticks» یا دست‌کم «Every tick» روی همان بازه اجرا کنید. راهنمای کامل را در آموزش بک‌تست ربات در متاتریدر ۵ ببینید.
  4. زمان ورود و خروج ده معامله اول را کنار هم بگذارید. اگر جهت و کندل ورود یکی است، منطق درست تبدیل شده و اختلاف عدد سود از داده و هزینه‌هاست.
  5. اگر معاملاتی در یک پلتفرم هست و در دیگری نیست، شرط‌ها، فیلتر ساعت و منطقه زمانی را دوباره بسنجید.
  6. بعد از تطبیق، اکسپرت را چند هفته روی حساب دمو اجرا کنید؛ فوروارد تست چیزهایی را نشان می‌دهد که هیچ بک‌تستی نشان نمی‌دهد.

چه زمانی تبدیل را به برنامه‌نویس بسپاریم؟

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

سؤالات متداول

آیا ابزاری هست که Pine Script را خودکار به MQL تبدیل کند؟

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

اندیکاتور تریدینگ‌ویو را هم می‌شود به متاتریدر برد؟

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

چرا نتیجه بک‌تست اکسپرت با تریدینگ‌ویو یکی نیست؟

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

برای متاتریدر ۴ بنویسیم یا ۵؟

به حساب و بروکر شما بستگی دارد. اکسپرت فقط روی همان نسخه‌ای اجرا می‌شود که برایش نوشته شده است. اگر حساب تازه باز می‌کنید، متاتریدر ۵ تستر دقیق‌تر و امکانات بیشتری دارد.

منابع

یادآوری ریسک: تبدیل درست یک استراتژی، سودده بودن آن را تضمین نمی‌کند. معامله در بازارهای مالی ریسک از دست دادن سرمایه دارد؛ هر اکسپرت را پیش از حساب واقعی روی حساب دمو بسنجید.

هشدار ریسک: این مطلب جنبه آموزشی دارد و توصیه سرمایه‌گذاری نیست. معامله در بازارهای مالی با ریسک از دست دادن سرمایه همراه است و نتایج گذشته یا بک‌تست تضمینی برای آینده نیست.

نویسنده

تیم متااکسپرت در طراحی و برنامه‌نویسی ربات‌های معامله‌گر و اکسپرت‌های متاتریدر با MQL4 و MQL5 تخصص دارد و تجربه‌های عملی خود را در قالب این مقالات منتشر می‌کند.

دیدگاه‌ها

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *