در این مقاله
- از کجا شروع کنید اگر اندیکاتور خودتان را میخواهید؟
- اندیکاتور سفارشی در MQL5 دقیقاً چیست؟
- بافر و رسم چه تفاوتی دارند؟
- چرخهی اجرا و اجزای فایل را چگونه بچینید؟
- آمادهسازی پیش از محاسبه
- یک میانگین ساده را گامبهگام محاسبه و نمایش دهید
- با کندل تازه، تاریخچهی بیشتر و ورودی نامعتبر چه کنید؟
- کدام خطاها باعث خروجی اشتباه یا خط خالی میشوند؟
- چکلیست کامپایل و آزمون اندیکاتور
- قدم بعدی: استفاده از اسکریپتها یا ساخت اکسپرت
خلاصه در ۳۰ ثانیه
- اندیکاتور MQL5 مقدار محاسبهشده را در بافر میگذارد تا روی نمودار نمایش داده شود.
- OnInit برای آمادهسازی و اتصال بافرهاست؛ OnCalculate محل دریافت اطلاعات و محاسبه است.
- rates_total تعداد کندلهای موجود و prev_calculated تعداد کندلهای پردازششده در فراخوانی پیشین را نشان میدهد.
- جهت اندیسگذاری آرایهها را صریح تنظیم کنید و فرض نکنید اندیس صفر همیشه کندل قدیمیتر است.
- پیش از استفاده، کامپایل و نمایش اندیکاتور را در متاتریدر بررسی کنید.
از کجا شروع کنید اگر اندیکاتور خودتان را میخواهید؟
این راهنما برای شماست اگر برنامهنویسی بلدید، با اندیکاتورها آشنا هستید و پیشتر با Pine Script کار کردهاید. هدف این مقاله آموزش نحو پایهی برنامهنویسی نیست. قرار است یک قاعدهی محاسباتی را روی قیمتهای کندلها اجرا کنید و نتیجه را روی نمودار ببینید.
با انتخاب MQL5، اندیکاتور را با زبان و ابزارهای متاتریدر ۵ میسازید. در TradingView اسکریپت را با Pine Script مینویسید. هر دو محیط برای ساخت ابزارهای نموداری کاربرد دارند؛ انتخاب به پلتفرم اجرای اندیکاتور بستگی دارد.
پیشنیاز و خروجی
پیش از شروع، مقالههای «وضعیت ایچیموکو کریپکس»، «هشدار قیمت و اندیکاتور در تریدینگویو» و «آموزش پایهی Pine Script» را بخوانید. این مقالهها با رفتار اندیکاتورها، کار با نمودار و منطق اسکریپتنویسی آشنا میکنند. اینجا همان ایده را با ساختار MQL5 پیاده میکنید.
خروجی این آموزش، اندیکاتوری است که میانگین چند قیمت پایانی را حساب میکند و آن را بهصورت خط روی نمودار نشان میدهد. در مثال اصلی مقاله، سه قیمت پایانی محاسبه و نتیجه در بافر ثبت میشود؛ این کار در بخش محاسبه انجام میشود. همینقدر کافی است بدانید خط از مقادیر ثبتشده در بافر ترسیم میشود.
مسیر ساخت
کار را به پنج مرحله تقسیم کنید: خروجی و تعداد نمودارها را تعریف کنید، بافر نمایشی را وصل کنید، قیمتهای لازم را محاسبه کنید، کد را کامپایل کنید و در پایان خط را روی نمودار بررسی کنید. برای دیدن ابزارهای آماده، به اندیکاتورها و اسکریپتهای کریپکس سر بزنید.
اندیکاتور سفارشی در MQL5 دقیقاً چیست؟
اندیکاتور سفارشی (custom indicator) برنامهای است که قیمت یا ورودی دیگری را میگیرد، طبق منطق مشخص محاسبه میکند و نتیجه را روی نمودار نمایش میدهد یا به برنامههای دیگر میدهد. سه جزء آن را جدا ببینید: ورودیها، مثل قیمت پایانی یا دورهی محاسبه؛ منطق محاسبه، که ورودی را به نتیجه تبدیل میکند؛ و خروجیها، که نتیجه را در بافرها نگه میدارند.

