มาหัดใช้เม้าส์ดูข้อมูลกันเถอะ, ChartEvent, Mouse, LabelObj
Jun 27, 2016 22:10:17 GMT 7
Post by iamgotzaa on Jun 27, 2016 22:10:17 GMT 7
กราบสวัสดีมิตรรักสมาชิก thaiea
หายไปสักหลายวันได้อยู่ สำหรับแอดมิน เนื่องจากงานยุ่งโค๊ดดๆ
Bฺrexit ที่ผ่านหวังว่าทุกคนจะยังคงอยู่ดี นั่งเงียบๆทับมือตัวเอง ปิด ea แล้วไปพักผ่อนกันนะครับ
ผมก็ไม่ได้รันอะไรทิ้งไว้สักเท่าไร ทุนก็ไม่มี ก็เลยนั่งเขียนโค้ดเก่าเอามาปัดฝุ่นใหม่ซะหน่อย กะว่าจะทำอะไรเล่น บังเอิญไปเจอ code ที่เกี่ยวกับchart ดึงค่าจาก chart ผ่านทางตำแหน่งของ mouse cursor ที่อยู่บนหน้าจอนี่แหละ
เอาเจ๋งดีแฮะ เผื่อเอาไว้เทรด red green คำนวณ lot size ได้
ก็เลยเอาทำเล่น
ประมาณว่า ถ้า mouse อยู่ที่แท่งเที่ยนไหนก็ให้บอกราคาณที่เม้าส์ชี้อยู่ แล้วก็บอกว่าแท่งเทียนนั้นมีระยะระหว่างสูงต่ำกี่ pips
อูววว
น่าสนุกจุง
งานนี้พระเอกคือ
ก่อนการใช้งานต้อง enable ที่ OnInit() ด้วยว่า
วิธีใช้ก็ไม่ยาก นะครับ คือไอ้พวก events ต่างๆที่เกิดจากการกระทำบน chart นั้นเปิด help อ่านได้ว่ามีอะไรบ้าง
จากนั้นก็ใช้ ประโยคที่ว่า
นั้นก็คือ ถ้าเม้าส์ขยับ ฉันก็จะทำโน่นทำนี่ ไม่เกี่ยวกับ OnTick แม้แต่นิดเดียว แค่เม้าส์ขยับก็ให้รันไอ้ที่อยู่ใน if นั้นได้เลย
อีกฟังก์ชั่นนึงก็คือ ChartXYToTimePrice เป็นการแปลง ตำแหน่งของลูกศรเม้าส์ ที่ออกมาเป็นค่า pixel X Y บนหน้าจอ ให้เปลี่ยนเป็น ราคา และ เวลาของแท่งเทียนที่มันชี้อยู่
ผมก็เลยประกาศตัวแปลมารับก็คือ sub time price สามตัว
sub ก็ คือ subwindows index กรณีที่chart นั้นๆมีหลาย indicator windows มันก็สามารถบอกเราได้ ปกติก็จะได้ค่ามาก็คือ 0 หรือ main window นั่นเอง
time ก็คือ เวลาของแท่งเทียนที่เม้าส์ชี้อยู่ Price ก็คือ ราคา
ย้อนไปด้านบนนิสนึง ผมสร้าง object graphic มาสองตัวก็คือ "mouse" "range" ที่ทำหน้าที่เป็น label text เพื่อที่จะได้เอาผลลัพท์ไปแสดงออกไปได้ โดยใช้ ฟังก์ชั่นที่สร้างขึ้นมาเอง ชื่อว่า LabelCreate() ซึ่งก็ต้องใช้ค่าอะไรยุ่บยั่บไปหมด ลองอ่านกันดูนะครับ (ขี้เกียจสอน มันย๊าวยาว)
กลับมาต่อ ถ้า เม้าส์เราขยับแล้วเราก็สามารถอ่านค่าต่างๆได้ โดยแสดงออกทันที่โดยการเปลี่ยน value ของ label text โดยใช้ function LabelTextChange() (เขียนเองเช่นกัน)
สุดท้ายลอง รันดู ก้ได้ หน้าตาประมาณนี้ะครับ
หายไปสักหลายวันได้อยู่ สำหรับแอดมิน เนื่องจากงานยุ่งโค๊ดดๆ
Bฺrexit ที่ผ่านหวังว่าทุกคนจะยังคงอยู่ดี นั่งเงียบๆทับมือตัวเอง ปิด ea แล้วไปพักผ่อนกันนะครับ
ผมก็ไม่ได้รันอะไรทิ้งไว้สักเท่าไร ทุนก็ไม่มี ก็เลยนั่งเขียนโค้ดเก่าเอามาปัดฝุ่นใหม่ซะหน่อย กะว่าจะทำอะไรเล่น บังเอิญไปเจอ code ที่เกี่ยวกับchart ดึงค่าจาก chart ผ่านทางตำแหน่งของ mouse cursor ที่อยู่บนหน้าจอนี่แหละ
เอาเจ๋งดีแฮะ เผื่อเอาไว้เทรด red green คำนวณ lot size ได้
ก็เลยเอาทำเล่น
ประมาณว่า ถ้า mouse อยู่ที่แท่งเที่ยนไหนก็ให้บอกราคาณที่เม้าส์ชี้อยู่ แล้วก็บอกว่าแท่งเทียนนั้นมีระยะระหว่างสูงต่ำกี่ pips
อูววว
น่าสนุกจุง
งานนี้พระเอกคือ
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
}
ก่อนการใช้งานต้อง enable ที่ OnInit() ด้วยว่า
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
ห้ามลืมเด็ดขาดวิธีใช้ก็ไม่ยาก นะครับ คือไอ้พวก events ต่างๆที่เกิดจากการกระทำบน chart นั้นเปิด help อ่านได้ว่ามีอะไรบ้าง
จากนั้นก็ใช้ ประโยคที่ว่า
if(id==CHARTEVENT_MOUSE_MOVE)
{
...สิ่งที่อยากทำ
}
CHARTEVENT_MOUSE_MOVE
อีกฟังก์ชั่นนึงก็คือ ChartXYToTimePrice เป็นการแปลง ตำแหน่งของลูกศรเม้าส์ ที่ออกมาเป็นค่า pixel X Y บนหน้าจอ ให้เปลี่ยนเป็น ราคา และ เวลาของแท่งเทียนที่มันชี้อยู่
ผมก็เลยประกาศตัวแปลมารับก็คือ sub time price สามตัว
sub ก็ คือ subwindows index กรณีที่chart นั้นๆมีหลาย indicator windows มันก็สามารถบอกเราได้ ปกติก็จะได้ค่ามาก็คือ 0 หรือ main window นั่นเอง
time ก็คือ เวลาของแท่งเทียนที่เม้าส์ชี้อยู่ Price ก็คือ ราคา
int sub;
datetime time;
double price;
ChartXYToTimePrice(0,lparam,dparam,sub,time,price);
ย้อนไปด้านบนนิสนึง ผมสร้าง object graphic มาสองตัวก็คือ "mouse" "range" ที่ทำหน้าที่เป็น label text เพื่อที่จะได้เอาผลลัพท์ไปแสดงออกไปได้ โดยใช้ ฟังก์ชั่นที่สร้างขึ้นมาเอง ชื่อว่า LabelCreate() ซึ่งก็ต้องใช้ค่าอะไรยุ่บยั่บไปหมด ลองอ่านกันดูนะครับ (ขี้เกียจสอน มันย๊าวยาว)
กลับมาต่อ ถ้า เม้าส์เราขยับแล้วเราก็สามารถอ่านค่าต่างๆได้ โดยแสดงออกทันที่โดยการเปลี่ยน value ของ label text โดยใช้ function LabelTextChange() (เขียนเองเช่นกัน)
สุดท้ายลอง รันดู ก้ได้ หน้าตาประมาณนี้ะครับ
//+------------------------------------------------------------------+
//| testmouse.mq4 |
//| iamgotzaa |
//| http://a7a8zz.blogspot.com |
//+------------------------------------------------------------------+
#property copyright "iamgotzaa"
#property link "http://a7a8zz.blogspot.com"
#property version "1.00"
//#property strict
//#include <MQL4OBJ.mqh>
//#include <SmallFunc.mqh>
string c;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
LabelCreate(0,"mouse",0,0,0,0,"X","Arial",10,clrRed,0,ANCHOR_LEFT_UPPER);
LabelCreate(0,"range",0,20,50,0,"Range=","Courier New",10,clrYellow,0,ANCHOR_LEFT_UPPER);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
ObjectDelete(0,"mouse");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
Comment(c);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//---
if(id==CHARTEVENT_MOUSE_MOVE)
{
//Print("x=",lparam,", y=",dparam);
c="x="+(double)DoubleToString(lparam,0)+", y="+(double)DoubleToString(dparam,0);
LabelMove(0,"mouse",lparam,dparam);
int sub;
datetime time;
double price;
ChartXYToTimePrice(0,lparam,dparam,sub,time,price);
int shift=iBarShift(NULL,0,time);
double range=High[shift]-Low[shift];
//LabelTextChange(0,"range","Range="+DoubleToString(range,Digits));
LabelTextChange(0,"range","Range="+pxpipStr(range));
LabelTextChange(0,"mouse"," P="+DoubleToString(price,Digits));
}
}
//+------------------------------------------------------------------+
bool LabelCreate(const long chart_ID=0, // chart's ID
const string name="Label", // label name
const int sub_window=0, // subwindow index
const int x=0, // X coordinate
const int y=0, // Y coordinate
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
const string objtext="Label",// objtext
const string font="Arial", // font
const int font_size=10, // font size
const color clr=clrRed, // color
const double angle=0.0, // objtext slope
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // anchor type
const bool back=false, // in the background
const bool selection=false, // highlight to move
const bool hidden=true, // hidden in the object list
const long z_order=0) // priority for mouse click
{
//--- reset the error value
ResetLastError();
//--- create a objtext label
if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create objtext label! Error code = ",GetLastError());
return(false);
}
//--- set label coordinates
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- set the chart's corner, relative to which point coordinates are defined
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- set the objtext
ObjectSetString(chart_ID,name,OBJPROP_TEXT,objtext);
//--- set objtext font
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- set font size
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- set the slope angle of the objtext
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- set anchor type
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- set color
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the objtext label |
//+------------------------------------------------------------------+
bool LabelMove(const long chart_ID=0, // chart's ID
const string name="Label", // label name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the objtext label
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the label! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the label! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the object objtext |
//+------------------------------------------------------------------+
bool LabelTextChange(const long chart_ID=0, // chart's ID
const string name="Label", // object name
const string objtext="Text") // objtext
{
//--- reset the error value
ResetLastError();
//--- change object objtext
bool notsame=false;
if(ObjectGetString(chart_ID,name,OBJPROP_TEXT)!=objtext)
{
notsame=true;
}
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,objtext) && notsame)
{
Print(__FUNCTION__,
": failed to change the objtext! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string pxpipStr(double pricegap,
int decimal=0,
bool showunits=true)//zero or one
{
if(!showunits)
{
return(DoubleToString(pxpip(pricegap),decimal));
}
return(DoubleToString(pxpip(pricegap),decimal)+" pips");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
double pxpip(double pricegap)
{
double retval=0;
retval=pricegap*MathPow(10,Digits-1);
return(retval);
}