دورة البرمجة في الفوركس للمبتدئين – الدرس السابع
دورة البرمجة في الفوركس للمبتدئين الحلقة السابعة
المتغيرات والمتغيرات الخارجية
القسم التالي من دورة البرمجة نتحدث عن ملف الكود المصدري لـ Expert Advisor هو المتغيرات الخارجية. هذه هي
معلمات قابلة للتعديل لنظام التداول لدينا. يتضمن ذلك إعدادات التداول الخاصة بك (وقف الخسارة ، جني الأرباح ،
حجم اللوت) وإعدادات المؤشر. عند فتح مربع حوار Expert Properties (خصائص الخبير) لمستشار خبير ،
تقوم بعرض المتغيرات الخارجية لهذا البرنامج.
نحدد متغيرًا خارجيًا بإضافة extern أمام المتغير. هذا يحدد أن المتغير سيظهر في مربع حوار خصائص الخبير ، وسيكون قابلاً للعرض والتعديل من قبل المستخدم.
مثال:
كود:
extern double StopLoss = 50;
تأكد من أن معرف المتغير الخارجي الخاص بك وصفي لما يفعله بالفعل. (“إيقاف الخسارة”
أفضل من “stop”” أو “SL” ، على سبيل المثال). لديك 31 حرفًا لوصف المتغير الخاص بك ، لذا اصنع
معظمها. ستكون القيمة الافتراضية للمتغير الخاص بك هي أيضًا القيمة الافتراضية لتلك المعلمة ، لذلك
اختر قيمة افتراضية منطقية.
المتغيرات العامة Global Variables
نعلن عن أي متغيرات عامة في الجزء العلوي من ملف الكود المصدري ، بشكل عام بعد المتغيرات الخارجية
. لا يهم الموقع ، طالما تم وضع كل من المتغيرات العامة والخارجية
خارج وقبل أي وظائف.
المتغير العام هو المتغير المتاح لأي وظيفة في البرنامج. ما دام البرنامج
قيد التشغيل ، يظل المتغير العام وقيمته في الذاكرة ، ويمكن الرجوع إليه وتغييره بواسطة
أي وظيفة في البرنامج.
من الناحية الفنية ، المتغيرات الخارجية عمة أيضًا ، لكن المتغيرات العامة التي نناقشها في هذا
القسم هة داخلية ، مما يعني أنه لا يمكن للمستخدم عرضه أو تغييره.
وظائف خاصة Special Functions
يحتوي MQL على 3 وظائف مدمجة للتحكم في تنفيذ البرنامج: init () ، deinit () و start (). ال
تتكون وظيفة init () من رمز يتم تشغيله مرة واحدة ، عند بدء تشغيل EA لأول مرة. الحرف الأول ()
الوظيفة اختيارية ، ويمكن استبعادها إذا كنت لا تستخدمها.
تتكون وظيفة deinit () من رمز يتم تشغيله مرة واحدة ، عندما يتم إيقاف EA. هذه الوظيفة
اختياري أيضًا ، ومن غير المحتمل أن تحتاج إلى استخدامه في مستشار خبير.
تحتوي وظيفة start () على رمز البرنامج الرئيسي ، وهي مطلوبة في المستشار الخبير الخاص بك. في كل مرة
يتم تشغيل وظيفة start ، ويتم فحص شروط التداول الخاصة بك ، ويتم وضع الأوامر أو إغلاقها وفقًا لذلك
حول كيفية تقييم هذه الشروط.
يتم تشغيل وظيفة start () على كل علامة. العلامة هي حركة سعر ، أو تغيير في العرض أو الطلب
سعر زوج العملات. خلال الأسواق النشطة ، قد يكون هناك عدة تكات في الثانية. أثناء البطء
الأسواق ، يمكن أن تمر الدقائق بدون علامة.
وظائف أخرى Other Functions
يجب الإعلان عن أي وظائف أخرى قد تستخدمها EA بعد وظيفة start (). هؤلاء
سيتم استدعاء الدوال من البداية () أو init () أو deinit () أو من وظائف أخرى
التي يتم استدعاؤها من البرنامج الرئيسي. سنغطي الوظائف المخصصة لاحقًا ان شاء الله.
العرض والطلب والسبريد
بصفتك متداولًا في فوركس ، ربما تكون على دراية بأسعار العرض والطلب. لكن قد لا تكون كذلك
على دراية بدورهم في ترتيب الاوامر. من المهم جدًا استخدام السعر الصحيح عند الفتح أو
أوامر الإغلاق.
سعر العرض هو ما تراه على الرسوم البيانية للميتاتريدر. عادة ما نفكر فيه عندما نفكر
من “السعر الحالي”. يكون سعر الطلب بشكل عام أعلى ببضع نقاط من سعر العرض. القرق
بين العرض والطلب هو الفارق او السبريد، وهو عمولة الوسيط لوضع الترتيب.
سعر الطلب هو المكان الذي نفتح فيه أوامر الشراء ونغلق أوامر البيع. سعر العرض هو المكان الذي نفتح فيه البيع
الطلبات وإغلاق أوامر الشراء. ستحتاج إلى الإشارة إلى السعر الصحيح عند فتح أمر السوق ،
أو عند إغلاق أمر في السوق ، لذلك تذكر الفرق بين الاثنين.
أنواع الأوامر
هناك ثلاثة أنواع من الأوامر التي يمكن وضعها في MetaTrader: أوامر السوق والإيقاف والحد( market, stop and limit ).
أوامر السوق هي الأكثر شيوعًا market. يفتح أمر السوق مركزًا فورًا بالسعر السائد سعر العرض أو الطلب.
عند وضع أمر سوق في MQL ، يجب أن نحدد سعر الافتتاح (بشكل عام أحدث العروض أو
الطلبات). إذا كان سعر الافتتاح المحدد قديمًا ، بسبب سرعة الحركة في السوق أو التأخير
تنفيذ البرنامج ، ستحاول المحطة وضع الأمر بسعر السوق الحالي ، بشرط
إنه ضمن الحد الأقصى للانزلاق السعري slippage..
إذا قمت بتقديم طلب سوق باستخدام مربع حوار أمر جديد New Order في MetaTrader ، فسترى إعدادًا في
أسفل العنوان “تمكين أقصى انحراف عن السعر المعروض” “Enable maximum deviation from quoted price.. عندما يتم التحقق من هذا ، يمكنك بعد ذلك تحدد الحد الأقصى للانحراف بالنقاط. هذا هو الحد الأقصى للانزلاق السعري.
إذا انخفض السعر الحالي عن سعر الافتتاح المحدد لدينا ، زائد أو ناقص الانزلاق ، إعادة تسعير
سيحدث خطأ ولن يتم تقديم الطلب او تنفيذ الامر. ربما لاحظت هذا عند محاولة وضع
أمر سوق خلال سوق سريع الحركة. لاحظ أن وسطاء ECN / STP لا يستخدمون الانزلاق السعري
تحديد ، وسيفتح دائمًا أوامر السوق بالسعر الحالي.
أمر الإيقاف stop هو نوع من الأوامر المعلقة. الأوامر المعلقة هي طلب لفتح أمر سوق بسعر
سعر معين. يتم وضع أمر إيقاف الشراء buy stop فوق السعر الحالي ، بينما يتم وضع أمر إيقاف البيع
sell stop أقل من السعر الحالي. التوقع هو أن السعر سيرتفع أو ينخفض في النهاية إلى هذا المستوى و
الاستمرار في هذا الاتجاه ، مما يؤدي إلى ربح.
أمر الحد limit هو عكس أمر الإيقاف. يتم وضع أمر حد الشراء buy limit أسفل السعر الحالي ، بينما
يتم وضع أمر حد البيع sell limit فوق السعر الحالي. التوقع هو أن السعر سيرتفع أو ينخفض إلى
هذا المستوى ، مما يؤدي إلى تشغيل الأمر ، ثم الانعكاس.
يمكن تعيين وقت انتهاء الصلاحية expiration للأوامر المعلقة. إذا لم يتم تنفيذ الطلب بحلول وقت انتهاء الصلاحية ، فسيتم حذف الطلب تلقائيًا. لا يدعم جميع الوسطاء انتهاء صلاحية التداول.
عملية تقديم الطلب
تتضمن عملية تقديم طلب في MQL عدة خطوات. يجب أن نحدد ما يلي
قبل تقديم الطلب:
نوع الأمر المطلوب تقديمه – شراء أو بيع ؛ توقف stop أو سوق market أو حد limit.
• زوج العملات المطلوب تداوله – بشكل عام الرسم البياني الذي يتم إرفاق EA به.
• حجم اللوت. يمكن أن يكون هذا حجم عقد ثابت ، أو حجم يتم حسابه باستخدام روتين الإدارة المال.
• سعر فتح الأمر. بالنسبة لأوامر السوق ، سيكون هذا هو سعر العرض أو الطلب الحالي. اما بالنسبة
للأوامر المعلقة ، يجب أن يكون سعر الافتتاح على مسافة لا تقل عن السعر الحالي ، و
يجب أن يكون أعلى أو أقل من السعر الحالي كما هو مطلوب بواسطة نوع الأمر.
سعر وقف الخسارة. يمكن أن يكون وقف الخسارة سعرًا محددًا مسبقًا أو قيمة مؤشر أو سعرًا ثابتًا
عدد النقاط من سعر فتح الأمر ، أو يمكن حسابه ديناميكيًا باستخدام
روتين إدارة المخاطرة. يمكن وضع وقف الخسارة مع الأمر ، أو يمكن إضافته إلى
طلب بعد ذلك.
• سعر جني الأرباح. هذا بشكل عام عدد ثابت من النقاط من سعر فتح الأمر ،
على الرغم من أنه يمكن حسابها باستخدام طرق أخرى أيضًا. يمكن وضع جني الأرباح مع
الطلب ، أو يمكن إضافته إلى الأمر بعد ذلك.
• معرفات الطلب مثل تعليق الطلب comment ، أو “الرقم السحري” magic number الذي يحدد الطلب على أنه
يتم وضعها من قبل مستشار خبير محدد.
• سعر انتهاء صلاحية expiration وهواختياري للأوامر المعلقة ، إذا كان الوسيط يدعمها.
OrderSend
تُستخدم وظيفة OrderSend () لوضع أوامر فتح العقود في MQL. بناء الجملة كما يلي:
int OrderSend(string Symbol, int Type, double Lots, double Price,
int Slippage, double StopLoss, double TakeProfit, string Comment = NULL,
int MagicNumber = 0, datetime Expiration = 0, color Arrow = CLR_NONE);
Symbol : سلسلة تمثل زوج العملات المطلوب تداوله ، على سبيل المثال GBPUSD. يتم استخدام وظيفة Symbol() لزوج عملات الرسم البياني الحالي.
Type : نوع الأمر المطلوب تقديمه: شراء أو بيع ؛ السوق أو التوقف أو الحد. هذه قيمة عددية ،تمثلها الثوابت التالية:
OP_BUY – شراء أمر السوق (قيمة عدد صحيح 0).
OP_SELL – بيع أمر السوق (قيمة عدد صحيح 1).
OP_BUYSTOP – أمر إيقاف الشراء (قيمة عدد صحيح 2).
OP_SELLSTOP – أمر إيقاف البيع (قيمة عدد صحيح 3).
OP_BUYLIMIT – أمر حد الشراء (قيمة عدد صحيح 4).
OP_SELLLIMIT – أمر حد البيع (قيمة عدد صحيح 5).
Lots : حجم العقد المطلوب تداولها. يمكنك تحديد عقود ميني (0.1) أو ميكرو لوت (0.01) إذا كان لديك
وسيط يدعمها.
Price : السعر الذي يتم عنده فتح الأمر. بالنسبة لأمر الشراء في السوق ، سيكون هذا هو الطلب.
لأمر بيع في السوق ، سيكون هذا هو العطاء. بالنسبة للأوامر المعلقة ، سيكون هذا أي سعر صالح
أعلى أو أقل من السعر الحالي.
Slippage : الحد الأقصى للانزلاق بالنقاط. استخدم إعدادًا كبيرًا بدرجة كافية عند التشغيل التلقائي. الوسطاء الذين لا يستخدمون الانزلاق سوف يتجاهلون هذه المعلمة.
StopLoss : سعر وقف الخسارة. بالنسبة لأمر الشراء ، يكون سعر وقف الخسارة أقل من الأمر
سعر الافتتاح وأمر البيع أعلاه. إذا تم الضبط على 0 ، فلن يتم استخدام وقف الخسارة.
TakeProfit : سعر جني الأرباح. بالنسبة لأمر الشراء ، يكون جني الأرباح أعلى من الأمر
سعر الافتتاح وأمر البيع أدناه. إذا تم التعيين على 0 ، فلن يتم استخدام جني الأرباح.
Comment : سلسلة اختيارية ستكون بمثابة تعليق على الطلب. تظهر التعليقات
تحت علامة تبويب التجارة في نافذة المحطة الطرفية. يمكن أيضًا استخدام تعليقات الطلب كطلب
المعرف.
MagicNumber : قيمة عدد صحيح اختياري تحدد الطلب على أنه تم وضعه بواسطة ألمستشار الخبير المحدد. يوصى بشدة باستخدامه.
Expiration : وقت انتهاء صلاحية اختياري للأوامر المعلقة. ليس كل الوسطاء يقبلون أوقات انتهاء الصلاحية – بالنسبة لهؤلاء الوسطاء ، سينتج خطأ إذا تم تحديد وقت انتهاء الصلاحية.
Arrow : لون اختياري للسهم الذي سيتم رسمه على الرسم البياني ، يشير إلى
سعر الافتتاح والوقت. إذا لم يتم تحديد لون ، فلن يتم رسم السهم.
ترجع الدالة OrderSend () رقم تذكرة الأمر الذي تم تقديمه للتو. إذا لم يكن هناك أمر
تم وضعه ، نظرًا لوجود حالة خطأ ، ستكون القيمة المرتجعة -1.
يمكننا حفظ بطاقة الطلب في متغير عام أو ثابت لاستخدامها لاحقًا. إذا لم يتم تقديم الطلب
نظرًا لوجود حالة خطأ ، يمكننا تحليل الخطأ واتخاذ الإجراء المناسب بناءً على
إرجاع رمز الخطأ.
كيفية كتابة أوامر البيع والشراء Market
فيما يلي مثال على أمر شراء في السوق. سنفترض أن المتغيرات LotSize و Slippage
BuyStopLoss و BuyTakeProfit و MagicNumber تم تخصيصها.
كود:
OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,BuyStopLoss,BuyTakeProfit, "Buy Order",MagicNumber,0,Green);
ترجع الدالة Symbol () رمز الزوج الحالي. سنقوم بوضع أوامر في زوج الرسم البياني الحالي 99٪ من الوقت. يشير OP_BUY إلى أن هذا أمر شراء في السوق. Ask وهو متغير محددًا مسبقًا في MQL الذي يخزن أحدث عرض أسعار. (تذكر أن أوامر الشراء مفتوحة عند طلب السعر)
يتم ضبط الانزلاق السعري باستخدام متغير خارجي. معلمة الانزلاق هي عدد صحيح يشير إلى عدد النقاط للسماح بانزلاق السعر. إذا كان وسيطك يستخدم عروض أسعار مكونة من 4 أرقام (2 لأزواج الين) ، 1 ستكون النقطة تساوي نقطة واحدة. إذا كان الوسيط الخاص بك يقدم عروض أسعار مكونة من 3 و 5 أرقام ، فإن نقطة واحدة ستفعل يكون 0.1 نقطة. في هذه الحالة ، ستحتاج إلى إضافة صفر إضافي إلى نهاية إعداد الانزلاق السعري.
لقد أضفنا التعليق العام “طلب الشراء” إلى هذا الطلب. نظرًا لعدم وجود انتهاء صلاحية للسوق الطلبات ، معلمة انتهاء الصلاحية هي 0. أخيرًا ، نحدد ثابت اللون الأخضر لرسم أخضر السهم على الرسم البياني.
فيما يلي مثال على أمر بيع بالسوق ، باستخدام نفس المعلمات المذكورة أعلاه:
كود:
OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,SellStopLoss,SellTakeProfit, "Sell Order",MagicNumber,0,Red);
نستخدم OP_SELL كنوع الأمر لتحديد أمر بيع في السوق. نحن نستخدم Bid باعتباره فتح الأمر السعر ، ليعكس حقيقة أن أوامر البيع مفتوحة بسعر العرض. “أمر البيع” هو تعليقنا على الأمر ، ونستخدم اللون الأحمر كلون سهم للتمييز عن أوامر الشراء.
كيفية كتابة أمر معلق من نوع Stop
الفرق بين الأوامر المعلقة وأوامر السوق هو أن سعر فتح الأمر سيكون شيء آخر غير سعر السوق الحالي. يجب أن تكون قيم وقف الخسارة وجني الأرباح محسوبة بالنسبة لسعر فتح الأمر المعلق. في هذه الأمثلة ، سنستخدم السعر المعلق المتغير لسعر الأمر المعلق PendingPrice. يمكن أن يكون محسوبة على أساس خوارزمية التداول لدينا ، أو يمكن تعيينها كمعامل خارجي. بالنسبة لأمر إيقاف الشراء ، يجب أن يكون السعر المعلق أكبر من سعر الطلب الحالي. سنفترض ذلك تم حساب BuyStopLoss و BuyTakeProfit بشكل صحيح بالنسبة إلى السعر المعلق. هنامثال على وضع أمر إيقاف الشراء:
كود:
OrderSend(Symbol(),OP_BUYSTOP,LotSize,PendingPrice ,Slippage,BuyStopLoss, BuyTakeProfit,"Buy Stop Order",MagicNumber,0,Green);
لاحظ أننا نستخدم OP_BUYSTOP للإشارة إلى أمر إيقاف الشراء والسعر المعلق لفتح الأمر السعر. لم يتم تحديد وقت انتهاء صلاحية لهذا الطلب.
بالنسبة لأمر إيقاف البيع ، يجب أن يكون السعر المعلق أقل من سعر العطاء الحالي PendingPrice. في هذا المثال ، سنقوم أضف وقت انتهاء صلاحية الأمر ، باستخدام انتهاء الصلاحية المتغير Expiration. يجب أن يكون وقت انتهاء الصلاحية أكبر من وقت الخادم الحالي. فيما يلي مثال على وضع أمر إيقاف البيع:
كود:
OrderSend(Symbol(),OP_SELLSTOP,LotSize,PendingPrice,Slippage,SellStopLoss, SellTakeProfit,"Sell Stop Order",MagicNumber,Expiration,Red);
كيفية كتابة أمر معلق من نوع Limit
أوامر الحد مشابهة لأوامر الإيقاف ، فيما عدا أنه تم عكس سعر الأمر المعلق بالنسبة لـ السعر الحالي ونوع الأمر. لأوامر الشراء المعلقة ، يجب أن يكون سعر الأمر المعلق أقل من سعر العطاء الحالي Bid. فيما يلي مثال على أمر حد الشراء:
كود:
OrderSend(Symbol(),OP_BUYLIMIT,LotSize,PendingPrice,Slippage,BuyStopLoss, BuyTakeProfit,"Buy Limit Order",MagicNumber,0,Green);
لاحظ أننا استخدمنا OP_BUYLIMIT للإشارة إلى أمر حد الشراء. خلاف ذلك ، المعلمات لدينا متطابقة لأولئك الذين لديهم أوامر الإيقاف.لأمر حد البيع ، يجب أن يكون سعر الأمر المعلق أكبر من سعر الطلب الحالي. هنا مثال على أمر حد البيع:
كود:
OrderSend(Symbol(),OP_SELLLIMIT,LotSize,PendingPrice,Slippage,SellStopLoss, SellTakeProfit,"Sell Limit Order",MagicNumber,Expiration,Red);
حساب وقف الخسارة وجني الأرباح
هناك عدة طرق لحساب أسعار وقف الخسارة وجني الأرباح. الطريقة الأكثر شيوعًا هي
حدد عدد النقاط بعيدًا عن سعر فتح الأمر لوضع أمر وقف الخسارة. على سبيل المثال ، إذا كنا
وضع وقف الخسارة عند 50 نقطة ، وهذا يعني أن سعر وقف الخسارة سيكون على بعد 50 نقطة من موقعنا
سعر فتح الأمر.يمكننا أيضًا استخدام قيمة مؤشر أو معلمة خارجية أو نوع آخر من حساب السعر.
سنحتاج إلى التحقق من صحة سعر وقف الخسارة أو جني الأرباح.
حساب بالنقاط
الطريقة الأكثر شيوعًا لحساب التوقفات ، سنستخدم متغيرًا خارجيًا يكون فيه
يحدد المستخدم عدد النقاط لإيقاف الخسارة وجني الأرباح. ثم نحسب نقاط التوقف
بالنسبة لسعر فتح الأمر.
بالنسبة لأوامر الشراء في السوق ، سيكون سعر الافتتاح هو الطلب Ask ، أما بالنسبة لأوامر البيع في السوق ، فسيكون الافتتاح
السعر سيكون العطاء Bid. بالنسبة لأوامر الإيقاف والحد المعلقة ، نقوم بتعيين سعر افتتاح صالح وهو
شيء آخر غير سعر السوق الحالي. سنقوم بتعيين السعر المناسب للمتغير OpenPrice.
فيما يلي المتغيرات الخارجية التي سنستخدمها لإعدادات وقف الخسارة وجني الأرباح:
كود:
extern int StopLoss = 50; extern int TakeProfit = 100;
في هذا المثال ، قمنا بإدخال أمر إيقاف الخسارة بمقدار 50 نقطة ، وجني الأرباح بمقدار 100 نقطة. من المحتمل أنك رأيت
إعدادات مشابهة لتلك الموجودة في EAs التي استخدمتها.
لحساب وقف الخسارة ، نحتاج إلى إضافة أو طرح 50 نقطة من سعر فتح الأمر. اولا نحن
نحتاج إلى تحويل القيمة الصحيحة 50 إلى القيمة الكسرية التي سنستخدمها للجمع أو الطرح من
سعر الافتتاح. لأزواج الين ، 50 نقطة تساوي 0.50. بالنسبة لجميع الأزواج الأخرى ، يكون 0.0050.
لتحويل عدد صحيح إلى قيمة كسرية مناسبة ، نحتاج إلى مضاعفة StopLoss الخارجية متغير Point
النقطة
النقطة هي متغير محدد مسبقًا في MQL يُرجع أصغر وحدة سعر للعملة ، اعتمادًا على
عدد المنازل العشرية. بالنسبة لزوج عملات بأربعة منازل عشرية ، فإن النقطة هي 0.0001. لزوج الين ،
إنه 0.01.
دعنا نحسب وقف الخسارة لأمر شراء في السوق. سنقوم بتعيين سعر الطلب الحالي لـ OpenPrice ،
واستخدم ذلك كسعر فتح الأمر. سوف نتحقق لمعرفة ما إذا كان إعداد StopLoss الخاص بنا أكبر من
صفر. إذا كان الأمر كذلك ، فسنضرب StopLoss بالنقطة. ثم سنطرح ذلك من OpenPrice.
سيتم تخزين النتيجة في المتغير BuyStopLoss.
كود:
double OpenPrice = Ask; if(StopLoss > 0) double BuyStopLoss = OpenPrice – (StopLoss * Point); // 1.4600 - (50 * 0.0001) = 1.4550
إذا لم يكن StopLoss أكبر من الصفر ، فسيتم تهيئة BuyStopLoss بقيمة 0 ، ولا يوجد توقف
سيتم وضع الخسارة مع الطلب. بافتراض أن النقطة تساوي 0.0001 ، إذا كان سعر فتح الأمر
1.4600 ، ووقف الخسارة 50 نقطة ، ثم سعر وقف الخسارة لأمر الشراء سيكون 1.4600 –
(0.0050) = 1.4550.
في الآونة الأخيرة ، كان العديد من الوسطاء يتجهون نحو عروض أسعار النقطة الجزئية ، مع 3 منازل عشرية
لأزواج الين و 5 منازل عشرية لجميع الأزواج الأخرى. إذا كان الوسيط يستخدم أسعار النقطة الكسرية ، فعندئذٍ في
مثالنا أعلاه ، ستكون النقطة تساوي 0.00001.
إذا استخدمنا قيمة نقطة 0.00001 في مثال حساب وقف الخسارة أعلاه ، فسيكون وقف الخسارة
محسوبة على أنها 5 نقاط من سعر الافتتاح ، بدلاً من 50 نقطة. هذا يطرح مشكلة. للحصول على
القيمة الصحيحة ، سيتعين علينا إضافة صفر إضافي إلى إعداد وقف الخسارة – أي StopLoss = 500.
بدلاً من مطالبة المستخدم بإضافة صفر إضافي إلى إعدادات وقف الخسارة وجني الأرباح كل مرة
في الوقت الذي يتداولون فيه على وسيط من نقطة الكسر ، سننشئ وظيفة تعيد دائمًا 0.01 أو 0.0001 ،
بغض النظر عما إذا كان الوسيط يستخدم كسور النقاط أم لا. سنسمي هذه الوظيفة PipPoint ،
لأنها ستعيد دائمًا قيمة النقطة التي تساوي نقطة واحدة.
كود:
double PipPoint(string Currency) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01; else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001; return(CalcPoint); }
Currency هي رمز زوج العملات الذي نريد استرداد النقطة له.
ترجع الدالة MarketInfo () مع المعلمة MODE_DIGITS عدد الفاصلة العشرية
أماكن (أرقام) لهذا الزوج. تقوم عبارة if-else بتعيين قيمة النقطة المناسبة لملف
متغير CalcPoint ، اعتمادًا على عدد الأرقام.
فيما يلي مثال على استخدام هذه الوظيفة. ستستخدم زوج الرسم البياني الحالي
معظم الوقت ، لذلك سنقوم بتمرير الدالة Symbol () كوسيطة. هذا سيعيد النقطة للرسم البياني الحالي.
كود:
double UsePoint = PipPoint(Symbol());
إليك مجموعة من الأمثلة باستخدام أزواج محددة:
كود:
double UsePoint = PipPoint(EURUSD); // Result is 0.0001 double UsePoint = PipPoint(USDJPY); // Result is 0.01
سنستخدم هذه الوظيفة لإيجاد قيمة نقطة واحدة لبقية هذه الدروس
كما أوضحنا أن متغير النقطة Point لن يعمل بشكل صحيح على وسطاء البيب الكسري عندما
حساب قيمة النقطة الواحدة. لا يمكنك أبدًا افتراض أن EA سيتم استخدامه فقط على 2 و 4
وسيط رقم ، لذلك من الضروري تحديد قيمة النقطة تلقائيًا باستخدام وظيفة
PipPoint ().
الانزلاق والنقطة
دعنا ننشئ وظيفة لتغيير حجم معامل الانزلاق بشكل صحيح. مثل
المذكورة سابقًا ، في الوسيط الذي لديه عروض أسعار كسرية ، معامل الانزلاق
سيحتاج وظيفة OrderSend () إلى الزيادة بمعامل 10 للحصول على الانزلاق الصحيح
القيمة.
ستعمل هذه الوظيفة تلقائيًا على ضبط معلمة الانزلاق على عدد النقاط المحدد بواسطة
معلمة Slippage الخارجية:
كود:
int GetSlippage(string Currency, int SlippagePips) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 4) double CalcSlippage = SlippagePips; else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips * 10; return(CalcSlippage); }
نقوم بتمرير رمز العملة ومعامل الانزلاق الخارجي كوسائط. إذا كانت العملة تستخدم
علامات الاقتباس المكونة من 2 أو 4 أرقام ، نستخدم وسيطة SlippagePips غير المتغيرة كإعداد للإنزلاق. إذا كان
تستخدم العملة أسعارًا مكونة من 3 أو 5 أرقام ، ونضرب SlippagePips في 10. إليك كيفية استخدام هذه الوظيفة
في OrderSend():
كود:
// External parameters extern int Slippage = 5; // Order placement OrderSend(Symbol(),OP_BUY,LotSize,Ask,GetSlippage( Symbol(),Slippage),BuyStopLoss, BuyTakeProfit,"Buy Order",MagicNumber,0,Green);
سيكون الانزلاق في هذا المثال 5 نقاط ، وسيتم تعديل معامل الانزلاق تلقائيًا
بناءً على عدد الأرقام في عرض أسعار العملة.
الانزلاق والنقطة كمتغيرات عامة
عيب استخدام دالة لإرجاع النقطة أو قيمة الانزلاق هو الكتابة الإضافية المطلوبة
لمتغيرات الدالة. سننشئ متغيرات عالمية تحمل النقطة المناسبة و
قيم الانزلاق السعري لزوج العملات الخاص بنا ، وسنستخدمها في أي وقت نحتاج إليه للإشارة إلى تلك القيم.
نظرًا لأن هذه القيم لن تتغير أبدًا أثناء تنفيذ البرنامج ، فسنحسب هذه القيم في دالة
init () . سنفترض أن المتغير الصحيح الخارجي Slippage موجود بالفعل:
كود:
/ Global variables double UsePoint; int UseSlippage; int init() { UsePoint = PipPoint(Symbol()); UseSlippage = GetSlippage(Symbol(),Slippage); }
من الآن فصاعدًا ، سنستخدم UsePoint و UseSlippage للإشارة إلى هذه القيم. الكود أعلاه
يفترض أن المستشار الخبير الخاص بك يقوم بوضع أوامر على عملة واحدة فقط. سيكون هذا هو الحال 98٪ من الوقت ،
ولكن إذا كنت تنشئ مستشارًا خبيرًا يضع أوامر على عملات متعددة (أو على عملة ما
بخلاف الرسم البياني الحالي) ، ستحتاج إلى استخدام وظائف PipPoint () و GetSlippage () في كل
مرة تحتاج لحساب هذه القيم.
وظيفة MarketInfo():
استخدمنا وظيفة MarketInfo () أعلاه لاسترداد قيمة النقطة وعدد الأرقام في لأي زوج.
وظيفة MarketInfo () لها استخدامات عديدة ، وسوف تستخدمها لاسترداد
معلومات الأسعار الضرورية في برامجك. فيما يلي بناء الجملة لوظيفة MarketInfo ():
كود:
double MarketInfo(string Symbol, int RequestType);
الوسيطة Symbol هي ببساطة رمز العملة الذي تريد استرداد المعلومات الخاصة به.
بالنسبة لرمز المخطط الحالي ، يمكن استخدام الوظيفة Symbol (). للرموز الأخرى ، ستحتاج إلى
تحديد رمز العملة ، مثل EURJPY.
RequestType هو عدد صحيح ثابت يمثل المعلومات التي تطلبها من
وظيفة MarketInfo. فيما يلي قائمة بأكثر ثوابت MarketInfo () فائدة. يمكن العثور على قائمة كاملة في
مرجع MQL ، ضمن الثوابت القياسية – MarketInfo.
MODE_POINT – قيمة النقطة. على سبيل المثال ، 0.01 أو 0.00001.
MODE_DIGITS – عدد المنازل العشرية في السعر. سيكون 2 أو 3 لأزواج الين ، و 4
أو 5 لكل أزواج أخرى.
MODE_SPREAD – الانتشار الحالي. على سبيل المثال ، 3 نقاط (أو 30 لسمسار النقطة الجزئية).
MODE_STOPLEVEL – مستوى التوقف. على سبيل المثال ، 3 نقاط (أو 30 لسمسار النقطة الجزئية).
تُستخدم معرّفات الطلبات هذه بشكل عام عند التحقق من معلومات الأسعار لعملة أخرى ، أو
في أي مكان حيث قد يكون الرمز أي شيء بخلاف رمز المخطط الحالي:
MODE_BID – سعر العطاء الحالي (البيع) للرمز المحدد.
MODE_ASK – سعر الطلب الحالي (الشراء) للرمز المحدد.
MODE_LOW – أدنى مستوى للشريط الحالي للرمز المحدد.
MODE_HIGH – أعلى مستوى للشريط الحالي للرمز المحدد.
حساب وقف الخسارة
الآن وقد حددنا قيمة النقطة المناسبة ، حان الوقت لحساب وقف الخسارة. لأوامر الشراء ،
سيكون وقف الخسارة أقل من سعر فتح الأمر ، وبالنسبة لأوامر البيع ، سيكون وقف الخسارة أعلى من
سعر فتح الأمر.
إليك حساب وقف الخسارة الخاص بأمر الشراء من وقت سابق ، مع إضافة متغير UsePoint. لاحظ أن
لقد قمنا بتعيين سعر الطلب Ask لمتغير OpenPrice:
كود:
double OpenPrice = Ask; if(StopLoss > 0) double BuyStopLoss = OpenPrice – (StopLoss * UsePoint);
وإليك طريقة حساب أمر البيع. لاحظ أننا قمنا بتعيين سعر العطاء Bid على OpenPrice و
التي نضيفها ببساطة بدلاً من طرحها:
كود:
double OpenPrice = Bid; if(StopLoss > 0) double SellStopLoss = OpenPrice + (StopLoss * UsePoint);
بالنسبة للأوامر المعلقة ، سيتم حساب وقف الخسارة بالنسبة لسعر الأمر المعلق. في هذه الحالة،
استخدم OpenPrice المتغير لتخزين سعر الأمر المعلق بدلاً من سعر السوق الحالي.
سيكون المنطق مطابقًا للأمثلة أعلاه.
حساب جني الأرباح
يشبه حساب سعر جني الأرباح حساب وقف الخسارة ، باستثناء أننا سننعكس
جمع وطرح. بالنسبة لأمر الشراء ، سيكون سعر جني الأرباح أعلى من سعر فتح الأمر ،
وبالنسبة لأمر البيع ، سيكون سعر جني الأرباح أقل من سعر فتح الأمر. سنفترض أن
تم تخصيص السعر المناسب لـ OpenPrice:
كود:
if(TakeProfit > 0) double BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint); if(TakeProfit > 0) double SellTakeProfit = OpenPrice - (TakeProfit * UsePoint);
طرق إيقاف الخسارة البديلة
هناك طرق أخرى لتحديد أسعار وقف الخسارة وجني الأرباح. على سبيل المثال ، ارتفاع حديث أو
منخفض ، أو يمكن استخدام قيمة المؤشر لتحديد وقف الخسارة. دعونا نوضح كيف يمكننا ذلك
احسب هذه.
لنفترض أننا نستخدم نظام تداول يضع وقف الخسارة تحت قاع الشريط بمقدار نقطتين
. نستخدم مصفوفة الأسعار المحددة مسبقًا Low [] لاسترداد أدنى مستوى للشريط. منخفض [0] هو أدنى مستوى من
العمود الحالي ، المنخفض [1] هو أدنى مستوى للشريط السابق ، وهكذا.
بمجرد تحديد أدنى مستوى للشريط الحالي ، نضرب 2 في UsePoint للحصول على قيمة عشرية ،
وطرح ذلك من قاعنا:
كود:
double BuyStopLoss = Low[0] – (2 * UsePoint);
لذلك إذا كان أدنى مستوى للشريط هو 1.4760 ، فسيتم وضع وقف الخسارة عند 1.4758.
ولكن ربما ترغب في وضع وقف الخسارة عند أدنى قاع لآخر عدد س من الأشرطة. هناك
وظيفة مدمجة في MetaTrader فقط من أجل ذلك. تُرجع iLowest () قيمة التحول التي تشير إلى الشريط الذي يحتوي على
أدنى قيمة في نطاق زمني محدد. يمكننا استخدام قيم عالية أو منخفضة أو مفتوحة أو قريبة.
فيما يلي مثال لكيفية استخدام iLowest () للعثور على أدنى مستوى أدنى من آخر 10 أشرطة:
كود:
int CountBars = 10; int LowestShift = iLowest(NULL,0,MODE_LOW,CountBars,0); double BuyStopLoss = Low[LowestShift];
المعلمة الأولى لـ iLowest () هي رمز العملة – NULL تعني أننا نستخدم الرمز او( الزوج) الحالي.
تستخدم العديد من الدالات في MQL ثابت السلسلة NULL للإشارة إلى رمز المخطط الحالي. ال
المعلمة الثانية هي فترة الرسم البياني – 0 تشير إلى إطار الرسم البياني الحالي.
MODE_LOW هو ثابت عدد صحيح يحدد مصفوفة سلسلة السعر المنخفض. بعبارة أخرى ، نحن
نبحث عن أدنى مستوى أدنى لأشرطة التعداد الأخيرة. إذا أردنا العثور على أدنى إغلاق ، على سبيل المثال ،
سنستخدم MODE_CLOSE. يمكنك العثور على جميع ثوابت السلسلة في مرجع MQL أسفل
الثوابت القياسية – صفائف متسلسلة.
CountBars هو عدد الأشرطة التي نريد البحث عنها ، في هذه الحالة 10. أخيرًا ، المعلمة الأخيرة هي
موقع الانطلاق. 0 هو الشريط الحالي. للبدء من شريط سابق ، عد للخلف من الشريط الحالي
– الشريط السابق هو 1 ، والشريط الذي قبله هو 2 ، إلخ.
ناتج دالة iLowest () هو عدد صحيح يشير إلى التحول للخلف للشريط باستخدام
أدنى قيمة في سلسلة الأسعار. في المثال أعلاه ، إذا قامت iLowest () بإرجاع 6 ، فهذا يعني أن
أدنى انخفاض هو 6 أشرطة للخلف. نقوم بتخزين هذه القيمة في المتغير LowestShift. للعثور على السعر الفعلي ،
نحن ببساطة نسترجع قيمة السعر المنخفضة [LowestShift] ، أو بعبارة أخرى ، Low [6].
إذا أردت حساب وقف الخسارة لأمر بيع باستخدام هذه الطريقة ، فإن وظيفة iHighest ()
يعمل بنفس الطريقة. بالرجوع إلى المثال أعلاه ، يمكنك استخدام MODE_HIGH لمصفوفة السلسلة الخاصة بك.
إليك مثال باستخدام مؤشر. لنفترض أن لدينا متوسط متحرك ، ونريد استخدام
خط المتوسط المتحرك هو وقف الخسارة. سنستخدم المتغير MA لتمثيل قيمة المتوسط المتحرك
للشريط الحالي. كل ما عليك فعله هو تعيين قيمة المتوسط المتحرك الحالي لإيقاف الخسارة:
كود:
double BuyStopLoss = MA;
إذا كان خط المتوسط المتحرك حاليًا عند 1.6894 ، فسيكون هذا هو وقف الخسارة.
هذه هي ببساطة أكثر الطرق شيوعًا لتحديد سعر وقف الخسارة أو جني الأرباح.
يمكن تطوير الأساليب الاخرى باستخدام معرفتك بالتحليل الفني أو خيالك.
استرجاع معلومات الطلب
بمجرد أن نضع طلبًا بنجاح ، سنحتاج إلى استرداد بعض المعلومات حول الطلب إذا
نريد تعديله أو إغلاقه. نقوم بذلك باستخدام وظيفة OrderSelect (). لاستخدام OrderSelect () ،
يمكننا إما استخدام رقم بطاقة الطلب ، أو يمكننا المرور عبر مجموعة الطلبات المفتوحة و
حدد كل منهم بالترتيب.
بمجرد اختيار طلب باستخدام OrderSelect () ، يمكننا استخدام مجموعة متنوعة من معلومات الطلب
وظائف لإرجاع معلومات حول الأمر ، بما في ذلك وقف الخسارة الحالي ، وجني الأرباح ، والأمر
سعر الافتتاح وسعر الإغلاق والمزيد.
OrderSelect()
فيما يلي بناء الجملة لوظيفة OrderSelect ():
كود:
bool OrderSelect(int Index, int Select, int Pool = MODE_TRADES)
Index – هذا إما رقم تذكرة الأمر الذي نريد تحديده ، أو المركز
في تجمع الطلبات. ستشير المعلمة Select إلى أي من هؤلاء نستخدمه.
Select – ثابت يشير إلى ما إذا كانت معلمة الفهرس هي رقم تذكرة أم أمر
موقف التجمع:
SELECT_BY_TICKET – قيمة معلمة الفهرس هي رقم تذكرة الطلب.
SELECT_BY_POS – قيمة معلمة الفهرس هي موضع تجمع الطلبات.
Pool – ثابت اختياري يشير إلى تجمع الأوامر: الأوامر المعلقة / المفتوحة ، أو الأوامر المغلقة.
MODE_TRADES – بشكل افتراضي ، نحن نفحص مجموعة الطلبات المفتوحة حاليًا.
MODE_HISTORY – يفحص تجمع الأوامر المغلقة (سجل الطلبات).
إذا حددت الدالة OrderSelect () موقع الطلب بنجاح ، فستكون قيمة الإرجاع صحيحة ،
خلاف ذلك ، ستكون القيمة المعادة خطأ.
فيما يلي مثال على وظيفة OrderSelect () باستخدام رقم تذكرة الطلب. متغير التذكرة
يجب أن تحتوي على بطاقة طلب صالحة:
كود:
OrderSelect(Ticket,SELECT_BY_TICKET);
بعد استدعاء وظيفة OrderSelect () ، يمكننا استخدام أي من وظائف معلومات الطلب
لاسترداد معلومات حول هذا الطلب. قائمة كاملة بالوظائف التي يمكن استخدامها
يمكن العثور على OrderSelect () في مرجع MQL ضمن وظائف التداول. فيما يلي قائمة بالأكثر
وظائف معلومات الطلب شائعة الاستخدام:
OrderSymbol () – رمز الأداة التي تم وضع الأمر المحدد عليها.
OrderType () – نوع الأمر للأمر المحدد: شراء أو بيع ؛ السوق أو التوقف أو الحد. ال
القيمة المرجعة هي عدد صحيح مطابق لثوابت نوع الأمر في .
OrderOpenPrice () – سعر فتح الأمر المحدد.
OrderLots () – حجم اللوت للأمر المحدد.
OrderStopLoss () – سعر وقف الخسارة للأمر المحدد.
OrderTakeProfit () – سعر جني الأرباح للأمر المحدد.
OrderTicket () – رقم تذكرة الأمر المحدد. تستخدم بشكل عام عند ركوب الدراجات
من خلال تجمع الطلبات مع المعلمة SELECT_BY_POS.
OrderMagicNumber () – الرقم السحري للترتيب المحدد. عند ركوب الدراجات من خلال
الطلبات ، ستحتاج إلى استخدام هذا لتحديد الطلبات التي قدمتها EA الخاص بك.
OrderComment () – التعليق الذي تم وضعه مع الطلب. يمكن استخدام هذا كملف
معرّف الطلب الثانوي.
OrderClosePrice () – سعر إغلاق الأمر المحدد. يجب أن يكون الطلب بالفعل
مغلق (أي موجود في تجمع محفوظات الطلبات).
OrderOpenTime () – وقت فتح الأمر المحدد.
OrderCloseTime () – وقت إغلاق الأمر المحدد.
OrderProfit () – إرجاع الربح (بعملة الإيداع) للأمر المحدد.
سنحتاج إلى استخدام OrderSelect () قبل إغلاق أو تعديل أمر. دعونا نوضح كيف نستخدم
OrderSelect() لإغلاق الأمر.
أوامر الإغلاق
عندما نغلق طلب السوق ، فإننا نغادر الصفقة بسعر السوق الحالي. لأوامر الشراء ،
نغلق عند سعر العرض ، وبالنسبة لأوامر البيع ، نغلق عند الطلب. للأوامر المعلقة ، نحن ببساطة
حذف الأمر من مجمع التجارة (المراكز التي قمنا بدخولها او اغلاقها ).
OrderClose()
نقوم بإغلاق أوامر السوق باستخدام وظيفة OrderClose (). هنا بناء الجملة:
كود:
bool OrderClose(int Ticket, double Lots, double Price, int Slippage, color Arrow);
Ticket- رقم التذكرة لأمر السوق للإغلاق.
Lots- عدد اللوتات المطلوب إغلاقها. يسمح معظم الوسطاء بالإغلاق الجزئي.
Price- السعر المفضل لإغلاق الصفقة. لأوامر الشراء ، سيكون هذا هو
سعر العطاء الحالي ، وأوامر البيع ، سعر الطلب الحالي.
Slippage – الانزلاق السعري المسموح به من سعر الإغلاق بالنقاط.
Color- ثابت اللون لسهم الإغلاق. إذا لم تتم الإشارة إلى أي لون ، فلن يظهر أي سهم
يمكنك إغلاق جزء من الصفقة عن طريق تحديد حجم جزئي للوت. على سبيل المثال ، إذا كان لديك صفقة مفتوحة
بحجم 2.00 ، وتريد إغلاق نصف الصفقة ، ثم حدد عقدًا واحدًا للعقد. لاحظ أنه لا يدعم جميع الوسطاء عمليات الإغلاق الجزئي.
من المستحسن أنه إذا كنت بحاجة إلى إغلاق مركز في عدة أجزاء ، فيجب عليك وضع عدة مرات
أوامر بدلاً من القيام بإغلاق جزئي. باستخدام المثال أعلاه ، يمكنك وضع أمرين بقيمة 1.00
لوت لكل منها ، ثم ببساطة أغلق أحد الأوامر عندما تريد إغلاق نصف المركز ، سنقوم دائمًا بإغلاق الطلب الكامل.
المثال التالي يغلق أمر شراء في السوق:
كود:
OrderSelect(CloseTicket,SELECT_BY_TICKET); if(OrderCloseTime() == 0 && OrderType() == OP_BUY) { double CloseLots = OrderLots(); double ClosePrice = Bid; bool Closed = OrderClose(CloseTicket,CloseLots,ClosePrice,UseSli ppage,Red); }
متغير CloseTicket هو رقم تذكرة الأمر الذي نرغب في إغلاقه. اختر ()
تحدد الوظيفة الطلب ، وتسمح لنا باسترداد معلومات الطلب. نحن نستخدم
OrderCloseTime () للتحقق من وقت إغلاق الأمر لمعرفة ما إذا كان الأمر قد تم إغلاقه بالفعل. لو
تُعيد OrderCloseTime () 0 ، ثم نعلم أن الأمر لم يُغلق بعد.
نحتاج أيضًا إلى التحقق من نوع الأمر ، لأن نوع الأمر يحدد سعر الإغلاق للأمر.
ترجع الدالة OrderType () عددًا صحيحًا يشير إلى نوع الأمر. إذا كان طلب شراء في السوق ،
المشار إليه بواسطة OP_BUY ، سنستمر في إغلاق الأمر.
بعد ذلك ، نسترجع حجم حصة الأمر باستخدام OrderLots () ، ونخزن هذه القيمة في CloseLots.
تعيين سعر العطاء الحالي إلى ClosePrice. ثم نسمي وظيفة OrderClose () للإغلاق
طلبنا.
نحدد إعداد Slippage الخاص بنا باستخدام UseSlippage ، ونشير إلى السهم الأحمر الذي ستتم طباعته على
جدول. يتم تخزين قيمة إرجاع منطقية في المتغير Closed. إذا تم إغلاق الأمر
بنجاح ، فإن قيمة Closed ستكون صحيحة true ، وإلا ستكون خطأ false.
لإغلاق أمر بيع في السوق ، كل ما عليك فعله هو تغيير نوع الأمر إلى OP_SELL وتعيين
سعر الطلب Ask الحالي للإغلاق
كود:
if(OrderCloseTime() == 0 && OrderType() == OP_SELL) { double CloseLots = OrderLots(); double ClosePrice = Ask; bool Closed = OrderClose(CloseTicket,CloseLots,ClosePrice,UseSli ppage,Red); }
هناك وظيفة منفصلة لإغلاق الأوامر المعلقة. يحتوي OrderDelete () على وسيطتين ، وهما
رقم التذكرة ولون السهم. لا يلزم سعر إغلاق أو حجم عقد أو انزلاق. ها هو الكود
لإغلاق أمر إيقاف شراء معلق:
كود:
OrderSelect(CloseTicket,SELECT_BY_TICKET); if(OrderCloseTime() == 0 && OrderType() == OP_BUYSTOP) { bool Deleted = OrderDelete(CloseTicket,Red); }
كما فعلنا مع وظيفة OrderClose () في الدرس السابق ، نحتاج إلى التحقق من نوع الأمر للتأكد من أنه
طلب معلق. ثوابت نوع الأمر المعلق هي OP_BUYSTOP و OP_SELLSTOP و OP_BUYLIMIT و
OP_SELLLIMIT. لإغلاق أنواع أخرى من الأوامر المعلقة ، ما عليك سوى تغيير نوع الأمر.
إذا تم تنفيذ الأمر ، فهو الآن أمر سوق ، ويجب إغلاقه باستخدام OrderClose ()
بدلاً من.
مستشار خبير بسيط
دعونا نرى كيف ستعمل الشفرة التي ناقشناها حتى الآن في مستشار خبير. هذا بسيط
نظام المتوسط المتحرك. يتم فتح أمر الشراء عندما يكون المتوسط المتحرك لفترة 10 أكبر
من المتوسط المتحرك لمدة 20 فترة. عندما يكون المتوسط المتحرك لفترة 10 أقل من فترة 20
المتوسط المتحرك ، يتم فتح أمر بيع.
سوف يتناوب المستشار الخبير هذا بين أوامر البيع والشراء المفتوحة. سيتم إغلاق الطلبات عندما يتم الأمر
فتح في الاتجاه المعاكس ، أو عن طريق وقف الخسارة أو جني الأرباح. سوف نستخدم المتغيرات العالمية
BuyTicket و SellTicket لتخزين تذكرة الطلب الأخيرة. عندما يتم فتح أمر جديد ، فإن الأخير
تم مسح تذكرة الطلب. هذا يمنع عدة أوامر متتالية من الفتح.
كود:
#property copyright "Mohammad alturk" // External variables extern double LotSize = 0.1; extern double StopLoss = 50; extern double TakeProfit = 100; extern int Slippage = 5; extern int MagicNumber = 123; extern int FastMAPeriod = 10; extern int SlowMAPeriod = 20; // Global variables int BuyTicket; int SellTicket; double UsePoint; int UseSlippage; // Init function int init() { UsePoint = PipPoint(Symbol()); UseSlippage = GetSlippage(Symbol(),Slippage); } // Start function int start() { // Moving averages double FastMA = iMA(NULL,0,FastMAPeriod,0,0,0,0); double SlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,0); // Buy order if(FastMA > SlowMA && BuyTicket == 0) { OrderSelect(SellTicket,SELECT_BY_TICKET); // Close order if(OrderCloseTime() == 0 && SellTicket > 0) { double CloseLots = OrderLots(); double ClosePrice = Ask; bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red); } double OpenPrice = Ask; // Calculate stop loss and take profit if(StopLoss > 0) double BuyStopLoss = OpenPrice - (StopLoss * UsePoint); if(TakeProfit > 0) double BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint); // Open buy order BuyTicket = OrderSend(Symbol(),OP_BUY,LotSize,OpenPrice,UseSli ppage, BuyStopLoss,BuyTakeProfit,"Buy Order",MagicNumber,0,Green); SellTicket = 0; } // Sell Order if(FastMA < SlowMA && SellTicket == 0) { OrderSelect(BuyTicket,SELECT_BY_TICKET); if(OrderCloseTime() == 0 && BuyTicket > 0) { CloseLots = OrderLots(); ClosePrice = Bid; Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlipp age,Red); } OpenPrice = Bid; if(StopLoss > 0) double SellStopLoss = OpenPrice + (StopLoss * UsePoint); if(TakeProfit > 0) double SellTakeProfit = OpenPrice - (TakeProfit * UsePoint); SellTicket = OrderSend(Symbol(),OP_SELL,LotSize,OpenPrice,UseSl ippage, SellStopLoss,SellTakeProfit,"Sell Order",MagicNumber,0,Red); BuyTicket = 0; } return(0); } // Pip Point Function double PipPoint(string Currency) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01; else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001; return(CalcPoint); } // Get Slippage Function int GetSlippage(string Currency, int SlippagePips) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 4) double CalcSlippage = SlippagePips; else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips * 10; return(CalcSlippage); }
نبدأ بتوجيه المعالج المسبق لحقوق الطبع والنشر #property الخاص بنا والذي يحدد الرمز على أنه ينتمي
لنا. المتغيرات الخارجية هي التالية . نعلن BuyTicket وSellTicket كمتغيرات عالمية
بهذه الطريقة يتم تخزين بطاقة الطلب بين عمليات تنفيذ البرنامج.
يمكن أن يكون قد أعلنا عنها أيضًا كمتغيرات ثابتة داخل وظيفة start ().
نضيف UsePoint و UseSlippage كمتغيرات عامة – سنحسب قيمة هذه المتغيرات التالية. ملكنا
يتم تشغيل وظيفة init () أولاً. نحن نسمي وظائف PipPoint () و GetSlippage ()
وقم بتعيين قيم الإرجاع لمتغيراتنا العامة. سنستخدم هذه عندما
الإشارة إلى قيم النقطة أو الانزلاق السعري في باقي المستشار الخبير لدينا.
التالي هو وظيفة start () ، تنفيذ البرنامج الرئيسي لدينا. لقد استبعدنا deinit () ، لأننا فعلنا ذلك
لا فائدة له هنا. تحسب الدالة iMA () المتوسط المتحرك. يحتفظ متغير FastMA بامتداد
المتوسط المتحرك لمدة 10 فترات ، والذي يتم تعيينه باستخدام متغير FastMAPeriod. متغير SlowMA هو
متوسط متحرك لمدة 20 فترة ، تم ضبطه باستخدام SlowMAPeriod. تم تعيين كل شيء آخر على الوضع الافتراضي (
المتوسط المتحرك البسيط محسوبًا على سعر الإغلاق).
نستخدم عامل التشغيل if لتحديد شروط فتح الأمر. إذا كانت الفترة الحالية 10 تتحرك
المتوسط (FastMA) أكبر من المتوسط المتحرك لـ 20 فترة (SlowMA) ، وإذا كان BuyTicket
يساوي 0 ، سنفتح أمر شراء.
قبل أن نفتح أمر الشراء ، سنغلق أمر البيع الحالي ، إن وجد. نحن نستخدم OrderSelect ()
لاسترداد بطاقة SellTicket الحالية. إذا كان وقت إغلاق الأمر 0 (يشير إلى أن الأمر لم يحدث بعد
تم إغلاقه) ، وتذكرة SellTicket أكبر من 0 (مما يشير إلى أن SellTicket من المحتمل أن تكون صالحة) ،
سنمضي قدمًا ونغلق أمر البيع. نقوم باسترداد حجم اللوت لأمر البيع والحجم الحالي
سعر الطلب ، وهو سعر الإغلاق لأمر البيع. ثم نقوم بإغلاق أمر البيع باستخدام
OrderClose ().
بعد ذلك ، نقوم بتعيين سعر الطلب الحالي لمتغير OpenPrice – سيكون هذا هو سعر الافتتاح
طلب الشراء لدينا. نحسب وقف الخسارة وجني الأرباح بالنسبة لسعر الافتتاح ، والتحقق أولاً
للتأكد من أننا حددنا قيمة StopLoss أو TakeProfit في الإعدادات. ثم نضع
الطلب باستخدام وظيفة OrderSend () ، وتخزين تذكرة الطلب في BuyTicket. أخيرًا ، نحن واضحون
قيمة SellTicket ، مما يسمح بوضع أمر بيع آخر عند شرط الأمر
تصبح صالحة.
تتبع كتلة أمر البيع نفس منطق كتلة أمر الشراء. نغلق أمر الشراء أولاً ، و
استخدم العطاء Bid باعتباره OpenPrice وأمر الشراء ClosePrice. وقف الخسارة وجني الأرباح
الحسابات معكوسة.
تنتهي وظيفة start () بعامل إرجاع. PipPoint () المخصص لدينا و GetSlippage ()
يتم تحديد الوظائف في النهاية بعد وظيفة start(). سنقوم بتضمين هذه الوظائف في كل
مثال في الدروس القادمة ان شاء الله.
استخدام الأوامر المعلقة
دعونا نعدل المستشار الخبير الخاص بنا لاستخدام الأوامر المعلقة. سنستخدم أوامر الإيقاف في هذا المثال. عند
المتوسط المتحرك السريع أكبر من المتوسط المتحرك البطيء ، وسوف نضع أمر إيقاف شراء بمقدار 10 نقاط
فوق الارتفاع الحالي. عندما يكون العكس صحيحًا ، سنضع أمر إيقاف بيع بمقدار 10 نقاط أسفل
المنخفض الحالي. دعنا نعلن عن متغير خارجي لضبط هذا الإعداد ، يسمى PendingPips.
كود:
extern int PendingPips = 10;
نقوم بإضافة وظيفة OrderDelete () إلى مجموعة أوامر البيع والشراء لإغلاق أي
أوامر معلقة شاغرة. نحتاج إلى التحقق من نوع الأمر الخاص بالطلب المشار إليه بواسطة SellTicket للتأكد
أننا نستخدم الوظيفة الصحيحة لإغلاق الأمر.
كود:
OrderSelect(SellTicket,SELECT_BY_TICKET); // Close Order if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELL) { double CloseLots = OrderLots(); double ClosePrice = Ask; bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red); if(Closed == true) SellTicket = 0; } // Delete Order else if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELLSTOP) { bool Deleted = OrderDelete(SellTicket,Red); if(Deleted == true) SellTicket = 0; }
نستخدم OrderType () للتحقق مما إذا كان أمر البيع المحدد أمر سوق أم أمر إيقاف. لو
إنه أمر سوق ، نقوم بإغلاقه باستخدام OrderClose (). إذا كان الأمر معلقًا ، فإننا نغلقه باستخدام
OrderDelete().
إليك حساب سعر الأمر المعلق. نقوم ببساطة بتحويل PendingPips إلى قيمة كسرية باستخدام
UsePoint ، وقم بإضافتها إلى سعر الإغلاق الحالي. سنقوم بتخزين هذه القيمة في متغير PendingPrice.
بعد ذلك ، نقوم بحساب وقف الخسارة وجني الأرباح بالنسبة لسعر الأمر المعلق لدينا. أخيرًا ، نضع
طلبنا المعلق باستخدام OrderSend () ، تخزين نتيجة التجارة في BuyTicket المتغير:
كود:
double PendingPrice = Close[0] + (PendingPips * UsePoint); if(StopLoss > 0) double BuyStopLoss = PendingPrice - (StopLoss * UsePoint); if(TakeProfit > 0) double BuyTakeProfit = PendingPrice + (TakeProfit * UsePoint); BuyTicket = OrderSend(Symbol(),OP_BUYSTOP,LotSize,PendingPrice ,UseSlippage, BuyStopLoss,BuyTakeProfit,"Buy Stop Order",MagicNumber,0,Green); SellTicket = 0; The code below shows the changes for the sell stop order block: OrderSelect(BuyTicket,SELECT_BY_TICKET); // Close Order if(OrderCloseTime() == 0 && BuyTicket > 0 && OrderType() == OP_BUY) { CloseLots = OrderLots(); ClosePrice = Bid; Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlipp age,Red); if(Closed == true) BuyTicket = 0; } // Delete Order else if(OrderCloseTime() == 0 && BuyTicket > 0 && OrderType() == OP_BUYSTOP) { Closed = OrderDelete(BuyTicket,Red); if(Closed == true) BuyTicket = 0; } PendingPrice = Close[0] - (PendingPips * UsePoint); double SellStopLoss = PendingPrice + (StopLoss * UsePoint); double SellTakeProfit = PendingPrice - (TakeProfit * UsePoint); SellTicket = OrderSend(Symbol(),OP_SELLSTOP,LotSize,PendingPric e,UseSlippage, SellStopLoss,SellTakeProfit,"Sell Stop Order",MagicNumber,0,Red); BuyTicket = 0;
هذا الكود الكامل لاكسبيرت الاوامر المعلقة
كود:
#property copyright"Mohammad alturk" // External variables extern double LotSize = 0.1; extern double StopLoss = 50; extern double TakeProfit = 100; extern int PendingPips = 10; extern int Slippage = 5; extern int MagicNumber = 123; extern int FastMAPeriod = 10; extern int SlowMAPeriod = 20; // Global variables int BuyTicket; int SellTicket; double UsePoint; int UseSlippage; // Init function int init() { UsePoint = PipPoint(Symbol()); UseSlippage = GetSlippage(Symbol(),Slippage); } // Start function int start() { // Moving averages double FastMA = iMA(NULL,0,FastMAPeriod,0,0,0,0); double SlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,0); // Buy order if(FastMA > SlowMA && BuyTicket == 0) { OrderSelect(SellTicket,SELECT_BY_TICKET); // Close order if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELL) { double CloseLots = OrderLots(); double ClosePrice = Ask; bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red); } // Delete Order else if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELLSTOP) { bool Deleted = OrderDelete(SellTicket,Red); } double PendingPrice = High[0] + (PendingPips * UsePoint); // Calculate stop loss and take profit if(StopLoss > 0) double BuyStopLoss = PendingPrice - (StopLoss * UsePoint); if(TakeProfit > 0) double BuyTakeProfit = PendingPrice + (TakeProfit * UsePoint); // Open buy order BuyTicket = OrderSend(Symbol(),OP_BUYSTOP,LotSize,PendingPrice ,UseSlippage, BuyStopLoss,BuyTakeProfit,"Buy Stop Order",MagicNumber,0,Green); SellTicket = 0; } // Sell Order if(FastMA < SlowMA && SellTicket == 0) { OrderSelect(BuyTicket,SELECT_BY_TICKET); if(OrderCloseTime() == 0 && BuyTicket > 0 && OrderType() == OP_BUY) { CloseLots = OrderLots(); ClosePrice = Bid; Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlipp age,Red); } else if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_BUYSTOP) { Deleted = OrderDelete(SellTicket,Red); } PendingPrice = Low[0] - (PendingPips * UsePoint); if(StopLoss > 0) double SellStopLoss = PendingPrice + (StopLoss * UsePoint); if(TakeProfit > 0) double SellTakeProfit = PendingPrice - (TakeProfit * UsePoint); SellTicket = OrderSend(Symbol(),OP_SELLSTOP,LotSize,PendingPric e,UseSlippage, SellStopLoss,SellTakeProfit,"Sell Stop Order",MagicNumber,0,Red); BuyTicket = 0; } return(0); } // Pip Point Function double PipPoint(string Currency) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01; else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001; return(CalcPoint); } // Get Slippage Function int GetSlippage(string Currency, int SlippagePips) { int CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 4) double CalcSlippage = SlippagePips; else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips * 10; return(CalcSlippage); }