در تصویر بالا مسیر ورودی تا نمایش نتیجه را میبینید. بافر آرایهای پویاست و ترمینال اندازهی آن را مدیریت میکند؛ هر خانه مقدار متناظر با یک کندل را نگه میدارد. مثلاً خروجی محاسبهی یک کندل در خانهی همان کندل ذخیره میشود. مهم: پیش از دسترسی به اندیس قیمت یا بافر، شرط rates_total >= ۱ را بررسی کنید و اندیسگذاری بافر را صریحاً با آرایههای قیمت هماهنگ کنید.
بافر و رسم چه تفاوتی دارند؟
بافر نمایشی را در تابع OnInit با SetIndexBuffer و نوع INDICATOR_DATA متصل کنید و بعد جهت اندیسگذاری را با ArraySetAsSeries تنظیم کنید. بافر کمکی از نوع INDICATOR_CALCULATIONS برای نگهداری مقادیر میانی و محاسبات داخلی است و خودش روی نمودار رسم نمیشود. تعداد بافرها و نمودارها را از ابتدا با #property indicator_buffers و #property indicator_plots تعیین کنید.
رسم (plot) مشخص میکند مقدار بافر چطور روی نمودار دیده شود؛ مثلاً به شکل خط یا میله. در محاسبهی دورهای، دستکم به تعداد period کندل نیاز دارید؛ اگر کندل کافی نیست، خروجی را ترسیم نکنید. برای محاسبهی افزایشی، مبنا را prev_calculated قرار دهید و اگر مقدار آن صفر شد، محاسبه را از نو شروع کنید؛ در پایان OnCalculate مقدار rates_total را برگردانید. مثال کامل میانگین و ذخیرهی نتیجه در بافر در بخش محاسبهی میانگین آمده است.
مرز وظیفهی اندیکاتور
اندیکاتور فقط محاسبه میکند و نتیجه را نمایش میدهد؛ ارسال سفارش کار آن نیست. ساخت برنامه برای اجرای معامله موضوع اکسپرتها و مقالهی بعدی است.
برای مقایسهی این ساختار با نمونههای آماده، ابزار اندیکاتورها و اسکریپتهای کریپکس را ببینید.
چرخهی اجرا و اجزای فایل را چگونه بچینید؟
فایل اندیکاتور از چهار بخش ساخته میشود: ویژگیهای نمایشی، ورودیهای قابلتنظیم، آرایههای بافر و توابع رویدادی. ویژگیها را با دستورهای `#property` در ابتدای فایل بنویسید. ورودیها را با `input` تعریف کنید. هر بافر یک آرایه از نوع `double` است که مقدارهای قابلرسم را نگه میدارد. `OnInit` آمادهسازی را انجام میدهد و `OnCalculate` محاسبه را.

