الحلقة السادسة و العشرون من سلسلة تعلم البرمجة باسهل طريقة

تقليص
X
 
  • تصفية - فلترة
  • الوقت
  • عرض
إلغاء تحديد الكل
مشاركات جديدة

  • الحلقة السادسة و العشرون من سلسلة تعلم البرمجة باسهل طريقة

    لنضع كل شيء معا
    Putting It All Together



    سنقوم بإضافة جميع الميزات التي غطيناها في الدروس السابقة إلى مستشار خبير بسيط
    تم إنشاؤه في درس سابق. سنضيف تعديل الأمر ، والتحقق من مستوى الإيقاف ، وسياق التجارة
    التحقق والتحديث المتغير المحدد مسبقًا والتحقق من حجم اللوت إلى المستشار الخبير لدينا. ها هو الاكسبيرت ، بدءًا من
    البداية:
    كود PHP:
    #property copyright "Mohammad al turk"
    #include <stdlib.mqh>
    // External variables
    extern bool DynamicLotSize = true;
    extern double EquityPercent = 2;
    extern double FixedLotSize = 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;
    int ErrorCode; 
    
    لقد أضفنا العبارة #include لملف stdlib.mqh الذي يحتوي على الامتداد
    ErrorDescription () وظيفة لإجراءات معالجة الأخطاء لدينا. أضفنا ثلاثة متغيرات خارجية
    لحجم اللوت ، ومتغير عام لرمز الخطأ.

    يتم وضع الكود التالي في بداية وظيفة start ():

    كود PHP:
    // Moving averages
    double FastMA = iMA(NULL,0,FastMAPeriod,0,0,0,0);
    double SlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,0);
    // Lot size calculation
    if(DynamicLotSize == true)
    {
    double RiskAmount = AccountEquity() * (EquityPercent / 100);
    double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
    if(Point == 0.001 || Point == 0.00001) TickValue *= 10;
    double CalcLots = (RiskAmount / StopLoss) / TickValue;
    double LotSize = CalcLots;
    }
    else LotSize = FixedLotSize;
    // Lot size verification
    if(LotSize < MarketInfo(Symbol(),MODE_MINLOT))
    {
    LotSize = MarketInfo(Symbol(),MODE_MINLOT);
    }
    else if(LotSize > MarketInfo(Symbol(),MODE_MAXLOT))
    {
    LotSize = MarketInfo(Symbol(),MODE_MAXLOT);
    }
    if(MarketInfo(Symbol(),MODE_LOTSTEP) == 0.1)
    {
    LotSize = NormalizeDouble(LotSize,1);
    }
    else LotSize = NormalizeDouble(LotSize,2); 
    
    تمت إضافة رمز التحقق وحساب حجم اللوت إلى بداية
    وظيفة start() . نظرًا لأن مستوى وقف الخسارة معروف مسبقًا ، يعد هذا مكانًا جيدًا كأي مكان لوضعه. ال
    الرمز المتبقي هو روتين أوامر الشراء المعدل لدينا:

    كود PHP:
    // Buy Order
    if(FastMA > SlowMA && BuyTicket == 0)
    {
    // Close Order
    OrderSelect(SellTicket,SELECT_BY_TICKET);
    if(OrderCloseTime() == 0 && SellTicket > 0)
    {
    double CloseLots = OrderLots();
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    double ClosePrice = Ask;
    bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red);
    // Error handling
    if(Closed == false)
    {
    ErrorCode = GetLastError();
    string ErrDesc = ErrorDescription(ErrorCode);
    string ErrAlert = StringConcatenate("Close Sell Order - Error ",
    ErrorCode,": ",ErrDesc);
    Alert(ErrAlert);
    string ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize,
    " Ticket: ",SellTicket);
    Print(ErrLog);
    }
    }
    
    // Open buy order
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    BuyTicket = OrderSend(Symbol(),OP_BUY,LotSize,Ask,UseSlippage, 0,0,
    "Buy Order",MagicNumber,0,Green);
    // Error handling
    if(BuyTicket == -1)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Open Buy Order - Error ",
    ErrorCode,": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize);
    Print(ErrLog);
    }
    // Order modification
    else
    {
    OrderSelect(BuyTicket,SELECT_BY_TICKET);
    double OpenPrice = OrderOpenPrice();
    // Calculate stop level
    double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;
    *******Rates();
    double UpperStopLevel = Ask + StopLevel;
    double LowerStopLevel = Bid - StopLevel;
    double MinStop = 5 * UsePoint;
    
    // Calculate stop loss and take profit
    if(StopLoss > 0) double BuyStopLoss = OpenPrice - (StopLoss * UsePoint);
    if(TakeProfit > 0) double BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint);
    // Verify stop loss and take profit
    if(BuyStopLoss > 0 && BuyStopLoss > LowerStopLevel)
    {
    BuyStopLoss = LowerStopLevel - MinStop;
    }
    if(BuyTakeProfit > 0 && BuyTakeProfit < UpperStopLevel)
    {
    BuyTakeProfit = UpperStopLevel + MinStop;
    }
    // Modify order
    if(IsTradeCon****Busy()) Sleep(10);
    if(BuyStopLoss > 0 || BuyTakeProfit > 0)
    {
    bool TicketMod = OrderModify(BuyTicket,OpenPrice,BuyStopLoss,
    BuyTakeProfit,0);
    // Error handling
    if(TicketMod == false)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Modify Buy Order - Error ",
    ErrorCode,": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Bid: ",Bid," Ticket: ",
    BuyTicket," Stop: ",BuyStopLoss," Profit: ",BuyTakeProfit);
    Print(ErrLog);
    }
    }
    }
    SellTicket = 0;
    } 
    
    يحتوي الجزء المتبقي من الكود الخاص بنا على كتلة وضع أوامر البيع بالسوق ، بالإضافة إلى
    وظائف PipPoint () و GetSlippage ().

    لاحظ أننا أضفنا وظيفة IsTradeCon****Busy () قبل كل عملية تداول. نحن نريد
    التأكد من ان سياق التجارة غير مشغول قبل محاولة التداول. نحن نستخدم وظيفة *******Rates ()
    قبل كل مرجع لمتغيرات العطاء Bid أو الطلب Ask ، للتأكد من أننا نستخدم دائمًا
    أحدث الأسعار.

    نبدأ بتحديد تذكرة أمر البيع السابقة وإغلاقها باستخدام OrderClose (). فإذا
    فشلت الوظيفة ، يتم تشغيل كتلة معالجة الخطأ. بعد ذلك ، نفتح أمر شراء السوق باستخدام
    OrderSend (). إذا فشلت الوظيفة ، يتم تشغيل كتلة معالجة الخطأ. خلاف ذلك ، نواصل إلى
    كتلة تعديل الطلب.

    نختار تذكرة الأمر الذي تم تقديمه للتو باستخدام OrderSelect () ، ونحدد سعر فتح الأمر
    إلى متغير OpenPrice. ثم نحسب مستوى الإيقاف ومستوى الإيقاف العلوي والسفلي
    للأسعار. بعد ذلك ، نحسب أسعار وقف الخسارة وجني الأرباح ، ونتحقق منها ، وأخيرًا نقوم بتعديل
    الطلب باستخدام OrderModify (). كتلة معالجة الخطأ النهائية تتعامل مع الأخطاء من
    تعديل الطلب.

    إليك كيفية تعديل كود أمر إيقاف الشراء المعلق:

    كود PHP:
    // Close order
    OrderSelect(SellTicket,SELECT_BY_TICKET);
    if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELL)
    {
    double CloseLots = OrderLots();
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    double ClosePrice = Ask;
    bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red);
    // Error handling
    if(Closed == false)
    {
    ErrorCode = GetLastError();
    string ErrDesc = ErrorDescription(ErrorCode);
    string ErrAlert = StringConcatenate("Close Sell Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    string ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize,
    " Ticket: ",SellTicket);
    Print(ErrLog);
    }
    }
    
    // Delete order
    else if(OrderCloseTime() == 0 && SellTicket > 0 && OrderType() == OP_SELLSTOP)
    {
    bool Deleted = OrderDelete(SellTicket,Red);
    if(Deleted == true) SellTicket = 0;
    // Error handling
    if(Deleted == false)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Delete Sell Stop Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Ticket: ",SellTicket);
    Print(ErrLog);
    }
    } 
    

    لقد أضفنا الكود لحذف الطلبات المعلقة باستخدام OrderDelete () بعد وظيفة OrderClose ()
    يحدد نوع أمر البيع السابق الوظيفة المستخدمة لإغلاق الطلب.

    يتمثل الاختلاف الرئيسي بين الكود التالي وكود أمر السوق في أنه ليس لدينا
    كتلة تعديل الطلب. ليس من الضروري وضع وقف الخسارة وجني الأرباح بشكل منفصل
    للأوامر المعلقة. لذلك سنقوم بحساب وقف الخسارة وجني الأرباح قبل وضع الأمر مع
    OrderSend ().

    كود PHP:
    // Calculate stop level
    double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;
    *******Rates();
    double UpperStopLevel = Ask + StopLevel;
    double MinStop = 5 * UsePoint;
    // Calculate pending price
    double PendingPrice = High[0] + (PendingPips * UsePoint);
    if(PendingPrice < UpperStopLevel) PendingPrice = UpperStopLevel + MinStop;
    // Calculate stop loss and take profit
    if(StopLoss > 0) double BuyStopLoss = PendingPrice - (StopLoss * UsePoint);
    if(TakeProfit > 0) double BuyTakeProfit = PendingPrice + (TakeProfit * UsePoint);
    // Verify stop loss and take profit
    UpperStopLevel = PendingPrice + StopLevel;
    double LowerStopLevel = PendingPrice – StopLevel;
    if(BuyStopLoss > 0 && BuyStopLoss > LowerStopLevel)
    {
    BuyStopLoss = LowerStopLevel - MinStop;
    }
    if(BuyTakeProfit > 0 && BuyTakeProfit < UpperStopLevel)
    {
    BuyTakeProfit = UpperStopLevel + MinStop;
    }
    // Place pending order
    if(IsTradeCon****Busy()) Sleep(10);
    BuyTicket = OrderSend(Symbol(),OP_BUYSTOP,LotSize,PendingPrice ,UseSlippage,
    BuyStopLoss,BuyTakeProfit,"Buy Stop Order",MagicNumber,0,Green);
    // Error handling
    if(BuyTicket == -1)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Open Buy Stop Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize," Price: ",PendingPrice,
    " Stop: ",BuyStopLoss," Profit: ",BuyTakeProfit);
    Print(ErrLog);
    }
    SellTicket = 0; 
    
    أولاً ، نحسب مستوى التوقف العلوي. ثم نحسب ونتحقق من سعر الأمر المعلق لدينا ، والذي
    يتم تخزينه في PendingPrice. ثم نعيد حساب UpperStopLevel ونحسب LowerStopLevel
    بحيث تكون مرتبطة بسعر الأمر المعلق. لاحظ أننا لسنا بحاجة إلى استخدام العرض Bid أو الطلب Ask
    الأسعار ، أو الرقم في السبريد عند التحقق من أسعار وقف الخسارة وجني الأرباح.

    أخيرًا ، نضع أمرنا المعلق باستخدام OrderSend () ، مع وضع وقف الخسارة وجني الأرباح
    معها. لدينا وظيفة معالجة الأخطاء القياسية للتعامل مع أخطاء وضع الطلبات.

    على الرغم من كل التعليمات البرمجية الإضافية ، فإن هؤلاء المستشارين الخبراء يستخدمون نفس الإستراتيجية .
    يحتوي هذا الكود ببساطة على ميزات إضافية لحساب والتحقق من حجم اللوت ومستويات الإيقاف و وقف
    الخسارة وجني الأرباح وأسعار الأوامر المعلقة. لقد أضفنا أيضًا فحوصات سياق التجارة ومعالجة الأخطاء
    ، في الدروس القادمة ان شاء الله سنتعلم كيفية إنشاء وظائف functions حتى نتمكن من إعادة استخدام هذا الكود وتبسيطه.



    الكود الكامل لهذا الخبير المستشار


    كود PHP:
    #property copyright "Mohammad al turk"
    #include <stdlib.mqh>
    // External variables
    extern bool DynamicLotSize = true;
    extern double EquityPercent = 2;
    extern double FixedLotSize = 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;
    int ErrorCode;
    // 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,1);
    double SlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,1);
    / Lot size calculation
    if(DynamicLotSize == true)
    {
    double RiskAmount = AccountEquity() * (EquityPercent / 100);
    double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
    if(Point == 0.001 || Point == 0.00001) TickValue *= 10;
    double CalcLots = (RiskAmount / StopLoss) / TickValue;
    double LotSize = CalcLots;
    }
    else LotSize = FixedLotSize;
    // Lot size verification
    if(LotSize < MarketInfo(Symbol(),MODE_MINLOT))
    {
    LotSize = MarketInfo(Symbol(),MODE_MINLOT);
    }
    else if(LotSize > MarketInfo(Symbol(),MODE_MAXLOT))
    {
    LotSize = MarketInfo(Symbol(),MODE_MAXLOT);
    }
    if(MarketInfo(Symbol(),MODE_LOTSTEP) == 0.1)
    {
    LotSize = NormalizeDouble(LotSize,1);
    }
    else LotSize = NormalizeDouble(LotSize,2);
    // Buy Order
    if(FastMA > SlowMA && BuyTicket == 0)
    {
    // Close Order
    OrderSelect(SellTicket,SELECT_BY_TICKET);
    if(OrderCloseTime() == 0 && SellTicket > 0)
    {
    double CloseLots = OrderLots();
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    double ClosePrice = Ask;
    bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlip page,Red);
    // Error handling
    if(Closed == false)
    {
    ErrorCode = GetLastError();
    string ErrDesc = ErrorDescription(ErrorCode);
    string ErrAlert = StringConcatenate("Close Sell Order - Error ",
    ErrorCode,": ",ErrDesc);
    Alert(ErrAlert);
    string ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize,
    " Ticket: ",SellTicket);
    Print(ErrLog);
    }
    }
    // Open buy order
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    BuyTicket = OrderSend(Symbol(),OP_BUY,LotSize,Ask,UseSlippage, 0,0,
    "Buy Order",MagicNumber,0,Green);
    // Error handling
    if(BuyTicket == -1)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Open Buy Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize);
    Print(ErrLog);
    }
    // Order modification
    else
    {
    OrderSelect(BuyTicket,SELECT_BY_TICKET);
    double OpenPrice = OrderOpenPrice();
    // Calculate stop level
    double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;
    *******Rates();
    double UpperStopLevel = Ask + StopLevel;
    double LowerStopLevel = Bid - StopLevel;
    double MinStop = 5 * UsePoint;
    // Calculate stop loss and take profit
    if(StopLoss > 0) double BuyStopLoss = OpenPrice - (StopLoss * UsePoint);
    if(TakeProfit > 0) double BuyTakeProfit = OpenPrice +
    (TakeProfit * UsePoint);
    // Verify stop loss and take profit
    if(BuyStopLoss > 0 && BuyStopLoss > LowerStopLevel)
    {
    BuyStopLoss = LowerStopLevel - MinStop;
    }
    if(BuyTakeProfit > 0 && BuyTakeProfit < UpperStopLevel)
    {
    BuyTakeProfit = UpperStopLevel + MinStop;
    }
    // Modify order
    if(IsTradeCon****Busy()) Sleep(10);
    if(BuyStopLoss > 0 || BuyTakeProfit > 0)
    {
    bool TicketMod = OrderModify(BuyTicket,OpenPrice,BuyStopLoss,
    BuyTakeProfit,0);
    // Error handling
    if(TicketMod == false)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Modify Buy Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Bid: ",Bid," Ticket: ",
    BuyTicket," Stop: ",BuyStopLoss," Profit: ",BuyTakeProfit);
    Print(ErrLog);
    }
    }
    }
    SellTicket = 0;
    }
    // Sell Order
    if(FastMA < SlowMA && SellTicket == 0)
    {
    OrderSelect(BuyTicket,SELECT_BY_TICKET);
    if(OrderCloseTime() == 0 && BuyTicket > 0)
    {
    CloseLots = OrderLots();
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    ClosePrice = Bid;
    Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlipp age,Red);
    // Error handling
    if(Closed == false)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Close Buy Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize," Ticket: ",
    BuyTicket);
    Print(ErrLog);
    }
    }
    while(IsTradeCon****Busy()) Sleep(10);
    *******Rates();
    SellTicket = OrderSend(Symbol(),OP_SELL,LotSize,Bid,UseSlippage ,0,0,
    "Sell Order", MagicNumber,0,Red);
    // Error handling
    if(SellTicket == -1)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Open Sell Order - Error ",ErrorCode,
    ": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize);
    Print(ErrLog);
    }
    else
    {
    OrderSelect(SellTicket,SELECT_BY_TICKET);
    OpenPrice = OrderOpenPrice();
    StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;
    *******Rates();
    UpperStopLevel = Ask + StopLevel;
    LowerStopLevel = Bid - StopLevel;
    MinStop = 5 * UsePoint;
    if(StopLoss > 0) double SellStopLoss = OpenPrice + (StopLoss * UsePoint);
    if(TakeProfit > 0) double SellTakeProfit = OpenPrice -
    (TakeProfit * UsePoint);
    if(SellStopLoss > 0 && SellStopLoss < UpperStopLevel)
    {
    SellStopLoss = UpperStopLevel + MinStop;
    }
    if(SellTakeProfit > 0 && SellTakeProfit > LowerStopLevel)
    {
    SellTakeProfit = LowerStopLevel - MinStop;
    }
    if(IsTradeCon****Busy()) Sleep(10);
    if(SellStopLoss > 0 || SellTakeProfit > 0)
    {
    TicketMod = OrderModify(SellTicket,OpenPrice,SellStopLoss,
    SellTakeProfit,0);
    // Error handling
    if(TicketMod == false)
    {
    ErrorCode = GetLastError();
    ErrDesc = ErrorDescription(ErrorCode);
    ErrAlert = StringConcatenate("Modify Sell Order - Error ",
    ErrorCode,": ",ErrDesc);
    Alert(ErrAlert);
    ErrLog = StringConcatenate("Ask: ",Ask," Bid: ",Bid," Ticket: ",
    SellTicket," Stop: ",SellStopLoss," Profit: ",SellTakeProfit);
    Print(ErrLog);
    }
    }
    }
    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);
    } 
    
يعمل...
X