3 مرفق
موضوع تعليمي : التعامل مع الكائنات على الشارت وإستخدام الداله OnChartEvent
سابقا عندما كنا نريد التعامل مع الكائنات على الشارت ( معرفة هل تم الضغط على زر على الشارت - هل تم رسم كائن جديد - هل تم حذف كائن - تحرك الماوس على الشارت .... ) كنا نستخدم مكتبات
خارجيه لكن الآن يمكننا مباشرة بتنفيذ جميع الأوامر المتعلقه بالشارت بلغة MQL4 مباشرة
في هذا الموضوع سوف نتكلم بتفصيل أكثر عن الداله OnChartEvent وهي أحد الدوال التي تم إضافتها جديدا بعد التحديث الجديد للغة MQL4 وسوف نقوم بعمل إكسبرت يرسم أزرار على الشارت تمكنك من تنفيذ أوامر البيع و الشراء بضغطة زر
سنقوم بكتابة الداله في كود المؤشر
كود PHP:
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
وهي تأخذ أربعة قيم
id تحفظ نوع الحدث الذي تم ( تحرك الماوس - ضغط على الشارت - تحريك كائن - ضغط على زر في الكيبورد ... )
وأنواعها هي
كود PHP:
CHARTEVENT_KEYDOWN
حدث الضغط على زر على الكيبورد
كود PHP:
CHARTEVENT_MOUSE_MOVE
تحرك الماوس على الشارت
كود PHP:
CHARTEVENT_OBJECT_CREATE
رسم كائن جديد على الشارت
كود PHP:
CHARTEVENT_OBJECT_CHANGE
تغيير قيم كائن
كود PHP:
CHARTEVENT_OBJECT_DELETE
حذف كائن
كود PHP:
CHARTEVENT_CLICK
كليك على الشارت
كود PHP:
CHARTEVENT_OBJECT_CLICK
كليك على كائن
كود PHP:
CHARTEVENT_OBJECT_DRAG
إضافة كائن على الشارت
كود PHP:
CHARTEVENT_OBJECT_ENDEDIT
الإنتهاء من تعديل نص في الكائن
كود PHP:
CHARTEVENT_CHART_CHANGE
تعديل قيم الشارت
كود PHP:
CHARTEVENT_CUSTOM+N
عمل كائن فرعي محدد
المتغيرات الثلاث الأخرى تحفظ قيمة معينه حسب نوع الحدث
فمثلا بالنسبه للحدث CHARTEVENT_OBJECT_CREATE
sparam تحفظ إسم الكائن الذي تم رسمه
مثلا CHARTEVENT_OBJECT_CLICK
lparam تحفظ قيمة الإحداثي الأفقي
dparam تحفظ قيمة الإحداثي الراسي
sparam تحفظ إسم الكائن الذي تم الضغط عليه
هذه قائمة بكل حدث و تعريف له
الملف المرفق 403861
نعود الآن بالنسبه للإكسبرت الذي سنقوم بعمله
قمت بعمل دالة لرسم الأزرار على الشارت
كود PHP:
void CreatePanel(string name,ENUM_OBJECT Type,string text,int XDistance,int YDistance,int Width,int Hight,
color Color_,color TextColor,color boarderColor,int fontsize)
{
ObjectCreate(0,name,Type,0,0,0);
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,XDistance);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,YDistance);
ObjectSetInteger(0,name,OBJPROP_XSIZE,Width);
ObjectSetInteger(0,name,OBJPROP_YSIZE,Hight);
ObjectSetString(0,name,OBJPROP_TEXT,text);
ObjectSetString(0,name,OBJPROP_FONT,"Arial Bold");
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
ObjectSetInteger(0,name,OBJPROP_CORNER,Panel_Corner);
ObjectSetInteger(0,name,OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,boarderColor);
ObjectSetInteger(0,name,OBJPROP_BGCOLOR,Color_);
if(Type==OBJ_EDIT)ObjectSetInteger(0,name,OBJPROP_ALIGN,ALIGN_CENTER);
}
بداخل الدالة OnInit قمت برسم الأزرار الخاصة بالشراء و البيع و إغلاق و حذف الأوام
كود PHP:
CreatePanel("Panel_Buy",OBJ_BUTTON,"BUY", 10, 45,60,30,DodgerBlue,White,Blue,12);
CreatePanel("Panel_Lot",OBJ_EDIT,"0.1", 70, 50,30,20,White,Black,Black,9);
CreatePanel("Panel_+",OBJ_BUTTON,"+", 75, 38,20,10,Lime,Black,Lime,9);
CreatePanel("Panel_-",OBJ_BUTTON,"-", 75, 72,20,10,Red,Black,Red,9);
CreatePanel("Panel_Sell",OBJ_BUTTON,"SELL",100,45,60,30,OrangeRed,White,Red,12);
CreatePanel("Panel_TP",OBJ_BUTTON,"TP", 10, 80,20,20,Blue,White,Blue,10);
CreatePanel("Panel_SL",OBJ_BUTTON,"SL", 140,80,20,20,Blue,White,Blue,10);
CreatePanel("Panel_TP_text",OBJ_EDIT,"0",30, 80,40,20,White,Black,Red,9);
CreatePanel("Panel_SL_text",OBJ_EDIT,"0",100,80,40,20,White,Black,Red,9);
if(Enable_CloseAll)CreatePanel("Panel_CloseAll",OBJ_BUTTON,
"CLOSE ALL",10, 105,70,20,Red,White,Red,8);
if(Enable_DeleteAll)CreatePanel("Panel_DeleteAll",OBJ_BUTTON,
"DELETE ALL",90, 105,70,20,Red,White,Red,8);
الآن نعود مرة أخرى للداله OnChartEvent
في البداية سأقوم بإضافة شرط لمعرفة إذا ما تم الضغط على أي زر على الشارت بإستدعاء إسمه
كود PHP:
if(id==CHARTEVENT_OBJECT_CLICK)
{
string Object_Name=ObjectGetString(0,sparam,OBJPROP_NAME);
if(Object_Name=="Panel_Buy")
{
// open buy
}
if(Object_Name=="Panel_Sell")
{
// open sell
}
if(Object_Name=="Panel_CloseAll")
{
// close all
}
if(Object_Name=="Panel_DeleteAll")
{
// delete all
}
}
بقي فقط أن نضيف الأوامر كما هي محدده في الكومنتات لكن قبل ذلك يجب أن نقوم بمعرفة قيم حجم اللوت و الهدف و الاستوب لذلك اضفت الكود
كود PHP:
double Lots=StringToDouble(ObjectDescription("Panel_Lot")); StopLoss=StringToDouble(ObjectDescription("Panel_SL_text")); TakeProfit=StringToDouble(ObjectDescription("Panel_TP_text"));
أيضا سأضيف كود آخر بحيث بعد الضغط على الأزار تعود إلى طبيعتها مره أخرى
كود PHP:
ObjectSetInteger(0,Object_Name,OBJPROP_SELECTED,false); ObjectSetInteger(0,Object_Name,OBJPROP_STATE,false);
وسيكون الكود في النهاية بشكل كامل
كود PHP:
if(id==CHARTEVENT_OBJECT_CLICK)
{
double StopLoss,TakeProfit;
double Lots=StringToDouble(ObjectDescription("Panel_Lot"));
StopLoss=StringToDouble(ObjectDescription("Panel_SL_text"));
TakeProfit=StringToDouble(ObjectDescription("Panel_TP_text"));
double SL,TP;
int ticket;
string Object_Name=ObjectGetString(0,sparam,OBJPROP_NAME);
if(Object_Name=="Panel_Buy")
{
if(StopLoss==0)SL=0;else SL=Ask-StopLoss*point;
if(TakeProfit==0)TP=0;else TP=Ask+TakeProfit*point;
ticket=OrderSend(Symbol(),OP_BUY,Lots,NormalizeDouble(Ask,Digits),3*P,SL,TP,"Panel EA",0,0,Blue);
ObjectSetInteger(0,Object_Name,OBJPROP_SELECTED,false);
ObjectSetInteger(0,Object_Name,OBJPROP_STATE,false);
}
if(Object_Name=="Panel_Sell")
{
if(StopLoss==0)SL=0;else SL=Bid+StopLoss*point;
if(TakeProfit==0)TP=0;else TP=Bid-TakeProfit*point;
ticket=OrderSend(Symbol(),OP_SELL,Lots,NormalizeDouble(Bid,Digits),3*P,SL,TP,"Panel EA",0,0,Blue);
ObjectSetInteger(0,Object_Name,OBJPROP_SELECTED,false);
ObjectSetInteger(0,Object_Name,OBJPROP_STATE,false);
}
if(Object_Name=="Panel_CloseAll")
{
CloseOrders(OP_BUY);
CloseOrders(OP_SELL);
ObjectSetInteger(0,Object_Name,OBJPROP_SELECTED,false);
ObjectSetInteger(0,Object_Name,OBJPROP_STATE,false);
}
if(Object_Name=="Panel_DeleteAll")
{
CloseOrders(OP_BUYLIMIT);
CloseOrders(OP_SELLLIMIT);
CloseOrders(OP_BUYSTOP);
CloseOrders(OP_SELLSTOP);
ObjectSetInteger(0,Object_Name,OBJPROP_SELECTED,false);
ObjectSetInteger(0,Object_Name,OBJPROP_STATE,false);
}
}
بقي الآن أن أضيف كود لزيادة أوتقليل حجم اللوت عندما يتم الضغط على زر + أو -
كود PHP:
if(Object_Name=="Panel_+")
{
ObjectSetString(0,"Panel_Lot",OBJPROP_TEXT,DoubleToStr(Lots+MarketInfo(Symbol(),MODE_MINLOT),2));
}
if(Object_Name=="Panel_-")
{
Lots=MathMax(Lots-MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_MINLOT));
ObjectSetString(0,"Panel_Lot",OBJPROP_TEXT,DoubleToStr(Lots,2));
}
ولا ننسى الجزء البسيط وهو دالة إغلاق الصفقات
كود PHP:
void CloseOrders(int type)
{
for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
bool select=OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
int ticket=OrderTicket();
double lots=OrderLots();
int Otype=OrderType();
if(OrderSymbol()==Symbol()&&Otype==type)
{
if(Otype==OP_BUY)
{
bool close= OrderClose(ticket,lots,NormalizeDouble(Bid,Digits),3*P);
}
if(Otype==OP_SELL)
{
close= OrderClose(ticket,lots,NormalizeDouble(Ask,Digits),3*P);
}
if(Otype>OP_SELL)
{
OrderDelete(ticket);
}
}
}
}
وبذلك يكون الإكسبرت جاهز للتجربه و العمل
الملف المرفق 403860
مرفق الإكسبرت