در تصویر بالا، هر جزء جای مشخصی دارد. ویژگیها تعداد و شکل نمودار را تعیین میکنند. `OnInit` بافر را به اندیکاتور وصل میکند و `OnCalculate` مقدارها را در آن مینویسد. برای رسم یک خط، این سه را کنار هم بگذارید: `#property indicator_buffers ۱`، `#property indicator_plots ۱` و `#property indicator_type1 DRAW_LINE`. اولی یک بافر میسازد، دومی یک نمودار و سومی نوع رسم را مشخص میکند. ([mql5.com](https://www.mql5.com/en/docs/customind?utm_source=openai))
آمادهسازی پیش از محاسبه
`OnInit` هنگام بارگذاری اندیکاتور اجرا میشود. در آن ورودیها را بررسی کنید و بافر نمایشی را با `SetIndexBuffer(۰,LineBuffer,INDICATOR_DATA)` متصل کنید. نام کوتاه را هم با `IndicatorSetString(INDICATOR_SHORTNAME,"نام اندیکاتور")` تنظیم کنید. اگر آمادهسازی موفق بود، `INIT_SUCCEEDED` را برگردانید. مهم: اتصال بافر، جهت اندیسگذاری را به ترتیب معمولی برمیگرداند، پس بعد از اتصال حتماً جهت را با `ArraySetAsSeries(LineBuffer,true)` یا `false` صریحاً تنظیم کنید. ([mql5.com](https://www.mql5.com/en/docs/customind/setindexbuffer?utm_source=openai))
`OnCalculate` با هر رویداد محاسبه فراخوانی میشود، مثلاً وقتی اطلاعات قیمت تغییر میکند. محل اصلی محاسبهی اندیکاتور همین تابع است. مهم: پیش از دسترسی به اندیسهای قیمت یا بافر، حتماً شرط `rates_total >= ۱` را بررسی کنید. اگر محاسبه به دورهای با طول `period` نیاز دارد، دستکم `period` کندل لازم است؛ تا پیش از آن خروجی را ترسیم نکنید.
دو شکل ورودی تابع محاسبه
برای هر اندیکاتور، یکی از دو امضای تابع را انتخاب میکنید. شکل کوتاه، آرایهی قیمت `price[]` را همراه با `begin` میگیرد. شکل کامل، دسترسی جداگانه به آرایههای زمان، بازشدن، بیشینه، کمینه، بستهشدن، حجم تیک، حجم واقعی و اسپرد میدهد. جهت اندیسگذاری آرایههای ورودی را هم صریحاً تنظیم کنید تا محاسبه به ترتیب پیشفرض وابسته نباشد. ([mql5.com](https://www.mql5.com/en/docs/event_handlers/oncalculate?utm_source=openai))
`rates_total` تعداد خانههای آرایهی ورودی یا کندلهای در دسترس را نشان میدهد. `prev_calculated` تعداد خانههایی است که تابع در اجرای قبلی پردازش کرده است. برای محاسبهی افزایشی، از `prev_calculated` شروع کنید؛ اگر صفر بود، از ابتدا محاسبه کنید. در پایان حتماً `rates_total` را برگردانید تا تعداد کندلهای پردازششده برای فراخوانی بعدی ثبت شود. ([mql5.com](https://www.mql5.com/en/docs/event_handlers/oncalculate?utm_source=openai))
یک میانگین ساده را گامبهگام محاسبه و نمایش دهید
برای ساخت میانگین متحرک ساده، دوره را روی ۳ میگذاریم و یک بافر نمایشی برای خط تعریف میکنیم. سه قیمت پایانی فرضی کندلهای موردنظر ۱۰۰، ۱۰۲ و ۱۰۱ هستند. بافر، مقدار بهدستآمده را در خانهی همان کندل نگه میدارد.
از قیمت تا مقدار بافر
فرمول ساده است: میانگین سه قیمت پایانی برابر مجموع آنها تقسیم بر ۳ است. در این محاسبه، ۱۰۰ + ۱۰۲ + ۱۰۱ = ۳۰۳ و سپس ۳۰۳ ÷ ۳ = ۱۰۱. برای کندلی که هر سه قیمت لازم را دارد، مقدار ۱۰۱ در خانهی متناظر بافر ثبت میشود.

در تصویر بالا، سه قیمت ورودی به یک مقدار میانگین تبدیل شدهاند و آن مقدار روی خط اندیکاتور قرار میگیرد. از ابتدا یک بافر و یک رسم تعیین کنید: #property indicator_buffers ۱ و #property indicator_plots ۱. سپس با SetIndexBuffer(۰,LineBuffer,INDICATOR_DATA) بافر را در OnInit به رسم وصل کنید. بعد از اتصال، جهت اندیسگذاری آرایه را با ArraySetAsSeries مشخص کنید تا معلوم شود اندیس صفر به کدام کندل اشاره دارد. ([mql5.com](https://www.mql5.com/en/book/applications/indicators_make/indicators_buffers_plots?utm_source=openai))
- ورودی دوره را با مقدار آغازین ۳ تعریف کنید و یک آرایهی بافری برای خط داشته باشید؛ نوع رسم خطی را برای همان یک رسم مشخص کنید.
- در OnCalculate، پیش از دسترسی به اندیس قیمت یا بافر، بررسی کنید rates_total >= ۱ باشد. سپس کافیبودن تاریخچه را بسنجید: برای دورهی ۳، دستکم ۳ کندل لازم است؛ تا پیش از فراهمشدن آنها مقدار محاسبهشدهای ننویسید.
- برای خانههایی که هنوز سه قیمت ندارند، EMPTY_VALUE را در بافر بگذارید تا خط ناقص و گمراهکننده رسم نشود. از prev_calculated برای شروع محاسبهی افزایشی استفاده کنید؛ اگر صفر بود، محاسبه را از نو آغاز کنید.
- پس از محاسبه، میانگین را در خانهی متناظر با کندل بنویسید و rates_total را برگردانید تا تعداد کندلهای پردازششده برای فراخوانی بعدی ثبت شود. ([mql5.com](https://www.mql5.com/en/docs/event_handlers/oncalculate?utm_source=openai))
برای نمایش این خط روی نمودار قیمت، #property indicator_chart_window را انتخاب کنید. اگر میخواهید آن را جدا از نمودار قیمت ببینید، #property indicator_separate_window را بهکار ببرید. در این مثال فقط محل نمایش عوض میشود؛ دوره، قیمتهای ورودی و مقدار ۱۰۱ در بافر ثابت میمانند.
با کندل تازه، تاریخچهی بیشتر و ورودی نامعتبر چه کنید؟
پیش از خواندن هر اندیس از آرایهی قیمت یا بافر، شرط rates_total >= ۱ را بررسی کنید. برای محاسبهی دورهای هم شرط جداگانهی rates_total >= period لازم است. اگر کندل کافی ندارید، بافر را خروجی معتبر نشان ندهید و از OnCalculate مقدار ۰ برگردانید. وقتی تاریخچه به حد لازم رسید، محاسبهی اولیه را برای همهی خانههای قابلمحاسبه انجام دهید. سپس مقدار rates_total را برگردانید تا ترمینال تعداد کندلهای پردازششده را برای فراخوانی بعدی ثبت کند.
در محاسبهی افزایشی، prev_calculated مبناست: اگر صفر باشد، کل محدودهی لازم را دوباره محاسبه کنید؛ وگرنه فقط محدودهی تغییرکرده را پردازش کنید. کندل جاری را هم در هر فراخوانی بازبینی کنید، چون قیمت پایانی آن تا بستهشدن کندل تغییر میکند. برای نمونه، اگر فقط کندل جاری تغییر کرده باشد، لازم نیست کل تاریخچه را دوباره حساب کنید؛ فقط خانهی همان کندل را بهروز کنید.
ترمینال هنگام بارگیری تاریخچهی قدیمیتر یا پرکردن شکاف اطلاعات، prev_calculated را صفر میکند. این وضعیت را نشانهی محاسبهی مجدد بگیرید، نه ادامهی عادی از محدودهی قبلی. جهت اندیسگذاری آرایههای ورودی و بافر را جداگانه بررسی و تنظیم کنید. برای نمونه، اگر اندیس صفر در ورودیها کندل جاری باشد، همان قاعده را در بافر خروجی هم رعایت کنید تا مقدار در خانهی اشتباه رسم نشود.
ورودی معتبر و دریافت مطمئن
در آغاز مقداردهی، دورهی صفر یا منفی را رد کنید و پیام روشنی مانند «دوره باید بزرگتر از صفر باشد» بدهید. آن را پنهانی با مقدار دیگری جایگزین نکنید. اگر محاسبه به اندیکاتور دیگری وابسته است، هندل آن را بسازید و اعتبارش را بسنجید. سپس با CopyBuffer مقدارها را دریافت کنید و تعداد مقدارهای کپیشده را بررسی کنید. دریافت ناموفق یا ناقص را وارد محاسبه نکنید.
| وضعیت | اقدام |
|---|---|
| کمتر از یک کندل در دسترس است | پیش از دسترسی به آرایه، مقدار صفر برگردانید. |
| کندلها از دوره کمترند | صفر برگردانید؛ پس از کافیشدن تاریخچه، محاسبهی اولیه را کامل انجام دهید. |
| کندل جاری تغییر کرده است | خانهی کندل جاری را دوباره محاسبه کنید. |
| تاریخچه بارگیری یا شکاف پر شده است | با صفرشدن prev_calculated محاسبه را از نو آغاز کنید. |
| ورودی نامعتبر یا دریافت بافر ناقص است | خطا را روشن اعلام کنید و از مقدار نامعتبر استفاده نکنید. |
مقدار ناقص را معتبر نشان ندهید
تا وقتی دورهی معتبر و اطلاعات کافی در دسترس نیست، خروجی ناقص را بهعنوان مقدار محاسبهشده نمایش ندهید. اگر ورودی اندیکاتور وابسته کامل کپی نشده است، محاسبهی مبتنی بر آن را انجام ندهید.
کدام خطاها باعث خروجی اشتباه یا خط خالی میشوند؟
بیشتر خطاهای خروجی از ناهماهنگی بین تعداد بافرها، ترتیب اندیسها و تعداد کندلهای در دسترس میآید. قبل از دسترسی به اندیسهای قیمت یا بافر، شرط rates_total >= ۱ را بررسی کنید. تعداد بافرها و نمودارها را هم از ابتدا با #property indicator_buffers و #property indicator_plots تعیین کنید.
در تعریف ویژگیها، شمارهی رسم از یک شروع میشود، اما اندیس بافر از صفر شروع میشود: #property indicator_type1 رسم نخست را تعریف میکند و SetIndexBuffer(۰, Buffer, INDICATOR_DATA) بافر شمارهی صفر را به آن وصل میکند. هر بافر نمایشی را در OnInit با نوع INDICATOR_DATA وصل کنید، بعد جهت اندیسگذاری را با ArraySetAsSeries صریحاً تنظیم کنید. توجه کنید: بعد از اتصال، اندازهی بافر را ترمینال مدیریت میکند و برنامه نباید آن را خودش تغییر دهد.
این جدول نشانهها را به اقدام اصلاحی وصل میکند:
برای خطی که از کندلهای نخست رسم نمیشود، آغاز رسم را با دورهی لازم هماهنگ کنید. برای میانگین دورهای، مقدار PLOT_DRAW_BEGIN را برابر period-۱ بگذارید تا بخش بدون مقدار معتبر نمایش داده نشود. قاعدهی مقدار خالی را هم یکسان نگه دارید: اگر EMPTY_VALUE را برای خانههای محاسبهنشده انتخاب میکنید، همان را با PLOT_EMPTY_VALUE برای رسم تنظیم کنید. صفر را فقط وقتی مقدار واقعی است، صفر بگذارید.
محدودیت اندیکاتور
توابع ارسال سفارش، مثل <code>OrderSend</code>، در اندیکاتورها کار نمیکنند. اگر هدف اجرای معامله است، مسیر ساخت اکسپرت را دنبال کنید.
چکلیست کامپایل و آزمون اندیکاتور
کنترل پیش از اجرا
پیش از کامپایل، این موارد را در فایل بررسی کنید: فایل باید در پوشهی Indicators باشد؛ تعداد بافرها و نمودارها باید با خروجی موردنیاز هماهنگ باشد؛ و هر بافر نمایشی در OnInit باید با SetIndexBuffer و نوع INDICATOR_DATA متصل شود. پس از اتصال، جهت اندیسگذاری را با ArraySetAsSeries مشخص کنید. در OnCalculate، پیش از دسترسی به اندیس قیمت یا بافر، شرط rates_total >= ۱ را حتماً بررسی کنید.
- فایل را در MetaEditor کامپایل کنید و همهی خطاها و هشدارهای کامپایل را پیش از افزودن اندیکاتور به نمودار برطرف کنید؛ متن هشدارها را هم بخوانید، نه اینکه فقط وجود فایل خروجی را ملاک بگیرید.
- اندیکاتور را روی نمودار آزمایشی بیندازید و نام، محل نمایش، رنگ خط و مقدار بافر را بررسی کنید. با رسیدن کندل تازه، ببینید مقدار جدید به خانهی درست اضافه میشود و مقادیر قبلی جابهجا یا پاک نمیشوند.
- آزمون کوتاه و کامل را جدا انجام دهید: با دورهی ۳، ابتدا ۲ کندل در اختیار بگذارید و بررسی کنید خروجی ترسیم نشود؛ سپس با دستکم ۳ کندل، محاسبه را بررسی کنید. در آزمونی جداگانه، ورودی نامعتبر مانند دورهی ۰ را وارد کنید و پیام خطا یا رفتار کنترلشدهی اندیکاتور را ثبت کنید.
تطبیق مقدار و محاسبهی مجدد
در پنجرهی اطلاعات اندیکاتور، یک خانه را انتخاب کنید. همان ورودیها را با فرمول اندیکاتور دستی حساب کنید و با مقدار بافر همان خانه مقایسه کنید. برای میانگین دورهای، تعداد کندلها باید دستکم برابر دوره باشد؛ اگر اطلاعات کافی نیست، خروجی ترسیم نمیشود. در آزمون محاسبهی افزایشی، prev_calculated را مبنا بگیرید: اگر صفر شد، محاسبه را از نو شروع کنید و در پایان rates_total را برگردانید.
ثبت آزمون بازمحاسبه
پس از تغییر تاریخچه یا بارگذاری اطلاعات بیشتر، خانههای بررسیشده را دوباره تطبیق دهید. نتیجه را با سه مورد ثبت کنید: وضعیت تاریخچه، مقدار بافر پیش و پس از بارگذاری، و اینکه محاسبه از نو انجام شد یا افزایشی ادامه یافت.
قدم بعدی: استفاده از اسکریپتها یا ساخت اکسپرت
مسیر ساخت اندیکاتور را اینطور جمعبندی کنید: قیمت را بهعنوان ورودی بگیرید، در OnCalculate محاسبه کنید، نتیجه را در بافر ذخیره کنید و با تنظیم رسم روی نمودار نمایش دهید. قبل از افزودن شرطها، چند خروجی یا محاسبهی پیچیده، یک نمونهی کوچک بسازید و هر مرحله را جدا بررسی کنید.
- یک ورودی انتخاب کنید؛ برای نمونه، دورهی میانگین متحرک را مشخص کنید.
- یک خروجی تعریف کنید؛ مثلاً مقدار میانگین برای هر کندل.
- اندیکاتور را کامپایل کنید و نتیجه را روی نمودار ببینید؛ بررسی کنید که مقدارها نمایش داده شوند و با تغییر ورودی، خروجی هم مطابق انتظار تغییر کند.
برای نمونههای آماده، ابزار اندیکاتورها و اسکریپتهای کریپکس را ببینید. از هر نمونه، نام ورودیها، نوع خروجی و تنظیم نمایش را پیدا کنید و فقط همان بخش مرتبط را در کار خود امتحان کنید.
مرز اندیکاتور و اکسپرت
اندیکاتور فقط محاسبه و نمایش اطلاعات روی نمودار است؛ خودکارسازی اجرای دستورها موضوع مسیر بعدی است. در مقالهی بعدی، «اکسپرت چیست و چه فرقی با اندیکاتور دارد؟»، تفاوت این دو ابزار و زمان استفاده از هرکدام را میبینیم.
ابزارهای کریپکس برای تمرین این مبحث
اندیکاتورها و اسکریپتهای کریپکس (/tools/scripts)
پرسشهای پرتکرار
برای نوشتن اندیکاتور در MQL5 چه پیشنیازی لازم است؟
آشنایی با متغیر، آرایه، تابع و حلقه لازم است. همچنین باید بدانید اندیکاتور چه ورودی و خروجیای دارد؛ این مقاله نحو پایهی برنامهنویسی را آموزش نمیدهد.
تفاوت OnInit و OnCalculate چیست؟
OnInit هنگام آغاز برنامه برای آمادهسازی و تنظیم اجزا اجرا میشود. OnCalculate محل دریافت اطلاعات قیمت و انجام محاسبهی اندیکاتور است.
بافر اندیکاتور در MQL5 چه کاربردی دارد؟
بافر آرایهای است که مقادیر محاسبهشده را نگه میدارد و ترمینال از آن برای نمایش خروجی استفاده میکند. بافر کمکی نیز برای مقادیر میانی به کار میرود.
rates_total و prev_calculated چه تفاوتی دارند؟
rates_total تعداد کندلهای موجود در آرایهی ورودی را نشان میدهد. prev_calculated مقدار بازگشتی اجرای قبلی OnCalculate است و برای مدیریت محاسبهی مجدد به کار میرود.
چرا اندیکاتور روی نمودار چیزی نشان نمیدهد؟
تعداد بافر و رسم، اتصال SetIndexBuffer، نوع رسم و جهت اندیسگذاری را بررسی کنید. همچنین مطمئن شوید برای محاسبه به تعداد کافی کندل در دسترس است و مقدار خالی را بهجای خروجی ثبت نکردهاید.
آیا اندیکاتور MQL5 میتواند خودش معامله باز کند؟
اندیکاتور برای محاسبه و نمایش خروجی طراحی شده است و توابع ارسال سفارش در آن قابل استفاده نیستند. برای خودکارسازی اجرای دستورها، مقالهی بعدی دربارهی اکسپرت را بخوانید.
منابع
این مقاله آموزشی است و توصیهی سرمایهگذاری یا سیگنال خرید و فروش نیست. معامله در بازارهای مالی ریسک دارد و مسئولیت تصمیمها با خود شماست.
اشتباهی دیدید؟ از صفحهی تماس با ما خبر بدهید تا بررسی و اصلاح شود.



