OnChartEvent
OnChartEvent
当ChartEvent事件发生时在指标和EA中调用这个函数。这个函数意在处理由用户或者MQL5程序所做的图表更改。
void OnChartEvent()
const int id, // 事件ID
const long& lparam, // 长整型(long)事件参数
const double& dparam, // 长整型(double)事件参数
const string& sparam // 字符串型(string)事件参数
);参数
- id
[in] 来自ENUM_CHART_EVENT枚举的事件ID。
- lparam
[in] 长整型(long)事件参数
- dparam
[in] 双精度型(double)事件参数
- sparam
[in] 字符串型(string)事件参数
返回值
无返回值
注意
共有11种事件类型可以使用预定义OnChartEvent()函数来处理。为自定义事件提供了从CHARTEVENT_CUSTOM到CHARTEVENT_CUSTOM_LAST包含的65535个ID。若要生成自定义事件,请使用EventChartCustom()函数。
来自ENUM_CHART_EVENT 枚举的简短事件描述:
- CHARTEVENT_KEYDOWN — 当图表窗口处于焦点时,按下键盘上的一个按键;
- CHARTEVENT_MOUSE_MOVE — 移动鼠标,并且鼠标按键点击(如果图表 CHART_EVENT_MOUSE_MOVE=true);
- CHARTEVENT_OBJECT_CREATE — 创建一个图形对象(如果图表 CHART_EVENT_OBJECT_CREATE=true);
- CHARTEVENT_OBJECT_CHANGE — 通过属性对话框更改对象属性;
- CHARTEVENT_OBJECT_DELETE — 删除一个图形对象(如果图表 CHART_EVENT_OBJECT_DELETE=true);
- CHARTEVENT_CLICK — 点击图表;
- CHARTEVENT_OBJECT_CLICK — 鼠标单击属于图表的图形对象;
- CHARTEVENT_OBJECT_DRAG — 用鼠标拖动图形对象;
- CHARTEVENT_OBJECT_ENDEDIT — 在图形对象的“编辑”输入框中完成文本编辑(OBJ_EDIT);
- CHARTEVENT_CHART_CHANGE — 更改图表;
- CHARTEVENT_CUSTOM+n — 自定义事件ID,这里n的范围是从0到65535。CHARTEVENT_CUSTOM_LAST包含最后可接受的自定义事件ID (CHARTEVENT_CUSTOM+65535)。
所有MQL5程序都使用了不同于应用程序主线程的其他线程。主应用程序线程负责处理所有的Windows系统消息,反过来,作为该处理的结果,为其自身的应用程序生成Windows消息。例如,在图表上移动鼠标(WM_MOUSE_MOVE事件)为随后呈现的应用程序窗口生成几个系统消息,并将内部消息发送到在图表上启动的EA和指标。可能会出现这样的情况,主要的应用程序线程还没有处理WM_PAINT系统消息(因此还没有呈现修改过的图表),而EA或指标却已经收到了鼠标移动事件。在这种情况下,只有在呈现图表之后,图表属性CHART_FIRST_VISIBLE_BAR才会更改。
对于每种事件类型,OnChartEvent()函数的输入都具有处理该事件所需的某些值。该表列出了通过参数传递的事件和值。
| 事件 | ‘id’ 参数值 | ’lparam’参数值 | ‘dparam’参数值 | ‘sparam’参数值 |
|---|---|---|---|---|
| Keystroke事件 | CHARTEVENT_KEYDOWN | 按下按键代码 | 在按键处于按下状态时生成的按键响应的数量 | 位掩码的字符串值,描述键盘按键的状态 |
| 鼠标事件 (如果图表CHART_EVENT_MOUSE_MOVE=true) | CHARTEVENT_MOUSE_MOVE | X 坐标 | Y 坐标 | 位掩码的字符串值,描述鼠标按键的状态 |
| 鼠标滚轮事件(如果CHART_EVENT_MOUSE_WHEEL=true为图表设置) | CHARTEVENT_MOUSE_WHEEL | 键盘按键和鼠标按键的状态标识,光标的X和Y坐标。请参阅示例中的描述 | 鼠标滚轮滚动的Delta值 | — |
| 创建一个图形对象(如果图表CHART_EVENT_OBJECT_CREATE=true) | CHARTEVENT_OBJECT_CREATE | — | — | 已创建图形对象的名称 |
| 通过属性对话框更改对象属性 | CHARTEVENT_OBJECT_CHANGE | — | — | 已更改图形对象的名称 |
| 移除一个图形对象(如果图表CHART_EVENT_OBJECT_DELETE=true) | CHARTEVENT_OBJECT_DELETE | — | — | 已移除图形对象的名称 |
| 图表点击图表 | CHARTEVENT_CLICK | X 坐标 | Y 坐标 | — |
| 鼠标点击图形对象 | CHARTEVENT_OBJECT_CLICK | X 坐标 | Y 坐标 | 事件所发生的图形对象的名称 |
| 使用鼠标移动图形对象 | CHARTEVENT_OBJECT_DRAG | — | — | 已移动图形对象的名称 |
| 在图形对象输入框的“输入字段”中完成文本编辑 | CHARTEVENT_OBJECT_ENDEDIT | — | — | “输入字段”图形对象的名称,在这里完成文本编辑 |
| 通过属性对话框窗口,调整图表大小或更改图表属性 | CHARTEVENT_CHART_CHANGE | — | — | — |
| N个数字的自定义事件 | CHARTEVENT_CUSTOM+N | 通过EventChartCustom()函数定义的值 | 通过EventChartCustom()函数定义的值 | 通过EventChartCustom()函数定义的值 |
示例图表事件监听器:
//+------------------------------------------------------------------+
//| OnChartEvent_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample chart event listener and custom events generator"
//--- 服务键ID
#define KEY_NUMPAD_5 12
#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39
#define KEY_DOWN 40
#define KEY_NUMLOCK_DOWN 98
#define KEY_NUMLOCK_LEFT 100
#define KEY_NUMLOCK_5 101
#define KEY_NUMLOCK_RIGHT 102
#define KEY_NUMLOCK_UP 104
//+------------------------------------------------------------------+
//| EA交易初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 显示CHARTEVENT_CUSTOM常数值
Print("CHARTEVENT_CUSTOM=",CHARTEVENT_CUSTOM);
//---
Print("Launched the EA ",MQLInfoString(MQL5_PROGRAM_NAME));
//--- 设置接收图表对象创建事件的标识
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_CREATE,true);
//--- 设置接收图表对象移除事件的标识
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_DELETE,true);
//--- 启用鼠标滚轮来滚动信息
ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
//--- 强制更新图表属性确保做好事件处理的准备
ChartRedraw();
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA报价函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 用于生成自定义事件的报价计数器
static int tick_counter=0;
//--- 通过这个值除以累积的报价
int simple_number=113;
//---
tick_counter++;
//--- 如果报价计数器是simple_number的倍数,则发送自定义事件
if(tick_counter%simple_number==0)
{
//--- 形成自定义事件ID(从0到65535)
ushort custom_event_id=ushort(tick_counter%65535);
//--- 发送参数填充的自定义事件
EventChartCustom(ChartID(),custom_event_id,tick_counter,SymbolInfoDouble(Symbol(),SYMBOL_BID),__FUNCTION__);
//--- 添加到日志来分析示例结果
Print(__FUNCTION__,": Sent a custom event ID=",custom_event_id);
}
//---
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- 按键响应
if(id==CHARTEVENT_KEYDOWN)
{
switch((int)lparam)
{
case KEY_NUMLOCK_LEFT: Print("Pressed KEY_NUMLOCK_LEFT"); break;
case KEY_LEFT: Print("Pressed KEY_LEFT"); break;
case KEY_NUMLOCK_UP: Print("Pressed KEY_NUMLOCK_UP"); break;
case KEY_UP: Print("Pressed KEY_UP"); break;
case KEY_NUMLOCK_RIGHT: Print("Pressed KEY_NUMLOCK_RIGHT"); break;
case KEY_RIGHT: Print("Pressed KEY_RIGHT"); break;
case KEY_NUMLOCK_DOWN: Print("Pressed KEY_NUMLOCK_DOWN"); break;
case KEY_DOWN: Print("Pressed KEY_DOWN"); break;
case KEY_NUMPAD_5: Print("Pressed KEY_NUMPAD_5"); break;
case KEY_NUMLOCK_5: Print("Pressed KEY_NUMLOCK_5"); break;
default: Print("Pressed unlisted key");
}
}
//--- 左击图表
if(id==CHARTEVENT_CLICK)
Print("Mouse click coordinates on a chart: x = ",lparam," y = ",dparam);
//--- 点击图形对象
if(id==CHARTEVENT_OBJECT_CLICK)
Print("Clicking a mouse button on an object named '"+sparam+"'");
//--- 被移除的对象
if(id==CHARTEVENT_OBJECT_DELETE)
Print("Removed object named ",sparam);
//--- 被创建的对象
if(id==CHARTEVENT_OBJECT_CREATE)
Print("Created object named ",sparam);
//--- 被更改的对象
if(id==CHARTEVENT_OBJECT_CHANGE)
Print("Changed object named ",sparam);
//--- 被移动的对象或被改变的定位点坐标
if(id==CHARTEVENT_OBJECT_DRAG)
Print("Changing anchor points of object named ",sparam);
//--- 在“编辑”图形对象的输入字段更改文本
if(id==CHARTEVENT_OBJECT_ENDEDIT)
Print("Changed text in Edit object ",sparam," id=",id);
//--- 鼠标移动事件
if(id==CHARTEVENT_MOUSE_MOVE)
Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
if(id==CHARTEVENT_MOUSE_WHEEL)
{
//--- 考虑这个事件的鼠标按键和滚轮的状态
int flg_keys = (int)(lparam>>32); // Ctrl 和 Shift 键,鼠标按键的状态标识
int x_cursor = (int)(short)lparam; // 鼠标滚轮事件发生的X坐标
int y_cursor = (int)(short)(lparam>>16); // 鼠标滚轮事件发生的Y坐标
int delta = (int)dparam; // 鼠标滚动的总值,到达 +120 或 -120 时触发
//--- 处理标识
string str_keys="";
if((flg_keys&0x0001)!=0)
str_keys+="LMOUSE ";
if((flg_keys&0x0002)!=0)
str_keys+="RMOUSE ";
if((flg_keys&0x0004)!=0)
str_keys+="SHIFT ";
if((flg_keys&0x0008)!=0)
str_keys+="CTRL ";
if((flg_keys&0x0010)!=0)
str_keys+="MMOUSE ";
if((flg_keys&0x0020)!=0)
str_keys+="X1MOUSE ";
if((flg_keys&0x0040)!=0)
str_keys+="X2MOUSE ";
if(str_keys!="")
str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1)+"'";
PrintFormat("%s: X=%d, Y=%d, delta=%d%s",EnumToString(CHARTEVENT_MOUSE_WHEEL),x_cursor,y_cursor,delta,str_keys);
}
//--- 使用属性对话框窗口调整图表大小或更改图表属性的事件
if(id==CHARTEVENT_CHART_CHANGE)
Print("Changing the chart size or properties");
//--- 自定义事件
if(id>CHARTEVENT_CUSTOM)
PrintFormat("Custom event ID=%d, lparam=%d, dparam=%G, sparam=%s",id,lparam,dparam,sparam);
}
//+------------------------------------------------------------------+
//| 鼠标点选位置 |
//+------------------------------------------------------------------+
string MouseState(uint state)
{
string res;
res+="\nML: " +(((state& 1)== 1)?"DN":"UP"); // 鼠标左移
res+="\nMR: " +(((state& 2)== 2)?"DN":"UP"); // 鼠标右移
res+="\nMM: " +(((state&16)==16)?"DN":"UP"); // 鼠标居中
res+="\nMX: " +(((state&32)==32)?"DN":"UP"); // 鼠标点选第一个X键
res+="\nMY: " +(((state&64)==64)?"DN":"UP"); // 鼠标点选第二个 X 键
res+="\nSHIFT: "+(((state& 4)== 4)?"DN":"UP"); // 移位键
res+="\nCTRL: " +(((state& 8)== 8)?"DN":"UP"); // 控制键
return(res);
}