第十八章 图表操作
这些是使用图表的函数。 所有图表操作的函数只能在EA交易程序 和 脚本中使用。
设置图表属性的函数(ChartSetInteger,ChartSetDouble,ChartSetString)是不同步的,实际上用于向图表发送 更新 命令。如果这些函数成功执行,那么这个命令就包含在图表事件的公共队列中。在处理图表事件的队列时,相应的更改将实施到图表。
因此,不要期望在调用这些函数后立即直观地看到图表更新。 一般情况下,客户端会在更改事件后自动更新图表 —— 新的报价到达、调整图表窗口大小等。使用ChartRedraw()函数以强制更新图表的外观和属性。
函数 | 功能 |
---|---|
ChartApplyTemplate | 指定一个模板文件应用到图表 |
ChartSaveTemplate | 保存当前图表设置到指定名称的模板中 |
ChartWindowFind | 返回绘画指标的副图(子)窗口数字编号 |
ChartTimePriceToXY | 将图表的坐标从 时间/价格 转换为 X和Y轴 |
ChartXYToTimePrice | 转换图表的X和Y轴到 时间和价格 值 |
ChartOpen | 打开一个新图表显示指定的交易品种和时间周期 |
ChartClose | 关闭指定图表。 |
ChartFirst | 返回客户端的第一个图表的ID |
ChartNext | 返回指定图表的下一个图表的ID |
ChartSymbol | 返回指定图表的交易品种名称 |
ChartPeriod | 返回指定图表的时间周期 |
ChartRedraw | 指定图表强制重画 |
ChartSetDouble | 设置指定图表相关属性的双精度值 |
ChartSetInteger | 设置指定图表相关属性的整数值 |
ChartSetString | 设置指定图表相关属性的字符串值 |
ChartGetDouble | 返回指定图表的双精度值属性 |
ChartGetInteger | 返回指定图表的整数值属性 |
ChartGetString | 返回指定图表的字符串属性 |
ChartNavigate | 根据指定的图表 定位常量,跳转到指定位置 |
ChartID | 返回当前图表的ID编号 |
ChartIndicatorAdd | 将指定的指标(句柄)添加到图表窗口中 |
ChartIndicatorDelete | 从指定图表窗口移除一个指定名称的指标 |
ChartIndicatorGet | 返回图表窗口中指定短名称的指标的句柄 |
ChartIndicatorName | 在图表窗口,通过指定的数字编号,返回指标的短名称 |
ChartIndicatorsTotal | 返回应用到指定图表窗口中的全部指标的总数量。 |
ChartWindowOnDropped | 当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口的索引编号数字。 |
ChartPriceOnDropped | 当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的价格坐标。 |
ChartTimeOnDropped | 当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的时间坐标。 |
ChartXOnDropped | 当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的X坐标 |
ChartYOnDropped | 当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的Y坐标 |
ChartSetSymbolPeriod | 改变图表窗口中的交易品种 和 时间周期 |
ChartScreenShot | 根据指定的扩展名,以GIF,PNG或BMP格式对当前图表截屏 |
# 18.1 ChartApplyTemplate
在图表中应用指定文件中的特定模板。该命令添加到图表信息队列并且将在处理完之前所有命令后开始执行。
bool ChartApplyTemplate(
long chart_id, // 图表 ID
const string filename // 模板文件名
);
2
3
4
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
filename
[in] 包含模板的文件名。
返回值
如果该命令已添加到图表队列,则返回true,否则返回false。要获取有关错误的信息,请调用GetLastError()函数。
注意
如果成功将新模板加载到图表,EA交易程序将被卸载并且无法继续操作。
将模板应用于图表时,由于安全原因,交易权限可能会受到限制:
实时交易权限无法通过使用ChartApplyTemplate()函数应用模板而扩展到EA交易程序中。
如果调用ChartApplyTemplate()函数的mql5-程序没有交易权限,那么无论模板如何设置,通过模板启动的EA交易都将不能交易。
如果调用ChartApplyTemplate()函数的mql5-程序有交易权限,而在模板设置中没有这种权限,那么通过模板启动的EA交易程序也将不能交易。
使用模板
MQL5语言资源允许使用ChartSetInteger()函数设置多个图表的属性,包括颜色值:
• 图表背景色;
• 坐标轴,比例和OHLC线的颜色;
• 网格颜色;
• 交易量和持仓水平的颜色;
• 牛市蜡烛图的影线和边界的颜色;
• 熊市蜡烛图的影线和边界的颜色;
• 图表线和十字蜡烛图的颜色;
• 牛市蜡烛图主体的颜色;
• 熊市蜡烛图主体的颜色;
• 卖价(Bid)线的颜色;
• 买价(Ask)线的颜色;
• 最后成交价线(收盘价)的颜色;
• 止损订单价位的颜色(止损和获利)。
此外,在图表上可以有多个图形对象和指标。您可以创建一个包含所有必要指标的图表,然后将其保存为模板。这样的模板可以应用于任何图表。
ChartApplyTemplate()函数可以使用以前保存的模板,并且可以在任何mql5程序中使用。 存储模板的文件路径作为第二个参数传递给ChartApplyTemplate()。 根据以下规则搜索模板文件:
• 如果反斜杠 "" 分隔符(写为"\")位于路径的开头,则会搜索相对路径 _terminal_data_directory\MQL5中的模板文件, • 如果没有反斜杠,则搜索相对于可执行EX5文件的模板,在该EX5文件中调用ChartApplyTemplate(); • 如果在前两个路径中未找到模板,则在文件夹terminal_directory \ Profiles \ Templates \中执行搜索。
这里terminal_directory是指客户端运行的文件夹,terminal_data_directory是存储可编辑文件的 数据文件夹,它的位置取决于操作系统,用户名和计算机安全设置。通常它们是不同的文件夹,但某些情况下它们可能会重合。
文件夹 terminal_data_directory 和 terminal_directory 的位置可以使用TerminalInfoString()函数获取。
//--- 启动程序端的目录
string terminal_path=TerminalInfoString(TERMINAL_PATH);
Print("Terminal directory:",terminal_path);
//--- 程序端数据目录,这里存储MQL5的EA和指标文件夹
string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
Print("Terminal data directory:",terminal_data_path);
2
3
4
5
6
例如:
//--- 在terminal_data_directory\MQL5\搜索模板
ChartApplyTemplate(0,"\\first_template.tpl"))
//--- 在directory_of_EX5_file\搜索模板, 然后在文件夹terminal_data_directory\Profiles\Templates\
ChartApplyTemplate(0,"second_template.tpl"))
//--- 在directory_of_EX5_file\My_templates\搜索模板,然后在文件夹terminal_directory\Profiles\Templates\My_templates\
ChartApplyTemplate(0,"My_templates\\third_template.tpl"))
2
3
4
5
6
模板不是资源,它们不能被包含到可执行EX5文件。 示例:
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 应用模板示例,位于\MQL5\Files
if(FileIsExist("my_template.tpl"))
{
Print("The file my_template.tpl found in \Files'");
//--- 应用模板
if(ChartApplyTemplate(0,"\\Files\\my_template.tpl"))
{
Print("The template 'my_template.tpl' applied successfully");
//--- 重绘图表
ChartRedraw();
}
else
Print("Failed to apply 'my_template.tpl', error code ",GetLastError());
}
else
{
Print("File 'my_template.tpl' not found in "
+TerminalInfoString(TERMINAL_PATH)+"\\MQL5\\Files");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
相关参考
资源
# 18.2 ChartSaveTemplate
保存当前图表设置到指定名称的模板中。
bool ChartSaveTemplate(
long chart_id, // 图表 ID
const string filename // 保存模板的文件名
);
2
3
4
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
filename
[in] 保存模板的文件名。 “.tpl”扩展名将自动添加到文件名中; 无需指定。该模板保存在Templates \中,并可用于在客户端中手动加载。如果具有相同名称的模板文件已经存在,则该文件的内容将会被覆盖。
返回值
如果成功,函数返回true,否则返回false。若要获得有关错误的信息, 请调用 GetLastError() 函数。
注意
使用模板时,您可以保存所有应用指标和图形对象的图表设置,然后将其应用到另一个图表。
例如:
//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- 输入参数
input string symbol="GBPUSD"; // 新图表的交易品种
input ENUM_TIMEFRAMES period=PERIOD_H3; // 新图表的时间帧
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 首先附加指标到图表
int handle;
//--- 准备使用指标
if(!PrepareZigzag(NULL,0,handle)) return; // 失败,所以退出
//--- 附加指标到当前图表,但是在独立窗口。
if(!ChartIndicatorAdd(0,1,handle))
{
PrintFormat("Failed to attach to chart %s/%s an indicator with the handle=%d. Error code %d",
_Symbol,
EnumToString(_Period),
handle,
GetLastError());
//--- 终止程序操作
return;
}
//--- 刷新图表看指标
ChartRedraw();
//--- 找出最近两个Z字形断裂
double two_values[];
datetime two_times[];
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("Failed to find two last fractures in the Zigzag!");
//--- 终止程序操作
return;
}
//--- 现在附加标准偏差通道
string channel="StdDeviation Channel";
if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0))
{
PrintFormat("Failed to create object %s. Error code %d",
EnumToString(OBJ_STDDEVCHANNEL),GetLastError());
return;
}
else
{
//--- 通道已经创建,定义第二点
ObjectSetInteger(0,channel,OBJPROP_TIME,1,two_times[0]);
//--- 为通道设置提示工具文本
ObjectSetString(0,channel,OBJPROP_TOOLTIP,"Demo from MQL5 Help");
//--- 刷新图表
ChartRedraw();
}
//--- 在模板中保存结果
ChartSaveTemplate(0,"StdDevChannelOnZigzag");
//--- 打开新图表并应用保存的模板
long new_chart=ChartOpen(symbol,period);
//--- 启用图形对象的工具提示
ChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR,true);
if(new_chart!=0)
{
//--- 将保存的模板应用到图表
ChartApplyTemplate(new_chart,"StdDevChannelOnZigzag");
}
Sleep(10000);
}
//+------------------------------------------------------------------+
//| 创建Z字形句柄并确保其数据准备就绪 |
//+------------------------------------------------------------------+
bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h)
{
ResetLastError();
//--- Z字形指标必须位于terminal_data_folder\MQL5\Examples
h=iCustom(sym,tf,"Examples\\Zigzag");
if(h==INVALID_HANDLE)
{
PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",
__FUNCTION__,GetLastError());
return false;
}
//--- 创建指标句柄时,它需要时间计算价值
int k=0; // 等候指标计算的尝试数量
//--- 等候循环计算,如果计算还未做好准备,暂停50毫秒
while(BarsCalculated(h)<=0)
{
k++;
//--- 显示尝试的数量
PrintFormat("%s: k=%d",__FUNCTION__,k);
//--- 等候50毫秒,直至指标被计算
Sleep(50);
//--- 如果尝试超过100次,那么有些事情就是错误的
if(k>100)
{
//--- 报告问题
PrintFormat("Failed to calculate the indicator for %d attempts!");
//--- 终止程序操作
return false;
}
}
//--- 一切做好准备,指标被创建,价值被计算
return true;
}
//+------------------------------------------------------------------+
//| 搜索最近的2个Z字形断裂,置于数组 |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle)
{
double values[]; // Z字形价值的数组
datetime times[]; // 获得时间的数组
int size=100; // 数组大小
ResetLastError();
//--- 复制指标最近的100值
int copied=CopyBuffer(handle,0,0,size,values);
//--- 检查复制值的数量
if(copied<100)
{
PrintFormat("%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d",
__FUNCTION__,size,handle,GetLastError());
return false;
}
//--- 按照时间序列定义访问数组的顺序
ArraySetAsSeries(values,true);
//--- 在这里写下断裂处的柱形数量
int positions[];
//--- 设置数组大小
ArrayResize(get_values,3); ArrayResize(get_times,3); ArrayResize(positions,3);
//--- 计数器
int i=0,k=0;
//--- 开始搜索断裂处
while(i<100)
{
double v=values[i];
//--- 我们对空值不感兴趣W
if(v!=0.0)
{
//--- 记住柱形数
positions[k]=i;
//--- 记住断裂上的Z字形值
get_values[k]=values[i];
PrintFormat("%s: Zigzag[%d]=%G",__FUNCTION__,i,values[i]);
//--- 增加计数器
k++;
//--- 如果找到两个断裂,中断循环
if(k>2) break;
}
i++;
}
//--- 按照时间序列定义访问数组的顺序
ArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true);
if(CopyTime(_Symbol,_Period,0,size,times)<=0)
{
PrintFormat("%s: Failed to copy %d values from CopyTime(). Error code %d",
__FUNCTION__,size,GetLastError());
return false;
}
//--- 打开柱形图的开盘时间,在这上面出现最近的2个断裂
get_times[0]=times[positions[1]];// 倒数第二个值将被写成第一个断裂
get_times[1]=times[positions[2]];// 倒数第三个值将是第二个断裂
PrintFormat("%s: first=%s, second=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0]));
//--- 成功
return true;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
相关参考
ChartApplyTemplate(), 资源
# 18.3 ChartWindowFind
返回绘画指标的副图(子)窗口数字编号。该函数有两个变体。
- 该函数在指定的图表中搜索具有指定指标的“短名称”的子窗口(短名称显示在子窗口的左上部分),并在成功时返回子窗口号码。
int ChartWindowFind(
long chart_id, // 图表标识符
string indicator_shortname // 指标”短名称”, 见 INDICATOR_SHORTNAME
2
3
- 函数必须从自定义指标中调用。返回指标工作的子窗口数。
int ChartWindowFind();
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
indicator_shortname
[in] 指标的”短名称”。
返回值
成功的话返回子窗口的编号数字。失败,函数返回 -1。
注意
如果函数第二变体(无参数)是从脚本或者EA交易调用,则返回 -1。
不要将指标的 ”短名称” 和 文件名称 弄混, ”短名称”是使用iCustom()和IndicatorCreate()函数创建指标时指定的名称。如果指标的 ”短名称” 未明确设置,则在编译期间将指定包含该指标源代码的文件名称。
使用IndicatorSetString()函数正确地书写指标的 短名称 是很重要的,短名称 记录在INDICATOR_SHORTNAME属性中。建议 短名称 包含指标的输入参数的值,因为用ChartIndicatorDelete()函数从图表中删除指标,是通过其 短名称 进行识别的。 示例:
#property script_show_inputs
//--- 输入参量
input string shortname="MACD(12,26,9)";
//+------------------------------------------------------------------+
//| 返回带有这个指标的图表窗口号 |
//+------------------------------------------------------------------+
int GetIndicatorSubWindowNumber(long chartID=0,string short_name="")
{
int window=-1;
//---
if((ENUM_PROGRAM_TYPE)MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR)
{
//--- 函数从指标调用,名称不需要
window=ChartWindowFind();
}
else
{
//--- 函数从EA交易或者脚本调用
window=ChartWindowFind(0,short_name);
if(window==-1) Print(__FUNCTION__+"(): Error = ",GetLastError());
}
//---
return(window);
}
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int window=GetIndicatorSubWindowNumber(0,shortname);
if(window!=-1)
Print("Indicator "+shortname+" is in the window #"+(string)window);
else
Print("Indicator "+shortname+" is not found. window = "+(string)window);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
相关参考
ObjectCreate(), ObjectFind()
# 18.4 ChartTimePriceToXY
将图表的坐标从 时间/价格 转换为 X和Y轴
bool ChartTimePriceToXY(
long chart_id, // 图表 ID
int sub_window, // 子窗口数量
datetime time, // 图表上的时间轴
double price, // 图表上的价格轴
int& x, // 图表上时间的X轴
int& y // 图表上价格的Y轴
);
2
3
4
5
6
7
8
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
sub_window
[in] 图表子窗口的数字编号。0代表主图表窗口。
time
[in] 图表上的时间值,其中沿着X轴的像素值将被接收。原点位于主图表窗口的左上角
price
[in] 图表上的价格值,其中沿着Y轴的像素值将被接收。原点位于主图表窗口的左上角
x
[out] 接收X轴的时间转换的变量。
y
[out] 接收Y轴的价格转换的变量。
返回值
如果成功返回true,否则返回false。若要获得的错误信息,请调用GetLastError()函数。
相关参考
ChartXYToTimePrice()
# 18.5 ChartXYToTimePrice
转换图表的X和Y轴到 时间和价格 值
bool ChartXYToTimePrice(
long chart_id, // 图表 ID
int x, // 图表的 X 轴
int y, // 图表的 Y 轴
int& sub_window, // 子窗口的数量
datetime& time, // 图表上的时间
double& price, // 图表上的价格
);
2
3
4
5
6
7
8
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
x
[in] X 轴。
y
[in] Y 轴。
sub_window
[out] 将写入图表的子窗口数字编号。0意味着主图表窗口。
time
[in] 图表上的时间值,其中沿着X轴的像素值将被接收。原点位于主图表窗口的左上角
price
[in] 图表上的价格值,其中沿着Y轴的像素值将被接收。原点位于主图表窗口的左上角
返回值
如果成功返回true,否则返回false。若要获得的错误信息,请调用 GetLastError() 函数。 例如:
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- 在图表上显示事件参数
Comment(__FUNCTION__,": id=",id," lparam=",lparam," dparam=",dparam," sparam=",sparam);
//--- 如果这是鼠标点击事件图表
if(id==CHARTEVENT_CLICK)
{
//--- 准备变量
int x =(int)lparam;
int y =(int)dparam;
datetime dt =0;
double price =0;
int window=0;
//--- 依据日期/时间转换X和Y坐标
if(ChartXYToTimePrice(0,x,y,window,dt,price))
{
PrintFormat("Window=%d X=%d Y=%d => Time=%s Price=%G",window,x,y,TimeToString(dt),price);
//--- 执行反向转换:(X,Y) => (时间,价格)
if(ChartTimePriceToXY(0,window,dt,price,x,y))
PrintFormat("Time=%s Price=%G => X=%d Y=%d",TimeToString(dt),price,x,y);
else
Print("ChartTimePriceToXY return error code: ",GetLastError());
//--- 删除线
ObjectDelete(0,"V Line");
ObjectDelete(0,"H Line");
//--- 创建十字光标的水平线和垂直线
ObjectCreate(0,"H Line",OBJ_HLINE,window,dt,price);
ObjectCreate(0,"V Line",OBJ_VLINE,window,dt,price);
ChartRedraw(0);
}
else
Print("ChartXYToTimePrice return error code: ",GetLastError());
Print("+--------------------------------------------------------------+");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
相关参考
ChartTimePriceToXY()
# 18.6 ChartOpen
打开一个新图表,用于显示指定的交易品种和时间周期。
long ChartOpen(
string symbol, // 交易品种名称
ENUM_TIMEFRAMES period // 周期
);
2
3
4
参数
symbol
[in] 交易品种, NULL 意味着当前图表上的交易品种(附上EA交易的图表)。
period
[in] 图表周期(时间框架)。取值范围是ENUM_TIMEFRAMES枚举值之一。0代表当前图表的时间周期。
返回值
若成功,返回打开图表ID,否则返回0。
注意
客户端同时打开的图表数量,最大值不能超过CHARTS_MAX值。
# 18.7 ChartFirst
返回客户端的第一个图表的ID
long ChartFirst();
返回值
图表 ID。
# 18.8 ChartNext
返回指定图表的下一个图表的ID
long ChartNext(
long chart_id // 图表 ID
);
2
3
参数
chart_id
[in] 图表 ID. 0 不表示当前图表。0表示“返回第一图表”。
返回值
图表 ID。如果已经是最后一个图表,则返回 -1 。 示例:
//--- 用于图表 ID的变量
long currChart,prevChart=ChartFirst();
int i=0,limit=100;
Print("ChartFirst =",ChartSymbol(prevChart)," ID =",prevChart);
while(i<limit)// 不允许超过100个打开的窗口
{
currChart=ChartNext(prevChart); // 通过使用之前图表ID获得新图表ID
if(currChart<0) break; // 到达了图表列表末端
Print(i,ChartSymbol(currChart)," ID =",currChart);
prevChart=currChart;// 为ChartNext()保存当前图表ID
i++;// 不要忘记增加计数器
}
2
3
4
5
6
7
8
9
10
11
12
# 18.9 ChartClose
关闭指定图表。
bool ChartClose(
long chart_id=0 // 图表 ID
);
2
3
参数
chart_id=0
[in] 图表 ID编号。0 表示当前图表。
返回值
若成功,返回true,否则false。
# 18.10 ChartSymbol
返回指定图表的交易品种名称。
string ChartSymbol(
long chart_id=0 // 图表 ID
);
2
3
参数
chart_id=0
[in] 图表 ID编号。0 表示当前图表。
返回值
如果图表不存在,结果是空字符串。
相关参考
ChartSetSymbolPeriod
# 18.11 ChartPeriod
返回指定图表的时间周期。
ENUM_TIMEFRAMES ChartPeriod(
long chart_id=0 // Chart ID
);
2
3
参数
chart_id=0
[in] 图表 ID编号。0 表示当前图表。
返回值
函数返回ENUM_TIMEFRAMES枚举值之一,如果图表不存在,返回0。
# 18.12 ChartRedraw
指定图表强制重画一次。
void ChartRedraw(
long chart_id=0 // 图表 ID
);
2
3
参数
chart_id=0
[in] 图表 ID编号。0 表示当前图表。
注意
通常更改 对象属性 之后使用该函数。
相关参考
对象函数
# 18.13 ChartSetDouble
设置指定图表相关属性的双精度值。该命令被添加到图表消息队列中,并将在处理完所有以前的命令后执行。
bool ChartSetDouble(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
double value // 值
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
prop_id
[in] 图表属性 ID。 取值范围是 ENUM_CHART_PROPERTY_DOUBLE枚举值之一(除了只读属性)。
value
[in] 属性值。
返回值
如果该命令已成功添加到图表队列则返回true,否则返回false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
该函数为异步函数,这意味着该函数不会等待执行已成功添加到指定图表队列的命令。相反,而是立即返回控制。该属性将只会在处理图表队列的对应命令之后更改。若要立即执行来自图表队列的命令,请调用ChartRedraw函数。
如果您想立即改变多个图表属性,那么应该在一个代码框中执行对应的函数(ChartSetString, ChartSetDouble,ChartSetString),在此之后您应该马上调用ChartRedraw函数。
若要检查命令执行的结果,您可以使用一个函数,请求指定的图表属性(ChartGetInteger,ChartGetDouble, ChartSetString)。然而,请注意,这些都是同步函数,会等待执行结果。
# 18.14 ChartSetInteger
设置指定图表相关属性的整数值。图表属性必须是日期时间、整数、颜色、布尔型或者字符型。该命令被添加到图表消息队列中,并将在处理完所有以前的命令后执行。
bool ChartSetInteger(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
long value // 值
);
2
3
4
5
bool ChartSetInteger(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
int sub_window, // 子窗口号
long value // 值
);
2
3
4
5
6
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
prop_id
[in] 图表属性ID. 取值范围是ENUM_CHART_PROPERTY_INTEGER枚举值之一(除了只读属性)。
sub_window
[in] 图表子窗口编号数字。对于第一种情况,默认值为0(图表主窗口)。属性大部分情况不需要子窗口编号数字。
值
[in] 属性值。
返回值
如果该命令已成功添加到图表队列则返回true,否则返回false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
该函数为异步函数,这意味着该函数不会等待执行已成功添加到指定图表队列的命令。相反,而是立即返回控制。该属性将只会在处理图表队列的对应命令之后更改。若要立即执行来自图表队列的命令,请调用ChartRedraw函数。
如果您想立即改变多个图表属性,那么应该在一个代码框中执行对应的函数(ChartSetString, ChartSetDouble,ChartSetString),在此之后您应该马上调用ChartRedraw函数。
若要检查命令执行的结果,您可以使用一个函数,请求指定的图表属性(ChartGetInteger,ChartGetDouble, ChartSetString)。然而,请注意,这些都是同步函数,会等待执行结果。
//+------------------------------------------------------------------+
//| EA交易初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 在图表窗口中启用鼠标移动的事件
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//--- 强制更新图表属性确保做好事件处理的准备
ChartRedraw();
}
//+------------------------------------------------------------------+
//| 鼠标点选位置 |
//+------------------------------------------------------------------+
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);
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(id==CHARTEVENT_MOUSE_MOVE)
Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 18.15 ChartSetString
设置指定图表相关属性的字符串值。该命令添加到图表信息队列并且将在处理完之前所有命令后开始执行。该命令被添加到图表消息队列中,并将在处理完所有以前的命令后执行。
参量
chart_id
[in] 图表 ID编号。0 表示当前图表。
prop_id
[in] 图表属性 ID. 取值范围是ENUM_CHART_PROPERTY_STRING枚举值之一(除了只读属性)。
str_value
[in] 属性值字符串。字符串长度不能超过 2045 个字符(多出的字符会被删除)。
返回值
如果该命令已成功添加到图表队列则返回true,否则返回false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
该函数为异步函数,这意味着该函数不会等待执行已成功添加到指定图表队列的命令。相反,而是立即返回控制。该属性将只会在处理图表队列的对应命令之后更改。若要立即执行来自图表队列的命令,请调用ChartRedraw函数。
如果您想立即改变多个图表属性,那么应该在一个代码框中执行对应的函数(ChartSetString, ChartSetDouble,ChartSetString),在此之后您应该马上调用ChartRedraw函数。
若要检查命令执行的结果,您可以使用一个函数,请求指定的图表属性(ChartGetInteger,ChartGetDouble, ChartSetString)。然而,请注意,这些都是同步函数,会等待执行结果。
示例:
void OnTick()
{
//---
double Ask,Bid;
int Spread;
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
Spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
string comment=StringFormat("Printing prices:\nAsk = %G\nBid = %G\nSpread = %d",
Ask,Bid,Spread);
ChartSetString(0,CHART_COMMENT,comment);
}
2
3
4
5
6
7
8
9
10
11
12
相关参考
Comment , ChartGetString
# 18.16 ChartGetDouble
返回指定图表的双精度值属性。此函数有两个调用变体。
- 直接返回属性值。
double ChartGetDouble(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
int sub_window=0 // 子窗口号,如果需要的话
);
2
3
4
5
- 根据函数执行结果的成功与否,返回 true 或 false。如果成功,属性值保存于 形式参数的目标变量double_var。
bool ChartGetDouble(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
int sub_window, // 子窗口号
double& double_var // 用于保存图表属性的目标变量
);
2
3
4
5
6
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
prop_id
[in] 图表属性 ID. 取值范围是ENUM_CHART_PROPERTY_DOUBLE枚举值之一。
sub_window
[in] 图表子窗口编号数字。对于第一种情况,默认值为0(图表主窗口)。属性大部分情况不需要子窗口编号数字。
double_var
[out] 用于保存双精度类型属性值的目标变量。
返回值
双精度值。
对于第二种调用情况,如果指定属性有效且其值已保存于double_var变量中,函数返回true,否则返回 false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
该函数为同步函数,这意味着它会一直等待,在执行其调用之前已添加到图表队列的所有命令之后,再执行。
示例:
void OnStart()
{
double priceMin=ChartGetDouble(0,CHART_PRICE_MIN,0);
double priceMax=ChartGetDouble(0,CHART_PRICE_MAX,0);
Print("CHART_PRICE_MIN =",priceMin);
Print("CHART_PRICE_MAX =",priceMax);
}
2
3
4
5
6
7
# 18.17 ChartGetInteger
返回指定图表的整数值属性。图表属性必须是日期时间,整数,布尔型。此函数有两种调用变体。
- 直接返回属性值。
long ChartGetInteger(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
int sub_window=0 // 子窗口号,如果需要的话
);
2
3
4
5
- 根据函数执行结果的成功与否,返回 true 或 false。如果成功,属性值保存于 形式参数的目标变量long_var。
bool ChartGetInteger(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
int sub_window, // 子窗口号
long& long_var // 属性目标值
);
2
3
4
5
6
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。。
prop_id
[in] 图表属性 ID. 取值范围是 ENUM_CHART_PROPERTY_INTEGER 枚举值之一。
sub_window
[in] 图表子窗口编号数字。对于第一种情况,默认值为0(图表主窗口)。属性大部分情况都不需要子窗口编号数字。
long_var
[out] 用于保存长整型属性值的目标变量。
返回值
长整型值。
对于第二种调用情况,如果指定属性有效且其值已保存于long_var变量中,函数返回true,否则返回 false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
该函数为同步函数,这意味着它会一直等待,在执行其调用之前已添加到图表队列的所有命令之后,再执行。
示例:
void OnStart()
{
int height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
int width=ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
Print("CHART_HEIGHT_IN_PIXELS =",height,"pixels"); // 当前图表高度,单位像素
Print("CHART_WIDTH_IN_PIXELS =",width,"pixels"); // 当前图表宽度,单位像素
}
2
3
4
5
6
7
# 18.18 ChartGetString
返回指定图表的相关属性值。图表属性必须是字符串型。有两个函数调用变体。
- 直接返回属性值。
string ChartGetString(
long chart_id, // 图表 ID
int prop_id // 属性 ID
);
2
3
4
- 根据函数执行结果的成功与否,返回 true 或 false。如果成功,属性值保存于 形式参数的目标变量string_var。
bool ChartGetString(
long chart_id, // 图表 ID
int prop_id, // 属性 ID
string& string_var // 属性目标值
);
2
3
4
5
参数 chart_id [in] 图表 ID编号。0 表示当前图表。。 prop_id [in] 图表属性 ID。取值范围是 ENUM_CHART_PROPERTY_STRING 枚举值之一。 string_var [out] 用于保存字符串类型属性值的目标变量 返回值 字符串类型值。 对于第二种调用情况,如果指定属性有效且其值已保存于string_var变量中,函数返回true,否则返回 false。若想获得额外错误信息,需要调用函数GetLastError()。 注意 ChartGetString可用于读取使用Comment或ChartSetString函数绘制在图表上的评论。 该函数为同步函数,这意味着它会一直等待,在执行其调用之前已添加到图表队列的所有命令之后,再执行。 示例:
void OnStart()
{
ChartSetString(0,CHART_COMMENT,"Test comment.\nSecond line.\nThird!");
ChartRedraw();
Sleep(1000);
string comm=ChartGetString(0,CHART_COMMENT);
Print(comm);
}
2
3
4
5
6
7
8
相关参考
Comment ,ChartSetString
# 18.19 ChartNavigate
根据指定的图表 定位常量 和 移动偏移值,跳转到图表中指定的位置。
bool ChartNavigate(
long chart_id, // 图表 ID
ENUM_CHART_POSITION position, // 位置
int shift=0 // 移动值
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
position
[in] 图表定位常量。取值范围是ENUM_CHART_POSITION枚举值之一。
shift=0
[in] 移动偏移值,即K线柱的数量。正值意味着向右移动(图表末端),负值意味着左移(到图表起点)。0值用于跳转到图表的开始或结束。
返回值
若成功,返回true,否则返回false。
示例:
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 获得当前图表的句柄
long handle=ChartID();
string comm="";
if(handle>0) // 如果成功,另外设置图表
{
//--- 禁止自动滚动
ChartSetInteger(handle,CHART_AUTOSCROLL,false);
//--- 设置从右图表边界转移
ChartSetInteger(handle,CHART_SHIFT,true);
//--- 绘制蜡烛图
ChartSetInteger(handle,CHART_MODE,CHART_CANDLES);
//--- 设置跳动量的显示模式
ChartSetInteger(handle,CHART_SHOW_VOLUMES,CHART_VOLUME_TICK);
//--- 在Comment()准备输出文本
comm="Scroll 10 bars to the right of the history start";
//--- 显示注释
Comment(comm);
//--- 滚动10柱到历史记录开始的右侧
ChartNavigate(handle,CHART_BEGIN,10);
//--- 设置图表上第一柱显示的数量(类似时间帧的编号)
long first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
//--- 添加换行符
comm=comm+"\r\n";
//--- 添加到注释
comm=comm+"The first bar on the chart is number "+IntegerToString(first_bar)+"\r\n";
//--- 显示注释
Comment(comm);
//--- 等待5秒查看图表如何移动
Sleep(5000);
//--- 添加到注释文本
comm=comm+"\r\n"+"Scroll 10 bars to the left of the right chart border";
Comment(comm);
//--- 滚动10柱到右图表边界的左侧
ChartNavigate(handle,CHART_END,-10);
//--- 获得图表上第一注显示的数量(类似时间帧的编号)
first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
comm=comm+"\r\n";
comm=comm+"The first bar on the chart is number "+IntegerToString(first_bar)+"\r\n";
Comment(comm);
//--- 等待5秒查看图表如何移动
Sleep(5000);
//--- 图表滚动的新模块
comm=comm+"\r\n"+"Scroll 300 bars to the right of the history start";
Comment(comm);
//--- 滚动300柱到历史记录开始的右侧
ChartNavigate(handle,CHART_BEGIN,300);
first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
comm=comm+"\r\n";
comm=comm+"The first bar on the chart is number "+IntegerToString(first_bar)+"\r\n";
Comment(comm);
//--- 等待5秒查看图表如何移动
Sleep(5000);
//--- 图表滚动的新模块
comm=comm+"\r\n"+"Scroll 300 bars to the left of the right chart border";
Comment(comm);
//--- 滚动300柱到右图表边界的左侧
ChartNavigate(handle,CHART_END,-300);
first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
comm=comm+"\r\n";
comm=comm+"The first bar on the chart is number "+IntegerToString(first_bar)+"\r\n";
Comment(comm);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 18.20 ChartID
返回当前图表的ID。
long ChartID();
返回值
长整型 值。
# 18.21 ChartIndicatorAdd
将指定的指标(句柄)添加到图表窗口中。指标和图表应该在相同的交易品种和时间框架上生成。
bool ChartIndicatorAdd(
long chart_id, // 图表 ID
int sub_window // 子窗口号
int indicator_handle // 指标处理
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。。
sub_window
[in] 图表子窗口编号数字。0代表图表主窗口。若要在新窗口添加指标,此参数必须比现有最近窗口的索引编号 +1,例如,等于CHART_WINDOWS_TOTAL。如果参数值大于CHART_WINDOWS_TOTAL,将不会创建新窗口,指标也不会添加。
indicator_handle
[in] 指标的句柄。
返回值
若成功函数返回true,否则返回false。若要获得额外错误信息,需要调用GetLastError()函数。Error 4114 means that a chart and an added indicator differ by their symbol or time frame.
该函数在成功的情况下返回true,否则返回false。为了获取有关错误的信息,请调用GetLastError()函数。错误4114意味着图表和添加的指标因交易品种或时间框架不同。
注意
如果把一个 副图指标(应在单独的子窗口中绘制的指标,例如,内置的iMACD或具有指定#property indicator_separate_window属性的自定义指标)应用于主图表窗口,那么虽然它仍然会显示在 指标列表 清单中,却在图表上是看不见的。这意味着指标的比例尺与价格图表的比例不同,并且应用指标的值不符合价格图的显示范围。在这种情况下,GetLastError()返回 0 代码,指示没有错误。这种“隐形”指标的值可以在数据窗口中看到并从其它MQL5应用程序中收到。
示例:
#property description "Expert Advisor demonstrating the work with ChartIndicatorAdd() function."
#property description "After launching on the chart (and receiving the error in Journal), open"
#property description "the Expert Advisor's properties and specify correct <symbol> and <period> parameters."
#property description "MACD indicator will be added on the chart."
//--- input parameters
input string symbol="AUDUSD"; // symbol name
input ENUM_TIMEFRAMES period=PERIOD_M12; // time frame
input int fast_ema_period=12; // fast MACD period
input int slow_ema_period=26; // slow MACD period
input int signal_period=9; // signal period
input ENUM_APPLIED_PRICE apr=PRICE_CLOSE; // price type for MACD calculation
int indicator_handle=INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
indicator_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,apr);
//--- try to add the indicator on the chart
if(!AddIndicator())
{
//--- AddIndicator() function refused to add the indicator on the chart
int answer=MessageBox("Do you want to add MACD on the chart anyway?",
"Incorrect symbol and/or time frame for adding the indicator",
MB_YESNO // "Yes" and "No" selection buttons will be shown
);
//--- if a user still insists on incorrect usage of ChartIndicatorAdd()
if(answer==IDYES)
{
//--- first of all, a Journal entry will be made about that
PrintFormat("Attention! %s: Trying to add MACD(%s/%s) indicator on %s/%s chart. Receiving error 4114",
__FUNCTION__,symbol,EnumToString(period),_Symbol,EnumToString(_Period));
//--- receive the number of a new subwindow, to which we will try to add the indicator
int subwindow=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
//--- now make an attempt resulting in error
if(!ChartIndicatorAdd(0,subwindow,indicator_handle))
PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
subwindow,GetLastError());
}
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Expert Advisor performs nothing
}
//+------------------------------------------------------------------+
//| Function for checking and adding the indicator on the chart |
//+------------------------------------------------------------------+
bool AddIndicator()
{
//--- displayed message
string message;
//--- check if the indicator symbol and chart symbol match each other
if(symbol!=_Symbol)
{
message="Displaying the use of Demo_ChartIndicatorAdd() function:";
message=message+"\r\n";
message=message+"Unable to add the indicator calculated on another symbol on the chart.";
message=message+"\r\n";
message=message+"Specify the chart symbol in Expert Advisor's property - "+_Symbol+".";
Alert(message);
//--- premature exit, the indicator will not be added on the chart
return false;
}
//--- check if the indicator's and chart's time frames match each other
if(period!=_Period)
{
message="Unable to add the indicator calculated on another time frame on the chart.";
message=message+"\r\n";
message=message+"Specify the chart time frame in Expert Advisor properties - "+EnumToString(_Period)+".";
Alert(message);
//--- premature exit, the indicator will not be added on the chart
return false;
}
//--- all checks completed, symbol and indicator time frame match the chart
if(indicator_handle==INVALID_HANDLE)
{
Print(__FUNCTION__," Creating MACD indicator");
indicator_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,apr);
if(indicator_handle==INVALID_HANDLE)
{
Print("Failed to create MACD indicator. Error code ",GetLastError());
}
}
//--- reset the error code
ResetLastError();
//--- apply the indicator to the chart
Print(__FUNCTION__," Adding MACD indicator on the chart");
Print("MACD is generated on ",symbol,"/",EnumToString(period));
//--- receive the number of a new subwindow, to which MACD indicator is added
int subwindow=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
PrintFormat("Adding MACD indicator on %d chart window",subwindow);
if(!ChartIndicatorAdd(0,subwindow,indicator_handle))
{
PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
subwindow,GetLastError());
}
//--- Indicator added successfully
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
相关参考
ChartIndicatorDelete(), ChartIndicatorName(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate()
# 18.22 ChartIndicatorDelete
从指定图表窗口移除一个指定名称的指标。
bool ChartIndicatorDelete(
long chart_id, // 图表 id
int sub_window // 子窗口数量
const string indicator_shortname // 指标的缩略名
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
sub_window
[in] 图表子窗口的数字编号。0代表主图表的子窗口。
const indicator_shortname
[in] 通过IndicatorSetString()函数在INDICATOR_SHORTNAME属性中设置的指标的“短名称”。若要获得指标的“短名称”,请使用ChartIndicatorName()函数。
返回值
如果指标成功删除,返回true。否则返回false。若想要获得错误信息,请使用GetLastError()函数。
注意
如果在图表子窗口有两个相同“短名称”的指标,那么第一行的指标将被删除。
如果该图表上的另一个指标基于正被删除的指标值,那么这种指标也将被删除。
不要将指标的 ”短名称” 和 文件名称 弄混, ”短名称”是使用iCustom()和IndicatorCreate()函数创建指标时指定的名称。如果指标的 ”短名称” 未明确设置,则在编译期间将指定包含该指标源代码的文件名称。
从图表中删除指标并不意味着其计算部分将从客户端内存中删除。要释放指标句柄,请使用IndicatorRelease()函数。
使用IndicatorSetString()函数正确地书写指标的 短名称 是很重要的,短名称 记录在INDICATOR_SHORTNAME属性中。建议 短名称 包含指标的输入参数的值,因为用ChartIndicatorDelete()函数从图表中删除指标,是通过其 短名称 进行识别的。
初始化失败后删除指标的示例:
//+------------------------------------------------------------------+
//| Demo_ChartIndicatorDelete.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- 绘制柱状图
#property indicator_label1 "Histogram"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- 输入参数
input int first_param=1;
input int second_param=2;
input int third_param=3;
input bool wrong_init=true;
//--- 指标缓冲区
double HistogramBuffer[];
string shortname;
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
int res=INIT_SUCCEEDED;
//--- 连接柱状图缓冲区数组到指标缓冲区
SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
//--- 基于输入参数设置指标缩略名
shortname=StringFormat("Demo_ChartIndicatorDelete(%d,%d,%d)",
first_param,second_param,third_param);
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- 如果设置指标强制完成,返回非零值
if(wrong_init) res=INIT_FAILED;
return(res);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- 工作循环的起始位置
int start=prev_calculated-1;
if(start<0) start=0;
//--- 填写指标缓冲区的值
for(int i=start;i<rates_total;i++)
{
HistogramBuffer[i]=close[i];
}
//--- 返回prev_calculated值为了下次调用
return(rates_total);
}
//+------------------------------------------------------------------+
//| Deinit 事件的处理程序 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
if(reason==REASON_INITFAILED)
{
PrintFormat("An indicator with a short name %s (file %s) deletes itself from the chart",shortname,__FILE__);
int window=ChartWindowFind();
bool res=ChartIndicatorDelete(0,window,shortname);
//--- 分析调用ChartIndicatorDelete()的结果
if(!res)
{
PrintFormat("Failed to delete indicator %s from window #%d. Error code %d",
shortname,window,GetLastError());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
相关参考
ChartIndicatorAdd(), ChartIndicatorName(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate(), IndicatorSetString()
# 18.23 ChartIndicatorGet
返回图表窗口中指定短名称的指标的句柄。
int ChartIndicatorGet(
long chart_id, // 图表 ID
int sub_window // 子窗口数量
const string indicator_shortname // 指标的缩略名
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
sub_window
[in] 图表子窗口的数字编号。0代表主图表的子窗口。
const indicator_shortname
[in] 通过IndicatorSetString()函数在INDICATOR_SHORTNAME属性中设置的指标的“短名称”。若要获得指标的“短名称”,请使用ChartIndicatorName()函数。
返回值
如果成功返回指标句柄,否则返回 INVALID_HANDLE。若想要获得错误信息,请使用GetLastError()函数。
注意
使用IndicatorSetString()函数正确地书写指标的 短名称 是很重要的,短名称 记录在INDICATOR_SHORTNAME属性中。建议 短名称 包含指标的输入参数的值,因为用ChartIndicatorDelete()函数从图表中删除指标,是通过其 短名称 进行识别的。
识别指标的另一种方式就是使用IndicatorParameters()函数获取给定句柄的参数列表,然后分析获得的值。
例如:
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 图表上的窗口数量(至少一个主窗口始终存在)
int windows=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
//--- 检查所有窗口
for(int w=0;w<windows;w++)
{
//--- 该窗口/子窗口的指标数量
int total=ChartIndicatorsTotal(0,w);
//--- 检查窗口中的所有指标
for(int i=0;i<total;i++)
{
//--- 获得指标的缩略名
string name=ChartIndicatorName(0,w,i);
//--- 获得指标的句柄
int handle=ChartIndicatorGet(0,w,name);
//--- 添加到日志
PrintFormat("Window=%d, index=%d, Name=%s, handle=%d",w,i,name,handle);
//--- 当不再需要时您应该强制释放指标句柄
IndicatorRelease(handle);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
相关参考
ChartIndicatorAdd(), ChartIndicatorName(), ChartIndicatorsTotal(), IndicatorParameters()
# 18.24 ChartIndicatorName
在图表窗口,通过指定的数字编号,返回指标的短名称。
string ChartIndicatorName(
long chart_id, // 图表 id
int sub_window // 子窗口数量
int index // 添加到图表子窗口的指标列表中的指标标引
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
sub_window
[in] 图表子窗口的数字编号。0代表主图表的子窗口。
index
[in] 指标列表中的索引编号。指标索引编号从0开始,例如列表中的第一个指标编号为0。若要获得列表中的指标总数量,请使用ChartIndicatorsTotal()函数。
返回值
通过IndicatorSetString()函数在INDICATOR_SHORTNAME属性中设置的指标的“短名称”。若要获得指标的“短名称”,请使用ChartIndicatorName()函数。
注意
不要将指标的 ”短名称” 和 文件名称 弄混, ”短名称”是使用iCustom()和IndicatorCreate()函数创建指标时指定的名称。如果指标的 ”短名称” 未明确设置,则在编译期间将指定包含该指标源代码的文件名称。
使用IndicatorSetString()函数正确地书写指标的 短名称 是很重要的,短名称 记录在INDICATOR_SHORTNAME属性中。建议 短名称 包含指标的输入参数的值,因为用ChartIndicatorDelete()函数从图表中删除指标,是通过其 短名称 进行识别的。
相关参考
ChartIndicatorAdd(), ChartIndicatorDelete(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate(), IndicatorSetString()
# 18.25 ChartIndicatorsTotal
返回应用到指定图表窗口的指标总数量。
int ChartIndicatorsTotal(
long chart_id, // 图表 id
int sub_window // 子窗口数量
);
2
3
4
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
sub_window
[in] 图表子窗口的数字编号。0代表主图表的子窗口。
返回值
指定图表窗口中的指标总数量。若要获得错误信息,请使用 GetLastError() 函数。
注意
该函数被允许搜寻附加在图表中的所有指标。图表窗口的总数可以使用ChartGetInteger()函数从CHART_WINDOWS_TOTAL属性获得。
相关参考
ChartIndicatorAdd(), ChartIndicatorDelete(), iCustom(), IndicatorCreate(), IndicatorSetString()
# 18.26 ChartWindowOnDropped
当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口的索引编号数字。
int ChartWindowOnDropped();
返回值
整型 值。
示例:
int myWindow=ChartWindowOnDropped();
int windowsTotal=ChartGetInteger(0,CHART_WINDOWS_TOTAL);
Print("Script is running on the window #"+myWindow+ // 脚本运行的窗口编号是
". Total windows on the chart "+ChartSymbol()+":",windowsTotal); //窗口中图表总数为
2
3
4
相关参考
ChartPriceOnDropped, ChartTimeOnDropped, ChartXOnDropped, ChartYOnDropped
# 18.27 ChartPriceOnDropped
当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的价格坐标。
double ChartPriceOnDropped();
返回值
双精度值
示例:
double p=ChartPriceOnDropped();
Print("ChartPriceOnDropped() = ",p);
2
相关参考
ChartXOnDropped, ChartYOnDropped
# 18.28 ChartTimeOnDropped
当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的时间坐标。
datetime ChartTimeOnDropped();
返回值
日期时间 类型值。
datetime t=ChartTimeOnDropped();
Print("Script was dropped on the "+t);
2
相关参考
ChartXOnDropped, ChartYOnDropped
# 18.29 ChartXOnDropped
当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的X坐标。
int ChartXOnDropped();
返回值
X 坐标值
注意
X 轴的方向是自左向右的。
int X=ChartXOnDropped();
int Y=ChartYOnDropped();
Print("(X,Y) = ("+X+","+Y+")");
2
3
相关参考
ChartWindowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped
# 18.30 ChartYOnDropped
当拖动一个EA程序 或 脚本到图表窗口时,在 释放(松开) 鼠标左键时,此函数返回图表窗口对应的Y坐标。
int ChartYOnDropped();
返回值
Y 坐标值。
注意
Y 轴的方向是自上向下的。
相关参考
ChartWindowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped
# 18.31 ChartSetSymbolPeriod
更改指定图表的交易品种和周期。该函数是异步的,即它发送命令并且不会等待它执行完成。 该命令被添加到图表消息队列中,并将在处理完所有以前的命令后执行。
bool ChartSetSymbolPeriod(
long chart_id, // 图表 ID
string symbol, // 交易品种名称
ENUM_TIMEFRAMES period // 周期
);
2
3
4
5
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
symbol
[in] 图表上交易品种。 NULL 值意味着当前图表上的交易品种(即附上EA交易程序的图表)。
period
[in] 图表周期(时间框架)。取值范围是ENUM_TIMEFRAMES枚举值之一。0意味着当前图表时间周期。
返回值
如果该命令已添加到图表队列则返回true,否则false。若想获得额外错误信息,需要调用函数GetLastError()。
注意
更改 交易品种/周期 将会导致图表中EA交易程序重新初始化。
调用ChartSetSymbolPerid()函数时,指定相同的 交易品种 和 时间周期 作为形式参数,可以用来更新图表(类似于客户端的刷新命令)。反过来,图表的更新还会重新计算所有附加应用在图表上的指标。因此,即使没有报价您仍然可以通过这个方式来重新计算图表中的指标(例如:周末)。
相关参考
ChartSymbol, ChartPeriod
# 18.32 ChartScreenShot
根据指定的扩展名,以GIF,PNG或BMP格式对当前图表截屏。
bool ChartScreenShot(
long chart_id, // 图表 ID
string filename, // 交易品种名称
int width, // 宽度
int height, // 高度
ENUM_ALIGN_MODE align_mode=ALIGN_RIGHT // 对齐类型
);
2
3
4
5
6
7
参数
chart_id
[in] 图表 ID编号。0 表示当前图表。
filename
[in] 屏幕截图文件名。不能超过63个字符。屏幕截图文件位于directory \ Files。
width
[in] 屏幕截图宽度,单位:像素。
height
[in] 屏幕截图高度,单位:像素。
align_mode=ALIGN_RIGHT
[in] 屏幕截图的有限输出模式。取值范围是ENUM_ALIGN_MODE枚举值之一。ALIGN_RIGHT 表示右边距对齐(从图表的末端输出)。ALIGN_LEFT 表示左对齐。
返回值
若成功返回true,否则false。
注意
如果需要从图表中的某一点截图,应首先用ChartNavigate()函数定位图表。如果截图的水平尺寸小于图表窗口,则会根据align_mode设置,选择输出图表窗口的右侧部分或其左侧部分。
例如:
#property description "The Expert Advisor demonstrates how to create a series of screenshots of the current"
#property description "chart using the ChartScreenShot() function. For convenience, the file name is"
#property description "shown on the chart. The height and width of images is defined through macros."
#define WIDTH 800 // 图像宽度,调用ChartScreenShot()
#define HEIGHT 600 // 图像高度,调用ChartScreenShot()
//--- 输入参数
input int pictures=5; // 序列中的图像数量
int mode=-1; // -1 表示移到图表右边界,1 - 移到左边
int bars_shift=300;// 使用ChartNavigate()滚动图表时的柱形数量
//+------------------------------------------------------------------+
//| 专家初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 禁止图表自动滚动
ChartSetInteger(0,CHART_AUTOSCROLL,false);
//--- 设置图表右边界转移
ChartSetInteger(0,CHART_SHIFT,true);
//--- 显示蜡烛图图表
ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
//---
Print("Preparation of the Expert Advisor is completed");
}
//+------------------------------------------------------------------+
//| 专家订单号函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- 显示函数名称,调用时间和事件标识符
Print(__FUNCTION__,TimeCurrent()," id=",id," mode=",mode);
//--- 处理 CHARTEVENT_CLICK 事件 ("鼠标点击图表")
if(id==CHARTEVENT_CLICK)
{
//--- 从图表边界初始移动
int pos=0;
//--- 左侧图表边界操作
if(mode>0)
{
//--- 滚动图表至左侧边界
ChartNavigate(0,CHART_BEGIN,pos);
for(int i=0;i<pictures;i++)
{
//--- 准备在图表上显示的文本和文件名
string name="ChartScreenShot"+"CHART_BEGIN"+string(pos)+".gif";
//--- 在图表上显示名称作为注释
Comment(name);
//--- 在terminal_directory\MQL5\Files\文件中保存图表截图
if(ChartScreenShot(0,name,WIDTH,HEIGHT,ALIGN_LEFT))
Print("We've saved the screenshot ",name);
//---
pos+=bars_shift;
//--- 给予用户时间查看新的图表部分
Sleep(3000);
//--- 从当前位置bars_shift柱滚动图表到右侧
ChartNavigate(0,CHART_CURRENT_POS,bars_shift);
}
//--- 改变模式到相反方向
mode*=-1;
}
else // 图表右侧边界的操作
{
//--- 滚动图表至右侧边界
ChartNavigate(0,CHART_END,pos);
for(int i=0;i<pictures;i++)
{
//--- 准备在图表上显示的文本和文件名
string name="ChartScreenShot"+"CHART_END"+string(pos)+".gif";
//--- 在图表上显示名称作为注释
Comment(name);
//--- 在terminal_directory\MQL5\Files\文件中保存图表截图
if(ChartScreenShot(0,name,WIDTH,HEIGHT,ALIGN_RIGHT))
Print("We've saved the screenshot ",name);
//---
pos+=bars_shift;
//--- 给予用户时间查看新的图表部分
Sleep(3000);
//--- 从当前位置bars_shift柱滚动图表到右侧
ChartNavigate(0,CHART_CURRENT_POS,-bars_shift);
}
//--- 改变模式到相反方向
mode*=-1;
}
} // CHARTEVENT_CLICK 事件处理结束
//--- OnChartEvent()句柄末端
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
相关参考
ChartNavigate(), 资源