س :
قمت ببرمجة إكسبيرت ولكن لا ينفذ أي صفقات عند تحقق الشروط المبنيه عليه, محرر الأكواد لا يظهر لي أي خطأ برمجي ,فما هي الطرق التي من خلالها نعرف سبب هذا الخطأ الغريب ؟
ج :
للأسف فإن لغة MQL4 لا تحتوي مصحح أخطاء Debuger وبالتالي فإننا سنواجه صعوبة في معرفة لماذا لا يقوم المؤشر أو الاكسبيرت بالعمل بالشكل الذي خططناه له .
لذلك وبعد الخبرة فإن أفضل طريقة لعمل Debug يدوي إن صح التعبير هي في استخدام التعليمة Print في أماكن مختارة من البرنامج
وذلك لمعرفة قيمة متحول ما عند نقطة معينة أو معرفة ما إذا كان الشرط الفلاني قد تحقق أم لا .
فمثلا نستطيع استخدام الكود التالي :
كود PHP:
Print ( "A= " , A , " B= " , B ) ;
if (A==B)
{
Print ( " تحقق الشرط" );
......
}
لأنك تفترض عقلا أن المتحول A يساوي B ولكن الشرط مع ذلك لم يتحقق
ولكن عند طباعة قيمة المتحولات A و B تجد مثلا أن
المتحول A يساوي 1.1235
والمتحول B يساوي 1.123501
وطبعا فإن قيمة المتحولين ليست متساوية بالنسبة للكمبيوتر .
لذلك تستخدم مثلا وظائف أخرى برمجية لتقريب القيم والتأكد تماما أن القيمتين متساويتين فعلا .
هذا أحد الأمثلة على استخدام الوظيفة Print لعمل تصحيح يدوي .
ولكن قبل ذلك كله يجب أن يكون برنامجك متماسكا ومكتوبا بطريقة صحيحة برمجيا وأن يكون قد ناقش جميع الاحتمالات الممكنة بطريقة
برمجية صحيحة .
فمثلا الوظيفة التي تقوم بفتح صفقة ما في اكسبيرت OrderSend يجب أن تستخدم بطريقة صحيحة تماما لمعرفة لماذا فشلت
ولهذا يجب معرفة أن هذه الوظيفة تعود لنا بقيمة تمثل رقم الصفقة في حال نجحت في فتح الصفقة .
وتعود بقيمة -1 إذا فشلت لأي سبب من الأسباب .
لذلك فإن الاستخدام الخاطيء والشائع والذي لن نعرف من خلاله لماذا فشلت الوظيفة في فتح الصفقة هو على الشكل التالي :
كود PHP:
OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"",16384,0,Green);
أما الاستخدام الصحيح للوظيفة فهي على الشكل التالي :
كود PHP:
int ticket;
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"",16384,0,Green);
if(ticket<0)
{
Print("OrderSend failed with error #",GetLastError());
return(0);
}
في الكود السابق قمنا بفحص القيمة العائدة من الوظيفة وفي حال كانت تساوي -1 فهذا يعني وجود خطأ ما .
ولمعرفة نوع الخطأ قمنا باستخدام الوظيفة GetLastError والتي تعطينا رقم آخر خطأ حدث في البرنامج .
بعد ذلك قمنا بطباعة رقم الخطأ بواسطة الوظيفة Print .
وعندما نشغل الاكسبيرت ولا يقوم بفتح صفقة فإننا سنعرف على الأقل رقم الخطأ المسبب لهذه المشكلة .
ولدينا طبعا جدول بأرقام الأخطاء ومعانيها وهو كالتالي :
كود PHP:
ERR_NO_ERROR 0 No error returned.
ERR_NO_RESULT 1 No error returned, but the result is unknown.
ERR_COMMON_ERROR 2 Common error.
ERR_INVALID_TRADE_PARAMETERS 3 Invalid trade parameters.
ERR_SERVER_BUSY 4 Trade server is busy.
ERR_OLD_VERSION 5 Old version of the client terminal.
ERR_NO_CONNECTION 6 No connection with trade server.
ERR_NOT_ENOUGH_RIGHTS 7 Not enough rights.
ERR_TOO_FREQUENT_REQUESTS 8 Too frequent requests.
ERR_MALFUNCTIONAL_TRADE 9 Malfunctional trade operation.
ERR_ACCOUNT_DISABLED 64 Account disabled.
ERR_INVALID_ACCOUNT 65 Invalid account.
ERR_TRADE_TIMEOUT 128 Trade timeout.
ERR_INVALID_PRICE 129 Invalid price.
ERR_INVALID_STOPS 130 Invalid stops.
ERR_INVALID_TRADE_VOLUME 131 Invalid trade volume.
ERR_MARKET_CLOSED 132 Market is closed.
ERR_TRADE_DISABLED 133 Trade is disabled.
ERR_NOT_ENOUGH_MONEY 134 Not enough money.
ERR_PRICE_CHANGED 135 Price changed.
ERR_OFF_QUOTES 136 Off quotes.
ERR_BROKER_BUSY 137 Broker is busy.
ERR_REQUOTE 138 Requote.
ERR_ORDER_LOCKED 139 Order is locked.
ERR_LONG_POSITIONS_ONLY_ALLOWED 140 Long positions only allowed.
ERR_TOO_MANY_REQUESTS 141 Too many requests.
ERR_TRADE_MODIFY_DENIED 145 Modification denied because order too close to
market.
ERR_TRADE_CONTEXT_BUSY 146 Trade context is busy.
ERR_TRADE_EXPIRATION_DENIED 147 Expirations are denied by broker.
ERR_TRADE_TOO_MANY_ORDERS 148 The amount of open and pending orders has reached
the limit set by the broker.
طبعا هناك أخطاء أخرى ولكن هذه الأرقام هي الشائعة .
ويمكن طبعا طباعة رسالة الخطأ مباشرة وليس طباعة رقمها ولكن أفضل حاليا استخدام هذه الطريقة لمزيد من الخبرة والمرونة .
بهذه الطريقة نستطيع معرفة السبب الحقيقي وراء عدم فتح الاكسبيرت لصفقاته لأننا حصلنا على رقم الخطأ الذي حصل .
وغالبا يكون الخطأ نتيجة عدم صحة الأرقام والأسعار المدخلة للوظيفة OrderSend
ويجب القياس بنفس الطريقة على الاستخدامات الهامة الأخرى للوظائف الحيوية الأخرى كتعديل ستوب أو هدف لصفقة ما .