第二章 标准常量,列举和架构
为了简化编写程序的过程,以及使程序代码文本更容易理解,在MQL5语言中预定义了一些标准常量和枚举型常量,此外,结构 服务也用于存储信息。
标准常量与宏相似,且为int类型。
这些常量是按其用途分组的:
- 图表常量 与价格图表共同使用:开盘,导航,设置参量;
- 对象常量 可以用于处理在图表中创建和显示的图形对象;
- 指标常量 用于标准和自定义指标;
- 环境状态 环境状态常量描述了mql5程序的属性,显示了关于客户端、金融交易品种和当前帐户的信息;
- 交易常量 允许在交易过程中指定各种信息;
- 命名常量 是MQL5语言中的常量;
- 数据结构 描述数据存储格式;
- 错误和警告代码 描述编译器信息和交易服务器发出的交易请求;
- 输入/输出常量 通常与文件函数一起工作,并通过MessageBox()函数在屏幕上显示消息。
# 2 .1 图表常量
该常量描述了图表的各种属性,并分成如下组:
- 事件类型 —— 使用图表时发生的事件;
- 图表时间表 —— 标准内置周期;
- 图表属性 —— 用于图表函数参数的标识符;
- 定位常量 —— 用于ChartNavigate()函数的参数值 ;
- 展示图表 —— 设置图表外观.
# 2.1.1 图表事件类型
可以使用预定义函数OnChartEvent()处理11种图表上的事件类型。对于自定义事件,在CHARTEVENT_CUSTOM到CHARTEVENT_CUSTOM_LAST包含的范围内提供了65535标识符。要生成自定义事件,应该使用EventChartCustom()函数。
ENUM_CHART_EVENT
ID | 说明 |
---|---|
CHARTEVENT_KEYDOWN | 击键 |
CHARTEVENT_MOUSE_MOVE | 鼠标移动,鼠标点击 (如果 CHART_EVENT_MOUSE_MOVE (opens new window)=true 为图表设置) |
CHARTEVENT_MOUSE_WHEEL | 按下或滚动鼠标滚轮(如果CHART_EVENT_MOUSE_WHEEL (opens new window)=True为图表设置)。 |
CHARTEVENT_OBJECT_CREATE | 创建图形对象 (如果 CHART_EVENT_OBJECT_CREATE (opens new window)=true 为图表设置)。 |
CHARTEVENT_OBJECT_CHANGE | 修改图形对象 |
CHARTEVENT_OBJECT_DELETE | 创建图形对象 (如果 CHART_EVENT_OBJECT_DELETE (opens new window)=true 为图表设置)。 |
CHARTEVENT_CLICK | 点击一个图表。 |
CHARTEVENT_OBJECT_CLICK | 点击图形对象。 |
CHARTEVENT_OBJECT_DRAG | 拖放图形对象。 |
CHARTEVENT_OBJECT_ENDEDIT | 在图形对象编辑中结束文本编辑。 |
CHARTEVENT_CHART_CHANGE | 通过属性对话框改变了图表大小或更改图表属性。 |
CHARTEVENT_CUSTOM | 从一系列自定义事件中的初始化一个事件的数字编号。 |
CHARTEVENT_CUSTOM_LAST | 从一系列自定义事件中的获得最后一个数字编号。 |
对于每个事件类型,OnChartEvent()函数的输入参数都有固定值,这在该事件处理过程中是必须的,事件和相应的参数值通过形式参数传递并列举在下表中
事件 | ID参量值 | 参数常量值 | dparam 参数值 | sparam 参数值 |
---|---|---|---|---|
按键事件 | CHARTEVENT_KEYDOWN | 按键代码 | 重复计数(用户按住按键的重复击键次数) | 描述键盘按键状态的位掩码的字符串值 |
鼠标事件 (如果CHART_EVENT_MOUSE_MOVE=true 为图表设置) | CHARTEVENT_MOUSE_MOVE | X坐标 | Y坐标 | 描述鼠标按键状态的位掩码的字符串值 |
鼠标滚轮事件(如果CHART_EVENT_MOUSE_WHEEL=true为图表设置) | CHARTEVENT_MOUSE_WHEEL | 键盘按键和鼠标按键的状态标识,鼠标指针的X和Y坐标。在以下示例 (opens new window)查阅描述 | 鼠标滚轮滚动的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 | — | — | 在文本编辑完成后编辑标签图表对象名称 |
在N数字下用户使用ID事件 | CHARTEVENT_CUSTOM+N | EventChartCustom() 函数的值 | EventChartCustom() 函数的值 | EventChartCustom() 函数的值 |
示例:
#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
//+------------------------------------------------------------------+
//| 专家初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//---
Print("The expert with name ",MQL5InfoString(MQL5_PROGRAM_NAME)," is running");
//--- 启用对象创建事件
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_CREATE,true);
//--- 启用对象删除事件
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_DELETE,true);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // 事件标识符
const long& lparam, // 事件长整型参量
const double& dparam, // 事件双精度型参量
const string& sparam // 事件字符串型参量
)
{
//--- 鼠标左键点击图表
if(id==CHARTEVENT_CLICK)
{
Print("The coordinates of the mouse click on the chart are: x = ",lparam," y = ",dparam);
}
//--- 鼠标点击图形物件
if(id==CHARTEVENT_OBJECT_CLICK)
{
Print("The mouse has been clicked on the object with name '"+sparam+"'");
}
//--- 按下密钥
if(id==CHARTEVENT_KEYDOWN)
{
switch(lparam)
{
case KEY_NUMLOCK_LEFT: Print("The KEY_NUMLOCK_LEFT has been pressed"); break;
case KEY_LEFT: Print("The KEY_LEFT has been pressed"); break;
case KEY_NUMLOCK_UP: Print("The KEY_NUMLOCK_UP has been pressed"); break;
case KEY_UP: Print("The KEY_UP has been pressed"); break;
case KEY_NUMLOCK_RIGHT: Print("The KEY_NUMLOCK_RIGHT has been pressed"); break;
case KEY_RIGHT: Print("The KEY_RIGHT has been pressed"); break;
case KEY_NUMLOCK_DOWN: Print("The KEY_NUMLOCK_DOWN has been pressed"); break;
case KEY_DOWN: Print("The KEY_DOWN has been pressed"); break;
case KEY_NUMPAD_5: Print("The KEY_NUMPAD_5 has been pressed"); break;
case KEY_NUMLOCK_5: Print("The KEY_NUMLOCK_5 has been pressed"); break;
default: Print("Some not listed key has been pressed");
}
ChartRedraw();
}
//--- 物件被删除了
if(id==CHARTEVENT_OBJECT_DELETE)
{
Print("The object with name ",sparam," has been deleted");
}
//--- 物件被创建了
if(id==CHARTEVENT_OBJECT_CREATE)
{
Print("The object with name ",sparam," has been created");
}
//--- 移动物件或者更改定位点坐标
if(id==CHARTEVENT_OBJECT_DRAG)
{
Print("The anchor point coordinates of the object with name ",sparam," has been changed");
}
//--- 物件编辑文本被更改
if(id==CHARTEVENT_OBJECT_ENDEDIT)
{
Print("The text in the Edit field of the object with name ",sparam," has been changed");
}
}
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
对于CHARTEVENT_MOUSE_MOVE 事件 sparam 字符串参数包含有关键盘和鼠标按钮的状态信息:
Bit | 描述 |
---|---|
1 | 鼠标左按键状态 |
2 | 鼠标右按键状态 |
3 | SHIFT 按钮状态 |
4 | CTRL 按钮状态 |
5 | 鼠标中按键状态 |
6 | 第一个额外鼠标键的状态 |
7 | 第二个额外鼠标键的状态 |
示例:
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 启用 CHART_EVENT_MOUSE_MOVE 信息
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
}
//+------------------------------------------------------------------+
//| 鼠标点选位置 |
//+------------------------------------------------------------------+
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"); // shift 键
res+="\nCTRL: " +(((state& 8)== 8)?"DN":"UP"); // control 键
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
对于CHARTEVENT_MOUSE_WHEEL事件,参数lparam 和dparam 包含Ctrl和 Shift键,鼠标按键,光标坐标的状态信息和鼠标滚轮滚动值。为了更好的理解,请在图表上运行这个EA交易并滚动鼠标滚轮,同时按下不同的按键并按住代码中所描述的按键。
CHARTEVENT_MOUSE_WHEEL 事件处理示例:
//+------------------------------------------------------------------+
//| EA交易初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 启用鼠标滚轮来滚动信息
ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &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);
}
}
//+------------------------------------------------------------------+ /*
Example of the output
CHARTEVENT_MOUSE_WHEEL: Ctrl pressed: X=193, Y=445, delta=-120
CHARTEVENT_MOUSE_WHEEL: Shift pressed: X=186, Y=446, delta=120
CHARTEVENT_MOUSE_WHEEL: X=178, Y=447, delta=-120
CHARTEVENT_MOUSE_WHEEL: X=231, Y=449, delta=120
CHARTEVENT_MOUSE_WHEEL: MiddleButton pressed: X=231, Y=449, delta=120
CHARTEVENT_MOUSE_WHEEL: LeftButton pressed: X=279, Y=320, delta=-120
CHARTEVENT_MOUSE_WHEEL: RightButton pressed: X=253, Y=330, delta=120 */
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
另见
事件处理函数 ,工作事件
# 2.1.2 图表时间表
所有预定义的图表时间周期都有一个唯一的标识符,当MQL5程序运行时,PERIOD_CURRENT 标识符代表当前图表的时间周期。
ENUM_TIMEFRAMES
ID | 描述 |
---|---|
PERIOD_CURRENT | 当前图表的时间周期 |
PERIOD_M1 | 1 分钟 |
PERIOD_M2 | 2 分钟 |
PERIOD_M3 | 3 分钟 |
PERIOD_M4 | 4 分钟 |
PERIOD_M5 | 5 分钟 |
PERIOD_M6 | 6 分钟 |
PERIOD_M10 | 10 分钟 |
PERIOD_M12 | 12 分钟 |
PERIOD_M15 | 15 分钟 |
PERIOD_M20 | 20 分钟 |
PERIOD_M30 | 30 分钟 |
PERIOD_H1 | 1小时 |
PERIOD_H2 | 2 小时 |
PERIOD_H3 | 3 小时 |
PERIOD_H4 | 4 小时 |
PERIOD_H6 | 6小时 |
PERIOD_H8 | 8小时 |
PERIOD_H12 | 12 小时 |
PERIOD_D1 | 1 天 |
PERIOD_W1 | 1 周 |
PERIOD_MN1 | 1月 |
示例:
string chart_name="test_Object_Chart";
Print("Let's try to create a Chart object with the name ",chart_name);
//--- 如果没有这个物件-创建它
if(ObjectFind(0,chart_name) < 0)ObjectCreate(0,chart_name,OBJ_CHART,0,0,0,0,0);
//--- 定义交易品种
ObjectSetString(0,chart_name,OBJPROP_SYMBOL,"EURUSD");
//--- 设置定位点X坐标
ObjectSetInteger(0,chart_name,OBJPROP_XDISTANCE,100);
//--- 设置定位点Y坐标
ObjectSetInteger(0,chart_name,OBJPROP_YDISTANCE,100);
//--- 设置图表宽度
ObjectSetInteger(0,chart_name,OBJPROP_XSIZE,400);
//--- 设置高度
ObjectSetInteger(0,chart_name,OBJPROP_YSIZE,300);
//--- 设置时间表
ObjectSetInteger(0,chart_name,OBJPROP_PERIOD,PERIOD_D1);
//--- 设置规模(从 0 到 5)
ObjectSetDouble(0,chart_name,OBJPROP_SCALE,4);
//--- 禁止鼠标选择
ObjectSetInteger(0,chart_name,OBJPROP_SELECTABLE,false);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
另见
秒周期 ,周期,日期和时间,对象可见性
# 2.1.3 图表属性
枚举类型的标识符 ENUM_CHART_PROPERTY用于处理图表函数的参数。在“属性(性质)类型”字段栏(列)里的缩写r/o表示该属性是只读的,不能更改。“属性(性质)类型”字段栏(列)中的w/o缩写意味着该属性只能写入,不能接收。当访问某个属性时,有必要指定一个附加的参数修饰符,它用来显示图表子窗口的数量。 0表示主窗口。
定义图表属性的函数实际上用于向图表发送更改命令。如果这些函数成功执行,则该命令将包含在图表事件的公共队列中。在处理图表事件的队列时,将对图表执行更改。
因此,不要期望在调用这些函数后,图表会立即进行可视化的变化更新。通常情况下,该图表会在更改事件之后自动更新 —— 如一个新的报价到达,调整图表窗口的大小等等。使用ChartRedraw()函数可以强制刷新图表。
函数ChartSetInteger()和ChartGetInteger()。
ENUM_CHART_PROPERTY_INTEGER
ID | 描述 | 性质类型 |
---|---|---|
CHART_SHOW | 绘制价格图表。false情况下,不可绘制价格图表的任何属性并删除首行图表边界,包括时间和价格范围,快速导航条,日历事件标签,交易标签,指标和柱形图提示,指标子窗口,交易量直方图等等。 禁用绘制是使用图形资源创建自定义程序界面的理想方案。 无论CHART_SHOW属性值多少,都会始终绘制图形对象。 | bool |
CHART_IS_OBJECT | 识别“图表”(OBJ_CHART) 对象 ?C 图形对象返回true。真实图表返回false | Bool r/o |
CHART_BRING_TO_TOP | 显示其他图表之上的图表 | Bool w/o |
CHART_CONTEXT_MENU | 启用/禁用右击访问快捷菜单。 当CHART_CONTEXT_MENU=false时,仅禁用图表快捷菜单。图表上对象的快捷菜单仍可使用。 | bool (默认为false) |
CHART_CROSSHAIR_TOOL | 启用/禁用中间单击访问十字光标工具。 | Bool (默认为true) |
CHART_MOUSE_SCROLL | 使用鼠标左键水平滚动图表。如果以下属性的值设为true也可以垂直滚动:CHART_SCALEFIX, CHART_SCALEFIX_11 or CHART_SCALE_PT_PER_BAR 当CHART_MOUSE_SCROLL=false时,不可使用鼠标滚轮滚动图表。 | bool |
CHART_EVENT_MOUSE_WHEEL | 发送鼠标滚轮事件的消息(CHARTEVENT_MOUSE_WHEEL) 到图表上的所有mql5程序 | Bool (默认为true) |
CHART_EVENT_MOUSE_MOVE | 发送鼠标移动和鼠标点击事件的通知 (CHARTEVENT_MOUSE_MOVE) 到图表上的所有mql5程序 | bool |
CHART_EVENT_OBJECT_CREATE | 发送创建新对象的事件通知 (CHARTEVENT_OBJECT_CREATE) 到图表上的所有mql5程序 | bool |
CHART_EVENT_OBJECT_DELETE | 发送删除对象的事件通知 (CHARTEVENT_OBJECT_DELETE) 到图表上的所有mql5程序 | bool |
CHART_MODE | 图表类型(蜡烛台、字节或线) | enum ENUM_CHART_MODE |
CHART_FOREGROUND | 背景的价格图表 | bool |
CHART_SHIFT | 左边缩进价格图表 | bool |
CHART_AUTOSCROLL | 自动移向图表的右边框 | bool |
CHART_KEYBOARD_CONTROL | 可以使用键盘管理图表("Home","End","PageUp","+","-","up arrow"等)。设置为 false 的CHART_KEYBOARD_CONTROL在保留接收按下 OnChartEvent() | bool |
CHART_QUICK_NAVIGATION | 允许图表拦截空格键和回车键来激活快速导航栏。双击鼠标或按下空格/回车键后,快速导航栏自动出现在图表底部。这可以使您快速更改交易品种,时间周期和第一可视栏日期。 | bool |
CHART_SCALE | 测量 | Int 从0到5 |
CHART_SCALEFIX | 固定标盘模式 | bool |
CHART_SCALEFIX_11 | 测量方式1:1 | bool |
CHART_SCALE_PT_PER_BAR | 每字节指定相关测量 | bool |
CHART_SHOW_OHLC | 在左上角显示OHLC值 | bool |
CHART_SHOW_BID_LINE | 在图表水平线上显示出价值 | bool |
CHART_SHOW_ASK_LINE | 在图表水平线上显示要价值 | bool |
CHART_SHOW_LAST_LINE | 在图表水平线上显示最终值 | bool |
CHART_SHOW_PERIOD_SEP | 在相邻周期显示垂直分离器 | bool |
CHART_SHOW_GRID | 在图表中显示网格 | bool |
CHART_SHOW_VOLUMES | 在图表中显示成交量 | enum ENUM_CHART_VOLUME_MODE |
CHART_SHOW_OBJECT_DESCR | 显示对象的文本描述 (不可用于所有对象) | bool |
CHART_VISIBLE_BARS | 图表上显示的字节数量 | int r/o |
CHART_WINDOWS_TOTAL | 图表窗口总数,包括指标预览窗口 | int r/o |
CHART_WINDOW_IS_VISIBLE | 预览窗口可见性 | bool r/o 修饰符 - 子窗口号 |
CHART_WINDOW_HANDLE | 处理图表窗口(HWND) | int r/o |
CHART_WINDOW_YDISTANCE | 指标子窗口的上帧与主图表窗口的上帧之间的距离,沿着Y轴垂直,以像素为单位。在鼠标事件情况下,根据图表主窗口的坐标传递光标坐标,而将指标子窗口的图形对象坐标设置相对于子窗口的左上角。 需要该值是为了将主图表的绝对坐标转换为子窗口的本地坐标,以便图形对象的正确工作,该坐标设置位置相对于子窗口帧的左上角。 | int r/o 修饰符 - 子窗口号 |
CHART_FIRST_VISIBLE_BAR | 图表中第一可见字节字符。字节索引同于时序列 。 | int r/o |
CHART_WIDTH_IN_BARS | 以字节转发图表 | int r/o |
CHART_WIDTH_IN_PIXELS | 像素转发图表 | int r/o |
CHART_HEIGHT_IN_PIXELS | 图表像素高度 | Int 修饰符 - 子窗口号 |
CHART_COLOR_BACKGROUND | 图表背景颜色 | color |
CHART_COLOR_FOREGROUND | 轴线、缩放和OHLC线的颜色 | color |
CHART_COLOR_GRID | 网格颜色 | color |
CHART_COLOR_VOLUME | 成交量颜色和开仓水平 | color |
CHART_COLOR_CHART_UP | 上升字节、阴影和大型烛台整体边界的颜色 | color |
CHART_COLOR_CHART_DOWN | 下降字节、阴影和支撑烛台的颜色 | color |
CHART_COLOR_CHART_LINE | 折线图颜色和日语烛台躲闪颜色 | color |
CHART_COLOR_CANDLE_BULL | 大型烛台主体颜色 | color |
CHART_COLOR_CANDLE_BEAR | 承受烛台主体颜色 | color |
CHART_COLOR_BID | 出价水平颜色 | color |
CHART_COLOR_ASK | 要价水平颜色 | color |
CHART_COLOR_LAST | 最后执行交易价格水平线颜色(Last) | color |
CHART_COLOR_STOP_LEVEL | 停止订购水平颜色(斩仓和获利) | color |
CHART_SHOW_TRADE_LEVELS | 在图表中显示交易水平(开仓水平、斩仓、获利和代办订单) | bool |
CHART_DRAG_TRADE_LEVELS | 用鼠标在图表上拖拽交易水平的权限。拖拽模式默认启用(true 值) | bool |
CHART_SHOW_DATE_SCALE | 显示图表的时间比例 | bool |
CHART_SHOW_PRICE_SCALE | 显示图表的价格比例 | bool |
CHART_SHOW_ONE_CLICK | 显示 "单击交易"面板在图表上 | bool |
CHART_IS_MAXIMIZED | 图表窗口最大化 | bool |
CHART_IS_MINIMIZED | 图表窗口最小化 | bool |
函数 ChartSetDouble() 和 ChartGetDouble()
ENUM_CHART_PROPERTY_DOUBLE
ID | 描述 | 性质类型 |
---|---|---|
CHART_SHIFT_SIZE | 大小在右边百分比边界从零字节缩进 | double (10%-50%) |
CHART_FIXED_POSITION | 图表以百分比定位左边界的位置。在水平时间轴用小的灰白三角形标记定位的图表。只有在禁止进入订单号时图表自动滚到右侧它才会显示 (见 CHART_AUTOSCROLL property)。放大缩小时,定位的柱保留原位。 | double |
CHART_FIXED_MAX | 固定图表最大值 | double |
CHART_FIXED_MIN | 固定图表最小值 | double |
CHART_POINTS_PER_BAR | 测量相关的每个字节 | double |
CHART_PRICE_MIN | 图表最小值 | double r/o 修饰符 - 子窗口号 |
CHART_PRICE_MAX | 图表最大值 | double r/o 修饰符 - 子窗口号 |
ChartSetString() 和 ChartGetString() 函数
ENUM_CHART_PROPERTY_STRING
ID | 描述 | 性质类型 |
---|---|---|
CHART_COMMENT | 图表中的评论文本 | string |
CHART_EXPERT_NAME | 在指定chart_id 图表上运行的EA交易的名称 | string |
CHART_SCRIPT_NAME | 在指定chart_id 图表上运行的脚本名称 | string |
示例:
int chartMode=ChartGetInteger(0,CHART_MODE);
switch(chartMode)
{
case(CHART_BARS): Print("CHART_BARS"); break;
case(CHART_CANDLES): Print("CHART_CANDLES");break;
default:Print("CHART_LINE");
}
bool shifted=ChartGetInteger(0,CHART_SHIFT);
if(shifted) Print("CHART_SHIFT = true");
else Print("CHART_SHIFT = false");
bool autoscroll=ChartGetInteger(0,CHART_AUTOSCROLL);
if(autoscroll) Print("CHART_AUTOSCROLL = true");
else Print("CHART_AUTOSCROLL = false");
int chartHandle=ChartGetInteger(0,CHART_WINDOW_HANDLE);
Print("CHART_WINDOW_HANDLE = ",chartHandle);
int windows=ChartGetInteger(0,CHART_WINDOWS_TOTAL);
Print("CHART_WINDOWS_TOTAL = ",windows);
if(windows>1)
{
for(int i=0;i < windows;i++)
{
int height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,i);
double priceMin=ChartGetDouble(0,CHART_PRICE_MIN,i);
double priceMax=ChartGetDouble(0,CHART_PRICE_MAX,i);
Print(i+": CHART_HEIGHT_IN_PIXELS = ",height," pixels");
Print(i+": CHART_PRICE_MIN = ",priceMin);
Print(i+": CHART_PRICE_MAX = ",priceMax);
}
}
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
另见
使用图表示例
# 2.1.4 定位常量
ENUM_CHART_POSITION 列表中的三个标识符有可能是ChartNavigate()函数的位置参数的值。
ENUM_CHART_POSITION
ID | 描述 |
---|---|
CHART_BEGIN | 图表开始(最原始价位) |
CHART_CURRENT_POS | 当前位置 |
CHART_END | 图表末尾(当前价格) |
示例:
long handle=ChartOpen("EURUSD",PERIOD_H12);
if(handle!=0)
{
ChartSetInteger(handle,CHART_AUTOSCROLL,false);
ChartSetInteger(handle,CHART_SHIFT,true);
ChartSetInteger(handle,CHART_MODE,CHART_LINE);
ResetLastError();
bool res=ChartNavigate(handle,CHART_END,150);
if(!res) Print("Navigate failed. Error = ",GetLastError());
ChartRedraw();
}
2
3
4
5
6
7
8
9
10
11
# 2.1.5 图表陈述(表示)
价格图表可以用以下三种方式陈列(表示): • 棒线图; • 蜡烛图; • 折线图。
显示价格图表的具体方法是由函数ChartSetInteger(chart_handle、CHART_MODE、CHART_MODE)设置的,其中CHART_MODE是ENUM_CHART_MODE枚举的值之一。
ENUM_CHART_MODE
ID | 描述 |
---|---|
CHART_BARS | 显示为序列棒线 |
CHART_CANDLES | 显示日本蜡烛图 |
CHART_LINE | 以收盘价格显示折线图 |
要在指定的报价图表中显示成交量的方法是,使用函数ChartSetInteger(chart_handle, chart_show_volume, volume_mode),其中volume_mode是ENUM_CHART_VOLUME_MODE枚举的值之一。
ENUM_CHART_VOLUME_MODE
ID | 描述 |
---|---|
CHART_VOLUME_HIDE | 成交量隐藏 |
CHART_VOLUME_TICK | 最小价格成交量 |
CHART_VOLUME_REAL | 交易成交量 |
示例:
//--- 获得当前图表处理权
long handle=ChartID();
if(handle>0) // 如果成功,加上自定义
{
//--- 禁止自动滚动
ChartSetInteger(handle,CHART_AUTOSCROLL,false);
//--- 设置图表右缩进
ChartSetInteger(handle,CHART_SHIFT,true);
//--- 显示蜡烛图
ChartSetInteger(handle,CHART_MODE,CHART_CANDLES);
//--- 从历史记录起始位置按100柱为一页滚动
ChartNavigate(handle,CHART_CURRENT_POS,100);
//--- 设置订单交易量显示模式
ChartSetInteger(handle,CHART_SHOW_VOLUMES,CHART_VOLUME_TICK);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
另见:
打开图表 , 图表ID
# 2.1.6 使用图表示例
本节包含使用图表属性工作的示例。每个属性显示一个或两个完整的函数。这些函数允许设置/接收属性的值。这些函数可以在自定义的mql5应用程序中使用,可以被使用"as is"。
下面的屏幕截图展示了图形面板,说明了图表属性的变化是如何改变其外观的。单击Next按钮,可以设置相应属性的新值,并查看图表窗口中的变化。
面板的完整源代码位于 本节最后部分。
图表属性和使用它们的样本函数 •CHART_IS_OBJECT 定义对象是否是真实图表或是 图形对象。
//+------------------------------------------------------------------+
//| 定义对象是否是图表。如果它是 |
//| 图形对象,则结果为true。如果它是真实 |
//| 图表,则结果变量为false值。 |
//+------------------------------------------------------------------+
bool ChartIsObject(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 获得图表属性
if(!ChartGetInteger(chart_ID,CHART_IS_OBJECT,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
//--- 返回 false
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
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
•CHART_BRING_TO_TOP 显示所有其他图表的顶部的图表。
//+----------------------------------------------------------------------+
//| 发送命令到程序端展示所有其他图表上面的图表。 |
//+----------------------------------------------------------------------+
bool ChartBringToTop(const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 显示所有其他图表的顶部的图表
if(!ChartSetInteger(chart_ID,CHART_BRING_TO_TOP,0,true))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
•CHART_MOUSE_SCROLL 使用鼠标左键滚动图表的属性。
//+--------------------------------------------------------------------------+
//| 该函数定义了使用鼠标左键滚动图表是否 |
//| 被启用。 |
//+--------------------------------------------------------------------------+
bool ChartMouseScrollGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_MOUSE_SCROLL,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------+
//| 该函数启用/禁用使用鼠标左键滚动图表。 |
//+--------------------------------------------------------------------+
bool ChartMouseScrollSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_MOUSE_SCROLL,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_EVENT_MOUSE_MOVE 是发送有关移动事件和鼠标点击mql5应用程序 (CHARTEVENT_MOUSE_MOVE)的信息的属性。
//+------------------------------------------------------------------+
//| 检查有关移动事件和鼠标点击的信息 |
//| 被发送到图表上的所有mql5应用程序 |
//+------------------------------------------------------------------+
bool ChartEventMouseMoveGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_EVENT_MOUSE_MOVE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------------------+
//| 该函数启用/禁用发送信息模式,有关移动 |
//| 事件和在图表上鼠标点击mql5应用程序。 |
//+------------------------------------------------------------------------------+
bool ChartEventMouseMoveSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_EVENT_MOUSE_MOVE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_EVENT_OBJECT_CREATE 是发送有关创建图形对象事件到mql5应用程序 (CHARTEVENT_OBJECT_CREATE)的信息的属性。
//+---------------------------------------------------------------------+
//| 检查是否有关创建图形对象事件的信息 |
//| 被发送到图表上的所有mql5应用程序 |
//+---------------------------------------------------------------------+
bool ChartEventObjectCreateGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_EVENT_OBJECT_CREATE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------+
//| 该函数启用/禁用发送信息模式,有关 |
//| 图形对象创建事件到图表上所有的mql5应用程序。 |
//+--------------------------------------------------------------------------+
bool ChartEventObjectCreateSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_EVENT_OBJECT_CREATE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_EVENT_OBJECT_DELETE 是发送有关图表对象删除事件到mql5应用程序(CHARTEVENT_OBJECT_DELETE)的信息的属性。
//+---------------------------------------------------------------------+
//| 检查有关图形对象删除事件的信息 |
//| 被发送到图表上的所有mql5应用程序 |
//+---------------------------------------------------------------------+
bool ChartEventObjectDeleteGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_EVENT_OBJECT_DELETE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------+
//| 该函数启用/禁用发送信息模式,有关 |
//| 发送至所有mql5应用程序的图形对象删除事件的信息。 |
//+--------------------------------------------------------------------------+
bool ChartEventObjectDeleteSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_EVENT_OBJECT_DELETE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_MODE —— 图表类型(蜡烛图,棒线图 或 折线图)。
//+------------------------------------------------------------------+
//| 获得图表展示类型(蜡烛图,柱形图或 |
//| 线型图)。 |
//+------------------------------------------------------------------+
ENUM_CHART_MODE ChartModeGet(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=WRONG_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_MODE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((ENUM_CHART_MODE)result);
}
//+------------------------------------------------------------------+
//| 设置图表显示类型(蜡烛图,柱形图或 |
//| 线型图)。 |
//+------------------------------------------------------------------+
bool ChartModeSet(const long value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_MODE,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 获得图表展示类型(蜡烛图,柱形图或 |
//| 线型图)。 |
//+------------------------------------------------------------------+
ENUM_CHART_MODE ChartModeGet(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=WRONG_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_MODE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((ENUM_CHART_MODE)result);
}
//+------------------------------------------------------------------+
//| 设置图表显示类型(蜡烛图,柱形图或 |
//| 线型图)。 |
//+------------------------------------------------------------------+
bool ChartModeSet(const long value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_MODE,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_FOREGROUND是在前台显示价格图表的属性。
//+------------------------------------------------------------------+
//| 该函数定义是否价格图表显示在 |
//| 前台。 |
//+------------------------------------------------------------------+
bool ChartForegroundGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_FOREGROUND,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+---------------------------------------------------------------------------+
//| 函数启用/禁用价格图表展示模式在 |
//| 前台。 |
//+---------------------------------------------------------------------------+
bool ChartForegroundSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_FOREGROUND,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}0
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
•CHART_SHIFT —— 从右边缘移动价格图表的模式。
//+------------------------------------------------------------------------------------+
//| 函数定义是否从右边缘移动价格图表的模式 |
//| 被启用。 |
//+------------------------------------------------------------------------------------+
bool ChartShiftGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHIFT,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------+
//| 函数启用/禁用价格图表展示模式 |
//| 从右边缘开始移动。 |
//+--------------------------------------------------------------------------+
bool ChartShiftSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHIFT,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
CHART_AUTOSCROLL —— 自动移动到图表右边缘的模式。
//+---------------------------------------------------------------------+
//| 函数定义了新报价进入时是否启用 |
//| 图表向右的自动滚动模式。 |
//+---------------------------------------------------------------------+
bool ChartAutoscrollGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_AUTOSCROLL,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 该函数启用/禁用新报价进入时,图表向右的 |
//| 自动滚动模式。 |
//+------------------------------------------------------------------+
bool ChartAutoscrollSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_AUTOSCROLL,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SCALE —— 图表比例属性。
//+------------------------------------------------------------------+
//| 获得图表比例(从0到5)。 |
//+------------------------------------------------------------------+
int ChartScaleGet(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SCALE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
//+------------------------------------------------------------------+
//| 设置图表比例(从0到5)。 |
//+------------------------------------------------------------------+
bool ChartScaleSet(const long value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SCALE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SCALEFIX —— 固定图表比例模式。
//+------------------------------------------------------------------+
//| 函数定义了是否启用固定比例模式。 |
//+------------------------------------------------------------------+
bool ChartScaleFixGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SCALEFIX,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 函数启用/禁用固定比例模式。 |
//+------------------------------------------------------------------+
bool ChartScaleFixSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SCALEFIX,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SCALEFIX_11 —— 1:1 图表比例模式。
//+------------------------------------------------------------------+
//| 该函数定义了是否启用“1:1”比例。 |
//+------------------------------------------------------------------+
bool ChartScaleFix11Get(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SCALEFIX_11,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 函数启用/禁用“1:1”比例模式 |
//+------------------------------------------------------------------+
bool ChartScaleFix11Set(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SCALEFIX_11,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SCALE_PT_PER_BAR —— 指定每柱图表比例点数。
//+------------------------------------------------------------------------------+
//| 函数定义了是否启用指定每柱图表比例点数的 |
//| 模式。 |
//+------------------------------------------------------------------------------+
bool ChartScalePerBarGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SCALE_PT_PER_BAR,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------------------------+
//| 函数启用/禁用指定每柱图表比例点数的 |
//| 模式。 |
//+------------------------------------------------------------------------------------+
bool ChartScalePerBarSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SCALE_PT_PER_BAR,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_OHLC —— 在左上角展示OHLC值的属性。
//+------------------------------------------------------------------+
//| 函数定义了是否启用在左上角展示OHLC值 |
//| 的模式。 |
//+------------------------------------------------------------------+
bool ChartShowOHLCGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_OHLC,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------+
//| 该函数启用/禁用在图表左上角显示OHLC值 |
//| 的模式。 |
//+--------------------------------------------------------------------------+
bool ChartShowOHLCSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_OHLC,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_BID_LINE —— 图表水平线显示卖价值的属性
//+-----------------------------------------------------------------------------+
//| 函数定义了在图表展示卖价值的模式是否 |
//| 被启用。 |
//+-----------------------------------------------------------------------------+
bool ChartShowBidLineGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_BID_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------+
//| 该函数启用/禁用在图表上展示卖价行的模式。 |
//+--------------------------------------------------------------------+
bool ChartShowBidLineSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_BID_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_ASK_LINE —— 图表水平线显示买价值的属性
//+-----------------------------------------------------------------------+
//| 函数定义了是否启用在图表上展示买价值线的模式。 |
//+-----------------------------------------------------------------------+
bool ChartShowAskLineGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_ASK_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+-----------------------------------------------------------------------+
//| 该函数启用/禁用在图表上显示买价行的模式。 |
//+-----------------------------------------------------------------------+
bool ChartShowAskLineSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_ASK_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_LAST_LINE—— 图表水平线显示最近值的属性
//+---------------------------------------------------------------------------------+
//| 该函数定义了是否启用显示最近执行的交易的价格行模式。 |
//+---------------------------------------------------------------------------------+
bool ChartShowLastLineGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_LAST_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------------------+
//| 函数启用/禁用显示最近执行的交易的价格行模式。 |
//+--------------------------------------------------------------------------------------+
bool ChartShowLastLineSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_LAST_LINE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_PERIOD_SEP—— 在相邻周期间展示垂直分隔符的属性
//+------------------------------------------------------------------+
//| 该函数定义了是否启用在相邻周期间 |
//| 展示垂直分隔符的模式。 |
//+------------------------------------------------------------------+
bool ChartShowPeriodSeparatorGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_PERIOD_SEP,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//|该函数启用/禁用在相邻周期间 |
//| 展示垂直分隔符的模式。 |
//+------------------------------------------------------------------+
bool ChartShowPeriodSepapatorSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_PERIOD_SEP,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_GRID —— 展示图表网格的属性。
//+------------------------------------------------------------------+
//| 该函数定义了是否展示图表网格。 |
//+------------------------------------------------------------------+
bool ChartShowGridGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_GRID,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 该函数启用/禁用图表网格。 |
//+------------------------------------------------------------------+
bool ChartShowGridSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_GRID,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_VOLUMES —— 在图表上展示交易量的属性。
//+------------------------------------------------------------------------+
//| 该函数定义了是否在图表上展示交易量(不 |
//| 显示,显示订单交易量,显示实际交易量)。 |
//+------------------------------------------------------------------------+
ENUM_CHART_VOLUME_MODE ChartShowVolumesGet(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=WRONG_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_VOLUMES,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((ENUM_CHART_VOLUME_MODE)result);
}
//+------------------------------------------------------------------+
//| 该函数设置在图表上显示交易量的模式。 |
//+------------------------------------------------------------------+
bool ChartShowVolumesSet(const long value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_VOLUMES,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_OBJECT_DESCR —— 图形对象弹出描述的属性。
//+-------------------------------------------------------------------+
//| 函数定义了悬停鼠标时是否显示 |
//| 图形对象的弹出描述 。 |
//+-------------------------------------------------------------------+
bool ChartShowObjectDescriptionGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_OBJECT_DESCR,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------------+
//| 该函数启用/禁用鼠标悬停时 |
//| 显示图形对象弹出描述的模式。 |
//+--------------------------------------------------------------------------+
bool ChartShowObjectDescriptionSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_OBJECT_DESCR,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_VISIBLE_BARS —— 定义图表上可用于展示的柱的数量。
//+-----------------------------------------------------------------------+
//| 函数接收图表窗口中 |
//| 显示的柱数(可见)。 |
//+-----------------------------------------------------------------------+
int ChartVisibleBars(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_VISIBLE_BARS,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
•CHART_WINDOWS_TOTAL—— 定义包括指标子窗口的图表窗口总数。
//+--------------------------------------------------------------------------+
//| 该函数获得所有图表窗口的总数包括指标 |
//| 子窗口。 |
//+--------------------------------------------------------------------------+
int ChartWindowsTotal(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WINDOWS_TOTAL,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
•CHART_WINDOW_IS_VISIBLE —— 定义子窗口的可视性。
//+------------------------------------------------------------------+
//| 该函数定义了当前图表窗口或子窗口是否 |
//| 可见。 |
//+------------------------------------------------------------------+
bool ChartWindowsIsVisible(bool &result,const long chart_ID=0,const int sub_window=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WINDOW_IS_VISIBLE,sub_window,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
•CHART_WINDOW_HANDLE —— 返回图表句柄。
//+------------------------------------------------------------------+
//| 函数获取图表句柄 |
//+------------------------------------------------------------------+
int ChartWindowsHandle(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WINDOW_HANDLE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
•CHART_WINDOW_YDISTANCE —— 定义指标子窗口上边框和图表主窗口上边框之间的像素距离。
//+------------------------------------------------------------------+
//| 该函数获得子窗口上边框和 |
//| 图表主窗口上边框之间的像素距离。 |
//+------------------------------------------------------------------+
int ChartWindowsYDistance(const long chart_ID=0,const int sub_window=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WINDOW_YDISTANCE,sub_window,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
•CHART_FIRST_VISIBLE_BAR —— 返回图表上最先可见的柱的数量(与 时间序列相关的柱)。
//+----------------------------------------------------------------------------+
//| 该函数接收图表上最先可见的柱数。 |
//| 像在时间序列一样执行索引,最近的柱指数更小。 |
//+----------------------------------------------------------------------------+
int ChartFirstVisibleBar(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_FIRST_VISIBLE_BAR,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
•CHART_WIDTH_IN_BARS —— 返回图表柱形宽度。
//+------------------------------------------------------------------+
//| 函数接收图表柱形宽度。 |
//+------------------------------------------------------------------+
int ChartWidthInBars(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_BARS,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
•CHART_WIDTH_IN_PIXELS —— 返回图表像素宽度。
//+------------------------------------------------------------------+
//| 函数接收图表像素宽度。 |
//+------------------------------------------------------------------+
int ChartWidthInPixels(const long chart_ID=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
•CHART_HEIGHT_IN_PIXELS ——图表像素高度的属性。
//+------------------------------------------------------------------+
//| 该函数接收图表的像素高度值。 |
//+------------------------------------------------------------------+
int ChartHeightInPixelsGet(const long chart_ID=0,const int sub_window=0)
{
//--- 准备变量获得属性值
long result=-1;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_HEIGHT_IN_PIXELS,sub_window,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((int)result);
}
//+------------------------------------------------------------------+
//| 该函数设置了图表的像素高度值。 |
//+------------------------------------------------------------------+
bool ChartHeightInPixelsSet(const int value,const long chart_ID=0,const int sub_window=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_HEIGHT_IN_PIXELS,sub_window,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_BACKGROUND ——图表背景色。
//+------------------------------------------------------------------+
//| 该函数接收图表背景色。 |
//+------------------------------------------------------------------+
color ChartBackColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收图表背景色
if(!ChartGetInteger(chart_ID,CHART_COLOR_BACKGROUND,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置图表背景色。 |
//+------------------------------------------------------------------+
bool ChartBackColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置图表背景色
if(!ChartSetInteger(chart_ID,CHART_COLOR_BACKGROUND,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_FOREGROUND——坐标轴,比例尺和OHLC线的颜色。
//+------------------------------------------------------------------+
//| 该函数接收坐标轴,比例尺和OHLC线的颜色。 |
//+------------------------------------------------------------------+
color ChartForeColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收坐标轴,比例尺和OHLC线的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_FOREGROUND,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置坐标轴,比例尺和OHLC线的颜色。 |
//+------------------------------------------------------------------+
bool ChartForeColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置坐标轴,比例尺和OHLC线的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_FOREGROUND,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_GRID ——图表网格颜色。
//+------------------------------------------------------------------+
//| 这个函数接收图表网格颜色。 |
//+------------------------------------------------------------------+
color ChartGridColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//---接收图表网格颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_GRID,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 函数设置图表网格颜色。 |
//+------------------------------------------------------------------+
bool ChartGridColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置图表网格颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_GRID,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
• CHART_COLOR_VOLUME ——交易量和持仓水平的颜色
//+------------------------------------------------------------------+
//| 该函数接收交易量和市场入场水平 |
//| 的颜色。 |
//+------------------------------------------------------------------+
color ChartVolumeColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收交易量和市场入场水平的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_VOLUME,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置交易量和市场入场水平 |
//| 的颜色。 |
//+------------------------------------------------------------------+
bool ChartVolumeColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置交易量和市场入场水平的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_VOLUME,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
• CHART_COLOR_CHART_UP ——上柱,柱影和牛市蜡烛图主体边缘的颜色。
//+------------------------------------------------------------------+
//| 这个函数接收下柱,柱影和熊市蜡烛图主体边缘 |
//| 的颜色。 |
//+------------------------------------------------------------------+
color ChartUpColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收上柱,柱影和牛市蜡烛图主体边缘的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_CHART_UP,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 这个函数设置上柱,柱影和牛市蜡烛图主体边缘 |
//| 的颜色。 |
//+------------------------------------------------------------------+
bool ChartUpColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置上柱,柱影和牛市蜡烛图主体边缘的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_CHART_UP,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_CHART_DOWN——下柱,柱影和熊市蜡烛图主体边缘的颜色。
//+------------------------------------------------------------------+
//| 这个函数接收下柱,柱影和熊市蜡烛图主体边缘 |
//| 的颜色。 |
//+------------------------------------------------------------------+
color ChartDownColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收下柱,柱影和熊市蜡烛图主体边缘的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_CHART_DOWN,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 这个函数设置下柱,柱影和熊市蜡烛图主体边缘 |
//| 的颜色。 |
//+------------------------------------------------------------------+
bool ChartDownColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置下柱,柱影和熊市蜡烛图主体边缘的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_CHART_DOWN,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_CHART_LINE ——图表线和Doji蜡烛图的颜色。
//+------------------------------------------------------------------------+
//| 该函数接收图表线和Doji蜡烛图的颜色。 |
//+------------------------------------------------------------------------+
color ChartLineColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收图表线和Doji蜡烛图的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_CHART_LINE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置图表线和Doji蜡烛图的颜色。 |
//+------------------------------------------------------------------+
bool ChartLineColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置图表线和Doji蜡烛图的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_CHART_LINE,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_CANDLE_BULL——牛市蜡烛图主体的颜色。
//+------------------------------------------------------------------+
//| 该函数接收牛市蜡烛图主体的颜色。 |
//+------------------------------------------------------------------+
color ChartBullColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收牛市蜡烛图主体的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_CANDLE_BULL,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置牛市蜡烛图主体的颜色。 |
//+------------------------------------------------------------------+
bool ChartBullColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置牛市蜡烛图主体的颜色。
if(!ChartSetInteger(chart_ID,CHART_COLOR_CANDLE_BULL,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_CANDLE_BEAR—— 熊市蜡烛图主体的颜色。
//+------------------------------------------------------------------+
//| 该函数接收熊市蜡烛图主体的颜色。 |
//+------------------------------------------------------------------+
color ChartBearColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收熊市蜡烛图主体的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_CANDLE_BEAR,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置熊市蜡烛图主体的颜色。 |
//+------------------------------------------------------------------+
bool ChartBearColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置熊市蜡烛图主体的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_CANDLE_BEAR,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_BID ——卖价线的颜色。
//+------------------------------------------------------------------+
//| 函数接收卖价线的颜色。 |
//+------------------------------------------------------------------+
color ChartBidColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收卖价线的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_BID,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置卖价线的颜色。 |
//+------------------------------------------------------------------+
bool ChartBidColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置卖价线的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_BID,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_ASK ——买价线的颜色。
//+------------------------------------------------------------------+
//| 该函数接收买价线的颜色。 |
//+------------------------------------------------------------------+
color ChartAskColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收买价线的颜色
if(!ChartGetInteger(chart_ID,CHART_COLOR_ASK,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置买价线的颜色。 |
//+------------------------------------------------------------------+
bool ChartAskColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置买价线的颜色
if(!ChartSetInteger(chart_ID,CHART_COLOR_ASK,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_LAST ——最近交易的价格线的颜色(收盘价)。
//+----------------------------------------------------------------------+
//| 这个函数接收最近交易的价格线的颜色。 |
//+----------------------------------------------------------------------+
color ChartLastColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收最近交易的价格线的颜色(收盘价)
if(!ChartGetInteger(chart_ID,CHART_COLOR_LAST,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 这个函数设置最近交易的价格线 |
//| 的颜色。 |
//+------------------------------------------------------------------+
bool ChartLastColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置最近交易的价格线的颜色(收盘价)
if(!ChartSetInteger(chart_ID,CHART_COLOR_LAST,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_STOP_LEVEL——止损订单水平颜色(止损和获利)。
//+--------------------------------------------------------------------+
//| 这个函数接收止损和获利水平的颜色。 |
//+--------------------------------------------------------------------+
color ChartStopLevelColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收止损订单水平的颜色(止损和获利)
if(!ChartGetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置止损和获利水平的颜色。 |
//+------------------------------------------------------------------+
bool ChartStopLevelColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置止损订单水平的颜色(止损和获利)
if(!ChartSetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_COLOR_STOP_LEVEL——止损订单水平颜色(止损和获利)。
//+--------------------------------------------------------------------+
//| 这个函数接收止损和获利水平的颜色。 |
//+--------------------------------------------------------------------+
color ChartStopLevelColorGet(const long chart_ID=0)
{
//--- 准备变量接收颜色
long result=clrNONE;
//--- 重置错误的值
ResetLastError();
//--- 接收止损订单水平的颜色(止损和获利)
if(!ChartGetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return((color)result);
}
//+------------------------------------------------------------------+
//| 该函数设置止损和获利水平的颜色。 |
//+------------------------------------------------------------------+
bool ChartStopLevelColorSet(const color clr,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置止损订单水平的颜色(止损和获利)
if(!ChartSetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,clr))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_TRADE_LEVELS——在图表上显示交易水平的属性(持仓水平,止损,获利和挂单水平)。
//+---------------------------------------------------------------------+
//| 这个函数定义是否在图表上显示交易水平。 |
//+---------------------------------------------------------------------+
bool ChartShowTradeLevelsGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_TRADE_LEVELS,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 该函数启用/禁用交易水平显示模式。 |
//+------------------------------------------------------------------+
bool ChartShowTradeLevelsSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_TRADE_LEVELS,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_DRAG_TRADE_LEVELS——启用使用鼠标在图表上拖拽交易水平的能力的属性
//+---------------------------------------------------------------------------+
//| 这个函数定义是否允许使用鼠标在图表上拖拽交易 |
//| 水平。 |
//+---------------------------------------------------------------------------+
bool ChartDragTradeLevelsGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_DRAG_TRADE_LEVELS,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 该函数启用/禁用使用鼠标在图表上拖拽交易水平 |
//| 的模式。 |
//+------------------------------------------------------------------+
bool ChartDragTradeLevelsSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_DRAG_TRADE_LEVELS,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_DATE_SCALE——在图表上显示时间比例的属性。
//+--------------------------------------------------------------------+
//| 该函数定义是否在图表上显示时间比例。 |
//+--------------------------------------------------------------------+
bool ChartShowDateScaleGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_DATE_SCALE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+-----------------------------------------------------------------------------+
//| 该函数启用/禁用在图表上显示时间比例的模式。 |
//+-----------------------------------------------------------------------------+
bool ChartShowDateScaleSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_DATE_SCALE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_PRICE_SCALE ——在图表上显示价格比例的属性。
//+--------------------------------------------------------------------+
//| 该函数定义是否在图表上显示价格比例。 |
//+--------------------------------------------------------------------+
bool ChartShowPriceScaleGet(bool &result,const long chart_ID=0)
{
//--- 准备变量获得属性值
long value;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_PRICE_SCALE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+----------------------------------------------------------------------------+
//| 该函数启用/禁用在图表上显示价格比例的模式。 |
//+----------------------------------------------------------------------------+
bool ChartShowPriceScaleSet(const bool value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_PRICE_SCALE,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHOW_ONE_CLICK ——在图表上显示"一键交易"的属性。
//+------------------------------------------------------------------+
//| 检查"单击交易" 面板是否显示在图表上 |
//+------------------------------------------------------------------+
bool ChartShowOneClickPanelGet(bool &result,const long chart_ID=0)
{
//--- 准备变量以获得属性值
long value;
//--- 重置错误值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_SHOW_ONE_CLICK,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在内存中存储图表属性的值
result=value;
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 启用/禁用显示"单击交易" 面板 |
//| 在图表上 |
//+------------------------------------------------------------------+
bool ChartShowOneClickPanelSet(const bool value,const long chart_ID=0)
{
//--- 重置错误值
ResetLastError();
//--- 设置属性值
if(!ChartSetInteger(chart_ID,CHART_SHOW_ONE_CLICK,0,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_SHIFT_SIZE ——从右侧边界开始的零柱的百分比值转换大小。
//+---------------------------------------------------------------------------+
//| 该函数接收从图表右侧边界开始的零柱的 |
//| 百分比值 转换大小(从10%直到50%)。 |
//+---------------------------------------------------------------------------+
double ChartShiftSizeGet(const long chart_ID=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_SHIFT_SIZE,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
//+--------------------------------------------------------------------------------------+
//| 这个函数设置从图表右侧边界开始的零柱的 |
//| 百分比值转换大小(从10%直到50%)。要启用该转换 |
//| 模式,CHART_SHIFT 属性值应该设置为 |
//| true。 |
//+--------------------------------------------------------------------------------------+
bool ChartShiftSizeSet(const double value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetDouble(chart_ID,CHART_SHIFT_SIZE,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_FIXED_POSITION ——图表从左边界以百分比值固定位置。
//+--------------------------------------------------------------------------+
//| 这个函数接收从左边界以百分比值 |
//| 固定位置的图表的位置。 |
//+--------------------------------------------------------------------------+
double ChartFixedPositionGet(const long chart_ID=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_FIXED_POSITION,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
//+---------------------------------------------------------------------+
//| 这个函数设置从左边界以百分比值 |
//| 固定位置的图表的位置。若要查看固定位置 |
//| 图表的位置, CHART_AUTOSCROLL |
//| 属性值应该设置为false。 |
//+---------------------------------------------------------------------+
bool ChartFixedPositionSet(const double value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetDouble(chart_ID,CHART_FIXED_POSITION,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_FIXED_MAX ——表格的固定最大值属性。
//+------------------------------------------------------------------+
//| 这个函数接收图表的固定最大值。 |
//+------------------------------------------------------------------+
double ChartFixedMaxGet(const long chart_ID=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_FIXED_MAX,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
//+------------------------------------------------------------------+
//| 这个函数设置图表的固定最大值。 |
//| 要改变属性的值, |
//| CHART_SCALEFIX 属性值应该提前设置为 |
//| true。 |
//+------------------------------------------------------------------+
bool ChartFixedMaxSet(const double value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetDouble(chart_ID,CHART_FIXED_MAX,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_FIXED_MIN —— 图表固定最小值的属性。
//+------------------------------------------------------------------+
//| 这个函数接收图表的固定最小值。 |
//+------------------------------------------------------------------+
double ChartFixedMinGet(const long chart_ID=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_FIXED_MIN,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
//+------------------------------------------------------------------+
//| 这个函数设置图表的固定最小值。 |
//| 要改变属性的值, |
//| CHART_SCALEFIX 属性值应该提前设置为 |
//| true。 |
//+------------------------------------------------------------------+
bool ChartFixedMinSet(const double value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetDouble(chart_ID,CHART_FIXED_MIN,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_POINTS_PER_BAR —— 每柱比例尺的点数值。
//+---------------------------------------------------------------------------+
//| 这个函数接收每柱图表比例尺的点数值。 |
//+---------------------------------------------------------------------------+
double ChartPointsPerBarGet(const long chart_ID=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_POINTS_PER_BAR,0,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
//+----------------------------------------------------------------------+
//| 这个函数设置每柱的图表比例尺的点数值。 |
//| 要查看这个属性值的变化结果, |
//| 这个 |
//| CHART_SCALE_PT_PER_BAR 属性值应该提前设置为true。 |
//+----------------------------------------------------------------------+
bool ChartPointsPerBarSet(const double value,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetDouble(chart_ID,CHART_POINTS_PER_BAR,value))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_PRICE_MIN —— 返回图表的最小值。
//+---------------------------------------------------------------------------------+
//| 这个函数接收主窗口或子窗口的图表最小值。 |
//+---------------------------------------------------------------------------------+
double ChartPriceMin(const long chart_ID=0,const int sub_window=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_PRICE_MIN,sub_window,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
•CHART_PRICE_MAX —— 返回图表的最大值。
double ChartPriceMax(const long chart_ID=0,const int sub_window=0)
{
//--- 准备变量获得结果
double result=EMPTY_VALUE;
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetDouble(chart_ID,CHART_PRICE_MAX,sub_window,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- 返回图表属性值
return(result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
•CHART_COMMENT—— 图表评论。
//+----------------------------------------------------------------------+
//| 这个函数接收图表左上角的评论。 |
//+----------------------------------------------------------------------+
bool ChartCommentGet(string &result,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 接收属性值
if(!ChartGetString(chart_ID,CHART_COMMENT,result))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数设置图表左上角的评论。 |
//+------------------------------------------------------------------+
bool ChartCommentSet(const string str,const long chart_ID=0)
{
//--- 重置错误的值
ResetLastError();
//--- 设置属性值
if(!ChartSetString(chart_ID,CHART_COMMENT,str))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 成功执行
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
•CHART_IS_MAXIMIZED—— 图表窗口最大化。
//+------------------------------------------------------------------+
//| 定义如果当前图表窗口最大化 |
//+------------------------------------------------------------------+
bool ChartWindowsIsMaximized(bool &result,const long chart_ID=0)
{
//--- 准备接收属性值的变量
long value;
//--- 重置错误值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_IS_MAXIMIZED))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在变量中存储图表属性值
result=value;
//--- 成功执行
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
•CHART_IS_MINIMIZED —— 图表窗口最小化。
//+------------------------------------------------------------------+
//| 定义如果当前图表窗口最小化 |
//+------------------------------------------------------------------+
bool ChartWindowsIsMinimized(bool &result,const long chart_ID=0)
{
//--- 准备接收属性值的变量
long value;
//--- 重置错误值
ResetLastError();
//--- 接收属性值
if(!ChartGetInteger(chart_ID,CHART_IS_MINIMIZED))
{
//--- 在EA日志显示错误信息
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- 在变量中存储图表属性值
result=value;
//--- 成功执行
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
图表属性面板
//--- 连接控制元素的程序库
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- 预定义常量
#define X_PROPERTY_NAME_1 10 //第一列属性名的x坐标
#define X_PROPERTY_VALUE_1 225 //第一列属性值的 x 坐标
#define X_PROPERTY_NAME_2 345 // 第二和第三列的属性名的x坐标
#define X_PROPERTY_VALUE_2 550 // 第二和第三列的属性值的x坐标
#define X_BUTTON_1 285 // 第一列按钮的x坐标
#define X_BUTTON_2 700 //第二列按钮的 x 坐标
#define Y_PROPERTY_1 30 // 第一和第二列开始的y 坐标
#define Y_PROPERTY_2 286 // 第三列开始的y坐标
#define Y_DISTANCE 16 // y 轴的行间距
#define LAST_PROPERTY_NUMBER 111 // 最近图形的属性号
//--- 输入参数
input color InpFirstColor=clrDodgerBlue; // 奇数行的颜色
input color InpSecondColor=clrGoldenrod; // 偶数行的颜色
//--- 变量和数组
CChartObjectLabel ExtLabelsName[]; // 显示属性名的标签
CChartObjectLabel ExtLabelsValue[]; // 显示属性值的标签
CChartObjectButton ExtButtons[]; // 按钮
int ExtNumbers[]; // 属性指数
string ExtNames[]; // 属性名称
uchar ExtDataTypes[]; // 属性数据类型(整型,双精度,字符串)
uint ExtGroupTypes[]; // 存储有关属性归属于一个组的数据的数组
uchar ExtDrawTypes[]; // 存储有关属性显示类型的数据的数组
double ExtMaxValue[]; // 面板工作时最大可能的属性值
double ExtMinValue[]; // 面板工作时最小可能的属性值
double ExtStep[]; // 更改属性的步骤
int ExtCount; // 所有属性的总数
color ExtColors[2]; // 用于显示行的颜色的数组
string ExtComments[2]; // 评论数组 (用于CHART_COMMENT 属性)
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 在图表上显示评论
Comment("SomeComment");
//--- 数组中存储颜色以便过后能够在它们之间切换
ExtColors[0]=InpFirstColor;
ExtColors[1]=InpSecondColor;
//--- 数组中存储评论以便过后在它们之间切换
ExtComments[0]="FirstComment";
ExtComments[1]="SecondComment";
//--- 准备并显示管理图表属性的控制面板
if(!PrepareControls())
return(INIT_FAILED);
//--- 成功执行
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA的去初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- 在图表上移除评论
Comment("");
}
//+------------------------------------------------------------------+
//| 图表事件处理程序 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- 检查点击图表对象的事件
if(id==CHARTEVENT_OBJECT_CLICK)
{
//--- 用分隔符分开对象名称
string obj_name[];
StringSplit(sparam,'_',obj_name);
//--- 检查对象是否是个按钮
if(obj_name[0]=="Button")
{
//--- 接收按钮指数
int index=(int)StringToInteger(obj_name[1]);
//--- 不按按钮
ExtButtons[index].State(false);
//--- 根据类型设置新的属性值
if(ExtDataTypes[index]=='I')
ChangeIntegerProperty(index);
if(ExtDataTypes[index]=='D')
ChangeDoubleProperty(index);
if(ExtDataTypes[index]=='S')
ChangeStringProperty(index);
}
}
//--- 重画属性值
RedrawProperties();
ChartRedraw();
}
//+------------------------------------------------------------------+
//| 改变图表的整型属性 |
//+------------------------------------------------------------------+
void ChangeIntegerProperty(const int index)
{
//--- 接收当前属性值
long value=ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index]);
//--- 定义以下属性值
switch(ExtDrawTypes[index])
{
case 'C':
value=GetNextColor((color)value);
break;
default:
value=(long)GetNextValue((double)value,index);
break;
}
//--- 设置新的属性值
ChartSetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index],0,value);
}
//+------------------------------------------------------------------+
//| 改变图表的双精度属性 |
//+------------------------------------------------------------------+
void ChangeDoubleProperty(const int index)
{
//--- 接收当前属性值
double value=ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index]);
//--- 定义以下属性值
value=GetNextValue(value,index);
//--- 设置新的属性值
ChartSetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index],value);
}
//+------------------------------------------------------------------+
//| 改变图表的字符串属性 |
//+------------------------------------------------------------------+
void ChangeStringProperty(const int index)
{
//--- 用于 ExtComments数组内转换的静态变量
static uint comment_index=1;
//--- 改变接收另一个评论的指数
comment_index=1-comment_index;
//--- 设置新的属性值
ChartSetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[index],ExtComments[comment_index]);
}
//+------------------------------------------------------------------+
//| 定义下一个属性值 |
//+------------------------------------------------------------------+
double GetNextValue(const double value,const int index)
{
if(value+ExtStep[index] < =ExtMaxValue[index])
return(value+ExtStep[index]);
else
return(ExtMinValue[index]);
}
//+------------------------------------------------------------------+
//| 接收颜色类型属性的下一个颜色 |
//+------------------------------------------------------------------+
color GetNextColor(const color clr)
{
//--- 返回以下颜色值
switch(clr)
{
case clrWhite: return(clrRed);
case clrRed: return(clrGreen);
case clrGreen: return(clrBlue);
case clrBlue: return(clrBlack);
default: return(clrWhite);
}
}
//+------------------------------------------------------------------+
//| 重画属性值 |
//+------------------------------------------------------------------+
void RedrawProperties(void)
{
//--- 属性值文本
string text;
long value;
//--- 循环的属性数量
for(int i=0; i<ExtCount; i++)
{
text="";
switch(ExtDataTypes[i])
{
case 'I':
//--- 接收当前属性值
if(!ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[i],0,value))
break;
//--- 整型属性文本
switch(ExtDrawTypes[i])
{
//--- 颜色属性
case 'C':
text=(string)((color)value);
break;
//--- 布尔属性
case 'B':
text=(string)((bool)value);
break;
//--- ENUM_CHART_MODE 枚举属性
case 'M':
text=EnumToString((ENUM_CHART_MODE)value);
break;
//--- ENUM_CHART_VOLUME_MODE 枚举属性
case 'V':
text=EnumToString((ENUM_CHART_VOLUME_MODE)value);
break;
//--- int 类型号
default:
text=IntegerToString(value);
break;
}
break;
case 'D':
//--- 双精度属性文本
text=DoubleToString(ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[i]),4);
break;
case 'S':
//--- 字符串属性文本
text=ChartGetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[i]);
break;
}
//--- 显示属性值
ExtLabelsValue[i].Description(text);
}
}
//+------------------------------------------------------------------+
//| 创建管理图表属性面板 |
//+------------------------------------------------------------------+
bool PrepareControls(void)
{
//--- 为数组存储分配内存
MemoryAllocation(LAST_PROPERTY_NUMBER+1);
//--- 变量
int i=0; // 循环变量
int col_1=0; // 第一列的属性数
int col_2=0; // 第二列的属性数
int col_3=0; // 第三列的属性数
//--- 当前属性数 - 0
ExtCount=0;
//--- 在循环中查找属性
while(i < = LAST_PROPERTY_NUMBER)
{
//--- 存储当前属性数
ExtNumbers[ExtCount]=i;
//--- 增加循环变量值
i++;
//--- 检查是否有这个数的属性
if(CheckNumber(ExtNumbers[ExtCount],ExtNames[ExtCount],ExtDataTypes[ExtCount],ExtGroupTypes[ExtCount],ExtDrawTypes[ExtCount]))
{
//--- 创建属性的控制元素
switch(ExtGroupTypes[ExtCount])
{
case 1:
//--- 创建属性标签和按钮
if(!ShowProperty(ExtCount,0,X_PROPERTY_NAME_1,X_PROPERTY_VALUE_1,X_BUTTON_1,Y_PROPERTY_1+col_1*Y_DISTANCE,true))
return(false);
//--- 第一列的元素数已经增加
col_1++;
break;
case 2:
//--- 创建属性标签和按钮
if(!ShowProperty(ExtCount,1,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,X_BUTTON_2,Y_PROPERTY_1+col_2*Y_DISTANCE,true))
return(false);
//--- 第二列的元素数已经增加
col_2++;
break;
case 3:
//--- 只创建属性标签
if(!ShowProperty(ExtCount,2,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,0,Y_PROPERTY_2+col_3*Y_DISTANCE,false))
return(false);
//--- 第三列的元素数已经增加
col_3++;
break;
}
//--- 定义最大最小属性值和步骤
GetMaxMinStep(ExtNumbers[ExtCount],ExtMaxValue[ExtCount],ExtMinValue[ExtCount],ExtStep[ExtCount]);
//--- 增加属性数量
ExtCount++;
}
}
//--- 释放数组不用的内存
MemoryAllocation(ExtCount);
//--- 重画属性值
RedrawProperties();
ChartRedraw();
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 为数组分配内存 |
//+------------------------------------------------------------------+
void MemoryAllocation(const int size)
{
ArrayResize(ExtLabelsName,size);
ArrayResize(ExtLabelsValue,size);
ArrayResize(ExtButtons,size);
ArrayResize(ExtNumbers,size);
ArrayResize(ExtNames,size);
ArrayResize(ExtDataTypes,size);
ArrayResize(ExtGroupTypes,size);
ArrayResize(ExtDrawTypes,size);
ArrayResize(ExtMaxValue,size);
ArrayResize(ExtMinValue,size);
ArrayResize(ExtStep,size);
}
//+------------------------------------------------------------------+
//| 检查是否属性指数属于 |
//| ENUM_CHART_PROPERTIES 枚举 |
//+------------------------------------------------------------------+
bool CheckNumber(const int ind,string &name,uchar &data_type,uint &group_type,uchar &draw_type)
{
//--- 检查属性是否是整型类型的属性
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_INTEGER)ind);
if(_LastError==0)
{
data_type='I'; // 来自 ENUM_CHART_PROPERTY_INTEGER 枚举的属性
GetTypes(ind,group_type,draw_type); // 定义属性显示参数
return(true);
}
//--- 检查属性是否是双精度类型
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_DOUBLE)ind);
if(_LastError==0)
{
data_type='D'; // 来自 ENUM_CHART_PROPERTY_DOUBLE 枚举的属性
GetTypes(ind,group_type,draw_type); // 定义属性显示参数
return(true);
}
//--- 检查属性是否是字符串类型
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_STRING)ind);
if(_LastError==0)
{
data_type='S'; // 来自 ENUM_CHART_PROPERTY_STRING 枚举的属性
GetTypes(ind,group_type,draw_type); // 定义属性显示参数
return(true);
}
//--- 属性不属于任何枚举
return(false);
}
//+------------------------------------------------------------------+
//| 定义属性应该存储的组, |
//| 以及其展示类型 |
//+------------------------------------------------------------------+
void GetTypes(const int property_number,uint &group_type,uchar &draw_type)
{
//--- 检查属性是否属于第三组
//--- 第三组属性显示在从CHART_BRING_TO_TOP开始的第二列
if(CheckThirdGroup(property_number,group_type,draw_type))
return;
//--- 检查属性是否属于第二组
//--- 第二组属性显示在第二列的开头
if(CheckSecondGroup(property_number,group_type,draw_type))
return;
//--- 如果您在这里找到了自己,属性属于第一组(第一列)
CheckFirstGroup(property_number,group_type,draw_type);
}
//+----------------------------------------------------------------------+
//| 这个函数检查属性是否属于第三组并 |
//| 在肯定回答时定义显示类型 |
//+----------------------------------------------------------------------+
bool CheckThirdGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- 检查属性是否属于第三组
switch(property_number)
{
//--- 布尔属性
case CHART_IS_OBJECT:
case CHART_WINDOW_IS_VISIBLE:
draw_type='B';
break;
//--- 整型属性
case CHART_VISIBLE_BARS:
case CHART_WINDOWS_TOTAL:
case CHART_WINDOW_HANDLE:
case CHART_WINDOW_YDISTANCE:
case CHART_FIRST_VISIBLE_BAR:
case CHART_WIDTH_IN_BARS:
case CHART_WIDTH_IN_PIXELS:
draw_type='I';
break;
//--- 双精度属性
case CHART_PRICE_MIN:
case CHART_PRICE_MAX:
draw_type='D';
break;
//--- 实际上,这个属性实在所有其他的上面显示图表的命令
//--- 无需应用这个面板,因为窗口会始终保持
//--- 在其他的上面,在我们使用之前
case CHART_BRING_TO_TOP:
draw_type=' ';
break;
//--- 属性不属于第三组
default:
return(false);
}
//--- 属性属于第三组
group_type=3;
return(true);
}
//+----------------------------------------------------------------------+
//| 这个函数检查属性是否属于第二组并 |
//| 在肯定回答时定义显示类型 |
//+----------------------------------------------------------------------+
bool CheckSecondGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- 检查属性是否属于第二组
switch(property_number)
{
//--- ENUM_CHART_MODE 类型属性
case CHART_MODE:
draw_type='M';
break;
//--- ENUM_CHART_VOLUME_MODE 类型属性
case CHART_SHOW_VOLUMES:
draw_type='V';
break;
//--- 字符串属性
case CHART_COMMENT:
draw_type='S';
break;
//--- 颜色属性
case CHART_COLOR_BACKGROUND:
case CHART_COLOR_FOREGROUND:
case CHART_COLOR_GRID:
case CHART_COLOR_VOLUME:
case CHART_COLOR_CHART_UP:
case CHART_COLOR_CHART_DOWN:
case CHART_COLOR_CHART_LINE:
case CHART_COLOR_CANDLE_BULL:
case CHART_COLOR_CANDLE_BEAR:
case CHART_COLOR_BID:
case CHART_COLOR_ASK:
case CHART_COLOR_LAST:
case CHART_COLOR_STOP_LEVEL:
draw_type='C';
break;
//--- 属性不属于第二组
default:
return(false);
}
//--- 属性属于第二组
group_type=2;
return(true);
}
//+-----------------------------------------------------------------------+
//| 这个函数被调用只有在已知 |
//| 属性不属于第二和第三属性组时才可以 |
//+-----------------------------------------------------------------------+
void CheckFirstGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- 属性属于第一组
group_type=1;
//--- 定义属性显示类型
switch(property_number)
{
//--- 整型属性
case CHART_SCALE:
case CHART_HEIGHT_IN_PIXELS:
draw_type='I';
return;
//--- 双精度属性
case CHART_SHIFT_SIZE:
case CHART_FIXED_POSITION:
case CHART_FIXED_MAX:
case CHART_FIXED_MIN:
case CHART_POINTS_PER_BAR:
draw_type='D';
return;
//--- 只保留布尔属性
default:
draw_type='B';
return;
}
}
//+------------------------------------------------------------------+
//| 创建属性标签和按钮 |
//+------------------------------------------------------------------+
bool ShowProperty(const int ind,const int type,const int x1,const int x2,
const int xb,const int y,const bool btn)
{
//--- 用于ExtColors颜色数组内转换的静态数组
static uint color_index[3]={1,1,1};
//--- 改变指数,接收另一个颜色
color_index[type]=1-color_index[type];
//--- 显示属性的标签和按钮 (如果 btn=true)
if(!LabelCreate(ExtLabelsName[ind],"name_"+(string)ind,ExtNames[ind],ExtColors[color_index[type]],x1,y))
return(false);
if(!LabelCreate(ExtLabelsValue[ind],"value_"+(string)ind,"",ExtColors[color_index[type]],x2,y))
return(false);
if(btn && !ButtonCreate(ExtButtons[ind],(string)ind,xb,y+1))
return(false);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 创建标签 |
//+------------------------------------------------------------------+
bool LabelCreate(CChartObjectLabel &lbl,const string name,const string text,
const color clr,const int x,const int y)
{
if(!lbl.Create(0,"Label_"+name,0,x,y)) return(false);
if(!lbl.Description(text)) return(false);
if(!lbl.FontSize(10)) return(false);
if(!lbl.Color(clr)) return(false);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 创建按钮 |
//+------------------------------------------------------------------+
bool ButtonCreate(CChartObjectButton &btn,const string name,
const int x,const int y)
{
if(!btn.Create(0,"Button_"+name,0,x,y,50,15)) return(false);
if(!btn.Description("Next")) return(false);
if(!btn.FontSize(10)) return(false);
if(!btn.Color(clrBlack)) return(false);
if(!btn.BackColor(clrWhite)) return(false);
if(!btn.BorderColor(clrBlack)) return(false);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 定义最大和最小属性值和步骤 |
//+------------------------------------------------------------------+
void GetMaxMinStep(const int property_number,double &max,double &min,double &step)
{
double value;
//--- 根据属性类型设置值
switch(property_number)
{
case CHART_SCALE:
max=5;
min=0;
step=1;
break;
case CHART_MODE:
case CHART_SHOW_VOLUMES:
max=2;
min=0;
step=1;
break;
case CHART_SHIFT_SIZE:
max=50;
min=10;
step=2.5;
break;
case CHART_FIXED_POSITION:
max=90;
min=0;
step=15;
break;
case CHART_POINTS_PER_BAR:
max=19;
min=1;
step=3;
break;
case CHART_FIXED_MAX:
value=ChartGetDouble(0,CHART_FIXED_MAX);
max=value*1.25;
min=value;
step=value/32;
break;
case CHART_FIXED_MIN:
value=ChartGetDouble(0,CHART_FIXED_MIN);
max=value;
min=value*0.75;
step=value/32;
break;
case CHART_HEIGHT_IN_PIXELS:
max=700;
min=520;
step=30;
break;
//--- 默认值
default:
max=1;
min=0;
step=1;
}
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
# 2 .2 对象常量
在价格图表中可以创建44 个可显示的图解对象,所有与对象有关的常量都被分成9组:
• 对象类型 —— 图解对象的标识符; • 对象属性 —— 设置 或/和 获得 图解对象的属性参数; • 对象定位方法 —— 在图表中定位对象常量; • 定位角 —— 设置一个物体在图表上的相对位置; • 对象可见性 —— 设置对象在 哪些/全部 时间框架图表 可显示; • 艾略特波动水平 —— 波浪分级; • 江恩对象 —— 江恩角度线(Gann fan) 和 江恩网格(Gann grid)的趋向常量; • 网页颜色 —— 预定义网络颜色的常量; • Wingdings —— Wingdings字库的字符代码;
# 2.2.1 对象(物件)类型
当使用ObjectCreate()函数创建图形对象时,必须指定要创建的对象的类型,类型可以是枚举型变量 ENUM_OBJECT 的一个值。对象属性的进一步规范可以使用与图形对象一起工作的函数。
ENUM_OBJECT
ID | 图标 | 描述 |
---|---|---|
OBJ_VLINE | 垂直线 | |
OBJ_HLINE | 水平线 | |
OBJ_TREND | 趋势线 | |
OBJ_TRENDBYANGLE | 趋势线角度 | |
OBJ_CYCLES | 周期线 | |
OBJ_ARROWED_LINE | 箭头线 | |
OBJ_CHANNEL | 等距离通道 | |
OBJ_STDDEVCHANNEL | 标准偏离通道 | |
OBJ_REGRESSION | 线形回归通道 | |
OBJ_PITCHFORK | 安德鲁分叉线 | |
OBJ_GANNLINE | 江恩线 | |
OBJ_GANNFAN | 江恩扇形线 | |
OBJ_GANNGRID | 江恩网格线 | |
OBJ_FIBO | 斐波纳契回撤 | |
OBJ_FIBOTIMES | 斐波纳契时间周期线 | |
OBJ_FIBOFAN | 斐波纳契扇形线 | |
OBJ_FIBOARC | 斐波纳契弧线 | |
OBJ_FIBOCHANNEL | 斐波纳契通道 | |
OBJ_EXPANSION | 斐波纳契扩展 | |
OBJ_ELLIOTWAVE5 | 艾略特驱动浪 | |
OBJ_ELLIOTWAVE3 | 艾略特调整浪 | |
OBJ_RECTANGLE | 矩型 | |
OBJ_TRIANGLE | 三角形 | |
OBJ_ELLIPSE | 椭圆形 | |
OBJ_ARROW_THUMB_UP | 大拇指向上 | |
OBJ_ARROW_THUMB_DOWN | 大拇指向下 | |
OBJ_ARROW_UP | 向上箭头 | |
OBJ_ARROW_DOWN | 向下箭头 | |
OBJ_ARROW_STOP | 停止标志 | |
OBJ_ARROW_CHECK | 检测标志 | |
OBJ_ARROW_LEFT_PRICE | 左侧价格标签 | |
OBJ_ARROW_RIGHT_PRICE | 右侧价格标签 | |
OBJ_ARROW_BUY | 买入(做多)箭头 | |
OBJ_ARROW_SELL | 卖出(做空)箭头 | |
OBJ_ARROW | 箭头 | |
OBJ_TEXT | 文本 | |
OBJ_LABEL | 文本标签 | |
OBJ_BUTTON | 按钮 | |
OBJ_CHART | 图表 | |
OBJ_BITMAP | 位图 | |
OBJ_BITMAP_LABEL | 位图标签 | |
OBJ_EDIT | 文本编辑框 | |
OBJ_EVENT | “事件”对象在经济日历对应一个事件 | |
OBJ_RECTANGLE_LABEL | 用于创建和设计自定义图形界面的“矩形标签”对象。 |
# 2.2.1.1 OBJ_VLINE垂直线
ObjVLine
注意
绘制垂直线时,可以设置所有图表窗口的线显示模式(属性 OBJPROP_RAY)。
示例
下面的脚本创建并移动图表上的垂直线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Vertical Line\" graphical object."
#property description "Anchor point date is set in percentage of"
#property description "the chart window width in bars."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="VLine"; // 线的名称
input int InpDate=25; // 事件日期,%
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 线的风格
input int InpWidth=3; // 线的宽度
input bool InpBack=false; // 背景线
input bool InpSelection=true; // 突出移动
input bool InpRay=true; // 线延续下降
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建垂直线 |
//+------------------------------------------------------------------+
bool VLineCreate(const long chart_ID=0, // 图表 ID
const string name="VLine", // 线的名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 线的时间
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray=true, // 线延续下降
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 如果没有线的时间,通过收盘柱来绘制它
if(!time)
time=TimeCurrent();
//--- 重置错误的值
ResetLastError();
//--- 创建垂直线
if(!ObjectCreate(chart_ID,name,OBJ_VLINE,sub_window,time,0))
{
Print(__FUNCTION__,
": failed to create a vertical line! Error code = ",GetLastError());
return(false);
}
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动线的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) the mode of displaying the line in the chart subwindows
ObjectSetInteger(chart_ID,name,OBJPROP_RAY,ray);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动垂直线 |
//+------------------------------------------------------------------+
bool VLineMove(const long chart_ID=0, // 图表 ID
const string name="VLine", // 线的名称
datetime time=0) // 线的时间
{
//--- 如果没有设置线的时间,将线移动到收盘柱
if(!time)
time=TimeCurrent();
//--- 重置错误的值
ResetLastError();
//--- 移动垂直线
if(!ObjectMove(chart_ID,name,0,time,0))
{
Print(__FUNCTION__,
": failed to move the vertical line! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除垂直线 |
//+------------------------------------------------------------------+
bool VLineDelete(const long chart_ID=0, // 图表 ID
const string name="VLine") // 线的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除垂直线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the vertical line! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate < 0 || InpDate > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 存储要使用的日期值的数组
//--- 设置和改变线定位点的坐标
datetime date[];
//--- 内存分配
ArrayResize(date,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 定义画线的点
int d=InpDate*(bars-1)/100;
//--- 创建垂直线
if(!VLineCreate(0,InpName,0,date[d],InpColor,InpStyle,InpWidth,InpBack,
InpSelection,InpRay,InpHidden,InpZOrder))
return;
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动线
//--- 循环计数器
int h_steps=bars/2;
//--- 移动线
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!VLineMove(0,InpName,date[d]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.03 秒延迟
Sleep(30);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
VLineDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
# 2.2.1.3 OBJ_TREND趋势线
ObjTrend
注意
对于趋势线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
示例
下面的脚本创建并移动图表上的趋势线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Trend Line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Trend"; // 线的名称
input int InpDate1=35; // 第1个点的日期, %
input int InpPrice1=60; // 第1个点的价格, %
input int InpDate2=65; // 第2个点的日期,%
input int InpPrice2=40; // 第2个点的价格,%
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景线
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 线延续向左
input bool InpRayRight=false; // 线延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建趋势线 |
//+------------------------------------------------------------------+
bool TrendCreate(const long chart_ID=0, // 图表 ID
const string name="TrendLine", // 线的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 线延续向左
const bool ray_right=false, // 线延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeTrendEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建趋势线
if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create a trend line! Error code = ",GetLastError());
return(false);
}
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动线的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动趋势线定位点 |
//+------------------------------------------------------------------+
bool TrendPointChange(const long chart_ID=0, // 图表 ID
const string name="TrendLine", // 线的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动趋势线定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数删除图表的趋势线 |
//+------------------------------------------------------------------+
bool TrendDelete(const long chart_ID=0, // chart's ID
const string name="TrendLine") // 线的颜色
{
//--- 重置错误的值
ResetLastError();
//--- 删除趋势线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a trend line! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查趋势线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeTrendEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二点的价格没有设置,则它与第一点的价格相等
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变线定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i < accuracy;i++)
price[i]=min_price+i*step;
//--- 定义画线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建趋势线
if(!TrendCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,InpStyle,
InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动线的定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 垂直移动第一个定位点
for(int i=0;i < v_steps;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!TrendPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 垂直移动第二个定位点
for(int i=0;i < v_steps;i++)
{
//--- 使用下面的值
if(p2<accuracy-1)
p2+=1;
//--- 移动点
if(!TrendPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 半秒延迟
Sleep(500);
//--- 循环计数器
int h_steps=bars/2;
//--- 同时水平移动两个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d1<bars-1)
d1+=1;
if(d2>1)
d2-=1;
//--- 切换点
if(!TrendPointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!TrendPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.03 秒延迟
Sleep(30);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除趋势线
TrendDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# 2.2.1.4 OBJ_TRENDBYANGLE角度趋势线
ObjTrendByAngle
注意
对于角度趋势线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
角度 和 第二个锚点的坐标 这二个参数都可以用来设置直线的斜率。
示例
下面的脚本创建并移动图表上的角度趋势线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Trend Line By Angle\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Trend"; // 线的名称
input int InpDate1=50; // 第1个点的日期, %
input int InpPrice1=75; // 第1个点的价格, %
input int InpAngle=0; // 线型倾斜角
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景线
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 线延续向左
input bool InpRayRight=true; // 线延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建角度趋势线 |
//+------------------------------------------------------------------+
bool TrendByAngleCreate(const long chart_ID=0, // 图表 ID
const string name="TrendLine", // 线的名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 点的时间
double price=0, // 点的价格
const double angle=45.0, // 斜角
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 线延续向左
const bool ray_right=true, // 线延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 创建第二个点以便于鼠标拖拽趋势线
datetime time2=0;
double price2=0;
//--- 若未设置则设置定位点的坐标
ChangeTrendEmptyPoints(time,price,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 使用2个点创建趋势线
if(!ObjectCreate(chart_ID,name,OBJ_TRENDBYANGLE,sub_window,time,price,time2,price2))
{
Print(__FUNCTION__,
": failed to create a trend line! Error code = ",GetLastError());
return(false);
}
//--- 改变趋势线的斜角;改变斜角时,第二点的坐标
//--- 根据新的角度值,自动重新定义线的点
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动线的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变趋势线定位点的坐标 |
//+------------------------------------------------------------------+
bool TrendPointChange(const long chart_ID=0, // 图表 ID
const string name="TrendLine", // 线的名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动趋势线定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变趋势线的斜角 |
//+------------------------------------------------------------------+
bool TrendAngleChange(const long chart_ID=0, // 图表 ID
const string name="TrendLine", // 趋势线名称
const double angle=45) // 趋势线斜角
{
//--- 重置错误的值
ResetLastError();
//--- 改变趋势线的斜角
if(!ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle))
{
Print(__FUNCTION__,
": failed to change the line's slope angle! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除趋势线 |
//+------------------------------------------------------------------+
bool TrendDelete(const long chart_ID=0, // 图表 ID
const string name="TrendLine") // 线的颜色
{
//--- 重置错误的值
ResetLastError();
//--- 删除趋势线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a trend line! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查趋势线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeTrendEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 设置第二坐标,辅助点
//--- 第二个点是左侧第9个柱并且价格相同
datetime second_point_time[10];
CopyTime(Symbol(),Period(),time1,10,second_point_time);
time2=second_point_time[0];
price2=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变线定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义画线的点
int d1=InpDate1*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- 创建趋势线
if(!TrendByAngleCreate(0,InpName,0,date[d1],price[p1],InpAngle,InpColor,InpStyle,
InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动和旋转线
//--- 循环计数器
int v_steps=accuracy/2;
//--- 移动定位点并改变线的斜角
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!TrendPointChange(0,InpName,date[d1],price[p1]))
return;
if(!TrendAngleChange(0,InpName,18*(i+1)))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除
TrendDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# 2.2.1.5 OBJ_CYCLES循环周期线
ObjCycles
注意
坚直线之间的距离是由对象的两个定位锚点的时间坐标来设定的。
示例
下面的脚本创建并移动图表上的循环周期线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates cycle lines on the chart."
#property description "Anchor point coordinates are set in percentage"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Cycles"; // 对象的名称
input int InpDate1=10; // 第1个点的日期, %
input int InpPrice1=45; // 第1个点的价格, %
input int InpDate2=20; // 第2个点的日期, %
input int InpPrice2=55; // 第2个点的价格,%
input color InpColor=clrRed; //循环线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 循环线的风格
input int InpWidth=1; // 循环线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; //隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建循环线 |
//+------------------------------------------------------------------+
bool CyclesCreate(const long chart_ID=0, // 图表 ID
const string name="Cycles", // 对象名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 循环线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 循环线的风格
const int width=1, // 循环线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeCyclesEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建循环线
if(!ObjectCreate(chart_ID,name,OBJ_CYCLES,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create cycle lines! Error code = ",GetLastError());
return(false);
}
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动线的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool CyclesPointChange(const long chart_ID=0, // 图表ID
const string name="Cycles", // 对象的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除循环线 |
//+------------------------------------------------------------------+
bool CyclesDelete(const long chart_ID=0, // 图表 ID
const string name="Cycles") // 对象的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除循环线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete cycle lines! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+-----------------------------------------------------------------------+
//| 检查循环线定位点的值和为空点设置 |
//| 默认的值 |
//+-----------------------------------------------------------------------+
void ChangeCyclesEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二点的价格没有设置,则它与第一点的价格相等
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变循环线定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义画循环线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建趋势线
if(!CyclesCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int h_steps=bars/5;
//--- 移动第二个定位点
for(int i=0;i< h_steps ;i++)
{
//--- 使用下面的值
if(d2<bars-1)
d2+=1;
//--- 移动点
if(!CyclesPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
h_steps=bars/4;
//--- 移动第一个定位点
for(int i=0;i< h_steps ;i++)
{
//--- 使用下面的值
if(d1<bars-1)
d1+=1;
//--- 移动点
if(!CyclesPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
CyclesDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# 2.2.1.6 OBJ_ARROWED_LINE箭头线
ObjArrowedLine
示例
下面的脚本创建并移动图表上的箭头线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Arrowed line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ArrowedLine"; // 线的名称
input int InpDate1=35; // 第1个点的日期,%
input int InpPrice1=60; // 第1个点的价格,%
input int InpDate2=65; // 第2个点的日期,%
input int InpPrice2=40; // 第2个点的价格,%
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景线
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建箭头线 |
//+------------------------------------------------------------------+
bool ArrowedLineCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowedLine", // 线的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowedLineEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建箭头线
if(!ObjectCreate(chart_ID,name,OBJ_ARROWED_LINE,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create an arrowed line! Error code = ",GetLastError());
return(false);
}
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动线的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动箭头线的定位点 |
//+------------------------------------------------------------------+
bool ArrowedLinePointChange(const long chart_ID=0, // 图表 ID
const string name="ArrowedLine", // 线的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动线的定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数移除图表的箭头线 |
//+------------------------------------------------------------------+
bool ArrowedLineDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowedLine") // 线的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除箭头线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to create an arrowed line! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowedLineEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二点的价格没有设置,则它与第一点的价格相等
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变线定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义画线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建箭头线
if(!ArrowedLineCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动线的定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 垂直移动第二个定位点
for(int i=0;i< v_steps ;i++)
{
//--- 使用下面的值
if(p2< accuracy-1 )
p2+=1;
//--- 移动点
if(!ArrowedLinePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 垂直移动第一个定位点
for(int i=0;i< v_steps;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!ArrowedLinePointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 半秒延迟
Sleep(500);
//--- 循环计数器
int h_steps=bars/2;
//--- 同时水平移动两个定位点
for(int i=0;i< h_steps ;i++)
{
//--- 使用下面的值
if(d1< bars-1)
d1+=1;
if(d2>1)
d2-=1;
//--- 切换点
if(!ArrowedLinePointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ArrowedLinePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.03 秒延迟
Sleep(30);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除箭头线
ArrowedLineDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# 2.2.1.7 OBJ_CHANNEL等距通道
ObjChannel
注意
对于等距通道线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。也可以设置颜色填充通道的模式。
示例
下面的脚本创建并移动图表上的等距通道。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Equidistant Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Channel"; // 通道名称
input int InpDate1=25; // 第1个点的日期, %
input int InpPrice1=60; // 第1个点的价格, %
input int InpDate2=65; // 第2个点的日期,%
input int InpPrice2=80; // 第2个点的价格,%
input int InpDate3=30; // 第3个点的日期, %
input int InpPrice3=40; // 第3个点的价格,%
input color InpColor=clrRed; // 通道的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 通道线的风格
input int InpWidth=2; // 通道线的宽度
input bool InpBack=false; // 背景通道
input bool InpFill=false; // 填充通道颜色
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 通道延续向左
input bool InpRayRight=false; // 通道延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建等距通道 |
//+------------------------------------------------------------------+
bool ChannelCreate(const long chart_ID=0, // 图表 ID
const string name="Channel", // 通道的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, //第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, //第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 通道的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 通道线的风格
const int width=1, // 通道线的宽度
const bool fill=false, // 填充通道颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 通道延续向左
const bool ray_right=false, // 通道延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeChannelEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建通道
if(!ObjectCreate(chart_ID,name,OBJ_CHANNEL,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create an equidistant channel! Error code = ",GetLastError());
return(false);
}
//--- 设置通道颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置通道线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置通道线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动通道的定位点 |
//+------------------------------------------------------------------+
bool ChannelPointChange(const long chart_ID=0, // 图表 ID
const string name="Channel", // 通道的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除通道 |
//+------------------------------------------------------------------+
bool ChannelDelete(const long chart_ID=0, // 图表 ID
const string name="Channel") // 通道的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除通道
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+-------------------------------------------------------------------------+
//| 检查通道定位点的值和为空点设置 |
//| 默认的值 |
//+-------------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- 如果第二点(右侧)的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点(左侧)的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则高于第二个点移动300点
if(!price1)
price1=price2+300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第一个点的时间相一致
if(!time3)
time3=time1;
//--- 如果第三个点的价格没有设置,则它与第二点的价格相等
if(!price3)
price3=price2;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100 ||
InpDate3 < 0 || InpDate3 > 100 || InpPrice3 < 0 || InpPrice3 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变通道定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i < accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制通道的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建等距通道
if(!ChannelCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],InpColor,
InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动通道定位点
//--- 循环计数器
int h_steps=bars/6;
//--- 移动第二个定位点
for(int i=0;i< h_steps;i++)
{
//--- 使用下面的值
if(d2< bars-1)
d2+=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 移动第一个定位点
for(int i=0;i< h_steps ;i++)
{
//--- 使用下面的值
if(d1>1)
d1-=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/10;
//--- 移动第三个定位点
for(int i=0;i< v_steps ;i++)
{
//--- 使用下面的值
if(p3>1)
p3-=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
ChannelDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# 2.2.1.8 OBJ_STDDEVCHANNEL标准偏差通道。
ObjStdDevChannel
注意
对于等距通道线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。也可以设置颜色填充通道的模式。
示例
下面的脚本创建并移动图表上的等距通道线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Equidistant Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Channel"; // 通道名称
input int InpDate1=25; // 第1个点的日期, %
input int InpPrice1=60; // 第1个点的价格, %
input int InpDate2=65; // 第2个点的日期,%
input int InpPrice2=80; // 第2个点的价格,%
input int InpDate3=30; // 第3个点的日期, %
input int InpPrice3=40; // 第3个点的价格,%
input color InpColor=clrRed; // 通道的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 通道线的风格
input int InpWidth=2; // 通道线的宽度
input bool InpBack=false; // 背景通道
input bool InpFill=false; // 填充通道颜色
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 通道延续向左
input bool InpRayRight=false; // 通道延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建等距通道 |
//+------------------------------------------------------------------+
bool ChannelCreate(const long chart_ID=0, // 图表 ID
const string name="Channel", // 通道的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, //第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, //第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 通道的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 通道线的风格
const int width=1, // 通道线的宽度
const bool fill=false, // 填充通道颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 通道延续向左
const bool ray_right=false, // 通道延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeChannelEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建通道
if(!ObjectCreate(chart_ID,name,OBJ_CHANNEL,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create an equidistant channel! Error code = ",GetLastError());
return(false);
}
//--- 设置通道颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置通道线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置通道线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动通道的定位点 |
//+------------------------------------------------------------------+
bool ChannelPointChange(const long chart_ID=0, // 图表 ID
const string name="Channel", // 通道的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除通道 |
//+------------------------------------------------------------------+
bool ChannelDelete(const long chart_ID=0, // 图表 ID
const string name="Channel") // 通道的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除通道
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+-------------------------------------------------------------------------+
//| 检查通道定位点的值和为空点设置 |
//| 默认的值 |
//+-------------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- 如果第二点(右侧)的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点(左侧)的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则高于第二个点移动300点
if(!price1)
price1=price2+300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第一个点的时间相一致
if(!time3)
time3=time1;
//--- 如果第三个点的价格没有设置,则它与第二点的价格相等
if(!price3)
price3=price2;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100 ||
InpDate3 < 0 || InpDate3 > 100 || InpPrice3 < 0 || InpPrice3 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变通道定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制通道的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建等距通道
if(!ChannelCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],InpColor,
InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动通道定位点
//--- 循环计数器
int h_steps=bars/6;
//--- 移动第二个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d2< bars-1)
d2+=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 移动第一个定位点
for(int i=0;i< h_steps;i++)
{
//--- 使用下面的值
if(d1>1)
d1-=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/10;
//--- 移动第三个定位点
for(int i=0;i< v_steps ;i++)
{
//--- 使用下面的值
if(p3>1)
p3-=1;
//--- 移动点
if(!ChannelPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
ChannelDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# 2.2.1.9 OBJ_REGRESSION线性回归通道
ObjRegression
注意
对线性回归通道,它可以指定延续向右和/或向左展示的模式 (OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 相应的属性)。也可以设置颜色填充通道的模式。
示例
下面的脚本创建并移动图表上的等距通道线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Linear Regression Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Regression"; // 通道名称
input int InpDate1=10; // 第1个点的日期, %
input int InpDate2=40; // 第2个点的日期, %
input color InpColor=clrRed; // 通道的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 通道线的风格
input int InpWidth=2; // 通道线的宽度
input bool InpFill=false; // 填充通道颜色
input bool InpBack=false; // 背景通道
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 通道延续向左
input bool InpRayRight=false; // 通道延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建线性回归通道 |
//+------------------------------------------------------------------+
bool RegressionCreate(const long chart_ID=0, // 图表 ID
const string name="Regression", // 通道名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
datetime time2=0, // 第二个点的时间
const color clr=clrRed, // 通道的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 通道线的风格
const int width=1, // 通道线的宽度
const bool fill=false, // 填充通道颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 通道延续到向左
const bool ray_right=false, // 通道延续到向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeRegressionEmptyPoints(time1,time2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建通道
if(!ObjectCreate(chart_ID,name,OBJ_REGRESSION,sub_window,time1,0,time2,0))
{
Print(__FUNCTION__,
": failed to create linear regression channel! Error code = ",GetLastError());
return(false);
}
//--- 设置通道颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置通道线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置通道线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动通道的定位点 |
//+------------------------------------------------------------------+
bool RegressionPointChange(const long chart_ID=0, //图表 ID
const string name="Channel", // 通道名称
const int point_index=0, // 定位点指数
datetime time=0) // 定位点时间坐标
{
//--- 如果没有设置点的时间,将点移动到当前柱
if(!time)
time=TimeCurrent();
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,0))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除通道 |
//+------------------------------------------------------------------+
bool RegressionDelete(const long chart_ID=0, // 图表 ID
const string name="Channel") // 通道名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除通道
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+-------------------------------------------------------------------------+
//| 检查通道定位点的值和为空点设置 |
//| 默认的值 |
//+-------------------------------------------------------------------------+
void ChangeRegressionEmptyPoints(datetime &time1,datetime &time2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 ||
InpDate2 < 0 || InpDate2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变通道定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制通道的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
//--- 创建线性回归通道
if(!RegressionCreate(0,InpName,0,date[d1],date[d2],InpColor,InpStyle,InpWidth,
InpFill,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,水平向右移动通道
//--- 循环计数器
int h_steps=bars/2;
//--- 移动通道
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d1<bars-1)
d1+=1;
if(d2<bars-1)
d2+=1;
//--- 移动定位点
if(!RegressionPointChange(0,InpName,0,date[d1]))
return;
if(!RegressionPointChange(0,InpName,1,date[d2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
RegressionDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# 2.2.1.10 OBJ_PITCHFORK安德鲁鱼叉线
ObjPitchfork
注意
对于安德鲁鱼叉线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
您也可以指定线的级别数,它们的值和颜色。
示例
下面的脚本创建并移动图表上的安德鲁鱼叉线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Andrews’ Pitchfork\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Pitchfork"; // 鱼叉名称
input int InpDate1=14; // 第1个点的日期, %
input int InpPrice1=40; // 第1个点的价格, %
input int InpDate2=18; // 第2个点的日期, %
input int InpPrice2=50; // 第2个点的价格, %
input int InpDate3=18; // 第3个点的日期, %
input int InpPrice3=30; // 第3个点的价格, %
input color InpColor=clrRed; // 鱼叉颜色
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 鱼叉线的风格
input int InpWidth=1; // 鱼叉线的宽度
input bool InpBack=false; // 背景鱼叉线
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 鱼叉线延续向左
input bool InpRayRight=false; // 鱼叉线延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建安德鲁鱼叉线 |
//+------------------------------------------------------------------+
bool PitchforkCreate(const long chart_ID=0, // 图表 ID
const string name="Pitchfork", // 鱼叉线名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, // 第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 鱼叉线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 鱼叉线的风格
const int width=1, // 鱼叉线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 鱼叉线延续向左
const bool ray_right=false, // 鱼叉线延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeChannelEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建安德鲁鱼叉线
if(!ObjectCreate(chart_ID,name,OBJ_PITCHFORK,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create \"Andrews' Pitchfork\"! Error code = ",GetLastError());
return(false);
}
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//---设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出鱼叉线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示鱼叉线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示鱼叉线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置安德鲁鱼叉线水平的数量和参数 |
//+------------------------------------------------------------------+
bool PitchforkLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="Pitchfork") // 鱼叉线的名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i< levels ;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动安德鲁鱼叉线的定位点 |
//+------------------------------------------------------------------+
bool PitchforkPointChange(const long chart_ID=0, // 图表 ID
const string name="Pitchfork", // 通道的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除安德鲁鱼叉线 |
//+------------------------------------------------------------------+
bool PitchforkDelete(const long chart_ID=0, // 图表 ID
const string name="Pitchfork") // 通道的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除通道
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Andrews' Pitchfork\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+----------------------------------------------------------------------+
//| 检查安德鲁鱼叉线定位点的值和为空点设置 |
//| 默认的值 |
//+----------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- 如果第二点(右上侧)的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点(左侧)的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则低于第二个点移动200点
if(!price1)
price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第二个点的时间相一致
if(!time3)
time3=time2;
//---如果第三个点的价格没有设置,则低于第一个点移动200点
if(!price3)
price3=price1-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100 ||
InpDate3 < 0 || InpDate3 > 100 || InpPrice3 < 0 || InpPrice3 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变安德鲁鱼叉线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制安德鲁鱼叉线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建安德鲁鱼叉线
if(!PitchforkCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动鱼叉线定位点
//--- 循环计数器
int v_steps=accuracy/10;
//--- 移动第一个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!PitchforkPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars/8;
//--- 移动第三个定位点
for(int i=0;i<h_steps ;i++)
{
//--- 使用下面的值
if(d3<bars-1)
d3+=1;
//--- 移动点
if(!PitchforkPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy/10;
//--- 移动第二个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p2>1)
p2-=1;
//--- 移动点
if(!PitchforkPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表鱼叉线
PitchforkDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# 2.2.1.11 OBJ_GANNLINE江恩线
ObjPitchfork
注意
对于江恩线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
//--- 描述
#property description "Script draws \"Gann Line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="GannLine"; // 线的名称
input int InpDate1=20; // 第1个点的日期,%
input int InpPrice1=75; // 第1个点的价格, %
input int InpDate2=80; // 第2个点的日期,%
input double InpAngle=0.0; // 江恩角度线
input double InpScale=1.0; // 比例
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景线
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 线延续向左
input bool InpRayRight=true; // 线延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标,角度和比例创建江恩线 |
//+------------------------------------------------------------------+
bool GannLineCreate(const long chart_ID=0, // 图表 ID
const string name="GannLine", // 线的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
const double angle=1.0, // 江恩角度线
const double scale=1.0, // 比例
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 线延续向左
const bool ray_right=true, // 线延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeGannLineEmptyPoints(time1,price1,time2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建江恩线
//--- 第二定位点的正确坐标被重新定义
//--- 江恩角度线和/或比例自动更改后,
if(!ObjectCreate(chart_ID,name,OBJ_GANNLINE,sub_window,time1,price1,time2,0))
{
Print(__FUNCTION__,
": failed to create \"Gann Line\"! Error code = ",GetLastError());
return(false);
}
//--- 改变江恩角度线
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- 改变比例 (每柱的点数)
ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale);
//--- 设置线的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示线的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动江恩线定位点 |
//+------------------------------------------------------------------+
bool GannLinePointChange(const long chart_ID=0, // 图表 ID
const string name="GannLine", // 线的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动线的定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩角度线 |
//+------------------------------------------------------------------+
bool GannLineAngleChange(const long chart_ID=0, // 图表 ID
const string name="GannLine", // 线的名称
const double angle=1.0) // 江恩角度线
{
//--- 重置错误的值
ResetLastError();
//--- 改变江恩角度线
if(!ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle))
{
Print(__FUNCTION__,
": failed to change Gann angle! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩线的比例 |
//+------------------------------------------------------------------+
bool GannLineScaleChange(const long chart_ID=0, // 图表 ID
const string name="GannLine", // 线的名称
const double scale=1.0) // 比例
{
//--- 重置错误的值
ResetLastError();
//--- 改变比例 (每柱的点数)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数移除图表江恩线 |
//+------------------------------------------------------------------+
bool GannLineDelete(const long chart_ID=0, // 图表 ID
const string name="GannLine") // 线的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除江恩线。
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Line\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查江恩线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeGannLineEmptyPoints(datetime &time1,double &price1,datetime &time2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变线定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制江恩线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- 创建江恩线
if(!GannLineCreate(0,InpName,0,date[d1],price[p1],date[d2],InpAngle,InpScale,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动线的定位点和改变角度
//--- 循环计数器
int v_steps=accuracy/2;
//--- 垂直移动第一个定位点
for(int i=0;i< v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!GannLinePointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 半秒延迟
Sleep(500);
//--- 定义江恩角度线的当前值(已变化
//--- 当移动第一个定位点以后)
double curr_angle;
if(!ObjectGetDouble(0,InpName,OBJPROP_ANGLE,0,curr_angle))
return;
//--- 循环计数器
v_steps=accuracy/8;
//--- 改变江恩角度线
for(int i=0;i< v_steps ;i++)
{
if(!GannLineAngleChange(0,InpName,curr_angle-0.05*i))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表线
GannLineDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# 2.2.1.12 OBJ_GANNFAN江恩扇形线
ObjGannFan
注意
对于江恩扇形线,可以指定 ENUM_GANN_DIRECTION 枚举的趋势类型。通过调整比例值 (OBJPROP_SCALE),可以改变扇形线的倾斜角。
示例
下面的脚本创建并移动图表上的江恩扇形线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Gann Fan\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="GannFan"; // 扇形线名称
input int InpDate1=15; // 第1个点的日期,%
input int InpPrice1=25; // 第1个点的价格,%
input int InpDate2=85; // 第2个点的日期,%
input double InpScale=2.0; // 比例
input bool InpDirection=false; // 趋势方向
input color InpColor=clrRed; // 扇形线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 扇形线的风格
input int InpWidth=1; // 扇形线的宽度
input bool InpBack=false; // 背景扇形线
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建江恩扇形线 |
//+------------------------------------------------------------------+
bool GannFanCreate(const long chart_ID=0, // 图表 ID
const string name="GannFan", // 扇形线的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, //第一个点的价格
datetime time2=0, // 第二个点的时间
const double scale=1.0, // 比例
const bool direction=true, // 趋势方向
const color clr=clrRed, // 扇形线颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 扇形线的风格
const int width=1, // 扇形线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeGannFanEmptyPoints(time1,price1,time2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建江恩扇形线
if(!ObjectCreate(chart_ID,name,OBJ_GANNFAN,sub_window,time1,price1,time2,0))
{
Print(__FUNCTION__,
": failed to create \"Gann Fan\"! Error code = ",GetLastError());
return(false);
}
//--- 改变比例 (每柱的点数)
ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale);
//--- 改变江恩扇形线趋势方向(true - 下降,false - 上升)
ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction);
//--- 设置扇形线颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置扇形线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置扇形线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出扇形线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动江恩扇形线定位点 |
//+------------------------------------------------------------------+
bool GannFanPointChange(const long chart_ID=0, // 图表 ID
const string name="GannFan", // 扇形线的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动扇形线的定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩扇形线的比例 |
//+------------------------------------------------------------------+
bool GannFanScaleChange(const long chart_ID=0, // 图表 ID
const string name="GannFan", // 扇形线的名称
const double scale=1.0) // scale
{
//--- 重置错误的值
ResetLastError();
//--- 改变比例 (每柱的点数)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩扇形线的趋势方向 |
//+------------------------------------------------------------------+
bool GannFanDirectionChange(const long chart_ID=0, // 图表 ID
const string name="GannFan", // 扇形线的名称
const bool direction=true) // 趋势方向
{
//--- 重置错误的值
ResetLastError();
//--- 改变江恩扇形线的趋势方向
if(!ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction))
{
Print(__FUNCTION__,
": failed to change trend direction! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数移除图表的江恩扇形线 |
//+------------------------------------------------------------------+
bool GannFanDelete(const long chart_ID=0, // 图表 ID
const string name="GannFan") // 扇形线的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除江恩扇形线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Fan\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查江恩扇形线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeGannFanEmptyPoints(datetime &time1,double &price1,datetime &time2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变扇形线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制江恩扇形线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- 创建江恩扇形线
if(!GannFanCreate(0,InpName,0,date[d1],price[p1],date[d2],InpScale,InpDirection,
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动扇形线的定位点
//--- 循环计数器
int v_steps=accuracy/2;
//--- 垂直移动第一个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
//--- 移动点
if(!GannFanPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变扇形线的趋势方向降一级
GannFanDirectionChange(0,InpName,true);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表扇形线
GannFanDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# 2.2.1.13 OBJ_GANNGRID江恩网格
ObjGannGrid
注意
对于江恩网格,可以从 ENUM_GANN_DIRECTION指定趋势类型。通过调整比例值(OBJPROP_SCALE),可以改变网格线的倾斜角。
示例
下面的脚本创建并移动图表上的江恩网格。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Gann Grid\" graphical object."
#property description "Anchor point coordinates of the grid are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="GannGrid"; // 网格名称
input int InpDate1=15; // 第1个点的日期,%
input int InpPrice1=25; // 第1个点的价格,%
input int InpDate2=35; // 第2个点的日期,%
input double InpScale=3.0; // 比例
input bool InpDirection=false; // 趋势方向
input color InpColor=clrRed; // 网格颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 网格线的风格
input int InpWidth=1; // 扇形线的宽度
input bool InpBack=false; // 背景网格
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建江恩网格 |
//+------------------------------------------------------------------+
bool GannGridCreate(const long chart_ID=0, // 图表ID
const string name="GannGrid", // 网格的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
const double scale=1.0, // 比例
const bool direction=true, // 趋势方向
const color clr=clrRed, // 网格颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 网格线的风格
const int width=1, // 网格线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeGannGridEmptyPoints(time1,price1,time2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建江恩网格
if(!ObjectCreate(chart_ID,name,OBJ_GANNGRID,sub_window,time1,price1,time2,0))
{
Print(__FUNCTION__,
": failed to create \"Gann Grid\"! Error code = ",GetLastError());
return(false);
}
//--- 改变比例 (每柱的点数)
ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale);
//--- 改变江恩扇形线趋势方向(true - 下降,false - 上升)
ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction);
//--- 设置网格颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置网格线的显示风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置网格线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出网格线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动江恩网格定位点 |
//+------------------------------------------------------------------+
bool GannGridPointChange(const long chart_ID=0, // 图表 ID
const string name="GannGrid", // 网格的名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动网格的定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩网格的比例 |
//+------------------------------------------------------------------+
bool GannGridScaleChange(const long chart_ID=0, // 图表 ID
const string name="GannGrid", // 网格
const double scale=1.0) // 比例
{
//--- 重置错误的值
ResetLastError();
//--- 改变比例 (每柱的点数)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变江恩网格线的趋势方向 |
//+------------------------------------------------------------------+
bool GannGridDirectionChange(const long chart_ID=0, // 图表 ID
const string name="GannGrid", // 网格的名称
const bool direction=true) // 趋势方向
{
//--- 重置错误的值
ResetLastError();
//--- 改变江恩网格线的趋势方向
if(!ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction))
{
Print(__FUNCTION__,
": failed to change trend direction! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 这个函数移除图表的江恩扇形线 |
//+------------------------------------------------------------------+
bool GannGridDelete(const long chart_ID=0, // 图表 ID
const string name="GannGrid") // 网格的名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除江恩网格
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Grid\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查江恩网格线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeGannGridEmptyPoints(datetime &time1,double &price1,datetime &time2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变网格定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制江恩网格线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- 创建江恩网格
if(!GannGridCreate(0,InpName,0,date[d1],price[p1],date[d2],InpScale,InpDirection,
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- now, move the grid's anchor points
//--- 循环计数器
int v_steps=accuracy/4;
//--- 垂直移动第一个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
if(!GannGridPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars/4;
//---水平移动第二个定位点
for(int i=0;i< h_steps;i++)
{
//--- 使用下面的值
if(d2<bars-1)
d2+=1;
if(!GannGridPointChange(0,InpName,1,date[d2],0))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变网格线的趋势方向降一级
GannGridDirectionChange(0,InpName,true);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表网格
GannGridDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# 2.2.1.14 OBJ_FIBO斐波纳契回调线
ObjFiboLevels
注意
对于斐波纳契回调线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
您也可以指定线的级别数,它们的值和颜色。
示例
下面的脚本创建并移动图表上的斐波纳契回调线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Retracement\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboLevels"; // 对象名称
input int InpDate1=10; // 第1个点的日期,%
input int InpPrice1=65; // 第1个点的价格,%
input int InpDate2=90; // 第2个点的日期,%
input int InpPrice2=85; // 第2个点的价格,%
input color InpColor=clrRed; // 对象的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 对象延续向左
input bool InpRayRight=false; // 对象延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契回调线 |
//+------------------------------------------------------------------+
bool FiboLevelsCreate(const long chart_ID=0, // 图表 ID
const string name="FiboLevels", // 对象名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 对象颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 对象线的风格
const int width=1, // 对象线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 对象持续向左
const bool ray_right=false, // 对象持续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboLevelsEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 用给定的坐标创建斐波纳契回调线
if(!ObjectCreate(chart_ID,name,OBJ_FIBO,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Retracement\"! Error code = ",GetLastError());
return(false);
}
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示对象的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示对象的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表ID
const string name="FiboLevels") // 对象名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契回调线的定位点 |
//+------------------------------------------------------------------+
bool FiboLevelsPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboLevels", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除斐波纳契回调线 |
//+------------------------------------------------------------------+
bool FiboLevelsDelete(const long chart_ID=0, // 图表 ID
const string name="FiboLevels") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Retracement\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契回调线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboLevelsEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则低于第二个点移动200点
if(!price1)
price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变斐波纳契回调线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制斐波纳契回调线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建对象
if(!FiboLevelsCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy*2/5;
//--- 移动第一个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!FiboLevelsPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy*4/5;
//--- 移动第二个定位点
for(int i=0;i< v_steps;i++)
{
//--- 使用下面的值
if(p2>1)
p2-=1;
//--- 移动点
if(!FiboLevelsPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
FiboLevelsDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# 2.2.1.15 OBJ_FIBOTIMES斐波纳契(黄金分割)时间周期线
ObjFiboTimes
注意
对于 "斐波纳契时间周期线",可以指定线水平的数量,它们的值和颜色。
示例
下面的脚本创建并移动图表上的斐波纳契时间周期线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Time Zones\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboTimes"; // 对象名称
input int InpDate1=10; // 第1个点的日期,%
input int InpPrice1=45; // 第1个点的价格,%
input int InpDate2=20; // 第2个点的日期,%
input int InpPrice2=55; // 第2个点的价格,%
input color InpColor=clrRed; // 对象的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契时间周期线 |
//+------------------------------------------------------------------+
bool FiboTimesCreate(const long chart_ID=0, // 图表 ID
const string name="FiboTimes", // 对象名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 对象颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 对象线的风格
const int width=1, // 对象线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboTimesEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建斐波纳契时间周期线
if(!ObjectCreate(chart_ID,name,OBJ_FIBOTIMES,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Time Zones\"! Error code = ",GetLastError());
return(false);
}
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboTimesLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="FiboTimes") // 对象名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels ;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契时间周期线的定位点 |
//+------------------------------------------------------------------+
bool FiboTimesPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboTimes", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除斐波纳契时间周期线 |
//+------------------------------------------------------------------+
bool FiboTimesDelete(const long chart_ID=0, // 图表 ID
const string name="FiboTimes") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Time Zones\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契时间周期线定位点的值和 |
//| 为空点设置默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboTimesEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的2个柱
if(!time2)
{
//--- 接收最近3柱开盘时间的数组
datetime temp[3];
CopyTime(Symbol(),Period(),time1,3,temp);
//--- 在第二点左侧2柱设置第一点
time2=temp[0];
}
//--- 如果第二点的价格没有设置,则它与第一点的价格相等
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变斐波纳契时间周期线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制斐波纳契时间周期线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建对象
if(!FiboTimesCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int h_steps=bars*2/5;
//--- 移动第二个定位点
for(int i=0;i< h_steps;i++)
{
//--- 使用下面的值
if(d2< bars-1)
d2+=1;
//--- 移动点
if(!FiboTimesPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
h_steps=bars*3/5;
//--- 移动第一个定位点
for(int i=0;i<h_steps ;i++)
{
//--- 使用下面的值
if(d1< bars-1)
d1+=1;
//--- 移动点
if(!FiboTimesPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
FiboTimesDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# 2.2.1.16 OBJ_FIBOFAN斐波纳契(黄金分割)扇形线
ObjFiboFan
注意
对于"斐波纳契扇形线",可以指定线水平的数量,它们的值和颜色
示例
下面的脚本创建并移动图表上的斐波纳契扇形线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Fan\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboFan"; // 扇形线名称
input int InpDate1=10; // 第1个点的日期,%
input int InpPrice1=25; // 第1个点的价格,%
input int InpDate2=30; // 第2个点的日期,%
input int InpPrice2=50; // 第2个点的价格,%
input color InpColor=clrRed; // 扇形线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契扇形线 |
//+------------------------------------------------------------------+
bool FiboFanCreate(const long chart_ID=0, // 图表ID
const string name="FiboFan", // 扇形线名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, //第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 扇形线颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 扇形线的风格
const int width=1, // 扇形线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboFanEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建斐波纳契扇形线
if(!ObjectCreate(chart_ID,name,OBJ_FIBOFAN,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Fan\"! Error code = ",GetLastError());
return(false);
}
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出扇形线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboFanLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="FiboFan") // 扇形线名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels ;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契扇形线定位点 |
//+------------------------------------------------------------------+
bool FiboFanPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboFan", // 扇形线名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除斐波纳契扇形线 |
//+------------------------------------------------------------------+
bool FiboFanDelete(const long chart_ID=0, // 图表 ID
const string name="FiboFan") // 扇形线名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除扇形线
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Fan\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契扇形线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboFanEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则低于第二个点移动200点
if(!price1)
price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1 < 0 || InpDate1 > 100 || InpPrice1 < 0 || InpPrice1 > 100 ||
InpDate2 < 0 || InpDate2 > 100 || InpPrice2 < 0 || InpPrice2 > 100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变斐波纳契扇形线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制斐波纳契扇形线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建对象
if(!FiboFanCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动扇形线的定位点
//--- 循环计数器
int v_steps=accuracy/2;
//--- 移动第一个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
//--- 移动点
if(!FiboFanPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars/4;
//--- 移动第二个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d2<bars-1)
d2+=1;
//--- 移动点
if(!FiboFanPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
FiboFanDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# 2.2.1.17 OBJ_FIBOARC斐波纳契(黄金分割)弧形线
ObjFiboArc
注意
对于 "斐波纳契弧形线",可以指定整个椭圆的演示模式。曲率半径可以通过改变定位点比例和坐标来指定。
您也可以指定线的级别数,它们的值和颜色。
示例
下面的脚本创建并移动图表上的斐波纳契弧形线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Arcs\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboArc"; // 对象名称
input int InpDate1=25; // 第1个点的日期,%
input int InpPrice1=25; // 第1个点的价格,%
input int InpDate2=35; // 第2个点的日期,%
input int InpPrice2=55; // 第2个点的价格,%
input double InpScale=3.0; // 比例
input bool InpFullEllipse=true; // 弧形线的形状
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契弧形线 |
//+------------------------------------------------------------------+
bool FiboArcCreate(const long chart_ID=0, // 图表 ID
const string name="FiboArc", // 对象名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const double scale=1.0, // 比例
const bool full_ellipse=false, // 弧形线的形状
const color clr=clrRed, // 线的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboArcEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建斐波纳契弧形线
if(!ObjectCreate(chart_ID,name,OBJ_FIBOARC,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Arcs\"! Error code = ",GetLastError());
return(false);
}
//--- 设置比例
ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale);
//--- 设置弧形线显示为全椭圆(true) 或半椭圆(false)
ObjectSetInteger(chart_ID,name,OBJPROP_ELLIPSE,full_ellipse);
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出弧形线移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboArcLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="FiboArc") // 对象名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契弧形线的定位点 |
//+------------------------------------------------------------------+
bool FiboArcPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboArc", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除斐波纳契弧形线 |
//+------------------------------------------------------------------+
bool FiboArcDelete(const long chart_ID=0, // 图表 ID
const string name="FiboArc") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Arcs\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契弧形线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboArcEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第二点的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则低于第二个点移动300点
if(!price1)
price1=price2-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变斐波纳契弧形线的定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制斐波纳契弧形线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建对象
if(!FiboArcCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpScale,
InpFullEllipse,InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 移动第一个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
//--- 移动点
if(!FiboArcPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars/5;
//--- 移动第二个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d2<bars-1)
d2+=1;
//--- 移动点
if(!FiboArcPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
FiboArcDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# 2.2.1.18 OBJ_FIBOCHANNEL斐波纳契(黄金分割)通道线
ObjFiboChannel
注意
对于斐波纳契通道线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
您也可以指定线的级别数,它们的值和颜色。
示例
下面的脚本创建和移动图表上的斐波纳契通道线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboChannel"; // 通道名称
input int InpDate1=20; // 第1个点的日期,%
input int InpPrice1=10; // 第1个点的价格,%
input int InpDate2=60; // 第2个点的日期,%
input int InpPrice2=30; // 第2个点的价格,%
input int InpDate3=20; // 第3个点的日期,%
input int InpPrice3=25; // 第3个点的价格,%
input color InpColor=clrRed; // 通道的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 通道线的风格
input int InpWidth=2; // 通道线的宽度
input bool InpBack=false; // 背景通道
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 通道延续向左
input bool InpRayRight=false; // 通道延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契通道线 |
//+------------------------------------------------------------------+
bool FiboChannelCreate(const long chart_ID=0, // 图表 ID
const string name="FiboChannel", // 通道名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, // 第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 通道的颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 通道线的风格
const int width=1, // 通道线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 通道延续向左
const bool ray_right=false, // 通道延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboChannelEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建通道
if(!ObjectCreate(chart_ID,name,OBJ_FIBOCHANNEL,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Channel\"! Error code = ",GetLastError());
return(false);
}
//--- 设置通道颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置通道线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置通道线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右显示通道的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboChannelLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="FiboChannel") // 对象名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels ;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契通道线的定位点 |
//+------------------------------------------------------------------+
bool FiboChannelPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboChannel", // 通道名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除通道 |
//+------------------------------------------------------------------+
bool FiboChannelDelete(const long chart_ID=0, // 图表 ID
const string name="FiboChannel") // 通道名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除通道
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Channel\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契通道定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- 如果第二点(右侧)的时间没有设置,它将位于当前柱
if(!time2)
time2=TimeCurrent();
//--- 如果第二点的价格没有设置,则它将用卖价值
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点(左侧)的时间没有设置,它则位于第二点左侧的9个柱
if(!time1)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一个点的价格没有设置,则高于第二个点移动300点
if(!price1)
price1=price2+300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第一个点的时间相一致
if(!time3)
time3=time1;
//--- 如果第三个点的价格没有设置,则它与第二点的价格相等
if(!price3)
price3=price2;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变通道定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制通道的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建斐波纳契通道
if(!FiboChannelCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动通道定位点
//--- 循环计数器
int h_steps=bars/10;
//--- 移动第一个定位点
for(int i=0;i<h_steps ;i++)
{
//--- 使用下面的值
if(d1>1)
d1-=1;
//--- 移动点
if(!FiboChannelPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/10;
//--- 移动第二个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p2>1)
p2-=1;
//--- 移动点
if(!FiboChannelPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy/15;
//--- 移动第三个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p3<accuracy-1)
p3+=1;
//--- 移动点
if(!FiboChannelPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
FiboChannelDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# 2.2.1.19 OBJ_EXPANSION斐波纳契(黄金分割)扩展线
ObjFiboExpansion
注意
对于斐波纳契扩展线,可以指定它 向右 和/或 向左 延长显示的模式 (根据属性值OBJPROP_RAY_RIGHT 和 OBJPROP_RAY_LEFT 决定)。
您也可以指定线的级别数,它们的值和颜色。
示例
下面的脚本创建和移动图表上的斐波纳契扩展线。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Fibonacci Expansion\"graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="FiboExpansion"; // 对象名称
input int InpDate1=10; // 第1个点的日期,%
input int InpPrice1=55; // 第1个点的价格,%
input int InpDate2=30; // 第2个点的日期,%
input int InpPrice2=10; // 第2个点的价格,%
input int InpDate3=80; // 第3个点的日期,%
input int InpPrice3=75; // 第3个点的价格,%
input color InpColor=clrRed; // 对象的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpRayLeft=false; // 对象延续向左
input bool InpRayRight=false; // 对象延续向右
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建斐波纳契扩展线 |
//+------------------------------------------------------------------+
bool FiboExpansionCreate(const long chart_ID=0, // 图表 ID
const string name="FiboExpansion", // 通道的名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, // 第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 对象颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool ray_left=false, // 对象延续向左
const bool ray_right=false, // 对象延续向右
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeFiboExpansionEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建斐波纳契扩展线
if(!ObjectCreate(chart_ID,name,OBJ_EXPANSION,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create \"Fibonacci Extension\"! Error code = ",GetLastError());
return(false);
}
//--- 设置对象的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//---设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 启用 (true) 或禁用 (false) 延续向左的对象可视化的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- 启用 (true) 或禁用 (false) 延续向右的对象可视化的模式
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置水平的数量和参数 |
//+------------------------------------------------------------------+
bool FiboExpansionLevelsSet(int levels, // 水平线的数量
double &values[], // 水平线的值
color &colors[], // 水平线的颜色
ENUM_LINE_STYLE &styles[], // 水平线的风格
int &widths[], // 水平线的宽度
const long chart_ID=0, // 图表 ID
const string name="FiboExpansion") // 对象名称
{
//--- 检查数组大小
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- 设置水平数量
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- 设置循环中水平的属性
for(int i=0;i<levels ;i++)
{
//--- 水平的值
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- 水平的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- 水平的风格
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- 水平的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- 水平的描述
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,"FE "+DoubleToString(100*values[i],1));
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动斐波纳契扩展线的定位点 |
//+------------------------------------------------------------------+
bool FiboExpansionPointChange(const long chart_ID=0, // 图表 ID
const string name="FiboExpansion", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除斐波纳契扩展线 |
//+------------------------------------------------------------------+
bool FiboExpansionDelete(const long chart_ID=0, // 图表 ID
const string name="FiboExpansion") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Expansion\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查斐波纳契扩展线定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeFiboExpansionEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- 如果第三点(右侧)的时间没有设置,它将位于当前柱
if(!time3)
time3=TimeCurrent();
//--- 如果第三点的价格没有设置,则它将用卖价值
if(!price3)
price3=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第一点(左侧)的时间没有设置,它则位于第三点左侧的9个柱
//--- 接收最近10柱开盘时间的数组
datetime temp[];
ArrayResize(temp,10);
if(!time1)
{
CopyTime(Symbol(),Period(),time3,10,temp);
//--- 在第二点左侧9柱设置第一点
time1=temp[0];
}
//--- 如果第一点的价格没有设置,则它与第三点的价格相等
if(!price1)
price1=price3;
//--- 如果第二点的时间没有设置,它则位于第三点左侧的7个柱
if(!time2)
time2=temp[2];
//--- 如果第二个点的价格没有设置,则低于第一个点移动250点
if(!price2)
price2=price1-250*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变对象定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i< accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制斐波纳契扩展线的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建斐波纳契扩展线
if(!FiboExpansionCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy/10;
//--- 移动第一个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!FiboExpansionPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy/2;
//--- 移动第三个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p3>1)
p3-=1;
//--- 移动点
if(!FiboExpansionPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy*4/5;
//--- 移动第二个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p2<accuracy-1)
p2+=1;
//--- 移动点
if(!FiboExpansionPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
FiboExpansionDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# 2.2.1.20 OBJ_ELLIOTWAVE5艾略特驱动浪
ObjElliotWave5
注意
对于江恩网格,可以从 ENUM_GANN_DIRECTION指定趋势类型。通过调整比例值(OBJPROP_SCALE),可以改变网格线的倾斜角。
示例
下面的脚本创建和移动图表上的艾略特波浪驱动浪。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Elliott Motive Wave\"."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ElliotWave5"; // 对象名称
input int InpDate1=10; // 第1个点的日期, %
input int InpPrice1=90; // 第1个点的价格,%
input int InpDate2=20; // 第2个点的日期,%
input int InpPrice2=40; // 第2个点的价格,%
input int InpDate3=30; // 第3个点的日期,%
input int InpPrice3=60; // 第3个点的价格,%
input int InpDate4=40; // 第4个点的日期,%
input int InpPrice4=10; // 第4个点的价格,%
input int InpDate5=60; // 第5个点的日期,%
input int InpPrice5=40; // 第5个点的价格,%
input ENUM_ELLIOT_WAVE_DEGREE InpDegree=ELLIOTT_MINOR; // 水平
input bool InpDrawLines=true; // 显示线
input color InpColor=clrRed; // 线的颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 线的风格
input int InpWidth=2; // 线的宽度
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建“艾略特波浪动力” |
//+------------------------------------------------------------------+
bool ElliotWave5Create(const long chart_ID=0, // 图表 ID
const string name="ElliotWave5", // 波浪名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, // 第三个点的时间
double price3=0, // 第三个点的价格
datetime time4=0, // 第四个点的时间
double price4=0, // 第四个点的价格
datetime time5=0, // 第五个点的时间
double price5=0, // 第五个点的价格
const ENUM_ELLIOT_WAVE_DEGREE degree=ELLIOTT_MINUETTE, // 度数
const bool draw_lines=true, // 显示线
const color clr=clrRed, // 对象颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线的风格
const int width=1, // 线的宽度
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeElliotWave5EmptyPoints(time1,price1,time2,price2,time3,price3,time4,price4,time5,price5);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建“艾略特波浪动力”
if(!ObjectCreate(chart_ID,name,OBJ_ELLIOTWAVE5,sub_window,time1,price1,time2,price2,time3,
price3,time4,price4,time5,price5))
{
Print(__FUNCTION__,
": failed to create \"Elliott Motive Wave\"! Error code = ",GetLastError());
return(false);
}
//--- 设置程度(波动大小)
ObjectSetInteger(chart_ID,name,OBJPROP_DEGREE,degree);
//--- 启用 (true) 或禁用 (false) 展示线型的模式
ObjectSetInteger(chart_ID,name,OBJPROP_DRAWLINES,draw_lines);
//--- 设置对象的颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//---设置线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出通道移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动艾略特波浪动力定位点 |
//+------------------------------------------------------------------+
bool ElliotWave5PointChange(const long chart_ID=0, // 图表 ID
const string name="ElliotWave5", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除艾略特波浪动力 |
//+------------------------------------------------------------------+
bool ElliotWave5Delete(const long chart_ID=0, // 图表 ID
const string name="ElliotWave5") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Elliott Motive Wave\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查艾略特波浪动力定位点的值和 |
//| 为空点设置默认的值 |
//+------------------------------------------------------------------+
void ChangeElliotWave5EmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3,
datetime &time4,double &price4,
datetime &time5,double &price5)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[];
ArrayResize(temp,10);
//--- 接收数据
CopyTime(Symbol(),Period(),TimeCurrent(),10,temp);
//--- 接收当前图表一点的值
double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第一点的时间没有设置,它则位于最后柱左侧的9个柱
if(!time1)
time1=temp[0];
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于最后柱左侧的7个柱
if(!time2)
time2=temp[2];
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*point;
//--- 如果第三点的时间没有设置,它则位于最后柱左侧的5个柱
if(!time3)
time3=temp[4];
//--- 如果第三个点的价格没有设置,则低于第一个点移动250点
if(!price3)
price3=price1-250*point;
//--- 如果第四点的时间没有设置,它则位于最后柱左侧的3个柱
if(!time4)
time4=temp[6];
//--- 如果第四个点的价格没有设置,则低于第一个点移动550点
if(!price4)
price4=price1-550*point;
//--- 如果第四点的时间没有设置,它将位于最后的柱
if(!time5)
time5=temp[9];
//--- 如果第五个点的价格没有设置,则低于第一个点移动450点
if(!price5)
price5=price1-450*point;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100 ||
InpDate4<0 || InpDate4>100 || InpPrice4<0 || InpPrice4>100 ||
InpDate5<0 || InpDate5>100 || InpPrice5<0 || InpPrice5>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变对象定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制艾略特波浪动力的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int d4=InpDate4*(bars-1)/100;
int d5=InpDate5*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
int p4=InpPrice4*(accuracy-1)/100;
int p5=InpPrice5*(accuracy-1)/100;
//--- 创建艾略特波浪动力
if(!ElliotWave5Create(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
date[d4],price[p4],date[d5],price[p5],InpDegree,InpDrawLines,InpColor,InpStyle,InpWidth,
InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 移动第五个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p5<accuracy-1)
p5+=1;
//--- 移动点
if(!ElliotWave5PointChange(0,InpName,4,date[d5],price[p5]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy/5;
//--- 移动第二个和第三个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p2<accuracy-1)
p2+=1;
if(p3>1)
p3-=1;
//--- 切换点
if(!ElliotWave5PointChange(0,InpName,1,date[d2],price[p2]))
return;
if(!ElliotWave5PointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy*4/5;
//--- 移动第一个和第四个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
if(p4<accuracy-1)
p4+=1;
//--- 切换点
if(!ElliotWave5PointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ElliotWave5PointChange(0,InpName,3,date[d4],price[p4]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
ElliotWave5Delete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# 2.2.1.21 OBJ_ELLIOTWAVE3艾略特调整浪
ObjElliotWave3
注意
对于"艾略特调整浪",可以启用/禁用通过线连接点的模式 (OBJPROP_DRAWLINES 属性),以及设置波浪定位的水平(从 ENUM_ELLIOT_WAVE_DEGREE 枚举)。
示例
下面的脚本创建和移动图表上的艾略特调整浪。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动埃利奥特纠正波定位点 |
//+------------------------------------------------------------------+
bool ElliotWave3PointChange(const long chart_ID=0, // 图表 ID
const string name="ElliotWave3", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除埃利奥特纠正波 |
//+------------------------------------------------------------------+
bool ElliotWave3Delete(const long chart_ID=0, // 图表ID
const string name="ElliotWave3") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Elliott Correction Wave\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查埃利奥特纠正波定位点的值和 |
//| 为空点设置默认的值 |
//+------------------------------------------------------------------+
void ChangeElliotWave3EmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[];
ArrayResize(temp,10);
//--- 接收数据
CopyTime(Symbol(),Period(),TimeCurrent(),10,temp);
//--- 接收当前图表一点的值
double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第一点的时间没有设置,它则位于最后柱左侧的9个柱
if(!time1)
time1=temp[0];
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于最后柱左侧的5个柱
if(!time2)
time2=temp[4];
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*point;
//--- 如果第三点的时间没有设置,它则位于最后柱左侧的1个柱
if(!time3)
time3=temp[8];
//---如果第三个点的价格没有设置,则低于第一个点移动200点
if(!price3)
price3=price1-200*point;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变对象定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制埃利奥特纠正波的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建埃利奥特纠正波
if(!ElliotWave3Create(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpDegree,InpDrawLines,InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 移动第三个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p3<accuracy-1)
p3+=1;
//--- 移动点
if(!ElliotWave3PointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy*4/5;
//--- 移动第一个和第二个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
if(p2<accuracy-1)
p2+=1;
//--- 切换点
if(!ElliotWave3PointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ElliotWave3PointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
ElliotWave3Delete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 2.2.1.21 OBJ_ELLIOTWAVE3艾略特调整浪
ObjElliotWave3
注意
对于"艾略特调整浪",可以启用/禁用通过线连接点的模式 (OBJPROP_DRAWLINES 属性),以及设置波浪定位的水平(从 ENUM_ELLIOT_WAVE_DEGREE 枚举)。
示例
ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动埃利奥特纠正波定位点 |
//+------------------------------------------------------------------+
bool ElliotWave3PointChange(const long chart_ID=0, // 图表 ID
const string name="ElliotWave3", // 对象名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除埃利奥特纠正波 |
//+------------------------------------------------------------------+
bool ElliotWave3Delete(const long chart_ID=0, // 图表ID
const string name="ElliotWave3") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Elliott Correction Wave\"! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查埃利奥特纠正波定位点的值和 |
//| 为空点设置默认的值 |
//+------------------------------------------------------------------+
void ChangeElliotWave3EmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[];
ArrayResize(temp,10);
//--- 接收数据
CopyTime(Symbol(),Period(),TimeCurrent(),10,temp);
//--- 接收当前图表一点的值
double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第一点的时间没有设置,它则位于最后柱左侧的9个柱
if(!time1)
time1=temp[0];
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于最后柱左侧的5个柱
if(!time2)
time2=temp[4];
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*point;
//--- 如果第三点的时间没有设置,它则位于最后柱左侧的1个柱
if(!time3)
time3=temp[8];
//---如果第三个点的价格没有设置,则低于第一个点移动200点
if(!price3)
price3=price1-200*point;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变对象定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制埃利奥特纠正波的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建埃利奥特纠正波
if(!ElliotWave3Create(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpDegree,InpDrawLines,InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 移动第三个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p3<accuracy-1)
p3+=1;
//--- 移动点
if(!ElliotWave3PointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy*4/5;
//--- 移动第一个和第二个定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
if(p2<accuracy-1)
p2+=1;
//--- 切换点
if(!ElliotWave3PointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ElliotWave3PointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表对象
ElliotWave3Delete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 2.2.1.22 OBJ_RECTANGLE矩形
ObjRectangle
注意
对于矩形,颜色填充模式可以使用OBJPROP_FILL属性来设置。
示例
下面的脚本创建和移动图表上的矩形。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates rectangle on the chart."
#property description "Anchor point coordinates are set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Rectangle"; // 矩形名称
input int InpDate1=40; // 第1个点的日期,%
input int InpPrice1=40; // 第1个点的价格,%
input int InpDate2=60; // 第2个点的日期,%
input int InpPrice2=60; // 第2个点的价格,%
input color InpColor=clrRed; // 矩形颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // 矩形线的风格
input int InpWidth=2; // 矩形线的宽度
input bool InpFill=true; // 填充矩形颜色
input bool InpBack=false; // 背景矩形
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 通过已给的坐标创建矩形 |
//+------------------------------------------------------------------+
bool RectangleCreate(const long chart_ID=0, // 图表 ID
const string name="Rectangle", // 矩形名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
const color clr=clrRed, // 矩形颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 矩形线的风格
const int width=1, // 矩形线的宽度
const bool fill=false, // 填充矩形颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeRectangleEmptyPoints(time1,price1,time2,price2);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建矩形
if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create a rectangle! Error code = ",GetLastError());
return(false);
}
//--- 设置矩形颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置矩形线的风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置矩形线的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充矩形的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出矩形移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动矩形定位点 |
//+------------------------------------------------------------------+
bool RectanglePointChange(const long chart_ID=0, // 图表 ID
const string name="Rectangle", // 矩形名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除矩形 |
//+------------------------------------------------------------------+
bool RectangleDelete(const long chart_ID=0, // 图表 ID
const string name="Rectangle") // 矩形名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除矩形
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete rectangle! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查矩形定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeRectangleEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变矩形定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制矩形的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- 创建矩形
if(!RectangleCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,
InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动矩形的定位点
//--- 循环计数器
int h_steps=bars/2;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d1<bars-1)
d1+=1;
if(d2>1)
d2-=1;
//--- 切换点
if(!RectanglePointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!RectanglePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/2;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
if(p2>1)
p2-=1;
//--- 切换点
if(!RectanglePointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!RectanglePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表矩形
RectangleDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# 2.2.1.23 OBJ_TRIANGLE三角形
ObjTriangle
注意
对于三角形,颜色填充模式可以使用 OBJPROP_FILL 属性来设置。
示例
下面的脚本创建和移动图表上的三角形。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates triangle on the chart."
#property description "Anchor point coordinates are set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Triangle"; // 三角形名称
input int InpDate1=25; // 第1个点的日期,%
input int InpPrice1=50; // 第一个点的价格,%
input int InpDate2=70; // 第2个点的日期, %
input int InpPrice2=70; // 第2个点的价格,%
input int InpDate3=65; // 第3个点的日期,%
input int InpPrice3=20; // 第3个点的价格,%
input color InpColor=clrRed; // 三角形颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 三角形线条风格
input int InpWidth=2; // 三角形线条宽度
input bool InpFill=false; // 三角形填充颜色
input bool InpBack=false; // 背景三角形
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//|通过已给的坐标创建三角形 |
//+------------------------------------------------------------------+
bool TriangleCreate(const long chart_ID=0, //图表 ID
const string name="Triangle", //三角形名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, //第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, //三角形颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 三角形线条风格
const int width=1, // 三角形线条宽度
const bool fill=false, // 三角形填充颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeTriangleEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 通过已给的坐标创建三角形
if(!ObjectCreate(chart_ID,name,OBJ_TRIANGLE,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create a triangle! Error code = ",GetLastError());
return(false);
}
//--- 设置三角形颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置三角形线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置三角形线条宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充三角形的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出三角形移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动三角形定位点 |
//+------------------------------------------------------------------+
bool TrianglePointChange(const long chart_ID=0, // 图表 ID
const string name="Triangle", // 三角形名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除三角形 |
//+------------------------------------------------------------------+
bool TriangleDelete(const long chart_ID=0, // 图表 ID
const string name="Triangle") // 三角形名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除三角形
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the ellipse! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查三角形定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeTriangleEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第二个点的日期相一致
if(!time3)
time3=time2;
//--- 如果第三点的价格没有设置,则它与第一点的价格相等
if(!price3)
price3=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变三角形定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制三角形的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建三角形
if(!TriangleCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动三角形定位点
//--- 循环计数器
int v_steps=accuracy*3/10;
//--- 移动第一个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1>1)
p1-=1;
//--- 移动点
if(!TrianglePointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars*9/20-1;
//--- 移动第二个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d2>1)
d2-=1;
//--- 移动点
if(!TrianglePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
v_steps=accuracy/4;
//--- 移动第三个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p3<accuracy-1)
p3+=1;
//--- 移动点
if(!TrianglePointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除三角形
TriangleDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# 2.2.1.24 OBJ_ELLIPSE椭圆形
ObjEllipse
注意
对于椭圆形,颜色填充模式可以使用 OBJPROP_FILL 属性来设置。
示例
下面的脚本创建和移动图表上的椭圆形。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates ellipse on the chart."
#property description "Anchor point coordinates are set"
#property description "in percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Ellipse"; // 椭圆形名称
input int InpDate1=30; // 第1个点的日期,%
input int InpPrice1=20; // 第1个点的价格,%
input int InpDate2=70; // 第2个点的日期, %
input int InpPrice2=80; // 第2个点的价格,%
input int InpDate3=50; // 第3个点的日期,%
input int InpPrice3=60; // 第3个点的价格,%
input color InpColor=clrRed; // 椭圆形颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 椭圆形线条风格
input int InpWidth=2; // 椭圆形线条的宽度
input bool InpFill=false; // 椭圆形填充颜色
input bool InpBack=false; // 背景椭圆形
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 由给定坐标创建椭圆形 |
//+------------------------------------------------------------------+
bool EllipseCreate(const long chart_ID=0, // 图表ID
const string name="Ellipse", // 椭圆形名称
const int sub_window=0, // 子窗口指数
datetime time1=0, // 第一个点的时间
double price1=0, // 第一个点的价格
datetime time2=0, // 第二个点的时间
double price2=0, // 第二个点的价格
datetime time3=0, // 第三个点的时间
double price3=0, // 第三个点的价格
const color clr=clrRed, // 椭圆形颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 椭圆形线条风格
const int width=1, // 椭圆形线条的宽度
const bool fill=false, // 椭圆形填充颜色
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeEllipseEmptyPoints(time1,price1,time2,price2,time3,price3);
//--- 重置错误的值
ResetLastError();
//--- 由给定坐标创建椭圆形
if(!ObjectCreate(chart_ID,name,OBJ_ELLIPSE,sub_window,time1,price1,time2,price2,time3,price3))
{
Print(__FUNCTION__,
": failed to create an ellipse! Error code = ",GetLastError());
return(false);
}
//--- 设置椭圆形颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置椭圆形线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置椭圆形线条的宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 启用 (true) 或禁用 (false) 填充椭圆形的模式
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 突出椭圆形移动的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动椭圆形定位点 |
//+------------------------------------------------------------------+
bool EllipsePointChange(const long chart_ID=0, // 图表ID
const string name="Ellipse", // 椭圆形名称
const int point_index=0, // 定位点指数
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除椭圆形 |
//+------------------------------------------------------------------+
bool EllipseDelete(const long chart_ID=0, // 图表 ID
const string name="Ellipse") // 椭圆形名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除椭圆形
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete an ellipse! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查椭圆形定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeEllipseEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- 如果第一点的时间没有设置,它将位于当前柱
if(!time1)
time1=TimeCurrent();
//--- 如果第一点的价格没有设置,则它将用卖价值
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 如果第二点的时间没有设置,它则位于第二点左侧的9个柱
if(!time2)
{
//--- 接收最近10柱开盘时间的数组
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- 在第一点左侧9柱设置第二点
time2=temp[0];
}
//--- 如果第二个点的价格没有设置,则低于第一个点移动300点
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- 如果第三个点的时间没有设置,则它与第二个点的日期相一致
if(!time3)
time3=time2;
//--- 如果第三点的价格没有设置,则它与第一点的价格相等
if(!price3)
price3=price1;
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//---设置和改变椭圆形定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制椭圆形的点
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- 创建椭圆形
if(!EllipseCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动椭圆形定位点
//--- 循环计数器
int v_steps=accuracy/5;
//--- 移动第一个和第二个定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p1<accuracy-1)
p1+=1;
if(p2>1)
p2-=1;
//--- 切换点
if(!EllipsePointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!EllipsePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int h_steps=bars/5;
//--- 移动第三个定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d3>1)
d3-=1;
//--- 移动点
if(!EllipsePointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除椭圆形
EllipseDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# 2.2.1.25 OBJ_ARROW_THUMB_UP拇指向上符号
ObjArrowTumbUp
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举 值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的椭圆形。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Thumbs Up\" sign."
#property description "Anchor point coordinate is set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ThumbUp"; // 符号名称
input int InpDate=75; // 定位点日期在%
input int InpPrice=25; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建拇指向上符号 |
//+------------------------------------------------------------------+
bool ArrowThumbUpCreate(const long chart_ID=0, // 图表 ID
const string name="ThumbUp", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_THUMB_UP,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Thumbs Up\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowThumbUpMove(const long chart_ID=0, // 图表 ID
const string name="ThumbUp", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变拇指向上符号定位类型 |
//+------------------------------------------------------------------+
bool ArrowThumbUpAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ThumbUp", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除拇指向上符号 |
//+------------------------------------------------------------------+
bool ArrowThumbUpDelete(const long chart_ID=0, // 图表 ID
const string name="ThumbUp") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Thumbs Up\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表创建拇指向上符号
if(!ArrowThumbUpCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int h_steps=bars/4;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d>1)
d-=1;
//--- 移动点
if(!ArrowThumbUpMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/4;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p<accuracy-1)
p+=1;
//--- 移动点
if(!ArrowThumbUpMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 改变定位点相对于符号的位置
ArrowThumbUpAnchorChange(0,InpName,ANCHOR_BOTTOM);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowThumbUpDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# 2.2.1.26 OBJ_ARROW_THUMB_DOWN拇指向下符号
ObjArrowTumbDown
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的拇指向下符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Thumbs Down\" sign."
#property description "Anchor point coordinate is set in percentage of"
#property description "the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ThumbDown"; // 符号名称
input int InpDate=25; // 定位点日期在%
input int InpPrice=75; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建拇指向下符号 |
//+------------------------------------------------------------------+
bool ArrowThumbDownCreate(const long chart_ID=0, // 图表 ID
const string name="ThumbDown", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_THUMB_DOWN,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Thumbs Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowThumbDownMove(const long chart_ID=0, // 图表 ID
const string name="ThumbDown", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变手指向下符号定位类型 |
//+------------------------------------------------------------------+
bool ArrowThumbDownAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ThumbDown", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除拇指向下符号 |
//+------------------------------------------------------------------+
bool ArrowThumbDownDelete(const long chart_ID=0, // 图表 ID
const string name="ThumbDown") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Thumbs Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建拇指向下符号
if(!ArrowThumbDownCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int h_steps=bars/4;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!ArrowThumbDownMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 循环计数器
int v_steps=accuracy/4;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p>1)
p-=1;
//--- 移动点
if(!ArrowThumbDownMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 改变定位点相对于符号的位置
ArrowThumbDownAnchorChange(0,InpName,ANCHOR_TOP);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowThumbDownDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# 2.2.1.27 OBJ_ARROW_UP箭头向上符号
ObjArrowUp
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的箭头向上符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Arrow Up\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ArrowUp"; // 符号名称
input int InpDate=25; // 定位点日期在%
input int InpPrice=25; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建箭头向上符号 |
//+------------------------------------------------------------------+
bool ArrowUpCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowUp", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_UP,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Arrow Up\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowUpMove(const long chart_ID=0, // 图表 ID
const string name="ArrowUp", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变箭头向下符号定位类型 |
//+------------------------------------------------------------------+
bool ArrowUpAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ArrowUp", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位点位置
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除箭头向上符号 |
//+------------------------------------------------------------------+
bool ArrowUpDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowUp") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Arrow Up\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表创建箭头向上符号
if(!ArrowUpCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int v_steps=accuracy/2;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p<accuracy-1)
p+=1;
//--- 移动点
if(!ArrowUpMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变定位点相对于符号的位置
ArrowUpAnchorChange(0,InpName,ANCHOR_BOTTOM);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowUpDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# 2.2.1.28 OBJ_ARROW_DOWN箭头向下符号
ObjArrowDown
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的箭头向下符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Arrow Down\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ArrowDown"; // 符号名称
input int InpDate=75; // 定位点日期在 %
input int InpPrice=75; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建箭头向下符号 |
//+------------------------------------------------------------------+
bool ArrowDownCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowDown", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_DOWN,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Arrow Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- 定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowDownMove(const long chart_ID=0, // 图表 ID
const string name="ArrowDown", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变箭头向下符号定位类型 |
//+------------------------------------------------------------------+
bool ArrowDownAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ArrowDown", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位点位置
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除箭头向下符号 |
//+------------------------------------------------------------------+
bool ArrowDownDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowDown") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Arrow Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表创建箭头向下符号
if(!ArrowDownCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int v_steps=accuracy/2;
//--- 移动定位点
for(int i=0;i<v_steps ;i++)
{
//--- 使用下面的值
if(p>1)
p-=1;
//--- 移动点
if(!ArrowDownMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变定位点相对于符号的位置
ArrowDownAnchorChange(0,InpName,ANCHOR_TOP);
//--- 重画图表
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowDownDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# 2.2.1.29 OBJ_ARROW_STOP停止符号
ObjArrowStop
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的停止符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Stop\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ArrowStop"; // 符号名称
input int InpDate=10; // 定位点日期在 %
input int InpPrice=50; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| Create Stop sign |
//+------------------------------------------------------------------+
bool ArrowStopCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowStop", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_STOP,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Stop\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowStopMove(const long chart_ID=0, // 图表 ID
const string name="ArrowStop", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变停止符号定位类型 |
//+------------------------------------------------------------------+
bool ArrowStopAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ArrowStop", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位点位置
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除停止符号 |
//+------------------------------------------------------------------+
bool ArrowStopDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowStop") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Stop\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建停止符号
if(!ArrowStopCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int h_steps=bars*2/5;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!ArrowStopMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.025 秒延迟
Sleep(25);
}
//--- 改变定位点相对于符号的位置
ArrowStopAnchorChange(0,InpName,ANCHOR_TOP);
//--- 重画图表
ChartRedraw();
//--- 循环计数器
h_steps=bars*2/5;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!ArrowStopMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.025 秒延迟
Sleep(25);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowStopDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# 2.2.1.30 OBJ_ARROW_CHECK查验符号
ObjArrowCheck
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建和移动图表上的查验符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Check\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="ArrowCheck"; // 符号名称
input int InpDate=10; // 定位点日期在 %
input int InpPrice=50; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // 定位类型
input color InpColor=clrRed; // 符号颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // 边界线条风格
input int InpWidth=5; // 符号大小
input bool InpBack=false; // 背景符号
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建检查符号 |
//+------------------------------------------------------------------+
bool ArrowCheckCreate(const long chart_ID=0, // 图表标ID
const string name="ArrowCheck", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位类型
const color clr=clrRed, // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 符号大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_CHECK,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Check\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置符号大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowCheckMove(const long chart_ID=0, // 图表 ID
const string name="ArrowCheck", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 更改检查定位类型 |
//+------------------------------------------------------------------+
bool ArrowCheckAnchorChange(const long chart_ID=0, // 图表 ID
const string name="ArrowCheck", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除检查符号 |
//+------------------------------------------------------------------+
bool ArrowCheckDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowCheck") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Check\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy ;i++)
price[i]=min_price+i*step;
//--- 定义绘制符号的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建检查符号
if(!ArrowCheckCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点和改变其相对于符号的位置
//--- 循环计数器
int h_steps=bars*2/5;
//--- 移动定位点
for(int i=0;i<h_steps ;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!ArrowCheckMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.025 秒延迟
Sleep(25);
}
//--- 改变定位点相对于符号的位置
ArrowCheckAnchorChange(0,InpName,ANCHOR_BOTTOM);
//--- 重画图表
ChartRedraw();
//--- 循环计数器
h_steps=bars*2/5;
//--- 移动定位点
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d<bars-1)
d+=1;
//--- 移动点
if(!ArrowCheckMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.025 秒延迟
Sleep(25);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表符号
ArrowCheckDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# 2.2.1.31 OBJ_ARROW_LEFT_PRICE向左价格标签
ObjArrowLeftPrice
示例
下面的脚本创建和移动图表上的向左价格标签。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates the left price label on the chart."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="LeftPrice"; // 价格标签名称
input int InpDate=100; // 定位点日期在%
input int InpPrice=10; // 定位点价格在 %
input color InpColor=clrRed; // 价格标签颜色
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 边界线条风格
input int InpWidth=2; // 价格标签大小
input bool InpBack=false; // 背景标签
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建向左价格标签 |
//+------------------------------------------------------------------+
bool ArrowLeftPriceCreate(const long chart_ID=0, // 图表 ID
const string name="LeftPrice", // 价格标签名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const color clr=clrRed, // 价格标签颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=1, // 价格标签大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建价格标签
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_LEFT_PRICE,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create the left price label! Error code = ",GetLastError());
return(false);
}
//--- 设置标签颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置标签大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowLeftPriceMove(const long chart_ID=0, // 图表 ID
const string name="LeftPrice", // 标签名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 从图表删除向左价格标签 |
//+------------------------------------------------------------------+
bool ArrowLeftPriceDelete(const long chart_ID=0, // 图表 ID
const string name="LeftPrice") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the left price label! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 用于设置和改变标签定位点坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制标签的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建向左价格标签
if(!ArrowLeftPriceCreate(0,InpName,0,date[d],price[p],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy*4/5;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p<accuracy-1)
p+=1;
//--- 移动点
if(!ArrowLeftPriceMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除标签
ArrowLeftPriceDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# 2.2.1.32 OBJ_ARROW_RIGHT_PRICE向右价格标签
ObjArrowRightPrice
示例
下面的脚本创建和移动图表上的向右价格标签。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates the right price label on the chart."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="RightPrice"; // 价格标签名称
input int InpDate=0; // 定位点日期在%
input int InpPrice=90; // 定位点价格在 %
input color InpColor=clrRed; // 价格标签颜色
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 边界线条风格
input int InpWidth=2; // 价格标签大小
input bool InpBack=false; // 背景标签
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建向右价格标签 |
//+------------------------------------------------------------------+
bool ArrowRightPriceCreate(const long chart_ID=0, // 图表 ID
const string name="RightPrice", // 价格标签名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const color clr=clrRed, // 价格标签颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=1, // 价格标签大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建价格标签
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_RIGHT_PRICE,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create the right price label! Error code = ",GetLastError());
return(false);
}
//--- 设置标签颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置标签大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowRightPriceMove(const long chart_ID=0, // 图表 ID
const string name="RightPrice", // 标签名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 从图表删除向右价格标签 |
//+------------------------------------------------------------------+
bool ArrowRightPriceDelete(const long chart_ID=0, // 图表 ID
const string name="RightPrice") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the right price label! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 用于设置和改变标签定位点坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制标签的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建向右价格标签
if(!ArrowRightPriceCreate(0,InpName,0,date[d],price[p],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动定位点
//--- 循环计数器
int v_steps=accuracy*4/5;
//--- 移动定位点
for(int i=0;i<v_steps;i++)
{
//--- 使用下面的值
if(p>1)
p-=1;
//--- 移动点
if(!ArrowRightPriceMove(0,InpName,date[d],price[p]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除标签
ArrowRightPriceDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# 2.2.1.33 OBJ_ARROW_BUY买入符号
ObjArrowBuy
示例
下面的脚本创建和移动图表上的买入符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Buy\" signs in the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input color InpColor=C'3,95,172'; // 颜色符号
//+------------------------------------------------------------------+
//| 创建买入符号 |
//+------------------------------------------------------------------+
bool ArrowBuyCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowBuy", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const color clr=C'3,95,172', // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线条风格(当高亮显示时)
const int width=1, // 线条大小(当高亮显示时)
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_BUY,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Buy\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线条风格(当高亮显示时)
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线条大小(当高亮显示时)
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowBuyMove(const long chart_ID=0, // 图表 ID
const string name="ArrowBuy", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除买入符号 |
//+------------------------------------------------------------------+
bool ArrowBuyDelete(const long chart_ID=0, // 图表ID
const string name="ArrowBuy") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Buy\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // 存储可见柱日期的数组
double low[]; // 存储可见柱最低价格的数组
double high[]; // 存储可见柱最高价格的数组
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(low,bars);
ArrayResize(high,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写最低价格的数组
if(CopyLow(Symbol(),Period(),0,bars,low)==-1)
{
Print("Failed to copy the values of Low prices! Error code = ",GetLastError());
return;
}
//--- 填写最高价格的数组
if(CopyHigh(Symbol(),Period(),0,bars,high)==-1)
{
Print("Failed to copy the values of High prices! Error code = ",GetLastError());
return;
}
//--- 为每个可见柱创建最低点的买入符号
for(int i=0;i<bars;i++)
{
if(!ArrowBuyCreate(0,"ArrowBuy_"+(string)i,0,date[i],low[i],InpColor))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 为每个可见柱移动买入符号到最高点
for(int i=0;i<bars;i++)
{
if(!ArrowBuyMove(0,"ArrowBuy_"+(string)i,date[i],high[i]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 删除买入符号
for(int i=0;i<bars;i++)
{
if(!ArrowBuyDelete(0,"ArrowBuy_"+(string)i))
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//---
}
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
170
171
172
173
174
175
176
177
178
# 2.2.1.34 OBJ_ARROW_SELL卖出符号
ObjArrowSell
示例
下面的脚本创建和移动图表上的卖出符号。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Sell\" signs in the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input color InpColor=C'225,68,29'; // 颜色符号
//+------------------------------------------------------------------+
//| 创建卖出符号 |
//+------------------------------------------------------------------+
bool ArrowSellCreate(const long chart_ID=0, // 图表 ID
const string name="ArrowSell", // 符号名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const color clr=C'225,68,29', // 符号颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 线条风格(当高亮显示时)
const int width=1, // 线条大小(当高亮显示时)
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建符号
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_SELL,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Sell\" sign! Error code = ",GetLastError());
return(false);
}
//--- 设置符号颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置线条风格(当高亮显示时)
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置线条大小(当高亮显示时)
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动符号的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowSellMove(const long chart_ID=0, // 图表 ID
const string name="ArrowSell", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除卖出符号 |
//+------------------------------------------------------------------+
bool ArrowSellDelete(const long chart_ID=0, // 图表 ID
const string name="ArrowSell") // 符号名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除符号
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Sell\" sign! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // 存储可见柱日期的数组
double low[]; // 存储可见柱最低价格的数组
double high[]; // 存储可见柱最高价格的数组
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(low,bars);
ArrayResize(high,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写最低价格的数组
if(CopyLow(Symbol(),Period(),0,bars,low)==-1)
{
Print("Failed to copy the values of Low prices! Error code = ",GetLastError());
return;
}
//--- 填写最高价格的数组
if(CopyHigh(Symbol(),Period(),0,bars,high)==-1)
{
Print("Failed to copy the values of High prices! Error code = ",GetLastError());
return;
}
//--- 为每个可见柱创建最高点的卖出符号
for(int i=0;i<bars;i++)
{
if(!ArrowSellCreate(0,"ArrowSell_"+(string)i,0,date[i],high[i],InpColor))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 为每个可见柱移动卖出符号到最低点
for(int i=0;i<bars;i++)
{
if(!ArrowSellMove(0,"ArrowSell_"+(string)i,date[i],low[i]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 删除卖出符号
for(int i=0;i<bars;i++)
{
if(!ArrowSellDelete(0,"ArrowSell_"+(string)i))
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//---
}
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
170
171
172
173
174
175
176
177
178
# 2.2.1.35 OBJ_ARROW箭头对象
ObjArrow
注意
相对于符号的定位点位置可以从ENUM_ARROW_ANCHOR 枚举值中选择。
在MetaEditor中编写代码时,大型符号(大于5)只能通过设置适当的OBJPROP_WIDTH属性值来创建。
示例
下面的脚本创建图表上的箭头对象和改变其类型。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates a random arrow in the chart window."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Arrow"; // 箭头名称
input int InpDate=50; // 定位点日期在 %
input int InpPrice=50; // 定位点价格在 %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // 定位类型
input color InpColor=clrDodgerBlue; // 箭头颜色
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 边界线条风格
input int InpWidth=10; // 箭头大小
input bool InpBack=false; // 背景箭头
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建箭头 |
//+------------------------------------------------------------------+
bool ArrowCreate(const long chart_ID=0, // 图表 ID
const string name="Arrow", // 箭头名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const uchar arrow_code=252, // 箭头代码
const ENUM_ARROW_ANCHOR anchor=ANCHOR_BOTTOM, // 定位点位置
const color clr=clrRed, // 箭头颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 边界线条风格
const int width=3, // 箭头大小
const bool back=false, // 在背景中
const bool selection=true, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeArrowEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建箭头
if(!ObjectCreate(chart_ID,name,OBJ_ARROW,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create an arrow! Error code = ",GetLastError());
return(false);
}
//--- 设置箭头代码
ObjectSetInteger(chart_ID,name,OBJPROP_ARROWCODE,arrow_code);
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置箭头颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置箭头大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动箭头的模式
//--- 当使用ObjectCreate函数创建图形对象时,对象不能
//--- 默认下突出并移动。在这个方法中,默认选择参数
//--- true 可以突出移动对象
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool ArrowMove(const long chart_ID=0, // 图表 ID
const string name="Arrow", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变箭头代码 |
//+------------------------------------------------------------------+
bool ArrowCodeChange(const long chart_ID=0, // 图表 ID
const string name="Arrow", // 对象名称
const uchar code=252) // 箭头代码
{
//--- 重置错误的值
ResetLastError();
//--- 改变箭头代码
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ARROWCODE,code))
{
Print(__FUNCTION__,
": failed to change the arrow code! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变定向类型 |
//+------------------------------------------------------------------+
bool ArrowAnchorChange(const long chart_ID=0, // 图表 ID
const string name="Arrow", // 对象名称
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // 定位类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除箭头 |
//+------------------------------------------------------------------+
bool ArrowDelete(const long chart_ID=0, // 图表 ID
const string name="Arrow") // 箭头名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除箭头
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete an arrow! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 价格数组大小
int accuracy=1000;
//--- 存储要使用的日期和价格值的数组
//--- 设置和改变符号定位点的坐标
datetime date[];
double price[];
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写价格数组
//--- 找出图表的最高值和最低值
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- 定义变化的价格并填写该数组
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- 定义绘制箭头的点
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- 在图表上创建箭头
if(!ArrowCreate(0,InpName,0,date[d],price[p],32,InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表
ChartRedraw();
//--- 考虑循环中创建箭头的所有情况
for(int i=33;i<256;i++)
{
if(!ArrowCodeChange(0,InpName,(uchar)i))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 延迟半秒
Sleep(500);
}
//--- 1 秒延迟
Sleep(1000);
//--- 从图表删除箭头
ArrowDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# 2.2.1.36 OBJ_TEXT文本对象
ObjText
注意
相对于文本的定位点位置可以从 ENUM_ANCHOR_POINT 枚举值中选择。您也可以使用 OBJPROP_ANGLE 属性来改变文本定位角。
示例
下面的脚本创建图表上的多个文本对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates \"Text\" graphical object."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpFont="Arial"; // 字体
input int InpFontSize=10; // 字体大小
input color InpColor=clrRed; // 颜色
input double InpAngle=90.0; // 倾斜角度
input ENUM_ANCHOR_POINT InpAnchor=ANCHOR_BOTTOM; // 定位类型
input bool InpBack=false; // 背景对象
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建文本对象 |
//+------------------------------------------------------------------+
bool TextCreate(const long chart_ID=0, // 图表 ID
const string name="Text", // 对象名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const string text="Text", // 文本本身
const string font="Arial", // 字体
const int font_size=10, // 字体大小
const color clr=clrRed, // 颜色
const double angle=0.0, // 文本倾斜
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // 定位类型
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeTextEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建文本对象
if(!ObjectCreate(chart_ID,name,OBJ_TEXT,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Text\" object! Error code = ",GetLastError());
return(false);
}
//--- 设置文本
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- 设置文本字体
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- 设置字体大小
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- 设置文本的倾斜角
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动对象的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动定位点 |
//+------------------------------------------------------------------+
bool TextMove(const long chart_ID=0, // 图表 ID
const string name="Text", // 对象名称
datetime time=0, // 定位点时间坐标
double price=0) // 定位点价格坐标
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变对象文本 |
//+------------------------------------------------------------------+
bool TextChange(const long chart_ID=0, // 图表 ID
const string name="Text", // 对象名称
const string text="Text") // 文本
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象文本
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除文本对象 |
//+------------------------------------------------------------------+
bool TextDelete(const long chart_ID=0, // 图表 ID
const string name="Text") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Text\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeTextEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // 存储可见柱日期的数组
double low[]; // 存储可见柱最低价格的数组
double high[]; // 存储可见柱最高价格的数组
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(low,bars);
ArrayResize(high,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写最低价格的数组
if(CopyLow(Symbol(),Period(),0,bars,low)==-1)
{
Print("Failed to copy the values of Low prices! Error code = ",GetLastError());
return;
}
//--- 填写最高价格的数组
if(CopyHigh(Symbol(),Period(),0,bars,high)==-1)
{
Print("Failed to copy the values of High prices! Error code = ",GetLastError());
return;
}
//--- 定义文本显示的频率
int scale=(int)ChartGetInteger(0,CHART_SCALE);
//--- 定义步骤
int step=1;
switch(scale)
{
case 0:
step=12;
break;
case 1:
step=6;
break;
case 2:
step=4;
break;
case 3:
step=2;
break;
}
//--- 创建最高和最低柱的值的文本(间隔)。
for(int i=0;i<bars;i+=step)
{
//--- 创建文本
if(!TextCreate(0,"TextHigh_"+(string)i,0,date[i],high[i],DoubleToString(high[i],5),InpFont,InpFontSize,
InpColor,InpAngle,InpAnchor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
if(!TextCreate(0,"TextLow_"+(string)i,0,date[i],low[i],DoubleToString(low[i],5),InpFont,InpFontSize,
InpColor,-InpAngle,InpAnchor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 半秒延迟
Sleep(500);
//--- 删除文本
for(int i=0;i<bars;i+=step)
{
if(!TextDelete(0,"TextHigh_"+(string)i))
return;
if(!TextDelete(0,"TextLow_"+(string)i))
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# 2.2.1.37 OBJ_LABEL标签对象
ObjTextLabel
注意
相对于标签的定位点位置可以从 ENUM_ANCHOR_POINT 枚举值中选择。定位点坐标用像素设置。
您也可以从 ENUM_BASE_CORNER 枚举选择文本标签定位角。
示例
下面的脚本创建和移动图表上的编辑对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates \"Label\" graphical object."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Label"; // 标签名称
input int InpX=150; // X-轴距离
input int InpY=150; // Y-轴距离
input string InpFont="Arial"; // 字体
input int InpFontSize=14; // 字体大小
input color InpColor=clrRed; // 颜色
input double InpAngle=0.0; // 倾斜角度
input ENUM_ANCHOR_POINT InpAnchor=ANCHOR_CENTER; // 定位类型
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏对象列表中
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建文本标签 |
//+------------------------------------------------------------------+
bool LabelCreate(const long chart_ID=0, // 图表 ID
const string name="Label", // 标签名称
const int sub_window=0, // 子窗口指数
const int x=0, // X 坐标
const int y=0, // Y 坐标
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // 图表定位角
const string text="Label", // 文本
const string font="Arial", // 字体
const int font_size=10, // 字体大小
const color clr=clrRed, // 颜色
const double angle=0.0, // 文本倾斜
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // 定位类型
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 重置错误的值
ResetLastError();
//--- 创建文本标签
if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create text label! Error code = ",GetLastError());
return(false);
}
//--- 设置标签坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置相对于定义点坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置文本
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- 设置文本字体
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- 设置字体大小
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- 设置文本的倾斜角
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动文本标签 |
//+------------------------------------------------------------------+
bool LabelMove(const long chart_ID=0, // 图表 ID
const string name="Label", // 标签名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动文本标签
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);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变绑定标签的图表角落 |
//+------------------------------------------------------------------+
bool LabelChangeCorner(const long chart_ID=0, // 图表 ID
const string name="Label", // 标签名称
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER) // 图表定位角
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位角
if(!ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner))
{
Print(__FUNCTION__,
": failed to change the anchor corner! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变标签文本 |
//+------------------------------------------------------------------+
bool LabelTextChange(const long chart_ID=0, // 图表 ID
const string name="Label", // 对象名称
const string text="Text") // 文本
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象文本
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除文本标签 |
//+------------------------------------------------------------------+
bool LabelDelete(const long chart_ID=0, // 图表 ID
const string name="Label") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a text label! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 在本地变量存储标签坐标
int x=InpX;
int y=InpY;
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 检查输入参数的正确性
if(InpX<0 || InpX>x_distance-1 || InpY<0 || InpY>y_distance-1)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 准备标签的初始文本
string text;
StringConcatenate(text,"Upper left corner: ",x,",",y);
//--- 在图表上创建文本标签
if(!LabelCreate(0,InpName,0,InpX,InpY,CORNER_LEFT_UPPER,text,InpFont,InpFontSize,
InpColor,InpAngle,InpAnchor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待0.5秒
ChartRedraw();
Sleep(500);
//--- 同时移动标签和改变其文本
//--- 轴的迭代次数
int h_steps=(int)(x_distance/2-InpX);
int v_steps=(int)(y_distance/2-InpY);
//--- 向下移动标签
for(int i=0;i< v_steps;i++)
{
//--- 改变坐标
y+=2;
//--- 移动标签并更改其文本
MoveAndTextChange(x,y,"Upper left corner: ");
}
//--- 半秒延迟
Sleep(500);
//--- 向右移动标签
for(int i=0;i<h_steps ;i++)
{
//--- 改变坐标
x+=2;
//--- 移动标签并更改其文本
MoveAndTextChange(x,y,"Upper left corner: ");
}
//--- 半秒延迟
Sleep(500);
//--- 向上移动标签
for(int i=0;i<v_steps;i++)
{
//--- 改变坐标
y-=2;
//--- 移动标签并更改其文本
MoveAndTextChange(x,y,"Upper left corner: ");
}
//--- 半秒延迟
Sleep(500);
//--- 向左移动标签
for(int i=0;i<h_steps;i++)
{
//--- 改变坐标
x-=2;
//--- 移动标签并更改其文本
MoveAndTextChange(x,y,"Upper left corner: ");
}
//--- 半秒延迟
Sleep(500);
//--- 现在,通过改变定位角来移动点的位置
//--- 移动到左下角
if(!LabelChangeCorner(0,InpName,CORNER_LEFT_LOWER))
return;
//--- 改变标签文本
StringConcatenate(text,"Lower left corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- 重绘图表并等待2秒
ChartRedraw();
Sleep(2000);
//--- 移动到右下角
if(!LabelChangeCorner(0,InpName,CORNER_RIGHT_LOWER))
return;
//--- 改变标签文本
StringConcatenate(text,"Lower right corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- 重绘图表并等待2秒
ChartRedraw();
Sleep(2000);
//--- 移动到右上角
if(!LabelChangeCorner(0,InpName,CORNER_RIGHT_UPPER))
return;
//--- 改变标签文本
StringConcatenate(text,"Upper right corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- 重绘图表并等待2秒
ChartRedraw();
Sleep(2000);
//--- 移动到左上角
if(!LabelChangeCorner(0,InpName,CORNER_LEFT_UPPER))
return;
//--- 改变标签文本
StringConcatenate(text,"Upper left corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- 重绘图表并等待2秒
ChartRedraw();
Sleep(2000);
//--- 删除标签
LabelDelete(0,InpName);
//--- 重画图表并等待0.5秒
ChartRedraw();
Sleep(500);
//---
}
//+------------------------------------------------------------------+
//| 函数移动对象并改变其文本 |
//+------------------------------------------------------------------+
bool MoveAndTextChange(const int x,const int y,string text)
{
//--- 移动标签
if(!LabelMove(0,InpName,x,y))
return(false);
//--- 改变标签文本
StringConcatenate(text,text,x,",",y);
if(!LabelTextChange(0,InpName,text))
return(false);
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return(false);
//--- 重画图表
ChartRedraw();
// 0.01 秒延迟
Sleep(10);
//--- 推出函数
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# 2.2.1.38 OBJ_BUTTON按钮对象
ObjButton
注意
定位点坐标用像素设置。您可以从 ENUM_BASE_CORNER选择按钮定位角。
示例
下面的脚本创建和移动图表上的按钮对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates the button on the chart."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Button"; // 按钮名称
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // 图表定位角
input string InpFont="Arial"; // 字体
input int InpFontSize=14; // 字体大小
input color InpColor=clrBlack; // 文本颜色
input color InpBackColor=C'236,233,216'; // 背景色
input color InpBorderColor=clrNONE; // 边界颜色
input bool InpState=false; // 出版/发布
input bool InpBack=false; // 背景对象
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建按钮 |
//+------------------------------------------------------------------+
bool ButtonCreate(const long chart_ID=0, // 图表 ID
const string name="Button", // 按钮名称
const int sub_window=0, // 子窗口指数
const int x=0, // X 坐标
const int y=0, // Y 坐标
const int width=50, // 按钮宽度
const int height=18, // 按钮高度
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // 图表定位角
const string text="Button", // 文本
const string font="Arial", // 字体
const int font_size=10, // 字体大小
const color clr=clrBlack, // 文本颜色
const color back_clr=C'236,233,216', // 背景色
const color border_clr=clrNONE, // 边界颜色
const bool state=false, // 出版/发布
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 重置错误的值
ResetLastError();
//--- 创建按钮
if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create the button! Error code = ",GetLastError());
return(false);
}
//--- 设置按钮坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置按钮大小
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置相对于定义点坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置文本
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- 设置文本字体
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- 设置字体大小
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- 设置文本颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置背景颜色
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- 设置边界颜色
ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动按钮的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动按钮 |
//+------------------------------------------------------------------+
bool ButtonMove(const long chart_ID=0, // 图表 ID
const string name="Button", // 按钮名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动按钮
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the button! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the button! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变按钮大小 |
//+------------------------------------------------------------------+
bool ButtonChangeSize(const long chart_ID=0, // 图表 ID
const string name="Button", // 按钮名称
const int width=50, // 按钮宽度
const int height=18) // 按钮高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变按钮大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the button width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the button height! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变绑定按钮的图表角落 |
//+------------------------------------------------------------------+
bool ButtonChangeCorner(const long chart_ID=0, // 图表 ID
const string name="Button", // 按钮名称
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER) // 图表定位角
{
//--- 重置错误的值
ResetLastError();
//--- 改变定位角
if(!ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner))
{
Print(__FUNCTION__,
": failed to change the anchor corner! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变按钮文本 |
//+------------------------------------------------------------------+
bool ButtonTextChange(const long chart_ID=0, // 图表 ID
const string name="Button", // 按钮名称
const string text="Text") // 文本
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象文本
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除按钮 |
//+------------------------------------------------------------------+
bool ButtonDelete(const long chart_ID=0, // 图表 ID
const string name="Button") // 按钮名称
{
//--- 重置错误的值
ResetLastError();
//---删除按钮
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the button! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 定义改变按钮大小的步骤
int x_step=(int)x_distance/32;
int y_step=(int)y_distance/32;
//--- 设置按钮坐标及其大小
int x=(int)x_distance/32;
int y=(int)y_distance/32;
int x_size=(int)x_distance*15/16;
int y_size=(int)y_distance*15/16;
//--- 创建按钮
if(!ButtonCreate(0,InpName,0,x,y,x_size,y_size,InpCorner,"Press",InpFont,InpFontSize,
InpColor,InpBackColor,InpBorderColor,InpState,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表
ChartRedraw();
//--- 减少循环中的按钮
int i=0;
while(i < 13)
{
//--- 延迟半秒
Sleep(500);
//--- 转换按钮到出版状态
ObjectSetInteger(0,InpName,OBJPROP_STATE,true);
//--- 重绘图表,等候0.2 秒
ChartRedraw();
Sleep(200);
//--- 重新定义坐标和按钮大小
x+=x_step;
y+=y_step;
x_size-=x_step*2;
y_size-=y_step*2;
//--- 减少按钮
ButtonMove(0,InpName,x,y);
ButtonChangeSize(0,InpName,x_size,y_size);
//--- 按钮返回发布状态
ObjectSetInteger(0,InpName,OBJPROP_STATE,false);
//--- 重画图表
ChartRedraw();
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 增加循环计数器
i++;
}
//--- 半秒延迟
Sleep(500);
//---删除按钮
ButtonDelete(0,InpName);
ChartRedraw();
//--- 等待1秒
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# 2.2.1.39 OBJ_CHART图表对象
ObjChart
注意
定位点坐标用像素设置。您可以从 ENUM_BASE_CORNER 枚举值中选择定位角。
可以为图表对象选择交易品种,周期和比例尺。也可以 启用/禁用 价格比例和日期展示模式。
示例
下面的脚本创建和移动图表上的图表对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates \"Chart\" object."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Chart"; // 对象名称
input string InpSymbol="EURUSD"; // 交易品种
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H1; // 周期
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // 定位角
input int InpScale=2; // 比例
input bool InpDateScale=true; // 时间比例显示
input bool InpPriceScale=true; // 价格比例显示
input color InpColor=clrRed; // 高亮显示时的边界颜色
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // 高亮显示时的线条风格
input int InpPointWidth=1; // 移动点大小
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建图表对象 |
//+------------------------------------------------------------------+
bool ObjectChartCreate(const long chart_ID=0, // 图表 ID
const string name="Chart", // 对象名称
const int sub_window=0, // 子窗口指数
const string symbol="EURUSD", // 交易品种
const ENUM_TIMEFRAMES period=PERIOD_H1, // 周期
const int x=0, // X 坐标
const int y=0, // Y 坐标
const int width=300, // 宽度
const int height=200, // 高度
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // 定位角
const int scale=2, // 比例
const bool date_scale=true, // 时间比例显示
const bool price_scale=true, // 价格比例显示
const color clr=clrRed, // 高亮显示时的边界颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 高亮显示时的线条风格
const int point_width=1, // 移动点大小
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 重置错误的值
ResetLastError();
//--- 创建图表对象
if(!ObjectCreate(chart_ID,name,OBJ_CHART,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- 设置对象坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置对象大小
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置相对于定义点坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置交易品种
ObjectSetString(chart_ID,name,OBJPROP_SYMBOL,symbol);
//--- 设置周期
ObjectSetInteger(chart_ID,name,OBJPROP_PERIOD,period);
//--- 设置比例
ObjectSetInteger(chart_ID,name,OBJPROP_CHART_SCALE,scale);
//--- 显示 (true) 或隐藏 (false) 时间比例
ObjectSetInteger(chart_ID,name,OBJPROP_DATE_SCALE,date_scale);
//--- 显示 (true) 或隐藏 (false) 价格比例
ObjectSetInteger(chart_ID,name,OBJPROP_PRICE_SCALE,price_scale);
//--- 设置对象高亮模式启动时的边界颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置对象高亮模式启动时的边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置移动对象的定位点大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 设置交易品种和图表对象时间帧 |
//+------------------------------------------------------------------+
bool ObjectChartSetSymbolAndPeriod(const long chart_ID=0, // 图表 ID (非图表对象)
const string name="Chart", // 对象名称
const string symbol="EURUSD", // 交易品种
const ENUM_TIMEFRAMES period=PERIOD_H1) // 时间帧
{
//--- 重置错误的值
ResetLastError();
//--- 设置图表对象交易品种和时间帧
if(!ObjectSetString(chart_ID,name,OBJPROP_SYMBOL,symbol))
{
Print(__FUNCTION__,
": failed to set a symbol for \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_PERIOD,period))
{
Print(__FUNCTION__,
": failed to set a period for \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动图表对象 |
//+------------------------------------------------------------------+
bool ObjectChartMove(const long chart_ID=0, // 图表 ID (非图表对象)
const string name="Chart", // 对象名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动对象
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变图表对象大小 |
//+------------------------------------------------------------------+
bool ObjectChartChangeSize(const long chart_ID=0, // 图表 ID (非图表对象)
const string name="Chart", // 对象名称
const int width=300, // 宽度
const int height=200) // 高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the width of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the height of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 返回图表对象 ID |
//+------------------------------------------------------------------+
long ObjectChartGetID(const long chart_ID=0, // 图表 ID (非图表对象)
const string name="Chart") // 对象名称
{
//--- 准备变量获得图表对象 ID
long id=-1;
//--- 重置错误的值
ResetLastError();
//--- 获得ID
if(!ObjectGetInteger(chart_ID,name,OBJPROP_CHART_ID,0,id))
{
Print(__FUNCTION__,
": failed to get \"Chart\" object's ID! Error code = ",GetLastError());
}
//--- 返回结果
return(id);
}
//+------------------------------------------------------------------+
//| 删除图表对象 |
//+------------------------------------------------------------------+
bool ObjectChartDelete(const long chart_ID=0, // 图表 ID (非图表对象)
const string name="Chart") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//---删除按钮
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 获得市场报价交易品种的数量
int symbols=SymbolsTotal(true);
//--- 检查交易品种列表中是否存在指定名称的交易品种
bool exist=false;
for(int i=0;i< symbols;i++)
if(InpSymbol==SymbolName(i,true))
{
exist=true;
break;
}
if(!exist)
{
Print("Error! ",InpSymbol," symbol is not present in \"Market Watch\"!");
return;
}
//--- 检查导入参数的正确性
if(InpScale<0 || InpScale>5)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 设置图表对象坐标及其大小
int x=(int)x_distance/16;
int y=(int)y_distance/16;
int x_size=(int)x_distance*7/16;
int y_size=(int)y_distance*7/16;
//--- 创建图表对象
if(!ObjectChartCreate(0,InpName,0,InpSymbol,InpPeriod,x,y,x_size,y_size,InpCorner,InpScale,InpDateScale,
InpPriceScale,InpColor,InpStyle,InpPointWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 拉伸图表对象
int steps=(int)MathMin(x_distance*7/16,y_distance*7/16);
for(int i=0;i<steps;i++)
{
//--- resize
x_size+=1;
y_size+=1;
if(!ObjectChartChangeSize(0,InpName,x_size,y_size))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重绘图表并等待0.01秒
ChartRedraw();
Sleep(10);
}
//--- 半秒延迟
Sleep(500);
//--- 改变图表时间帧
if(!ObjectChartSetSymbolAndPeriod(0,InpName,InpSymbol,PERIOD_M1))
return;
ChartRedraw();
//--- 3秒延迟
Sleep(3000);
//--- 删除对象
ObjectChartDelete(0,InpName);
ChartRedraw();
//--- 等待1秒
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# 2.2.1.40 OBJ_BITMAP位图对象
ObjBitmap
注意
对于位图对象,您可以选择图像的可视范围 。
示例
下面的脚本创建图表上的多个位图。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates a bitmap in the chart window."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpFile="\\Images\\dollar.bmp"; // 位图文件名称
input int InpWidth=24; // 可见范围 X 坐标
input int InpHeight=24; // 可见范围 Y 坐标
input int InpXOffset=4; // 可见范围沿着 X 轴移动
input int InpYOffset=4; // 可见范围沿着 Y 轴移动
input color InpColor=clrRed; // 高亮显示时的边界颜色
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 高亮显示时的线条风格
input int InpPointWidth=1; // 移动点大小
input bool InpBack=false; // 背景对象
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 在图表窗口创建位图 |
//+------------------------------------------------------------------+
bool BitmapCreate(const long chart_ID=0, // 图表 ID
const string name="Bitmap", // 位图名称
const int sub_window=0, // 子窗口指数
datetime time=0, // 定位点时间
double price=0, // 定位点价格
const string file="", // 位图文件名称
const int width=10, // 可见范围 X 坐标
const int height=10, // 可见范围 Y 坐标
const int x_offset=0, // 可见范围沿着 X 轴移动
const int y_offset=0, // 可见范围沿着 Y 轴移动
const color clr=clrRed, // 高亮显示时的边界颜色
const ENUM_LINE_STYLE style=STYLE_SOLID, // 高亮显示时的线条风格
const int point_width=1, // 移动点大小
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 若未设置则设置定位点的坐标
ChangeBitmapEmptyPoint(time,price);
//--- 重置错误的值
ResetLastError();
//--- 创建位图
if(!ObjectCreate(chart_ID,name,OBJ_BITMAP,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create a bitmap in the chart window! Error code = ",GetLastError());
return(false);
}
//--- 设置图像文件路径
if(!ObjectSetString(chart_ID,name,OBJPROP_BMPFILE,file))
{
Print(__FUNCTION__,
": failed to download the image! Error code = ",GetLastError());
return(false);
}
//--- 设置图形的可见范围;如果有宽度或高度的值
//--- 分别超出源图像的宽度和高度,
//--- 则不绘制;相反,
//--- 只有对应这些值的部分才可绘制
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置将会显示在可见范围内的图像部分
//--- 默认显示图像的左上区域;该值允许
//--- 执行从该区域移动显示图像的另一个区域
ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset);
ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset);
//--- 设置对象高亮模式启动时的边界颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置对象高亮模式启动时的边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置移动对象的定位点大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 为位图设置新图形 |
//+------------------------------------------------------------------+
bool BitmapSetImage(const long chart_ID=0, // 图表 ID
const string name="Bitmap", // 位图名称
const string file="") // 文件路径
{
//--- 重置错误的值
ResetLastError();
//--- 设置图像文件路径
if(!ObjectSetString(chart_ID,name,OBJPROP_BMPFILE,file))
{
Print(__FUNCTION__,
": failed to download the image! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 在图表窗口移动位图 |
//+------------------------------------------------------------------+
bool BitmapMove(const long chart_ID=0, // 图表 ID
const string name="Bitmap", // 位图名称
datetime time=0, // 定位点时间
double price=0) // 定位点价格
{
//--- 如果没有设置点的位置,则将其移动到当前的卖价柱
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- 重置错误的值
ResetLastError();
//--- 移动定位点
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变可见范围(位图)大小 |
//+------------------------------------------------------------------+
bool BitmapChangeSize(const long chart_ID=0, // 图表 ID
const string name="Bitmap", // 位图名称
const int width=0, // 位图宽度
const int height=0) // 位图高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变位图大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the bitmap width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the bitmap height! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------+
//| 改变可见范围左上角的坐标 |
//+--------------------------------------------------------------------+
bool BitmapMoveVisibleArea(const long chart_ID=0, // 图表 ID
const string name="Bitmap", // 位图名称
const int x_offset=0, // 可见范围 X 坐标
const int y_offset=0) // 可见范围 Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 改变位图可见范围的坐标
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset))
{
Print(__FUNCTION__,
": failed to change X coordinate of the visibility scope! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset))
{
Print(__FUNCTION__,
": failed to change Y coordinate of the visibility scope! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除位图 |
//+------------------------------------------------------------------+
bool BitmapDelete(const long chart_ID=0, // 图表 ID
const string name="Bitmap") // 位图名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a bitmap! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 检查定位点的值和为空点设置 |
//| 默认的值 |
//+------------------------------------------------------------------+
void ChangeBitmapEmptyPoint(datetime &time,double &price)
{
//--- 如果点的时间没有设置,它将位于当前柱
if(!time)
time=TimeCurrent();
//--- 如果点的价格没有设置,则它将用卖价值
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // 存储可见柱日期的数组
double close[]; // 存储收盘价的数组
//--- 位图文件名称
string file="\\Images\\dollar.bmp";
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 内存分配
ArrayResize(date,bars);
ArrayResize(close,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 填写收盘价的数组
if(CopyClose(Symbol(),Period(),0,bars,close)==-1)
{
Print("Failed to copy the values of Close prices! Error code = ",GetLastError());
return;
}
//--- 定义图像显示的频率
int scale=(int)ChartGetInteger(0,CHART_SCALE);
//--- 定义步骤
int step=1;
switch(scale)
{
case 0:
step=27;
break;
case 1:
step=14;
break;
case 2:
step=7;
break;
case 3:
step=4;
break;
case 4:
step=2;
break;
}
//--- 创建最高和最低柱的值的位图(间隔)。
for(int i=0;i<bars ;i+=step)
{
//--- 创建位图
if(!BitmapCreate(0,"Bitmap_"+(string)i,0,date[i],close[i],InpFile,InpWidth,InpHeight,InpXOffset,
InpYOffset,InpColor,InpStyle,InpPointWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 半秒延迟
Sleep(500);
//--- 删除卖出符号
for(int i=0;i<bars ;i+=step)
{
if(!BitmapDelete(0,"Bitmap_"+(string)i))
return;
if(!BitmapDelete(0,"Bitmap_"+(string)i))
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# 2.2.1.41 OBJ_BITMAP_LABEL位图对象标签
ObjBitmapLabel
注意
相对于标签的定位点位置可以从 ENUM_ANCHOR_POINT 枚举值中选择。定位点坐标用像素设置。
您也可以从 ENUM_BASE_CORNER 枚举选择位图定位角。针对位图标签,您可以选择图像的 可视范围 。
示例
下面的脚本创建图表上的多个位图。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
FUNCTION__,
": failed to download the image for Off mode! Error code = ",GetLastError());
return(false);
}
//--- 设置标签坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置图形的可见范围;如果有宽度或高度的值
//--- 分别超出源图像的宽度和高度,
//--- 则不绘制;相反,
//--- 只有对应这些值的部分才可绘制
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置将会显示在可见范围内的图像部分
//--- 默认显示图像的左上区域;该值允许
//--- 执行从该区域移动显示图像的另一个区域
ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset);
ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset);
//--- 定义标签状态(出版或发布)
ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
//--- 设置相对于定义点坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置定位类型
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- 设置对象高亮模式启动时的边界颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置对象高亮模式启动时的边界线条风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置移动对象的定位点大小
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 为位图标签对象设置新图形 |
//+------------------------------------------------------------------+
bool BitmapLabelSetImage(const long chart_ID=0, // 图表 ID
const string name="BmpLabel", // 标签名称
const int on_off=0, // 修饰符 (On 或 Off)
const string file="") // 文件路径
{
//--- 重置错误的值
ResetLastError();
//--- 设置图像文件路径
if(!ObjectSetString(chart_ID,name,OBJPROP_BMPFILE,on_off,file))
{
Print(__FUNCTION__,
": failed to download the image! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动位图标签对象 |
//+------------------------------------------------------------------+
bool BitmapLabelMove(const long chart_ID=0, // 图表 ID
const string name="BmpLabel", // 标签名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动对象
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变可见范围(对象)大小 |
//+------------------------------------------------------------------+
bool BitmapLabelChangeSize(const long chart_ID=0, // 图表 ID
const string name="BmpLabel", // 标签名称
const int width=0, // 标签宽度
const int height=0) // 标签高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the object width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the object height! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+--------------------------------------------------------------------+
//| 改变可见范围左上角的坐标 |
//+--------------------------------------------------------------------+
bool BitmapLabelMoveVisibleArea(const long chart_ID=0, // 图表 ID
const string name="BmpLabel", // 标签名称
const int x_offset=0, // 可见范围 X 坐标
const int y_offset=0) // 可见范围Y坐标
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象可见范围的坐标
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset))
{
Print(__FUNCTION__,
": failed to change X coordinate of the visibility scope! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset))
{
Print(__FUNCTION__,
": failed to change Y coordinate of the visibility scope! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除“位图标签”对象 |
//+------------------------------------------------------------------+
bool BitmapLabelDelete(const long chart_ID=0, // 图表 ID
const string name="BmpLabel") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Bitmap label\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 定义位图标签坐标
int x=(int)x_distance/2;
int y=(int)y_distance/2;
//--- 设置标签大小和可见范围坐标
int width=32;
int height=32;
int x_offset=0;
int y_offset=0;
//--- 将位图标签置于窗口中心
if(!BitmapLabelCreate(0,InpName,0,x,y,InpFileOn,InpFileOff,width,height,x_offset,y_offset,InpState,
InpCorner,InpAnchor,InpColor,InpStyle,InpPointWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重绘图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 改变循环中标签可见范围的大小
for(int i=0;i < 6;i++)
{
//--- 改变可见范围大小
width--;
height--;
if(!BitmapLabelChangeSize(0,InpName,width,height))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.3 秒延迟
Sleep(300);
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变循环中标签可见范围的坐标
for(int i=0;i < 2;i++)
{
//--- 改变可见范围的坐标
x_offset++;
y_offset++;
if(!BitmapLabelMoveVisibleArea(0,InpName,x_offset,y_offset))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.3 秒延迟
Sleep(300);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除标签
BitmapLabelDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# 2.2.1.42 OBJ_EDIT编辑对象
ObjEdit
注意
定位点坐标用像素设置。您可以从ENUM_BASE_CORNER枚举值中选择编辑定位角。
您也可以从 ENUM_ALIGN_MODE 枚举在编辑中选择一种文本对齐类型。
示例
下面的脚本创建和移动图表上的编辑对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates \"Edit\" object."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Edit"; // 对象名称
input string InpText="Text"; // 对象文本
input string InpFont="Arial"; // 字体
input int InpFontSize=14; // 字体大小
input ENUM_ALIGN_MODE InpAlign=ALIGN_CENTER; // 文本对齐类型
input bool InpReadOnly=false; // 编辑能力
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // 图表定位角
input color InpColor=clrBlack; // 文本颜色
input color InpBackColor=clrWhite; // 背景色
input color InpBorderColor=clrBlack; // 边框颜色
input bool InpBack=false; // 背景对象
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建编辑对象 |
//+------------------------------------------------------------------+
bool EditCreate(const long chart_ID=0, // 图表 ID
const string name="Edit", // 对象名称
const int sub_window=0, // 子窗口指数
const int x=0, // X 坐标
const int y=0, // Y 坐标
const int width=50, // 宽度
const int height=18, // 高度
const string text="Text", // 文本
const string font="Arial", // 字体
const int font_size=10, // 字体大小
const ENUM_ALIGN_MODE align=ALIGN_CENTER, // 对齐类型
const bool read_only=false, // 编辑能力
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // 图表定位角
const color clr=clrBlack, // 文本颜色
const color back_clr=clrWhite, // 背景色
const color border_clr=clrNONE, // 边框颜色
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 重置错误的值
ResetLastError();
//--- 创建编辑字段
if(!ObjectCreate(chart_ID,name,OBJ_EDIT,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create \"Edit\" object! Error code = ",GetLastError());
return(false);
}
//--- 设置对象坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置对象大小
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置文本
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- 设置文本字体
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- 设置字体大小
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- 设置对象文本算法的类型
ObjectSetInteger(chart_ID,name,OBJPROP_ALIGN,align);
//--- 启用 (true) 或禁用 (false) 只读模式
ObjectSetInteger(chart_ID,name,OBJPROP_READONLY,read_only);
//--- 设置相对于定义对象坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置文本颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置背景颜色
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- 设置边界颜色
ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动编辑对象 |
//+------------------------------------------------------------------+
bool EditMove(const long chart_ID=0, // 图表ID
const string name="Edit", // 对象名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动对象
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 调整编辑对象 |
//+------------------------------------------------------------------+
bool EditChangeSize(const long chart_ID=0, // 图表 ID
const string name="Edit", // 对象名称
const int width=0, // 宽度
const int height=0) // 高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the object width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the object height! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变编辑对象文本 |
//+------------------------------------------------------------------+
bool EditTextChange(const long chart_ID=0, // 图表 ID
const string name="Edit", // 对象名称
const string text="Text") // 文本
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象文本
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 返回编辑对象文本 |
//+------------------------------------------------------------------+
bool EditTextGet(string &text, // 文本
const long chart_ID=0, // 图表's ID
const string name="Edit") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 获得对象文本
if(!ObjectGetString(chart_ID,name,OBJPROP_TEXT,0,text))
{
Print(__FUNCTION__,
": failed to get the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除编辑对象 |
//+------------------------------------------------------------------+
bool EditDelete(const long chart_ID=0, // 图表 ID
const string name="Edit") // 对象名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Edit\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 定义改变编辑字段的步骤
int x_step=(int)x_distance/64;
//--- 设置编辑字段坐标和其大小
int x=(int)x_distance/8;
int y=(int)y_distance/2;
int x_size=(int)x_distance/8;
int y_size=InpFontSize*2;
//--- 在本地变量存储文本
string text=InpText;
//--- 创建编辑字段
if(!EditCreate(0,InpName,0,x,y,x_size,y_size,InpText,InpFont,InpFontSize,InpAlign,InpReadOnly,
InpCorner,InpColor,InpBackColor,InpBorderColor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 延伸编辑字段
while(x_size-x<x_distance*5/8)
{
//--- increase edit field's width
x_size+=x_step;
if(!EditChangeSize(0,InpName,x_size,y_size))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重绘图表并等待0.05 秒
ChartRedraw();
Sleep(50);
}
//--- 半秒延迟
Sleep(500);
//--- 改变文本
for(int i=0;i < 20;i++)
{
//--- 在开始和结束添加 "+"
text="+"+text+"+";
if(!EditTextChange(0,InpName,text))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重绘图表并等待 0.1 秒
ChartRedraw();
Sleep(100);
}
//--- 半秒延迟
Sleep(500);
//--- 删除编辑字段
EditDelete(0,InpName);
ChartRedraw();
//--- 等待1秒
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# 2.2.1.43 OBJ_EVENT事件对象
ObjEvent
注意
当鼠标悬挂在事件上时,会显示其文本。
示例
下面的脚本创建和移动图表上的事件对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script draws \"Event\" graphical object."
#property description "Anchor point date is set in percentage of"
#property description "the chart window width in bars."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="Event"; // 事件名称
input int InpDate=25; // 事件日期,%
input string InpText="Text"; // 事件文本
input color InpColor=clrRed; // 事件颜色
input int InpWidth=1; // 高亮显示时的点大小
input bool InpBack=false; // 背景事件
input bool InpSelection=false; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 在图表上创建事件对象 |
//+------------------------------------------------------------------+
bool EventCreate(const long chart_ID=0, // 图表 ID
const string name="Event", // 事件名称
const int sub_window=0, // 子窗口指数
const string text="Text", // 事件文本
datetime time=0, // 时间
const color clr=clrRed, // 颜色
const int width=1, // 高亮显示时的点宽度
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 如果没有设置时间,请在最近的柱创建对象。
if(!time)
time=TimeCurrent();
//--- 重置错误的值
ResetLastError();
//--- 创建事件对象
if(!ObjectCreate(chart_ID,name,OBJ_EVENT,sub_window,time,0))
{
Print(__FUNCTION__,
": failed to create \"Event\" object! Error code = ",GetLastError());
return(false);
}
//--- 设置事件文本
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- 设置颜色
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 如果对象突出显示则设置定位点宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动事件的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变事件对象文本 |
//+------------------------------------------------------------------+
bool EventTextChange(const long chart_ID=0, // 图表 ID
const string name="Event", // 事件名称
const string text="Text") // 文本
{
//--- 重置错误的值
ResetLastError();
//--- 改变对象文本
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动事件对象 |
//+------------------------------------------------------------------+
bool EventMove(const long chart_ID=0, // 图表 ID
const string name="Event", // 事件名称
datetime time=0) // 时间
{
//--- 如果没有设置线的时间,将事件移动到收盘柱
if(!time)
time=TimeCurrent();
//--- 重置错误的值
ResetLastError();
//--- 移动对象
if(!ObjectMove(chart_ID,name,0,time,0))
{
Print(__FUNCTION__,
": failed to move \"Event\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除事件对象 |
//+------------------------------------------------------------------+
bool EventDelete(const long chart_ID=0, // 图表 ID
const string name="Event") // 事件名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除对象
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Event\" object! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 检查输入参数的正确性
if(InpDate<0 || InpDate>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- 图表窗口的可见柱的数量
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 存储要使用的日期值的数组
//--- 设置和改变事件定位点的坐标
datetime date[];
//--- 内存分配
ArrayResize(date,bars);
//--- 填写日期数组
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- 定义创建对象的点
int d=InpDate*(bars-1)/100;
//--- 创建事件对象
if(!EventCreate(0,InpName,0,InpText,date[d],InpColor,InpWidth,
InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 现在,移动对象
//--- 循环计数器
int h_steps=bars/2;
//--- 移动对象
for(int i=0;i<h_steps;i++)
{
//--- 使用下面的值
if(d< bars-1)
d+=1;
//--- 移动点
if(!EventMove(0,InpName,date[d]))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重画图表
ChartRedraw();
// 0.05 秒延迟
Sleep(50);
}
//--- 1 秒延迟
Sleep(1000);
//--- 删除图表通道
EventDelete(0,InpName);
ChartRedraw();
//--- 1 秒延迟
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# 2.2.1.44 OBJ_RECTANGLE_LABEL矩形标签对象
ObjRectangleLabel
注意
定位点坐标用像素设置。您可以选择矩形标签定位角从 ENUM_BASE_CORNER 枚举。矩形标签边框类型可以从 ENUM_BORDER_TYPE 枚举来选择。
该对象被用于创建和设计自定义的图形界面。
示例
下面的脚本创建和移动图表上的矩形标签对象。开发了特殊函数来创建和更改图形对象的属性。您可以在自己的应用程序中使用这些函数。
//--- 描述
#property description "Script creates \"Rectangle Label\" graphical object."
//--- 启动脚本期间显示输入参数的窗口
#property script_show_inputs
//--- 脚本的输入参数
input string InpName="RectLabel"; // 标签名称
input color InpBackColor=clrSkyBlue; // 背景色
input ENUM_BORDER_TYPE InpBorder=BORDER_FLAT; // 边框类型
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // 图表定位角
input color InpColor=clrDarkBlue; // 平面边框颜色 (Flat)
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // 平面边框风格 (Flat)
input int InpLineWidth=3; // 平面边框宽度(Flat)
input bool InpBack=false; // 背景对象
input bool InpSelection=true; // 突出移动
input bool InpHidden=true; // 隐藏在对象列表
input long InpZOrder=0; // 鼠标单击优先
//+------------------------------------------------------------------+
//| 创建矩形标签 |
//+------------------------------------------------------------------+
bool RectLabelCreate(const long chart_ID=0, // 图表 ID
const string name="RectLabel", // 标签名称
const int sub_window=0, // 子窗口指数
const int x=0, // X 坐标
const int y=0, // Y 坐标
const int width=50, // 宽度
const int height=18, // 高度
const color back_clr=C'236,233,216', // 背景色
const ENUM_BORDER_TYPE border=BORDER_SUNKEN, // 边框类型
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // 图表定位角
const color clr=clrRed, // 平面边框颜色 (Flat)
const ENUM_LINE_STYLE style=STYLE_SOLID, // 平面边框风格
const int line_width=1, // 平面边框宽度
const bool back=false, // 在背景中
const bool selection=false, // 突出移动
const bool hidden=true, // 隐藏在对象列表
const long z_order=0) // 鼠标单击优先
{
//--- 重置错误的值
ResetLastError();
//--- 创建矩形标签
if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0))
{
Print(__FUNCTION__,
": failed to create a rectangle label! Error code = ",GetLastError());
return(false);
}
//--- 设置标签坐标
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- 设置标签大小
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- 设置背景颜色
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- 设置边框类型
ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border);
//--- 设置相对于定义点坐标的图表的角
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- 设置平面边框颜色 (在平面模式下)
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- 设置平面边框线型风格
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- 设置平面边框宽度
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width);
//--- 显示前景 (false) 或背景 (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- 启用 (true) 或禁用 (false) 通过鼠标移动标签的模式
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- 在对象列表隐藏(true) 或显示 (false) 图形对象名称
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- 设置在图表中优先接收鼠标点击事件
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 移动矩形标签 |
//+------------------------------------------------------------------+
bool RectLabelMove(const long chart_ID=0, // 图表 ID
const string name="RectLabel", // 标签名称
const int x=0, // X 坐标
const int y=0) // Y 坐标
{
//--- 重置错误的值
ResetLastError();
//--- 移动矩形标签
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);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变矩形标签的大小 |
//+------------------------------------------------------------------+
bool RectLabelChangeSize(const long chart_ID=0, // 图表 ID
const string name="RectLabel", // 标签名称
const int width=50, // 标签宽度
const int height=18) // 标签高度
{
//--- 重置错误的值
ResetLastError();
//--- 改变标签大小
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the label's width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the label's height! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 改变矩形标签边框类型 |
//+------------------------------------------------------------------+
bool RectLabelChangeBorderType(const long chart_ID=0, // 图表 ID
const string name="RectLabel", // 标签名称
const ENUM_BORDER_TYPE border=BORDER_SUNKEN) // 边框类型
{
//--- 重置错误的值
ResetLastError();
//--- 改变边框类型
if(!ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border))
{
Print(__FUNCTION__,
": failed to change the border type! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 删除矩形标签 |
//+------------------------------------------------------------------+
bool RectLabelDelete(const long chart_ID=0, // 图表 ID
const string name="RectLabel") // 标签名称
{
//--- 重置错误的值
ResetLastError();
//--- 删除标签
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a rectangle label! Error code = ",GetLastError());
return(false);
}
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 图表窗口大小
long x_distance;
long y_distance;
//--- 设置窗口大小
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- 定义矩形标签坐标
int x=(int)x_distance/4;
int y=(int)y_distance/4;
//--- 设置标签大小
int width=(int)x_distance/4;
int height=(int)y_distance/4;
//--- 创建矩形标签
if(!RectLabelCreate(0,InpName,0,x,y,width,height,InpBackColor,InpBorder,InpCorner,
InpColor,InpStyle,InpLineWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- 重绘图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 改变矩形标签的大小
int steps=(int)MathMin(x_distance/4,y_distance/4);
for(int i=0;i<steps ;i++)
{
//--- resize
width+=1;
height+=1;
if(!RectLabelChangeSize(0,InpName,width,height))
return;
//--- 检查脚本操作是否已经强制禁用
if(IsStopped())
return;
//--- 重绘图表并等待0.01秒
ChartRedraw();
Sleep(10);
}
//--- 1 秒延迟
Sleep(1000);
//--- 改变边框类型
if(!RectLabelChangeBorderType(0,InpName,BORDER_RAISED))
return;
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 改变边框类型
if(!RectLabelChangeBorderType(0,InpName,BORDER_SUNKEN))
return;
//--- 重画图表并等待1秒
ChartRedraw();
Sleep(1000);
//--- 删除标签
RectLabelDelete(0,InpName);
ChartRedraw();
//--- 等待1秒
Sleep(1000);
//---
}
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# 2.2.2 对象属性
图形对象可以有不同的属性,这取决于对象类型。对象属性的值是通过与图形对象一起工作的相应函数来设置和接收的。
技术分析中使用的全部对象绑定时间和价格坐标:趋势线,通道,斐波纳契工具等等。但是有许多辅助对象,意在改善绑定图表始终可见部分的用户界面(主图表窗口或指标子窗口):
技术分析中使用的所有对象都绑定到时间和价格坐标:趋势线、通道、斐波那契工具等。但是,有一些辅助对象用于改进用户界面,这些对象绑定到图表的始终可见部分(主图表窗口或副图指标窗口):
对象 | ID | X/Y | 宽度/高度 | 日期/价格 | OBJPROP_CORNER | OBJPROP_ANCHOR | OBJPROP_ANGLE |
---|---|---|---|---|---|---|---|
文本 | OBJ_TEXT | — | — | Yes | — | Yes | Yes |
标签 | OBJ_LABEL | Yes | Yes(只读 | — | Yes | Yes | Yes |
按钮 | OBJ_BUTTON | Yes | Yes | — | Yes | — | — |
位图 | OBJ_BITMAP | — | Yes(只读) | Yes | — | Yes | |
位图标签 | OBJ_BITMAP_LABEL | Yes | Yes(只读) | — | Yes | Yes | — |
编辑 | OBJ_EDIT | Yes | Yes | — | Yes | — | — |
矩形标签 | OBJ_RECTANGLE_LABEL | Yes | Yes | — | Yes | — | — |
表中使用了下列字段名:
• X/Y —— 相对于图表角落,以像素指定的定位点(锚点)坐标; • 宽度/高度 —— 对象有宽度和高度。对于“只读”,只有对象呈现在图表上时才会计算宽度和高度值; • 日期/价格 —— 使用日期和价格值指定(锚点)定位点坐标; • OBJPROP_CORNER —— 定义了指定(锚点)定位点坐标相对的图表角落。可以是4个ENUM_BASE_CORNER 枚举值中的一个; • OBJPROP_ANCHOR —— 定义了对象本身的(锚点)定位点,可以是9个 ENUM_ANCHOR_POINT 枚举值中的一个。从这个点到选定的图表角指定像素坐标; • OBJPROP_ANGLE —— 定义逆时针对象旋转角度。
定义图形对象属性的函数,以及ObjectCreate()和ObjectMove()操作用于在图表中创建和移动对象,实际上是用来向图表发送命令。如果这些函数成功执行,则该命令将包含在图表公共事件的队列中。在处理图表事件的队列时,才会实施图形对象属性的视觉变化。
因此,不要期望在调用这些函数后 图形对象会立即发生视觉上的变化更新。通常情况下,图表上的图形对象会在发生了一个图表事件之后自动更新——例如:客户端收到一个新的报价,调整图表窗口的大小等等。使用ChartRedraw()函数可以强制更新图形对象。
函数 ObjectSetInteger() 和 ObjectGetInteger()
ENUM_OBJECT_PROPERTY_INTEGER
标识符 | 描述 | 属性类型 |
---|---|---|
OBJPROP_COLOR | 颜色 | color |
OBJPROP_STYLE | 类型 | ENUM_LINE_STYLE |
OBJPROP_WIDTH | 线条的宽(厚)度 | int |
OBJPROP_BACK | 显示背景上的对象 | bool |
OBJPROP_ZORDER | 图形对象优先接收点击图表事件(CHARTEVENT_CLICK)。创建对象时默认设置零值;若需要可以提高优先级。当一个接一个地应用对象时,只有级别最高的那个可以收到CHARTEVENT_CLICK 事件。 | long |
OBJPROP_FILL | 颜色填充对象 (针对以下对象 OBJ_RECTANGLE,矩形 OBJ_TRIANGLE,三角形 OBJ_ELLIPSE, 椭圆形 OBJ_CHANNEL,等距通道 OBJ_STDDEVCHANNEL,标准偏差通道 OBJ_REGRESSION 线性回归通道 ) | bool |
OBJPROP_HIDDEN | 当在客户终端文件菜单中顺序点击“图表”-->“对象”-->“对象列表”时,在显示出来的对象列表中隐藏该图形对象的名称。true表示将对象隐藏,即在列表中不显示该对象的名称。在MT5客户端中,默认情况下,下列对象的值被设置为true: 显示日历事件、交易历史和从MQL5程序创建的对象。要查看这些图形对象并访问其属性,请单击“对象列表”窗口中的“所有”按钮。 | bool |
OBJPROP_SELECTED | 对象是否被选中 | bool |
OBJPROP_READONLY | 是否可以在编辑对象中修改文本(是否只读) | bool |
OBJPROP_TYPE | 对象类型 | ENUM_OBJECT r/o |
OBJPROP_TIME | 时间坐标 | 修改时间 = 修改(锚点)定位点 |
OBJPROP_SELECTABLE | 对象是否可用 | bool |
OBJPROP_CREATETIME | 创建对象时间 | datetime r/o |
OBJPROP_LEVELS | 水平线数量 | int |
OBJPROP_LEVELCOLOR | 水平线颜色 | 修改颜色 = 水平线的数量 |
OBJPROP_LEVELSTYLE | 水平线风格 | 修改 ENUM_LINE_STYLE = 水平线的数量平线的数量 |
OBJPROP_LEVELWIDTH | 水平线宽度(粗细) | 修改 int = 水平线的数量 |
OBJPROP_ALIGN | “编辑”对象中的水平文本对齐 (OBJ_EDIT) | ENUM_ALIGN_MODE |
OBJPROP_FONTSIZE | 字体大小 | int |
OBJPROP_RAY_LEFT | 向左延长为射线 | bool |
OBJPROP_RAY_RIGHT | 向右延长为射线 | bool |
OBJPROP_RAY | 垂直线通过图表的全部窗口(包含副图指标窗口) | bool |
OBJPROP_ELLIPSE | 显示裴波那契弧形对象的完整椭圆 (OBJ_FIBOARC) | bool |
OBJPROP_ARROWCODE | 箭头对象代码 | char |
OBJPROP_TIMEFRAMES | 时间框架图表上的对象可见性 | 设置标识 flags 勾选框 |
OBJPROP_ANCHOR | 图解对象的(锚点)定位点 | ENUM_ARROW_ANCHOR (用于 OBJ_ARROW), ENUM_ANCHOR_POINT (用于 OBJ_LABEL, OBJ_BITMAP_LABEL, OBJ_TEXT) |
OBJPROP_XDISTANCE | X轴定位点像素距离 (请参考下面的注意) | int |
OBJPROP_YDISTANCE | Y轴定位点像素距离 (请参考下面的注意) | int |
OBJPROP_DIRECTION | 江恩对象趋势线 | ENUM_GANN_DIRECTION |
OBJPROP_DEGREE | 艾略特波浪标记级别 | ENUM_ELLIOT_WAVE_DEGREE |
OBJPROP_DRAWLINES | 显示用于标记艾略特波浪的线 | bool |
OBJPROP_STATE | 按钮状态(按下/弹起) | bool |
OBJPROP_CHART_ID | “图表”对象的ID (OBJ_CHART)。它允许使用图表操作中描述的函数来处理该对象的属性,比如使用正常的图表,但也有一些例外。 | long r/o |
OBJPROP_XSIZE | X轴向上对象的宽度,单位:像素。用于以下对象 OBJ_LABEL(只读) 标签对象 OBJ_BUTTON、按钮对象 OBJ_CHART、 图表对象 OBJ_BITMAP、位图对象 OBJ_BITMAP_LABEL、 位图对象标签 OBJ_EDIT、 编辑对象 OBJ_RECTANGLE_LABEL 矩形标签对象 | int |
OBJPROP_YSIZE | Y轴向上对象的高度,单位:像素。用于以下对象 OBJ_LABEL(只读) 标签对象 OBJ_BUTTON、按钮对象 OBJ_CHART、 图表对象 OBJ_BITMAP、位图对象 OBJ_BITMAP_LABEL、 位图对象标签 OBJ_EDIT、 编辑对象 OBJ_RECTANGLE_LABEL 矩形标签对象 | int |
OBJPROP_XOFFSET | 用于图形对象“位图标签”(OBJ_BITMAP_LABEL)和“位图”(OBJ_BITMAP) 中的矩形可见区域左上角的X坐标。该值由原始图片左上角对应的像素设置。 | int |
OBJPROP_YOFFSET | 用于图形对象“位图标签”(OBJ_BITMAP_LABEL)和“位图”(OBJ_BITMAP) 中的矩形可见区域左上角的Y坐标。该值由原始图片左上角对应的像素设置。 | int |
OBJPROP_PERIOD | 图解对象时间框架 | ENUM_TIMEFRAMES |
OBJPROP_DATE_SCALE | 显示图解对象时间刻度标尺 | bool |
OBJPROP_PRICE_SCALE | 显示图解对象价格刻度标尺 | bool |
OBJPROP_CHART_SCALE | 图表对象的刻度标尺 | 0-5的整数值 |
OBJPROP_BGCOLOR | 编辑对象背景颜色 OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL | color |
OBJPROP_CORNER | 图表连接到图解对象 | ENUM_BASE_CORNER |
OBJPROP_BORDER_TYPE | “矩形标签”对象的边框类型 | ENUM_BORDER_TYPE |
OBJPROP_BORDER_COLOR | OBJ_EDIT 和 OBJ_BUTTON 对象的边框色 | color |
当使用“图表”对象(OBJ_CHART)的 图表操作 时,会有以下限制:
• 不能使用 ChartClose()关闭; • 不能使用 ChartSetSymbolPeriod() 函数改变交易品种/周期; • 以下属性无效 CHART_SCALE, CHART_BRING_TO_TOP, CHART_SHOW_DATE_SCALE CHART_SHOW_PRICE_SCALE (ENUM_CHART_PROPERTY_INTEGER)
您可以为OBJ_BITMAP_LABEL和OBJ_BITMAP对象设置一个特殊的图像显示模式。在这种模式下,只显示原始图像的一部分(在这个图像中应用一个矩形的可见区域),而图像的其余部分则是不可见的。应该使用OBJPROP_XSIZE和OBJPROP_YSIZE的属性设置该区域的大小。可以使用OBJPROP_XOFFSET和OBJPROP_YOFFSET属性在原始图像中“移动”可见区域。
对于固定大小的对象:OBJ_BUTTON, OBJ_RECTANGLE_LABEL, OBJ_EDIT和OBJ_CHART, 属性 OBJPROP_XDISTANCE和OBJPROP_YDISTANCE设置对象的左上角的位置相对于图角(OBJPROP_CORNER),其中X和Y坐标将以像素计算。
函数 ObjectSetDouble() 和 ObjectGetDouble()
ENUM_OBJECT_PROPERTY_DOUBLE
标识符 | 描述 | 属性类型 |
---|---|---|
OBJPROP_PRICE | 价格坐标 | double 修饰符=定位点号 |
OBJPROP_LEVELVALUE | 水平线的值 | double 修饰符=水平号 |
OBJPROP_SCALE | 比例(江恩对象和斐波纳契 弧线) | double |
OBJPROP_ANGLE | 角度。对于程序创建的,无指定角度的对象来说,它的值等同于 EMPTY_VALUE | double |
OBJPROP_DEVIATION | 标准偏差通道误差 | double |
函数 ObjectSetString() 和 ObjectGetString()
nbsp;
ENUM_OBJECT_PROPERTY_STRING
标识符 | 描述 | 属性类型 |
---|---|---|
OBJPROP_NAME | 物件名称 | string |
OBJPROP_TEXT | 物件描述(物件中包含的文本) | string |
OBJPROP_TOOLTIP | 提示信息文本。如果没有设置属性,那么将显示程序端自动生成的提示信息。提示信息可以通过设置"\n" (line feed) 值来禁用 | string |
OBJPROP_LEVELTEXT | 水平描述 | string 修饰符=水平号 |
OBJPROP_FONT | 字体 | string |
OBJPROP_BMPFILE | 文件的位图标签名称 相关参考 Resources | string 修饰符: 0-state ON, 1-state OFF |
OBJPROP_SYMBOL | 图表对象的交易品种 | string |
对于 OBJ_RECTANGLE_LABEL 对象 ("矩形标签") 可以设置三个设计模式中的一种,与ENUM_BORDER_TYPE 以下值相对应。
标识符 | 描述 |
---|---|
BORDER_FLAT | 平面造型 |
BORDER_RAISED | 突出造型 |
BORDER_SUNKEN | 凹陷造型 |
对于 OBJ_EDIT 对象 ("编辑") 和对于 ChartScreenShot() 函数,您可以使用ENUM_ALIGN_MODE枚举值来指定水平对齐类型。
标识符 | 描述 |
---|---|
ALIGN_LEFT | 左对齐 |
ALIGN_CENTER | 集中(仅用于编辑对象) |
ALIGN_RIGHT | 右对齐 |
示例
#define UP "\x0431"
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
string label_name="my_OBJ_LABEL_object";
if(ObjectFind(0,label_name)<0)
{
Print("Object ",label_name," not found. Error code = ",GetLastError());
//--- create Label object
ObjectCreate(0,label_name,OBJ_LABEL,0,0,0);
//--- set X coordinate
ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200);
//--- set Y coordinate
ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300);
//--- define text color
ObjectSetInteger(0,label_name,OBJPROP_COLOR,clrWhite);
//--- define text for object Label
ObjectSetString(0,label_name,OBJPROP_TEXT,UP);
//--- define font
ObjectSetString(0,label_name,OBJPROP_FONT,"Wingdings");
//--- define font size
ObjectSetInteger(0,label_name,OBJPROP_FONTSIZE,10);
//--- 45 degrees rotation clockwise
ObjectSetDouble(0,label_name,OBJPROP_ANGLE,-45);
//--- disable for mouse selecting
ObjectSetInteger(0,label_name,OBJPROP_SELECTABLE,false);
//--- draw it on the chart
ChartRedraw(0);
}
}
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
# 2.2.3 对象定位方法
图形对象文本 OBJ_TEXT、标签 OBJ_LABEL、位图 OBJ_BITMAP 位图标签 OBJ_BITMAP_LABEL) 。可以使用OBJPROP_ANCHOR属性定义的9种不同的坐标绑定方法中的一种。
对象 | ID | X/Y | 宽度/高度 | 日期/价格 | OBJPROP_CORNER | OBJPROP_ANCHOR | OBJPROP_ANGLE |
---|---|---|---|---|---|---|---|
文本 | OBJ_TEXT | — | — | Yes | — | Yes | Yes |
标签 | OBJ_LABEL | Yes | Yes(只读 | — | Yes | Yes | Yes |
按钮 | OBJ_BUTTON | Yes | Yes | — | Yes | — | — |
位图 | OBJ_BITMAP | — | Yes(只读) | Yes | — | Yes | |
位图标签 | OBJ_BITMAP_LABEL | Yes | Yes(只读) | — | Yes | Yes | — |
编辑 | OBJ_EDIT | Yes | Yes | — | Yes | — | — |
矩形标签 | OBJ_RECTANGLE_LABEL | Yes | Yes | — | Yes | — | — |
表中使用了下列字段名:
• X/Y —— 相对于图表角落,以像素指定的定位点(锚点)坐标; • 宽度/高度 —— 对象有宽度和高度。对于“只读”,只有对象呈现在图表上时才会计算宽度和高度值; • 日期/价格 —— 使用日期和价格值指定(锚点)定位点坐标; • OBJPROP_CORNER —— 定义了指定(锚点)定位点坐标相对的图表角落。可以是4个ENUM_BASE_CORNER 枚举值中的一个; • OBJPROP_ANCHOR —— 定义了对象本身的(锚点)定位点,可以是9个 ENUM_ANCHOR_POINT 枚举值中的一个。从这个点到选定的图表角指定像素坐标; • OBJPROP_ANGLE —— 定义逆时针对象旋转角度。
可以使用函数
ObjectSetInteger(chart_handle、object_name、OBJPROP_ANCHOR、anchor_point_mode) 来指定必要的形式参数变量,其中形式参数 anchor_point_mode 的取值范围是ENUM_ANCHOR_POINT 的枚举值之一。
ENUM_ANCHOR_POINT
ID | 描述 |
---|---|
ANCHOR_LEFT_UPPER | 左上角定位点 |
ANCHOR_LEFT | 左侧定位点 |
ANCHOR_LEFT_LOWER | 左下角定位点 |
ANCHOR_LOWER | 下方定位点 |
ANCHOR_RIGHT_LOWER | 右下方定位点 |
ANCHOR_RIGHT | 右侧定位点 |
ANCHOR_RIGHT_UPPER | 右上角定位点 |
ANCHOR_UPPER | 上方定位点 |
ANCHOR_CENTER | 对象中间严格定位点 |
按钮 OBJ_BUTTON,矩形标签 OBJ_RECTANGLE_LABEL,编辑 OBJ_EDIT, 图表 OBJ_CHART 对象 在左上角(ANCHOR_LEFT_UPPER)有一个修正的定位点(锚点)。
示例
string text_name="my_OBJ_TEXT_object";
if(ObjectFind(0,text_name)<0)
{
Print("Object ",text_name," not found. Error code = ",GetLastError());
//--- 获得图表最大价格
double chart_max_price=ChartGetDouble(0,CHART_PRICE_MAX,0);
//--- 创建物件标签
ObjectCreate(0,text_name,OBJ_TEXT,0,TimeCurrent(),chart_max_price);
//--- 设置文本颜色
ObjectSetInteger(0,text_name,OBJPROP_COLOR,clrWhite);
//--- 设置背景色
ObjectSetInteger(0,text_name,OBJPROP_BGCOLOR,clrGreen);
//--- 设置标签物件文本
ObjectSetString(0,text_name,OBJPROP_TEXT,TimeToString(TimeCurrent()));
//--- 设置文本字体
ObjectSetString(0,text_name,OBJPROP_FONT,"Trebuchet MS");
//--- 设置字体大小
ObjectSetInteger(0,text_name,OBJPROP_FONTSIZE,10);
//--- 定位右上角
ObjectSetInteger(0,text_name,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER);
//--- 顺时针方向旋转90度
ObjectSetDouble(0,text_name,OBJPROP_ANGLE,90);
//--- 禁止鼠标选择物件
ObjectSetInteger(0,text_name,OBJPROP_SELECTABLE,false);
//--- 重画物件
ChartRedraw(0);
}
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
图解对象箭头(OBJ_ARROW)连接到坐标有两种方式,标识符连接到ENUM_ARROW_ANCHOR。 图形对象箭头(OBJ_ARROW)只有两种连接它们的坐标的方法。标识符列在ENUM_ARROW_ANCHOR中。
ENUM_ARROW_ANCHOR
标识符 | 描述 |
---|---|
ANCHOR_TOP | 上部定位点 |
ANCHOR_BOTTOM | 下部定位点 |
void OnStart()
{
//--- 辅助数组
double Ups[],Downs[];
datetime Time[];
//--- 设置数组为时间序列
ArraySetAsSeries(Ups,true);
ArraySetAsSeries(Downs,true);
ArraySetAsSeries(Time,true);
//--- 创建指标iFractals句柄
int FractalsHandle=iFractals(NULL,0);
Print("FractalsHandle = ",FractalsHandle);
//--- 设置最近的错误值到零
ResetLastError();
//--- 复制指标值
int copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
if(copied <= 0)
{
Print("Unable to copy the upper fractals. Error = ",GetLastError());
return;
}
ResetLastError();
//--- 复制指标值
copied=CopyBuffer(FractalsHandle,1,0,1000,Downs);
if(copied<=0)
{
Print("Unable to copy the bottom fractals. Error = ",GetLastError());
return;
}
ResetLastError();
//--- 复制包括最近1000开盘柱的时间序列
copied=CopyTime(NULL,0,0,1000,Time);
if(copied<=0)
{
Print("Unable to copy the Opening Time of the last 1000 bars");
return;
}
int upcounter=0,downcounter=0; // 数箭头数
bool created;// 接收尝试结果去创建物件
for(int i=2;i<copied;i++)// 运行通过指标iFractals值
{
if(Ups[i]!=EMPTY_VALUE)// 找到上面的分数据
{
if(upcounter < 10)// 创建少于10个“向上”箭头
{
//--- 创建 "向上" 物件
created=ObjectCreate(0,string(Time[i]),OBJ_ARROW_THUMB_UP,0,Time[i],Ups[i]);
if(created)// 若设置 - 调节它
{
//--- 定位点在下面为了不覆盖柱
ObjectSetInteger(0,string(Time[i]),OBJPROP_ANCHOR,ANCHOR_BOTTOM);
//--- 最后接触-绘画
ObjectSetInteger(0,string(Time[i]),OBJPROP_COLOR,clrBlue);
upcounter++;
}
}
}
if(Downs[i]!=EMPTY_VALUE)// 发现较低的分数据
{
if(downcounter < 10)// 创建少于10个“向下”箭头
{
//--- 创建 "向下" 物件
created=ObjectCreate(0,string(Time[i]),OBJ_ARROW_THUMB_DOWN,0,Time[i],Downs[i]);
if(created)// 若设置 - 调节它
{
//--- 定位点在上面为了不覆盖柱
ObjectSetInteger(0,string(Time[i]),OBJPROP_ANCHOR,ANCHOR_TOP);
//--- 最后接触-绘画
ObjectSetInteger(0,string(Time[i]),OBJPROP_COLOR,clrRed);
downcounter++;
}
}
}
}
}
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
在脚本执行完毕后,图表看起来像这样。
# 2.2.4 附加物件的图表角落
这里有大量的图形对象 ,为此您可以设置一个图表角落,相对于它指定像素坐标。以下是对象类型(括号中是指定的对象类型标识符):
• 标签 (OBJ_LABEL); • 按键 (OBJ_BUTTON); • 位图标签 (OBJ_BITMAP_LABEL); • 编辑(OBJ_EDIT)。 • 矩形标签(OBJ_RECTANGLE_LABEL);
# 2.2.3 对象定位方法
图形对象文本 OBJ_TEXT、标签 OBJ_LABEL、位图 OBJ_BITMAP 位图标签 OBJ_BITMAP_LABEL) 。可以使用OBJPROP_ANCHOR属性定义的9种不同的坐标绑定方法中的一种。
对象 | ID | X/Y | 宽度/高度 | 日期/价格 | OBJPROP_CORNER | OBJPROP_ANCHOR | OBJPROP_ANGLE |
---|---|---|---|---|---|---|---|
文本 | OBJ_TEXT | — | — | Yes | — | Yes | Yes |
标签 | OBJ_LABEL | Yes | Yes(只读 | — | Yes | Yes | Yes |
按钮 | OBJ_BUTTON | Yes | Yes | — | Yes | — | — |
位图 | OBJ_BITMAP | — | Yes(只读) | Yes | — | Yes | |
位图标签 | OBJ_BITMAP_LABEL | Yes | Yes(只读) | — | Yes | Yes | — |
编辑 | OBJ_EDIT | Yes | Yes | — | Yes | — | — |
矩形标签 | OBJ_RECTANGLE_LABEL | Yes | Yes | — | Yes | — | — |
表中使用了下列字段名:
• X/Y —— 相对于图表角落,以像素指定的定位点(锚点)坐标; • 宽度/高度 —— 对象有宽度和高度。对于“只读”,只有对象呈现在图表上时才会计算宽度和高度值; • 日期/价格 —— 使用日期和价格值指定(锚点)定位点坐标; • OBJPROP_CORNER —— 定义了指定(锚点)定位点坐标相对的图表角落。可以是4个ENUM_BASE_CORNER 枚举值中的一个; • OBJPROP_ANCHOR —— 定义了对象本身的(锚点)定位点,可以是9个 ENUM_ANCHOR_POINT 枚举值中的一个。从这个点到选定的图表角指定像素坐标; • OBJPROP_ANGLE —— 定义逆时针对象旋转角度。
为了指定图表内角,X和Y坐标都要测量像素,使用ObjectSetInteger(chartID,name,OBJPROP_CORNER,chart_corner):
为了指定图表的角,X和Y坐标将以像素为单位进行测量,使用函数 ObjectSetInteger(chartID, name, OBJPROP_CORNER, chart_corner),
其中形式参数的说明如下:
• chartID —— 图表标识符编号; • name —— 图解对象的名称; • OBJPROP_CORNER —— 指定捆绑一个角落的标识符编号ID ; • chart_corner —— 目标图表,可以是 ENUM_BASE_CORNER 枚具值中的一个。
ENUM_BASE_CORNER
ID | 描述 |
---|---|
CORNER_LEFT_UPPER | 中央坐标在图表左上角 |
CORNER_LEFT_LOWER | 中央左边在图表左下角 |
CORNER_RIGHT_LOWER | 中央坐标在图表右下角 |
CORNER_RIGHT_UPPER | 中央左边在图表右上角 |
示例
void CreateLabel(long chart_id,
string name,
int chart_corner,
int anchor_point,
string text_label,
int x_ord,
int y_ord)
{
//---
if(ObjectCreate(chart_id,name,OBJ_LABEL,0,0,0))
{
ObjectSetInteger(chart_id,name,OBJPROP_CORNER,chart_corner);
ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,anchor_point);
ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_ord);
ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_ord);
ObjectSetString(chart_id,name,OBJPROP_TEXT,text_label);
}
else
Print("Failed to create the object OBJ_LABEL ",name,", Error code = ", GetLastError());
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
int width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
string arrows[4]={"LEFT_UPPER","RIGHT_UPPER","RIGHT_LOWER","LEFT_LOWER"};
CreateLabel(0,arrows[0],CORNER_LEFT_UPPER,ANCHOR_LEFT_UPPER,arrows[0],50,50);
CreateLabel(0,arrows[1],CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,arrows[1],50,50);
CreateLabel(0,arrows[2],CORNER_RIGHT_LOWER,ANCHOR_RIGHT_LOWER,arrows[2],50,50);
CreateLabel(0,arrows[3],CORNER_LEFT_LOWER,ANCHOR_LEFT_LOWER,arrows[3],50,50);
}
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
# 2.2.5 对象可见性
对象可见性标志的组合决定了在哪些时间框架的图表上,对象是可见的(显示的),在哪些时间框架的图表上,对象是不可见的(隐藏的)。
要 设置 objprop_timeframe 属性的值,使用函数ObjectSetInteger(),
要 获取 objprop_timeframe 属性的值,使用函数 ObjectGetInteger()。
ID | 值 | 描述 |
---|---|---|
OBJ_NO_PERIODS | 0 | 所有时间图表中都不显示 |
OBJ_PERIOD_M1 | 0x00000001 | 1分钟图表显示 |
OBJ_PERIOD_M2 | 0x00000002 | 2分钟图表显示 |
OBJ_PERIOD_M3 | 0x00000004 | 3分钟图表显示 |
OBJ_PERIOD_M4 | 0x00000008 | 4分钟图表显示 |
OBJ_PERIOD_M5 | 0x00000010 | 5分钟图表显示 |
OBJ_PERIOD_M6 | 0x00000020 | 6分钟图表显示 |
OBJ_PERIOD_M10 | 0x00000040 | 10分钟图表显示 |
OBJ_PERIOD_M12 | 0x00000080 | 12分钟图表显示 |
OBJ_PERIOD_M15 | 0x00000100 | 15分钟图表显示 |
OBJ_PERIOD_M20 | 0x00000200 | 20分钟图表显示 |
OBJ_PERIOD_M30 | 0x00000400 | 30分钟图表显示 |
OBJ_PERIOD_H1 | 0x00000800 | 1小时图表显示 |
OBJ_PERIOD_H2 | 0x00001000 | 2小时图表显示 |
OBJ_PERIOD_H3 | 0x00002000 | 3小时图表显示 |
OBJ_PERIOD_H4 | 0x00004000 | 4小时图表显示 |
OBJ_PERIOD_H6 | 0x00008000 | 6小时图表显示 |
OBJ_PERIOD_H8 | 0x00010000 | 8小时图表显示 |
OBJ_PERIOD_H12 | 0x00020000 | 12小时图表显示 |
OBJ_PERIOD_D1 | 0x00040000 | 日线图表上显示 |
OBJ_PERIOD_W1 | 0x00080000 | 周线图表上显示 |
OBJ_PERIOD_MN1 | 0x00100000 | 月线图表上显示 |
OBJ_ALL_PERIODS | 0x001fffff | 所有时间图表上都显示 |
可以使用符号“|”将可见标志组合在一起,例如,OBJ_PERIOD_M10|OBJ_PERIOD_H4的组合表示将在10分钟和4小时的时间图表上显示该对象。
示例:
void OnStart()
{
//---
string highlevel="PreviousDayHigh";
string lowlevel="PreviousDayLow";
double prevHigh; // 前一天最高价
double prevLow; // 前一天最低价
double highs[],lows[]; // 最高和最低价数组
//--- 重置上一个错误
ResetLastError();
//--- 获得日常时间表最近的2个最高值
int highsgot=CopyHigh(Symbol(),PERIOD_D1,0,2,highs);
if(highsgot>0) // 如果复制成功
{
Print("High prices for the last 2 days were obtained successfully");
prevHigh=highs[0]; // 前一天最高价
Print("prevHigh = ",prevHigh);
if(ObjectFind(0,highlevel)<0) // 没有找到名为highlevel物件
{
ObjectCreate(0,highlevel,OBJ_HLINE,0,0,0); // 创建水平线物件
}
//--- 为高位线价格平面设置值
ObjectSetDouble(0,highlevel,OBJPROP_PRICE,0,prevHigh);
//--- 仅设置PERIOD_M10和PERIOD_H4的可见性
ObjectSetInteger(0,highlevel,OBJPROP_TIMEFRAMES,OBJ_PERIOD_M10|OBJ_PERIOD_H4);
}
else
{
Print("Could not get High prices over the past 2 days, Error = ",GetLastError());
}
//--- 重置上一个错误
ResetLastError();
//--- 获得日常时间表最近的2个最低值
int lowsgot=CopyLow(Symbol(),PERIOD_D1,0,2,lows);
if(lowsgot>0) // 如果复制成功
{
Print("Low prices for the last 2 days were obtained successfully");
prevLow=lows[0]; // 前一天最低价
Print("prevLow = ",prevLow);
if(ObjectFind(0,lowlevel)<0) // 没有找到名为lowlevel物件
{
ObjectCreate(0,lowlevel,OBJ_HLINE,0,0,0); // 创建水平线物件
}
//--- 为低位线价格平面设置值
ObjectSetDouble(0,lowlevel,OBJPROP_PRICE,0,prevLow);
//--- 仅设置PERIOD_M10和PERIOD_H4的可见性
ObjectSetInteger(0,lowlevel,OBJPROP_TIMEFRAMES,OBJ_PERIOD_M10|OBJ_PERIOD_H4);
}
else Print("Could not get Low prices for the last 2 days, Error = ",GetLastError());
ChartRedraw(0); // 强制重画图表
}
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
# 2.2.6 艾略特波浪级别
艾略特波由两种类型的图解对象(OBJ_ELLIOTWAVE5和OBJ_ELLIOTWAVE3)表示。为了设置波浪的大小(标记波浪的方法),使用OBJPROP_DEGREE属性,可以指定ENUM_ELLIOT_WAVE_DEGREE枚举型数据的一个值。
ENUM_ELLIOT_WAVE_DEGREE
ELLIOTT_GRAND_SUPERCYCLE | 特大超级循环级 |
---|---|
ELLIOTT_SUPERCYCLE | 超级循环级 |
ELLIOTT_CYCLE | 循环级 |
ELLIOTT_PRIMARY | 主级 |
ELLIOTT_INTERMEDIATE | 中级 |
ELLIOTT_MINOR | 次级 |
ELLIOTT_MINUTE | 小级 |
ELLIOTT_MINUETTE | 微级 |
ELLIOTT_SUBMINUETTE | 超微级 |
示例:
for(int i=0;i< ObjectsTotal(0);i++)
{
string currobj=ObjectName(0,i);
if((ObjectGetInteger(0,currobj,OBJPROP_TYPE)==OBJ_ELLIOTWAVE3) ||
((ObjectGetInteger(0,currobj,OBJPROP_TYPE)==OBJ_ELLIOTWAVE5)))
{
//--- 在INTERMEDIATE设置标记水平
ObjectSetInteger(0,currobj,OBJPROP_DEGREE,ELLIOTT_INTERMEDIATE);
//--- 显示波峰间的线
ObjectSetInteger(0,currobj,OBJPROP_DRAWLINES,true);
//--- 设置线颜色
ObjectSetInteger(0,currobj,OBJPROP_COLOR,clrBlue);
//--- 设置线宽
ObjectSetInteger(0,currobj,OBJPROP_WIDTH,5);
//--- 设置描述
ObjectSetString(0,currobj,OBJPROP_TEXT,"test script");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.2.7 江恩对象
对于 江恩角度线 (OBJ_GANNFAN) 和 江恩网格 (OBJ_GANNGRID)来说,您可以指定两个用于设置趋势方向的ENUM_GANN_DIRECTION枚举值。
ENUM_GANN_DIRECTION
ID | 描述 |
---|---|
GANN_UP_TREND | 与上升趋势一致的线 |
GANN_DOWN_TREND | 与下降趋势一致的线 |
建立主干线1x1规模,使用 ObjectSetDouble 函数(chart_handle, gann_object_name, OBJPROP_SCALE, scale):
要将主线程设置为1x1,使用函数 ObjectSetDouble(chart_handle, gann_object_name, OBJPROP_SCALE, scale),
其中形式参数的说明如下:
• chart_handle —— 对象加载的图表窗口; • gann_object_name —— 对象名称; • OBJPROP_SCALE —— “Scale”属性标识符; • scale —— 需要以Pips/Bar为单位。
创建江恩角度线示例:
void OnStart()
{
//---
string my_gann="OBJ_GANNFAN object";
if(ObjectFind(0,my_gann)<0)//物件没找到
{
//--- 通知失败
Print("Object ",my_gann," not found. Error code = ",GetLastError());
//--- 获得图表最大价格
double chart_max_price=ChartGetDouble(0,CHART_PRICE_MAX,0);
//--- 获得图表最小价格
double chart_min_price=ChartGetDouble(0,CHART_PRICE_MIN,0);
//--- 多少柱显示在图表上?
int bars_on_chart=ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- 创建一个数组,写下每个柱的开盘时间
datetime Time[];
//--- 像时间序列一样访问数组
ArraySetAsSeries(Time,true);
//--- 现在复制图表中可见的柱数据到数组中
int times=CopyTime(NULL,0,0,bars_on_chart,Time);
if(times<=0)
{
Print("Could not copy the array with the open time!");
return;
}
//--- 完成预备
//--- 图表中心柱指数
int center_bar=bars_on_chart/2;
//--- 图表赤道 - 最大和最小值之间
double mean=(chart_max_price+chart_min_price)/2.0;
//--- 设置第一定位点坐标到中心
ObjectCreate(0,my_gann,OBJ_GANNFAN,0,Time[center_bar],mean,
//--- 第二定位点到右边
Time[center_bar/2],(mean+chart_min_price)/2.0);
Print("Time[center_bar] = "+(string)Time[center_bar]+" Time[center_bar/2] = "+(string)Time[center_bar/2]);
//Print("Time[center_bar]/="+Time[center_bar]+" Time[center_bar/2]="+Time[center_bar/2]);
//--- 设置 Pips / Bar单元比例
ObjectSetDouble(0,my_gann,OBJPROP_SCALE,10);
//--- 设置趋向线
ObjectSetInteger(0,my_gann,OBJPROP_DIRECTION,GANN_UP_TREND);
//--- 设置线宽
ObjectSetInteger(0,my_gann,OBJPROP_WIDTH,1);
//--- 定义线型
ObjectSetInteger(0,my_gann,OBJPROP_STYLE,STYLE_DASHDOT);
//--- 设置线的颜色
ObjectSetInteger(0,my_gann,OBJPROP_COLOR,clrYellowGreen);
//--- 允许用户选择物件
ObjectSetInteger(0,my_gann,OBJPROP_SELECTABLE,true);
//--- 自动选择
ObjectSetInteger(0,my_gann,OBJPROP_SELECTED,true);
//--- 图表上绘画
ChartRedraw(0);
}
}
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
# 2.2.8 网页颜色
以下颜色参量是由颜色类型定义的:
通过使用 ObjectSetInteger() 函数,颜色可以建立一个对象,使用 PlotIndexSetInteger() 函数,可以设置颜色到常规指标中。为了得到颜色值,还可以使用简单函数 ObjectGetInteger() 和 PlotIndexGetInteger().
示例:
//---- 指标设置
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
#property indicator_type3 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_color3 clrLime
2
3
4
5
6
7
8
9
10
# 2.2.9 Wingding
该字符使用 OBJ_ARROW 对象:
示例:
void OnStart()
{
//---
string up_arrow="up_arrow";
datetime time=TimeCurrent();
double lastClose[1];
int close=CopyClose(Symbol(),Period(),0,1,lastClose); // 获得收盘价
//--- 如果获得价格
if(close>0)
{
ObjectCreate(0,up_arrow,OBJ_ARROW,0,0,0,0,0); // 创建一个箭头
ObjectSetInteger(0,up_arrow,OBJPROP_ARROWCODE,241); // 设置箭头代码
ObjectSetInteger(0,up_arrow,OBJPROP_TIME,time); // 设置时间
ObjectSetDouble(0,up_arrow,OBJPROP_PRICE,lastClose[0]);// 预定价格
ChartRedraw(0); // 现在绘制箭头
}
else
Print("Unable to get the latest Close price!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2 .3 指标常量
在MQL5语言程序中有37个预定义的技术指标可以使用。此外,还有机会使用iCustom()函数创建自定义的指标。所有指标中需要的常量被分成7 (5)组:
• 价格常量 —— 选择 价格 或 数量 的类型,用以计算指标; • 平滑方式常量 —— 指标中使用的内置过滤平滑方式; • 指标线常量 —— 当使用CopyBuffer()访问 指标 值时,指标数组的标识符; • 绘画样式常量 —— 用于绘画指标线条样式18种类型之一,并用于设置线条绘画风格; • 自定义指标属性常量 —— 用于处理自定义指标的函数; • 指标类型常量 ——在使用IndicatorCreate()创建句柄时, 用于指定技术指标类型; • 数据类型标识符常量 —— 当把MqlParam数组传到IndicatorCreate()函数中时用来指明数据类型。
# 2.3.1 价格常数
技术指标的计算通常 需要 价格值 和/或 交易量的值,之后才能执行计算。ENUM_APPLIED_PRICE枚举值中有7个预定义的标识符,用于指定所需的价格计算基数。
ENUM_APPLIED_PRICE
ID | 描述 |
---|---|
PRICE_CLOSE | 收盘价格 |
PRICE_OPEN | 开盘价格 |
PRICE_HIGH | 一段行情的最高价格 |
PRICE_LOW | 一段行情的最低价格 |
PRICE_MEDIAN | 中间价(最高价 + 最低价)/2 |
PRICE_TYPICAL | 典型价格(最高价 + 最低价 + 收盘价)/3 |
PRICE_WEIGHTED | 平均价格(最高价 + 最低价 + 收盘价 +开盘价)/4 |
如果在计算中需要使用交易量,则需要从枚举型常量ENUM_APPLIED_VOLUME的两个值中指定一个。
ENUM_APPLIED_VOLUME
ID | 描述 |
---|---|
STO_LOWHIGH | 基于最低价/最高价的计算 |
STO_CLOSECLOSE | 基于开盘价/收盘价的计算 |
如果一个 技术指标 用于计算价格的数据,它的类型是由ENUM_APPLIED_PRICE设置的,那么任何指标的句柄都可以作为输入价格序列(终端内置的 或 由用户编写)。在这种情况下,指标零缓冲值将用于计算。这使得用另一个指标的值更容易构建一个指标的值。自定义指标的句柄是通过调用iCustom()函数创建的。
示例:
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//--- 输入参数
input int RSIperiod=14; // RSI的计算周期
input int Smooth=8; // RSI平滑周期
input ENUM_MA_METHOD meth=MODE_SMMA; // 平滑方式
//---- RSI绘图样式
#property indicator_label1 "RSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//---- RSI_Smoothed 绘图样式
#property indicator_label2 "RSI_Smoothed"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrNavy
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- 指标缓冲数组区
double RSIBuffer[]; // 这里存储 RSI值
double RSI_SmoothedBuffer[]; // RSI平滑值
int RSIhandle; // 处理 RSI 指标
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 指标缓冲区绘图indicator buffers mapping
SetIndexBuffer(0,RSIBuffer,INDICATOR_DATA);
SetIndexBuffer(1,RSI_SmoothedBuffer,INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME,"iRSI");
IndicatorSetInteger(INDICATOR_DIGITS,2);
//---
RSIhandle=iRSI(NULL,0,RSIperiod,PRICE_CLOSE);
//---
}
//+------------------------------------------------------------------+
//| 自定义指标循环函数 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[]
)
{
//--- 重置上一个错误值
ResetLastError();
//--- 数组RSIBuffer []中获得 RSI 指标数据
int copied=CopyBuffer(RSIhandle,0,0,rates_total,RSIBuffer);
if(copied<=0)
{
Print("Unable to copy the values of the indicator RSI. Error = ",
GetLastError(),", copied =",copied);
return(0);
}
//--- 创建使用RSI值的平均值的指标
int RSI_MA_handle=iMA(NULL,0,Smooth,0,meth,RSIhandle);
copied=CopyBuffer(RSI_MA_handle,0,0,rates_total,RSI_SmoothedBuffer);
if(copied<=0)
{
Print("Unable to copy the smoothed indicator of RSI. Error = ",
GetLastError(),", copied =",copied);
return(0);
}
//--- 为下次调用返回prev_calculated值
return(rates_total);
}
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
# 2.3.2 平滑方式
许多技术指标都是基于各种价格序列的平滑(均)方法来计算的。一些标准技术指标要求将平滑(均)类型设置为输入参数。为了指定所需的平滑(均)类型,可以使用枚举常量ENUM_MA_METHOD中列出的标识符。
ENUM_MA_METHOD
ID | 描述 |
---|---|
MODE_SMA | 简单平均数 |
MODE_EMA | 指数平均数 |
MODE_SMMA | 平滑平均数 |
MODE_LWMA | 线性平均数 |
示例:
double ExtJaws[];
double ExtTeeth[];
double ExtLips[];
//---- 移动平均数句柄
int ExtJawsHandle;
int ExtTeethHandle;
int ExtLipsHandle;
//--- 获得 MA's 句柄
ExtJawsHandle=iMA(NULL,0,JawsPeriod,0,MODE_SMMA,PRICE_MEDIAN);
ExtTeethHandle=iMA(NULL,0,TeethPeriod,0,MODE_SMMA,PRICE_MEDIAN);
ExtLipsHandle=iMA(NULL,0,LipsPeriod,0,MODE_SMMA,PRICE_MEDIAN);
2
3
4
5
6
7
8
9
10
11
# 2.3.3 指标线
有一些技术指标,在图表中会显示几种不同的线(每种线对应一个缓冲区),指标缓冲区的编号起始数字是0,当使用CopyBuffer() 函数复制指标的值 到 双精度类型数组 时,对于一些指标来说,可以指定复制 缓冲区的标识符(线条的名称),而不是它的编号。
当复制指标 iMACD(), iRVI() 和 iStochastic() 的值时,可用的指标线标识符
常量 | 值 | 描述 |
---|---|---|
MAIN_LINE | 0 | 主线 |
SIGNAL_LINE | 1 | 信号线 |
当复制指标 ADX() 和 ADXW() 的值时,可用的指标线标识符。
常量 | 值 | 描述 |
---|---|---|
MAIN_LINE | 0 | 主线 |
PLUSDI_LINE | 1 | +DI |
MINUSDI_LINE | 2 | -DI |
当复制指标 iBands() 的值时,可用的指标线标识符
常量 | 值 | 描述 |
---|---|---|
BASE_LINE | 0 | 主线 |
UPPER_BAND | 1 | 上轨线 |
LOWER_BAND | 2 | 下轨线 |
当复制指标 iEnvelopes() 和 iFractals()的值时,可用的指标线标识符
常量 | 值 | 描述 |
---|---|---|
UPPER_LINE | 0 | 上轨线 |
LOWER_LINE | 1 | 下轨线 |
当复制指标 iGator()的值时,可用的指标线标识符。
常量 | 值 | 描述 |
---|---|---|
UPPER_HISTOGRAM | 0 | 上柱 |
LOWER_LINE | 1 | 下柱 |
当复制指标 iAlligator()的值时,可用的指标线标识符。
常量 | 值 | 描述 |
---|---|---|
GATORJAW_LINE | 0 | 爪线 |
GATORTEETH_LINE | 1 | 牙线 |
GATORLIPS_LINE | 2 | 唇线 |
当复制iIchimoku()值时可用的指标线标识符。
常量 | 值 | 描述 |
---|---|---|
TENKANSEN_LINE | 0 | 转换线 |
KIJUNSEN_LINE | 1 | 基准线 |
SENKOUSPANA_LINE | 2 | 通道跨度线A |
SENKOUSPANB_LINE | 3 | 通道跨度线B |
CHIKOUSPAN_LINE | 4 | 延迟线 |
# 2.3.4 绘画风格
当创建一个自定义指标时,您可以指定18种图解测绘方式中的任意一种(显示在主图表窗口 或 副图表子窗口),其值在枚举型常值 ENUM_DRAW_TYPE中指定。
在一个自定义指标中,可以 新建/绘画 ,任意绘画风格的线条类型。为存储绘图所需的数据,每个线条都要求对应1 -- 5个全局数组。通过使用SetIndexBuffer()函数将这些数据数组 与 指标缓冲区(即对应的一个线条)绑定在一起,应该为每个缓冲区指定来自ENUM_INDEXBUFFER_TYPE的数据类型。
根据绘图样式,您可能需要 1--4个缓冲区(标记为INDICATOR_DATA)。如果一个线条样式允许动态改变颜色(所有样式在名称中都包含颜色),那么您将需要多一个颜色缓冲区(指示类型为INDICATOR_COLOR_INDEX)。颜色缓冲区总是绑定到与样式对应的值的(数组)缓冲区。
ENUM_DRAW_TYPE
ID | 描述 | 数据缓冲 | 颜色缓冲 |
---|---|---|---|
DRAW_NONE | 什么也不画 | 1 | 0 |
DRAW_LINE | 画线 | 1 | 0 |
DRAW_SECTION | 线段 | 1 | 0 |
DRAW_HISTOGRAM | 从0值开始画柱状图 | 1 | 0 |
DRAW_HISTOGRAM2 | 两个指标值之间画柱状图 | 2 | 0 |
DRAW_ARROW | 画箭头 | 1 | 0 |
DRAW_ZIGZAG | ZigZag 样式允许K线的垂直部分 | 2 | 0 |
DRAW_FILLING | 两层间的颜色 | 2 | 0 |
DRAW_BARS | 显示一串棒线 | 4 | 0 |
DRAW_COLOR_LINE | 彩色线 | 1 | 1 |
DRAW_COLOR_SECTION | 彩色线段 | 1 | 1 |
DRAW_COLOR_HISTOGRAM | 从0线开始画彩色柱状图 | 1 | 1 |
DRAW_COLOR_HISTOGRAM2 | 两个指标值之间的彩色柱状图 | 2 | 1 |
DRAW_COLOR_ARROW | 描绘彩色箭头 | 1 | 1 |
DRAW_COLOR_ZIGZAG | 彩色ZigZag | 2 | 1 |
DRAW_COLOR_BARS | 彩色棒线 | 4 | 1 |
DRAW_COLOR_CANDLES | 彩色K线蜡烛图 | 4 | 1 |
为了优化所选的绘制类型标识符的显示,请使用ENUM_PLOT_PROPERTY中列出的标识符。 对于函数 PlotIndexSetInteger() 和 PlotIndexGetInteger()
ENUM_PLOT_PROPERTY_INTEGER
ID | 描述 | 属性类型 |
---|---|---|
PLOT_ARROW | DRAW_ARROW的箭头样式代码 | uchar |
PLOT_ARROW_SHIFT | DRAW_ARROW箭头样式在垂直方向上的偏移 | int |
PLOT_DRAW_BEGIN | 在 数据窗口 中没有绘图和值的初始K线数量 | int |
PLOT_DRAW_TYPE | 图解的类型 | ENUM_DRAW_TYPE |
PLOT_SHOW_DATA | 在 数据窗口 中显示构造值的标记 | bool |
PLOT_SHIFT | 在K线的时间轴(x轴)上描绘的指标的偏移 | int |
PLOT_LINE_STYLE | 画线的线型 | ENUM_LINE_STYLE |
PLOT_LINE_WIDTH | 画线粗细 | int |
PLOT_COLOR_INDEXES | 颜色数量 | int |
PLOT_LINE_COLOR | 包含绘图颜色的缓冲区的索引 | color modifier=index number of colors |
函数 PlotIndexSetDouble()
ENUM_PLOT_PROPERTY_DOUBLE
ID | 描述 | 属性类型 |
---|---|---|
PLOT_EMPTY_VALUE | 绘画值为空,表示没有绘图 | double |
函数 PlotIndexSetString()
ENUM_PLOT_PROPERTY_STRING
ID | 描述 | 属性类型 |
---|---|---|
PLOT_LABEL | 显示在 数据窗口 中的指标图解系列的名称. 当使用复杂的需要多个指标缓冲区来显示的图形风格时,可以使用 "," 作为分隔符来指定每个缓冲区的名称。示例代码请参考 DRAW_CANDLES | string |
在自定义的指标中,绘制线条可以使用5种样式。它们只适用于画线,并且粗细值为0或1。
ENUM_LINE_STYLE
ID | 描述 |
---|---|
STYLE_SOLID | 实线 |
STYLE_DASH | 折线 |
STYLE_DOT | 虚线 |
STYLE_DASHDOT | 折点线 |
STYLE_DASHDOTDOT | 双折点线 |
为了设置绘图样式和绘图类型,可以使用PlotIndexSetInteger()函数。对于斐波纳契(Fibonacci)扩展,可以使用ObjectSetInteger()函数来表示层级线的厚度和绘制风格。
示例
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- 指标缓冲区
double MABuffer[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 绑定数组和索引序号为0的指标缓冲区
SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
//--- 设置绘画的样式为 画线
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
//--- 设置线型
PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_DOT);
//--- 设置线颜色
PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrRed);
//--- 设置线粗细
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);
//--- 为线设置标签
PlotIndexSetString(0,PLOT_LABEL,"Moving Average");
//---
}
//+------------------------------------------------------------------+
//| 自定义指标重复函数 |
//+------------------------------------------------------------------+
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[])
{
//---
for(int i=prev_calculated;i<rates_total;i++)
{
MABuffer[i]=close[i];
}
//--- 为下次调用返回prev_calculated值
return(rates_total);
}
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
# 2.3.5 自定义指标属性
用在自定义指标中的指标缓冲区的数量是受限的,使用SetIndexBuffer()函数可以设计成自定义缓冲区,因为要存储,所有指定数据类型是有必要的,也可能是ENUM_INDEXBUFFER_TYPE其中一个值。
在自定义指标中使用的指标缓冲区(数组)的数量是无限的。但是对于每一个被指定为使用SetIndexBuffer()函数的指标缓冲区的数组,必须指定它存储的数据类型。取值范围可以是枚举型常量 ENUM_INDEXBUFFER_TYPE 的一个值。
ENUM_INDEXBUFFER_TYPE
ID | 描述 |
---|---|
INDICATOR_DATA | 描绘数据 |
INDICATOR_COLOR_INDEX | 颜色 |
INDICATOR_CALCULATIONS | 计算中的辅助缓冲区数组 |
自定义指标提供许多设置提供方便演绎,这些设置通过使用IndicatorSetDouble(),IndicatorSetInteger()和 IndicatorSetString() 函数来分别相应指标性质,指标属性的标识符列表在ENUM_CUSTOMIND_PROPERTY中。
自定义指标有许多设置,以提供方便的显示。这些设置是通过使用函数IndicatorSetDouble()、IndicatorSetInteger()和IndicatorSetString()来分别指定到对应的指标属性值来完成的。指标属性的标识符在ENUM_CUSTOMIND_PROPERTY枚举中列出。
ID | 描述 | 属性类型 |
---|---|---|
INDICATOR_DIGITS | 显示指标值的精确度(即,小数点后显示几位) | int |
INDICATOR_HEIGHT | 修正指标窗口的高度 (预处理命令 #property indicator_height) | int |
INDICATOR_LEVELS | 指标窗口中的水平线数量 | int |
INDICATOR_LEVELCOLOR | 水平线的颜色 | color modifier = level number |
INDICATOR_LEVELSTYLE | 水平线的类型 | ENUM_LINE_STYLE modifier = level number |
INDICATOR_LEVELWIDTH | 水平线的厚度 | int modifier = level number |
ENUM_CUSTOMIND_PROPERTY_DOUBLE
ID | 描述 | 属性类型 |
---|---|---|
INDICATOR_MINIMUM | 指标窗口最小化 | double |
INDICATOR_MAXIMUM | 指标窗口最大化 | double |
INDICATOR_LEVELVALUE | 水平线的值 | double modifier = level number |
ENUM_CUSTOMIND_PROPERTY_STRING
ID | 描述 | 属性描述 |
---|---|---|
INDICATOR_SHORTNAME | 指标短名称 | string |
INDICATOR_LEVELTEXT | 水平线说明 | string modifier = level number |
示例
//--- 指标设置
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 2
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
#property indicator_color2 clrRed
//--- 输入参数
extern int KPeriod=5;
extern int DPeriod=3;
extern int Slowing=3;
//--- 指标缓冲区
double MainBuffer[];
double SignalBuffer[];
double HighesBuffer[];
double LowesBuffer[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- 指标缓冲区绘图
SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
//--- 设置精确度
IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- 设置水平
IndicatorSetInteger(INDICATOR_LEVELS,2);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,20);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,80);
//--- 为子窗口设置最大最小值
IndicatorSetDouble(INDICATOR_MINIMUM,0);
IndicatorSetDouble(INDICATOR_MAXIMUM,100);
//--- 设置第一条画指数的柱
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,KPeriod+Slowing-2);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,KPeriod+Slowing+DPeriod);
//--- 为第二行设置STYLE_DOT类型
PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_DOT);
//--- 为DataWindow和指标子窗口标签命名
IndicatorSetString(INDICATOR_SHORTNAME,"Stoch("+KPeriod+","+DPeriod+","+Slowing+")");
PlotIndexSetString(0,PLOT_LABEL,"Main");
PlotIndexSetString(1,PLOT_LABEL,"Signal");
//--- 设置画线空值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
//--- 完成初始化
}
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
# 2.3.6 技术指标类型
有两种方法可以创建指标句柄,以便用于进一步访问其值。第一种方法是直接从技术指标列表中指定一个函数名。第二个方法是使用IndicatorCreate(),通过从ENUM_INDICATOR枚举值中分配一个标识符来统一地创建任何指标的句柄。两种句柄的创建方法都是相同的,您可以使用在MQL5中编写程序时选择最方便的方法。
当创建指标IND_CUSTOM类型时,输入参数 MqlParam 数组中第一个元素的字段 type(类型) 必须有TYPE_STRING 值,并且该值为 ENUM_DATATYPE 枚举中的其中之一,同时而第一个元素中的string_value一定包括自定义指标的名称。
ENUM_INDICATOR
标识符 | 指标 |
---|---|
IND_AC | 加速振荡器 |
IND_AD | 聚集/分散 |
IND_ADX | 均定向指标 |
IND_ADXW | 亚当理论的ADX |
IND_ALLIGATOR | 鳄鱼指标 |
IND_AMA | 相应的移动平均数 |
IND_AO | 动量振荡指标-AO指标 |
IND_ATR | 真实波动幅度均值 |
IND_BANDS | 布林线指标(AO指标) |
IND_BEARS | 熊市 |
IND_BULLS | 牛市 |
IND_BWMFI | 市场便利指标 |
IND_CCI | 顺势指标 |
IND_CHAIKIN | 佳庆指标 |
IND_CUSTOM | 自定义指标 |
IND_DEMA | 双精度移动平均线 |
IND_DEMARKER | DEM指标 |
IND_ENVELOPES | 轨道线指标 |
IND_FORCE | 强力指数 |
IND_FRACTALS | 拼图 |
IND_FRAMA | 自适拼图移动平均数 |
IND_GATOR | 振荡器 |
IND_ICHIMOKU | 一目均衡图 |
IND_MA | 平均移动 |
IND_MACD | MACD |
IND_MFI | 货币流量索引 |
IND_MOMENTUM | 动量 |
IND_OBV | 平衡成交量 |
IND_OsMA | OSMA |
IND_RSI | 相对强势索引 |
IND_RVI | 相对活力索引 |
IND_SAR | 抛物线SAR |
IND_STDDEV | 标准偏差 |
IND_STOCHASTIC | 随机振荡器 |
IND_TEMA | 三倍指数移动平均值 |
IND_TRIX | 三倍指数移动平均值振荡器 |
IND_VIDYA | 索引变量平均值 |
IND_VOLUMES | 成交量 |
IND_WPR | 威廉姆斯百分比幅度 |
# 2.3.7 数据类型标识符
当使用IndicatorCreate()函数创建自定义指标句柄时,必须将一个MqlParam类型的数组指定为最后一个参数。相应地,MqlParam结构,指标描述,包含一个特殊的字段 type。这个字段包含了数据类型的信息(实数型、整数型 或 字符串型),这些信息是由数组的特定元素传递的。MqlParam结构的这个字段的值可能是ENUM_DATATYPE枚举值之一。
ENUM_DATATYPE
标识符 | 数据类型 |
---|---|
TYPE_BOOL | bool |
TYPE_CHAR | char |
TYPE_UCHAR | uchar |
TYPE_SHORT | short |
TYPE_USHORT | ushort |
TYPE_COLOR | color |
TYPE_INT | int |
TYPE_UINT | uint |
TYPE_DATETIME | datetime |
TYPE_LONG | long |
TYPE_ULONG | ulong |
TYPE_FLOAT | float |
TYPE_DOUBLE | double |
TYPE_STRING | string |
数组的每个元素都描述了一个创建的技术指标的对应输入参数,因此,数组中元素的类型和顺序必须与描述保持严格一致。
# 2 .4 环境状态
描述MQL5程序当前运行环境的常量分为如下几组:
•客户端属性 —— 客户端信息; •运行MQL5程序属性 —— MQL5程序特征,它帮助控制执行命令; •交易品种属性 —— 获得有关交易品种的信息; •账户属性 —— 有关账户的信息; •测试统计 —— EA交易的测试结果。
# 2.4.1 客户端属性
关于客户端的信息可以通过两个函数来获得:TerminalInfoInteger()和TerminalInfoString()。关于于参数,这些函数分别接受来自ENUM_TERMINAL_INFO_INTEGER和ENUM_TERMINAL_INFO_STRING的枚举值。
ENUM_TERMINAL_INFO_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
TERMINAL_BUILD | 客户端版本建设号 | int |
TERMINAL_COMMUNITY_ACCOUNT | 该标帜指示在终端中存在MQL5.community授权数据 | bool |
TERMINAL_COMMUNITY_CONNECTION | 连接 MQL5.community | bool |
TERMINAL_CONNECTED | 连接交易服务器 | bool |
TERMINAL_DLLS_ALLOWED | 允许使用DLL | bool |
TERMINAL_TRADE_ALLOWED | 允许交易 | bool |
TERMINAL_EMAIL_ENABLED | 在终端设置允许使用SMTP-服务器 并 登录,发送邮件 | bool |
TERMINAL_FTP_ENABLED | 在终端设置中允许使用FTP-服务器 并 登录,发送报告 | bool |
TERMINAL_NOTIFICATIONS_ENABLED | 允许向智能手机发送通知消息 | bool |
TERMINAL_MAXBARS | 图表中的最大K线数量 | int |
TERMINAL_MQID | 该标帜指示MetaQuotes ID数据用于推送通知。 | bool |
TERMINAL_CODEPAGE | 在客户端中安装的 语言代码页 的编号数字 | int |
TERMINAL_CPU_CORES | 系统的CPU 内核数量 | int |
TERMINAL_DISK_SPACE | 客户端 MQL5\Files 文件夹(代理)中的空闲磁盘空间,单位:MB | int |
TERMINAL_MEMORY_PHYSICAL | 系统的物理内存,单位MB | int |
TERMINAL_MEMORY_TOTAL | 客户端(代理)进程的可用内存总数,MB | int |
TERMINAL_MEMORY_AVAILABLE | 客户端(代理)进程的空闲内存,MB | int |
TERMINAL_MEMORY_USED | 客户端(代理)已使用的内存,MB | int |
TERMINAL_X64 | “64位终端”的指示 | bool |
TERMINAL_OPENCL_SUPPORT | 支持OpenCL 的版本,格式为 0x00010002 = 1.2。 "0" 表示OpenCL 不被支持 | int |
TERMINAL_SCREEN_DPI | 屏幕上信息显示的分辨率是以每英寸的点数(DPI)来衡量的。 知道参数值后,您可以设置图形对象的大小,以便它们在具有不同分辨率特征的监视器上看起来相同。 | int |
TERMINAL_PING_LAST | 最后获得的交易服务器ping值(微秒). 一秒 = 一百万微秒 | int |
按键标识符 | 描述 | 类型 |
---|---|---|
TERMINAL_KEYSTATE_LEFT | “左箭头”键状态 | int |
TERMINAL_KEYSTATE_UP | “上箭头”键状态 | int |
TERMINAL_KEYSTATE_RIGHT | “右箭头”键状态 | int |
TERMINAL_KEYSTATE_DOWN | “下箭头”键状态 | int |
TERMINAL_KEYSTATE_SHIFT | “Shift”键状态 | int |
TERMINAL_KEYSTATE_CONTROL | “Ctrl”键状态 | int |
TERMINAL_KEYSTATE_MENU | “Windows”键状态 | int |
TERMINAL_KEYSTATE_CAPSLOCK/td> | “CapsLock”键状态 | int |
TERMINAL_KEYSTATE_NUMLOCK | “NumLock”键状态 | int |
TERMINAL_KEYSTATE_SCRLOCK | “ScrollLock”键状态 | int |
TERMINAL_KEYSTATE_ENTER | “Enter”键状态 | int |
TERMINAL_KEYSTATE_INSERT | “Insert”键状态 | int |
TERMINAL_KEYSTATE_DELETE | “Delete”键状态 | int |
TERMINAL_KEYSTATE_HOME | “Home”键状态 | int |
TERMINAL_KEYSTATE_END | “End”键状态 | int |
TERMINAL_KEYSTATE_TAB | “Tab”键状态 | int |
TERMINAL_KEYSTATE_PAGEUP | “PageUp”键状态 | int |
TERMINAL_KEYSTATE_PAGEDOWN | “PageDown”键状态 | int |
TERMINAL_KEYSTATE_ESCAPE | “Escape”键状态 | int |
调用TerminalInfoInteger(TERMINAL_KEYSTATE_XXX)返回一个按键的状态代码,与 在MSDN中的调用GetKeyState()函数的结果是一样的。
显示缩放比例系数计算示例 :
//--- 在屏幕上创建 1.5 英寸宽的按键
int screen_dpi = TerminalInfoInteger(TERMINAL_SCREEN_DPI); // 获得用户显示器的DPI
int base_width = 144; // DPI=96标准显示器的屏幕点的基本宽度
int width = (button_width * screen_dpi) / 96; // 为用户显示器(特别DPI)计算按键宽度
...
//--- 按百分比计算比例系数
int scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI) * 100) / 96;
//--- 使用比例系数
width=(base_width * scale_factor) / 100;
2
3
4
5
6
7
8
9
10
在上例中,图形资源在具有不同分辨率的监视器上看起来是相同的。控件元素的大小(按钮、对话框窗口等)对应于个性化设置。
ENUM_TERMINAL_INFO_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
TERMINAL_COMMUNITY_BALANCE | MQL5.community的余额 | double |
文件操作只能在两个目录中执行;可以通过使用TERMINAL_DATA_PATH和TERMINAL_COMMONDATA_PATH属性来获得相应的路径。
ENUM_TERMINAL_INFO_STRING
TERMINAL_LANGUAGE | 客户端语言 | |
---|---|---|
TERMINAL_COMPANY | 公司名称 | string |
TERMINAL_NAME | 客户端名称 | string |
TERMINAL_PATH | 客户端启动文件夹 | string |
TERMINAL_DATA_PATH | 客户端数据文件夹 | string |
TERMINAL_COMMONDATA_PATH | 电脑中所有客户端的共用文件夹 | string |
为了更好地理解文件夹路径,存储在参数TERMINAL_PATH、TERMINAL_DATA_PATH和TERMINAL_COMMONDATA_PATH中的属性,建议执行下面的脚本,该脚本将返回在您的计算机上安装的客户端的当前副本的这些路径值。
示例:脚本返回的有关客户端路径的信息
//+------------------------------------------------------------------+
//| Check_TerminalPaths.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//---
Print("TERMINAL_PATH = ",TerminalInfoString(TERMINAL_PATH));
Print("TERMINAL_DATA_PATH = ",TerminalInfoString(TERMINAL_DATA_PATH));
Print("TERMINAL_COMMONDATA_PATH = ",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
脚本执行的结果,会在 EA 日志中,看到如下的信息:
# 2.4.2 运行MQL程序属性
为了获取当前运行的MQL5程序的信息,可以使用ENUM_MQL_INFO_INTEGER 和 ENUM_MQL_INFO_STRING常量。 使用函数 MQLInfoInteger
ENUM_MQL_INFO_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
MQL_MEMORY_LIMIT | MQL5程序可用的最大动态内存,单位:MB | int |
MQL_MEMORY_USED | MQL5程序已使用的内存大小,MB | int |
MQL_PROGRAM_TYPE | MQL5程序类型 | ENUM_PROGRAM_TYPE |
MQL_DLLS_ALLOWED | 允许为给定的执行程序使用DLL | bool |
MQL_TRADE_ALLOWED | 允许已生效执行的程序进行交易 | bool |
MQL_SIGNALS_ALLOWED | 允许为给定的执行程序更改信号的权限 | bool |
MQL_DEBUG | 此标帜表示调试模式 | bool |
MQL_PROFILER | 此标帜表示以 代码分析模式 运行程序 | bool |
MQL_TESTER | 此标帜表示测试程序 | bool |
MQL_OPTIMIZATION | 此标帜表示优化程序 | bool |
MQL_VISUAL_MODE | 此标帜表示 可视化测试过程 | bool |
MQL_FRAME_MODE | 此标帜表示以收集优化结果框架模式执行EA | bool |
MQL_LICENSE_TYPE | EX5模块的许可类型。许可 是指使用MQLInfoInteger(MQL_LICENSE_TYPE)进行请求的EX5模块。 | ENUM |
函数 MQLInfoString
ENUM_MQL_INFO_STRING
标识符 | 描述 | 类型 |
---|---|---|
MQL_PROGRAM_NAME | mql5已执行的程序名称 | string |
MQL_PROGRAM_PATH | 给定的执行程序的路径 | string |
有关运行程序类型的信息,使用ENUM_PROGRAM_TYPE的值。
ENUM_PROGRAM_TYPE
标识符 | 描述 |
---|---|
PROGRAM_SCRIPT | 脚本 |
PROGRAM_EXPERT | 专家 |
PROGRAM_INDICATOR | 指标 |
ENUM_LICENSE_TYPE
标识符 | 描述 |
---|---|
LICENSE_FREE | 免费无限使用版 |
LICENSE_DEMO | 市场付费产品的试用版仅在策略测试中工作 |
LICENSE_FULL | 购买的授权版允许至少5次激活。激活次数由卖家设定。卖家可以提高允许的激活次数 |
LICENSE_TIME | 有时间期限的授权版 |
示例
ENUM_PROGRAM_TYPE mql_program=(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);
switch(mql_program)
{
case PROGRAM_SCRIPT:
{
Print(__FILE__+" is script这是个脚本");
break;
}
case PROGRAM_EXPERT:
{
Print(__FILE__+" is Expert Advisor这是个EA");
break;
}
case PROGRAM_INDICATOR:
{
Print(__FILE__+" is custom indicator这是个自定义指标");
break;
}
default:Print("MQL5 program type value is程序的类型值是 ",mql_program);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.4.3 交易品种属性
为了获得当前的市场信息,可以使用以下几个函数:SymbolInfoInteger()、SymbolInfoDouble()和SymbolInfoString()。第一个参数是 交易品种的代码符号名称,第二个函数的参数值可以是ENUM_SYMBOL_INFO_INTEGER、ENUM_SYMBOL_INFO_DOUBLE和ENUM_SYMBOL_INFO_STRING的枚举值之一。
函数 SymbolInfoInteger()
ENUM_SYMBOL_INFO_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
SYMBOL_CUSTOM | 这是一个自定义的 交易品种 代码——该交易品种是基于来自市场报价 和/或 外部数据源的另一个交易品种而综合创建的。 | bool |
SYMBOL_BACKGROUND_COLOR | 交易品种 在 市场报价 窗口中的 的背景色 | color |
SYMBOL_CHART_MODE | 用于生成 交易品种 K线柱的价格类型,例如 Bid 或 最新价格。 | ENUM_SYMBOL_CHART_MODE |
SYMBOL_SELECT | 在 市场报价 窗口选中的 交易品种 | bool |
SYMBOL_VISIBLE | 交易品种 在 市场报价 窗口中可见。 一些 交易品种(主要是用于计算保证金要求 或 存款货币利润的交叉汇率)是自动选择的,但在 市场报价 窗口中可能是不可见的。要显示这些交易品种,必须显式地选择。 | bool |
SYMBOL_SESSION_DEALS | 当前会话的交易数量 | long |
SYMBOL_SESSION_BUY_ORDERS | 当时的 做多 订单数量 | long |
SYMBOL_SESSION_SELL_ORDERS | 当时的 做空 订单数量 | long |
SYMBOL_VOLUME | 最后订单的交易成量 | long |
SYMBOL_VOLUMEHIGH | 当天最大订单的交易量 | long |
SYMBOL_VOLUMELOW | 当天最小订单交易量 | long |
SYMBOL_TIME | 最后的报价时间 | datetime |
SYMBOL_DIGITS | 小数点后数字位数 | int |
SYMBOL_SPREAD_FLOAT | 显示浮动点差 | bool |
SYMBOL_SPREAD | 点差值,以 点 为单位 | int |
SYMBOL_TICKS_BOOKDEPTH | 市场深度 窗口中显示的最大请求数。对于没有请求队列的 交易品种 ,值为0。 | int |
SYMBOL_TRADE_CALC_MODE | 合约价格计算方式 | ENUM_SYMBOL_CALC_MODE |
SYMBOL_TRADE_MODE | 订单执行类型 | ENUM_SYMBOL_TRADE_MODE |
SYMBOL_START_TIME | 交易品种 交易开始日期(通常用于期货产品) | datetime |
SYMBOL_EXPIRATION_TIME | 交易品种 交易结束日期(通常用于期货产品) | datetime |
SYMBOL_TRADE_STOPS_LEVEL | 当前 价格 到 止损价 之间的最小距离(停止位)。 | int |
SYMBOL_TRADE_FREEZE_LEVEL | 冻结交易操作的价格距离 | int |
SYMBOL_TRADE_EXEMODE | 交易执行方式 | ENUM_SYMBOL_TRADE_EXECUTION |
SYMBOL_SWAP_MODE | 隔夜利息计算模式 | ENUM_SYMBOL_SWAP_MODE |
SYMBOL_SWAP_ROLLOVER3DAYS | 三日翻转利息 | ENUM_DAY_OF_WEEK |
SYMBOL_MARGIN_HEDGED_USE_LEG | 计算锁仓保证金只收取单边交易手数最大值(做多 或 做空) | bool |
SYMBOL_EXPIRATION_MODE | 订单到期模式 权限标帜 | int |
SYMBOL_FILLING_MODE | 订单填充模式 权限标志 | int |
SYMBOL_ORDER_MODE | 订单类型 的 权限标识 | int |
SYMBOL_ORDER_GTC_MODE | 止损 和 止盈 订单到期模式,如果SYMBOL_EXPIRATION_MODE=SYMBOL_EXPIRATION_GTC(有效直至被取消) | ENUM_SYMBOL_ORDER_GTC_MODE |
SYMBOL_OPTION_MODE | 期权类型 | ENUM_SYMBOL_OPTION_MODE |
SYMBOL_OPTION_RIGHT | 期权(看涨/看跌) | ENUM_SYMBOL_OPTION_RIGHT |
函数 SymbolInfoDouble()
ENUM_SYMBOL_INFO_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
SYMBOL_BID | Bid市场买入价 —— 最佳卖出报价信息 | double |
SYMBOL_BIDHIGH | 一天中市场的最高买入价Bid | double |
SYMBOL_BIDLOW | 一天中市场的最低买入价Bid | double |
SYMBOL_ASK | Ask市场卖出价—— 最佳买入报价信息 | double |
SYMBOL_ASKHIGH | 一天中市场的最高卖出价 | double |
SYMBOL_ASKLOW | 一天中市场的最低卖出价 | double |
SYMBOL_LAST | 最新的交易价格 | double |
SYMBOL_LASTHIGH | 一天中最新的最高价 | double |
SYMBOL_LASTLOW | 一天中最新的最低价 | double |
SYMBOL_OPTION_STRIKE | 期权的执行价格。期权购买者可以购买(在看涨期权中)或卖出(看跌期权)标的资产的价格,而期权卖方有义务出售或购买适当数量的标的资产。 | double |
SYMBOL_POINT | 交易品种点值 | double |
SYMBOL_TRADE_TICK_VALUE | 交易品种每一点对应的金额 | double |
SYMBOL_TRADE_TICK_VALUE_PROFIT | 计算获利单的价格 | double |
SYMBOL_TRADE_TICK_VALUE_LOSS | 计算浮亏单的价格 | double |
SYMBOL_TRADE_TICK_SIZE | 最小报价跳动 | double |
SYMBOL_TRADE_CONTRACT_SIZE | 交易合约大小 | double |
SYMBOL_TRADE_ACCRUED_INTEREST | 应计利息 —— 累积息票利息,即息票利息的一部分,按息票债券发行或息票息后的天数计算。 | double |
SYMBOL_TRADE_FACE_VALUE | 票面价值 —— 发行人设定的初始债券价值。 | double |
SYMBOL_TRADE_LIQUIDITY_RATE | 流动性比率指的是可用于保证金的资产的份额。它被用来作为抵押品的象征。 | double |
SYMBOL_VOLUME_MIN | 一笔交易中的最小成交量(最小手数) | double |
SYMBOL_VOLUME_MAX | 一笔交易中的最大成交量(最大手数) | double |
SYMBOL_VOLUME_STEP | 执行交易的最小成交量(手数)变更单位 | double |
SYMBOL_VOLUME_LIMIT | 交易品种 单向(做多 或 做空)持仓 和 挂单允许的最大交易量(总手数)。例如,限定范围为5手内,即表示您可以拥有5手 做多 持仓订单 和 下单5手 限价做空挂单 订单。但是在这种情况下,你不能再下单 限价做多挂单(因为单向总交易量将会超出限定范围)或 下单超过5手的 限价做空 订单。 | double |
SYMBOL_SWAP_LONG | 做多订单 库存费(利息) | double |
SYMBOL_SWAP_SHORT | 做空订单 库存费(利息) | double |
SYMBOL_MARGIN_INITIAL | 初始保证金 是指每一笔交易在开立头寸时所需要的保证金金额,用于在客户进入市场时检查其资产。 | double |
SYMBOL_MARGIN_MAINTENANCE | 维持保证金。如果设置了,它将从一手交易订单中收取的 交易品种 的保证金货币中设置保证金金额。当客户的帐户状态发生变化时,它用于检查客户的资产。如果维持保证金等于0,则使用初始保证金。 | double |
SYMBOL_SESSION_VOLUME | 当前交易的总交易量 | double |
SYMBOL_SESSION_TURNOVER | 当前的总流通量 | double |
SYMBOL_SESSION_INTEREST | 总持仓利息 | double |
SYMBOL_SESSION_BUY_ORDERS_VOLUME | 当前 做多 订单的交易量 | double |
SYMBOL_SESSION_SELL_ORDERS_VOLUME | 当前 做空 订单的交易量 | double |
SYMBOL_SESSION_OPEN | 当前开仓价格 | double |
SYMBOL_SESSION_CLOSE | 当前平仓价格 | double |
SYMBOL_SESSION_AW | 当前加权平均价格 | double |
SYMBOL_SESSION_PRICE_SETTLEMENT | 当前结算价格 | double |
SYMBOL_SESSION_PRICE_LIMIT_MIN | 当前最低价格 | double |
SYMBOL_SESSION_PRICE_LIMIT_MAX | 当前最高价格 | double |
SYMBOL_MARGIN_HEDGED | 锁仓订单(一个 交易品种 的反向持仓订单)的每手合约大小 或 预付款。锁仓持仓可以使用两种预付款计算方式。计算方式由交易商定义。 基本计算: •如果为 交易品种 指定了初始保证金(symbol__initial),则对冲保证金被指定为绝对值(以货币形式)。 •如果没有指定初始预付款(等于0),SYMBOL_MARGIN_HEDGED 则等于合约大小,这将被用来根据 金融工具(交易品种) 的类型(SYMBOL_TRADE_CALC_MODE)来选定适当公式计算差额。 计算最大持仓: •SYMBOL_MARGIN_HEDGED 值不被考虑。 •计算交易品种所有 做多 和 做空 的交易量。 •对于每个方向,都会计算加权平均 开盘价 和 入金货币 的加权平均转化率。 •下一步,使用根据 交易品种 的类型来选定适当公式(SYMBOL_TRADE_CALC_MODE) 计算 做多 和 做空 持仓的预付款。 •取最大值用作预付款。 | double |
函数 SymbolInfoString()
ENUM_SYMBOL_INFO_STRING
标识符 | 描述 | 类型 |
---|---|---|
SYMBOL_BASIS | 基础衍生资产 | string |
SYMBOL_CURRENCY_BASE | 交易品种的基础货币 | string |
SYMBOL_CURRENCY_PROFIT | 利润货币 | string |
SYMBOL_CURRENCY_MARGIN | 保证金货币 | string |
SYMBOL_BANK | 当前报价数据源 | string |
SYMBOL_DESCRIPTION | 交易品种描述 | string |
SYMBOL_FORMULA | 用于自定义 交易品种 的定价公式 | string |
SYMBOL_ISIN | ISIN系统中交易品种的名称(国际证券识别号码)。国际证券识别号码是一个12位数字字母代码,是证券的唯一识别码。交易品种的属性是由交易服务器方面决定的 。 | string |
SYMBOL_PAGE | 包含交易品种信息的网页地址。这个地址将显示为一个链接,用于在程序端中查看交易品种的属性 | string |
SYMBOL_PATH | 交易品种树形路径 | string |
一个 交易品种 的价格图表可以基于 市场卖出价(Bid) 或 最新报价为基础。为 交易品种 图表选择的价格也会影响客户端中 K线柱的生成和展示。在ENUM_SYMBOL_CHART_MODE(枚举型 交易品种图表模式)中描述了SYMBOL_CHART_MODE属性的枚举值。
ENUM_SYMBOL_CHART_MODE
标识符 | 描述 |
---|---|
SYMBOL_CHART_MODE_BID | K线柱以卖价(Bid)为基础 |
SYMBOL_CHART_MODE_LAST | K线柱以最新报价为基础 |
对于每个 交易品种 而言,可以指定几种 挂单(待定订单)的过期模式。每个模式都匹配一个标志。可以使用逻辑 或(|)操作 来组合标志,例如,SYMBOL_EXPIRATION_GTC|SYMBOL_EXPIRATION_SPECIFIED。 为了检查 交易品种 是否允许某一种模式,可以使用逻辑 与(&)操作 来和模式的标志相比较。
如果交易品种的SYMBOL_EXPIRATION_SPECIFIED标志可以指定,那么在发送一个挂单时,您可以指定这个挂单的有效时间,直至成交激活前。
标识符 | 值 | 描述 |
---|---|---|
SYMBOL_EXPIRATION_GTC | 1 | 订单永久有效,直到被明确取消 |
SYMBOL_EXPIRATION_DAY | 2 | 订单在交易日当天有效 |
SYMBOL_EXPIRATION_SPECIFIED | 4 | 订单中指定的到期时间 |
SYMBOL_EXPIRATION_SPECIFIED_DAY | 8 | 订单中指定的到期日期 |
//+------------------------------------------------------------------+
//| 检测是否允许指定的到期模式 |
//+------------------------------------------------------------------+
bool IsExpirationTypeAllowed(string symbol,int exp_type)
{
//--- 获得描述允许到期模式的属性值
int expiration=(int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
//--- 如果exp_type模式被允许,返回true
return((expiration & exp_type)==exp_type);
}
2
3
4
5
6
7
8
9
10
当使用OrderSend()函数发送交易请求时,应该为一些操作指定来自ENUM_ORDER_TYPE枚举的订单类型。并不是所有类型的订单都可以适用于一个特定的 交易品种。SYMBOL_ORDER_MODE属性描述了允许的订单类型的标识。
例如
//+------------------------------------------------------------------+
//| 该函数打印出交易品种允许的订单类型 |
//+------------------------------------------------------------------+
void Check_SYMBOL_ORDER_MODE(string symbol)
{
//--- 接收描述允许订单类型的属性的值
int symbol_order_mode=(int)SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE);
//--- 检查市价单(市场执行)
if((SYMBOL_ORDER_MARKET & symbol_order_mode)==SYMBOL_ORDER_MARKET)
Print(symbol+": Market orders are allowed (Buy and Sell)");
//--- 检查限价单
if((SYMBOL_ORDER_LIMIT & symbol_order_mode)==SYMBOL_ORDER_LIMIT)
Print(symbol+": Buy Limit and Sell Limit orders are allowed");
//--- 检查止损单
if((SYMBOL_ORDER_STOP & symbol_order_mode)==SYMBOL_ORDER_STOP)
Print(symbol+": Buy Stop and Sell Stop orders are allowed");
//--- 检查止损限价订单
if((SYMBOL_ORDER_STOP_LIMIT & symbol_order_mode)==SYMBOL_ORDER_STOP_LIMIT)
Print(symbol+": Buy Stop Limit and Sell Stop Limit orders are allowed");
//--- 检查是否允许下止损订单
if((SYMBOL_ORDER_SL & symbol_order_mode)==SYMBOL_ORDER_SL)
Print(symbol+": Stop Loss orders are allowed");
//--- 检查是否允许下获利订单
if((SYMBOL_ORDER_TP & symbol_order_mode)==SYMBOL_ORDER_TP)
Print(symbol+": Take Profit orders are allowed");
//---
}
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
为计算 交易品种 的保证金要求,可以使用枚举型ENUM_SYMBOL_CALC_MODE来获取信息。
ENUM_SYMBOL_CALC_MODE
标识符 | 描述 | 公式 |
---|---|---|
SYMBOL_CALC_MODE_FOREX | 外汇模式 —— 按外汇品种计算利润和保证金 | 保证金: Lots * Contract_Size / Leverage Contract_Size / Leverage * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE | 外汇无杠杆模式 —— 不考虑杠杆作用的情况下来计算外汇品种的利润和预付款 | 保证金: Lots * Contract_Size * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_FUTURES | 期货模式 —— 按期货品种计算保证金和利润 | 保证金: Lots * InitialMargin * Percentage / 100 * Margin_Rate 利润: (close_price - open_price) * TickPrice / TickSize * Lots |
SYMBOL_CALC_MODE_CFD | CFD模式 —— 按合约产品计算保证金和利润 | 保证金: Lots * ContractSize * MarketPrice * Percentage / 100 * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_CFDINDEX | CFD指数模式 —— 通过指数计算保证金和利润 | 保证金: (Lots * ContractSize * MarketPrice) * TickPrice / TickSize * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_CFDLEVERAGE | CFD杠杆模式 —— 通过杠杆交易计算保证金和利润 | 保证金: (Lots * ContractSize * MarketPrice * Percentage) / Leverage * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_EXCH_STOCKS | 交换模式 —— 计算股票交易中,交易证券的保证金和赢利 | 保证金: Lots * ContractSize * LastPrice * Margin_Rate 利润: (close_price - open_price) * Contract_Size * Lots |
SYMBOL_CALC_MODE_EXCH_FUTURES | 期货模式—— 计算股票交易中,交易期货合约的保证金和赢利 | 保证金: Lots * InitialMargin or Lots * MaintenanceMargin * Margin_Rate 利润: (close_price - open_price) * Lots*TickPrice / TickSize |
SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS | 期货期权模式—— 计算期权交易中,交易期货合约的保证金和赢利。根据以下规则,保证金可能会因MarginDiscount 偏差的数额而减少: 1. 如果买入价格(做多订单)少于预估价格,MarginDiscount = Lots*((PriceSettle-PriceOrder)TickPrice/TickSize) 2. 如果卖出价格(做空)超过预估价格,MarginDiscount = Lots((PriceOrder-PriceSettle)*TickPrice/TickSize) 在这里: PriceSettle —— 前一交易日的预估价格(清算); PriceOrde——订单(请求)中设置的加权平均持仓价格或持仓价格; TickPrice —— 订单价(成本价格的点变化) TickSize——订单大小(最低价格变化的步骤) | 保证金: Lots * InitialMargin or Lots * MaintenanceMargin * Margin_Rate 利润: (close_price - open_price) * Lots * TickPrice / TickSize |
SYMBOL_CALC_MODE_SERV_COLLATERAL | 担保模式 —— 在交易账户中使用交易品种作为非交易资产。持仓的市值根据交易量,当前市价,合约大小和流动比率进行计算。价值包括在资产中,被加入到净值。这种交易品种的持仓提高了可用预付款的数额,并用作可交易工具持仓的额外预付款(担保)。 | 预付款: no 利润: no 市值: Lots*ContractSize * MarketPrice * LiqudityRate |
交易品种 有多种交易方式,某一 交易品种 的交易方式信息反映在ENUM_SYMBOL_TRADE_MODE枚举值中。
ENUM_SYMBOL_TRADE_MODE
标识符 | 描述 |
---|---|
SYMBOL_TRADE_MODE_DISABLED | 交易品种禁止交易 |
SYMBOL_TRADE_MODE_LONGONLY | 仅允许买入(做多)持仓 |
SYMBOL_TRADE_MODE_SHORTONLY | 仅允许卖出(做空)持仓 |
SYMBOL_TRADE_MODE_CLOSEONLY | 仅允许平仓操作 |
SYMBOL_TRADE_MODE_FULL | 没有交易限制 |
ENUM_SYMBOL_TRADE_EXECUTION枚举中定义了每一个 交易品种 可能的订单执行方式
ENUM_SYMBOL_TRADE_EXECUTION
标识符 | 描述 |
---|---|
SYMBOL_TRADE_MODE_DISABLED | 交易品种禁止交易 |
SYMBOL_TRADE_MODE_LONGONLY | 仅允许买入(做多)持仓 |
SYMBOL_TRADE_MODE_SHORTONLY | 仅允许卖出(做空)持仓 |
SYMBOL_TRADE_MODE_CLOSEONLY | 仅允许平仓操作 |
SYMBOL_TRADE_MODE_FULL | 没有交易限制 |
ENUM_SYMBOL_TRADE_EXECUTION枚举中定义了每一个 交易品种 可能的订单执行方式
ENUM_SYMBOL_TRADE_EXECUTION
标识符 | 描述 |
---|---|
SYMBOL_TRADE_EXECUTION_REQUEST | 请求执行 |
SYMBOL_TRADE_EXECUTION_INSTANT | 立即执行 |
SYMBOL_TRADE_EXECUTION_MARKET | 市场执行 |
SYMBOL_TRADE_EXECUTION_EXCHANGE | 交换执行 |
在枚举型常量ENUM_SYMBOL_SWAP_MODE中指定了仓位的隔夜利息计算方式。利息计算方式决定了 SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT 参数的度量单位。例如,如果以客户入金的货币来收取利息,那么那些参数的值则指定为客户入金货币的金额。
ENUM_SYMBOL_TRADE_EXECUTION
标识符 | 描述 |
---|---|
SYMBOL_SWAP_MODE_DISABLED | 禁用利息(无利息) |
SYMBOL_SWAP_MODE_POINTS | 以点数收取利息 |
SYMBOL_SWAP_MODE_CURRENCY_SYMBOL | 以交易品种基础货币的金额收取利息 |
SYMBOL_SWAP_MODE_CURRENCY_MARGIN | 以交易品种保证金货币的金额收取利息 |
SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT | 以客户入金货币的金额收取利息 |
SYMBOL_SWAP_MODE_INTEREST_CURRENT | 利息作为指定的年利息(标准银行年为360天)时,由 金融工具 的价格指定年度利息。 |
SYMBOL_SWAP_MODE_INTEREST_OPEN | 利息作为指定的年利息(标准银行年为360天)时,由 持仓的开盘价格收取。 |
SYMBOL_SWAP_MODE_REOPEN_CURRENT | 重新持仓收取利息。交易日结束,平仓。第二天以收盘价 +/- 指定点数 (参数 SYMBOL_SWAP_LONG 和SYMBOL_SWAP_SHORT)重新持仓 |
SYMBOL_SWAP_MODE_REOPEN_BID | 重新持仓收取利息。交易日结束,平仓。第二天以当前卖价(Bid) +/- 指定点数 (参数 SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT)重新持仓 |
ENUM_DAY_OF_WEEK枚举值用于指定一周的天数。
ENUM_DAY_OF_WEEK
标识符 | 描述 |
---|---|
SUNDAY | 星期日 |
MONDAY | 星期一 |
TUESDAY | 星期二 |
WEDNESDAY | 星期三 |
THURSDAY | 星期四 |
FRIGAY | 星期五 |
SATURDAY | 星期六 |
期权是一份合约,给予的是权限,而非责任,为了在指定价格或在特定日期前买入或出售基础资产(商品,股票,期货等等)。以下枚举描述了期权的属性,包括期权类型和由其产生的权限。
ENUM_SYMBOL_OPTION_RIGHT
标识符 | 描述 |
---|---|
SYMBOL_OPTION_RIGHT_CALL | 看涨期权就是提供给您在指定价格购买资产的权限 |
SYMBOL_OPTION_RIGHT_PUT | 看跌期权就是提供给您在特定价格出售资产的权限 |
ENUM_SYMBOL_OPTION_MODE
标识符 | 描述 |
---|---|
SYMBOL_OPTION_MODE_EUROPEAN | 欧式期权可能只能在特定日期行使 (到期,执行日期,交付日期) |
SYMBOL_OPTION_MODE_AMERICAN | 美式期权可以在任何交易日或到期之前行使。在指定周期买家可以行使期权 |
# 2.4.4 账户属性
使用 AccountInfoInteger(), AccountInfoDouble() 和 AccountInfoString() 函数可以获得当前账户信息,该函数的参数可以接受来自相应的ENUM_ACCOUNT_INFO枚举的值。
AccountInfoInteger() 函数
ENUM_ACCOUNT_INFO_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
ACCOUNT_LOGIN | 账号数字 | long |
ACCOUNT_TRADE_MODE | 账户交易方式 | ENUM_ACCOUNT_TRADE_MODE |
ACCOUNT_LEVERAGE | 账户杠杆 | long |
ACCOUNT_LIMIT_ORDERS | 最大持单和挂单的允许数量 | int |
ACCOUNT_MARGIN_SO_MODE | 设置最小允许的保证金模式 | ENUM_ACCOUNT_STOPOUT_MODE |
ACCOUNT_TRADE_ALLOWED | 账户允许交易 | bool |
ACCOUNT_TRADE_EXPERT | 允许EA交易 | bool |
ACCOUNT_MARGIN_MODE | 预付款计算模式 | ENUM_ACCOUNT_MARGIN_MODE |
函数 AccountInfoDouble()
ENUM_ACCOUNT_INFO_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
ACCOUNT_BALANCE | 账户余额 | double |
ACCOUNT_CREDIT | 账户信用额度 | double |
ACCOUNT_PROFIT | 账户当前盈利 | double |
ACCOUNT_EQUITY | 账户净值 | double |
ACCOUNT_MARGIN | 账户已用预付款(保证金) | double |
ACCOUNT_MARGIN_FREE | 账户可用预付款(保证金) | double |
ACCOUNT_MARGIN_LEVEL | 账户预付款(保证金)比例百分比形式 | double |
ACCOUNT_MARGIN_SO_CALL | 追加保证金水平,依据建立的ACCOUNT_MARGIN_SO_MODE,以百分比形式 或 存入货币时期表示 | double |
ACCOUNT_MARGIN_SO_SO | 保证金停用水平,依据建立的ACCOUNT_MARGIN_SO_MODE,以百分比形式 或 存入货币时期表示 | double |
ACCOUNT_MARGIN_INITIAL | 初始预付款。账户上保留的金额需要涵盖所有挂单的预付款 | double |
ACCOUNT_MARGIN_MAINTENANCE | 维持预付款。账户上保留的最小净值需要涵盖所有持仓的最小金额 | double |
ACCOUNT_ASSETS | 账户的流动资产 | double |
ACCOUNT_LIABILITIES | 账户的流动负债 | double |
ACCOUNT_COMMISSION_BLOCKED | 账户的当前锁定手续费金额 | double |
函数 AccountInfoString()
ENUM_ACCOUNT_INFO_STRING
标识符 | 描述 | 类型 |
---|---|---|
ACCOUNT_NAME | 帐户名称 | string |
ACCOUNT_SERVER | 交易服务器名称 | string |
ACCOUNT_CURRENCY | 账户货币 | string |
ACCOUNT_COMPANY | 提供账户的公司名称 | string |
交易服务器可以开设的账户类型有以下几种。MQL5程序可以使用枚举型常量ENUM_ACCOUNT_TRADE_MODE 来获得当前账户的类型.
标识符 | 描述 |
---|---|
ACCOUNT_TRADE_MODE_DEMO | 模拟账户 |
ACCOUNT_TRADE_MODE_CONTEST | 竞赛账户 |
ACCOUNT_TRADE_MODE_REAL | 真实账户 |
如果净值不足以保持持仓,止损离场的情况,例如强制平仓发生。出现止损离场的最小预付款水平能够以百分比或货币条款来设置。若要找到账户设置的模式,请使用ENUM_ACCOUNT_STOPOUT_MODE 枚举。
如果帐户净值不足以维持已持有的订单头寸,则会触发止损离场的情况,即强制平仓。触发强制平仓发生的最低保证金水平,可以用 百分比 或 货币金额的形式设定。要获得帐户的模式,请使用ENUM_ACCOUNT_STOPOUT_MODE枚举值。
标识符 | 描述 |
---|---|
ACCOUNT_STOPOUT_MODE_PERCENT | 账户以百分比方式触发强制平仓 |
ACCOUNT_STOPOUT_MODE_MONEY | 账户以货币金额方式触发强制平仓 |
ENUM_ACCOUNT_MARGIN_MODE
标识符 | 描述 |
---|---|
ACCOUNT_MARGIN_MODE_RETAIL_NETTING | 用于OTC市场(场外交易市场,又称柜台交易市场)“单边持仓”模式下的持仓说明 (一个交易品种只存在一个持仓)。预付款计算基于交易品种的类型 (SYMBOL_TRADE_CALC_MODE)。 |
ACCOUNT_MARGIN_MODE_EXCHANGE | 用于外汇交易市场。预付款计算基于交易品种设置中指定的折扣。折扣由交易商设定,但不能低于交易所设定的值。 |
ACCOUNT_MARGIN_MODE_RETAIL_HEDGING | 用于交易市场的个人头寸是可能的(一个 交易品种 允许对冲,可以存在多个头寸)。保证金是根据 交易品种 类型(SYMBOL_TRADE_CALC_MODE)计算的,考虑到对冲的差额(SYMBOL_MARGIN_HEDGED) |
输出简单账户信息的脚本示例。
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 公司名称
string company=AccountInfoString(ACCOUNT_COMPANY);
//--- 客户名称
string name=AccountInfoString(ACCOUNT_NAME);
//--- 账号
long login=AccountInfoInteger(ACCOUNT_LOGIN);
//--- 服务器名称
string server=AccountInfoString(ACCOUNT_SERVER);
//--- 账户货币
string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- 模拟,竞赛或真实账户
ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
//--- 现在将枚举的值转换为一个可理解的形式
string trade_mode;
switch(account_type)
{
case ACCOUNT_TRADE_MODE_DEMO:
trade_mode="demo";
break;
case ACCOUNT_TRADE_MODE_CONTEST:
trade_mode="contest";
break;
default:
trade_mode="real";
break;
}
//--- 以百分比或货币形式设置止损离场
ENUM_ACCOUNT_STOPOUT_MODE stop_out_mode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
//--- 获取当出现预付款调用和止损离场时的水平的值
double margin_call=AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
double stop_out=AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
//--- 显示账户信息简介
PrintFormat("这个帐户是 '%s' #%d %s 属于 '%s' 在服务器 '%s'上",
name,login,trade_mode,company,server);
PrintFormat("帐户资金 - %s, 追加保证金 和 强制止损平仓 水平设置为 %s",
currency,(stop_out_mode==ACCOUNT_STOPOUT_MODE_PERCENT)?"百分比":" 金额");
PrintFormat("追加保证金=%G, 强制止损平仓=%G",margin_call,stop_out);
}
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
# 2.4.5 测试统计
测试结束之后,会统计计算不同的参数的交易结果。通过指定来自ENUM_STATISTICS 枚举的参数ID,可以使用 TesterStatistics() 函数来获得参数值。
虽然两种类型的参数(int和double)都用于计算统计,但是函数会以double格式返回全部的值。double型的所有统计值默认以入金货币表示,除非另有说明。
ENUM_STATISTICS
ID | 统计参数的描述 | 类型 |
---|---|---|
STAT_INITIAL_DEPOSIT | 初始入金存款的金额 | double |
STAT_WITHDRAWAL | 从账户出金取款的金额 | double |
STAT_PROFIT | 测试后的净利润,STAT_GROSS_PROFIT 和 STAT_GROSS_LOSS 的总和(STAT_GROSS_LOSS 始终小于或等于0) | double |
STAT_GROSS_PROFIT | 总利润,所有获利(正值)交易的总和。该值大于或等于0 | double |
STAT_GROSS_LOSS | 总亏损,所有亏损交易的总和。该值小于或等于0 | double |
STAT_MAX_PROFITTRADE | 最大收益 —— 所有获利交易中的最大值。该值大于或等于0 | double |
STAT_MAX_LOSSTRADE | 最大亏损 —— 所有亏损交易中的最低值。该值小于或等于0 | double |
STAT_CONPROFITMAX | 一组连续获利交易中的最大收益。该值大于或等于0 | double |
STAT_CONPROFITMAX_TRADES | 已经形成STAT_CONPROFITMAX (一组获利交易中的最大收益)的交易的数量 | double |
STAT_MAX_CONWINS | 最长的一组获利交易的总利润 | double |
STAT_MAX_CONPROFIT_TRADES | 最长的一组获利交易中的交易总数量 STAT_MAX_CONWINS | double |
STAT_CONLOSSMAX | 一组连续亏损交易中的最大亏损。该值小于或等于0 | double |
STAT_CONLOSSMAX_TRADES | 已经形成 STAT_CONLOSSMAX (一组亏损交易中的最大亏损)的交易的数量 | int |
STAT_MAX_CONLOSSES | 最长一组亏损交易的总亏损 | double |
STAT_MAX_CONLOSS_TRADES | 最长的一组亏损交易中的交易数量 STAT_MAX_CONLOSSES | int |
STAT_BALANCEMIN | 余额的最小值 | double |
STAT_BALANCE_DD | 以货币计算,最大的余额跌幅。在交易处理过程中,余额可能有大幅度下跌,这里采用最大的值 | double |
STAT_BALANCEDD_PERCENT | 以百分比计算余额下跌,记录于货币计算的最大余额跌幅的时期 (STAT_BALANCE_DD)。 | double |
STAT_BALANCE_DDREL_PERCENT | 以百分比计算最大余额跌幅。在交易处理过程中,余额可能有大幅度下跌,每次相关的下跌值都以百分比计算返回最大的值 | double |
STAT_BALANCE_DD_RELATIVE | 以货币计算余额下跌,记录于百分比计算的最大余额跌幅时期 (STAT_BALANCE_DDREL_PERCENT) | double |
STAT_EQUITYMIN | 最小净值 | double |
STAT_EQUITY_DD | 以货币计算,最大的净值跌幅。在交易处理过程中,净值上可能出现大幅度下跌,这里采用最大的值 | double |
STAT_EQUITYDD_PERCENT | 以百分比计算下跌,记录于货币计算的最大净值跌幅的时期 (STAT_EQUITY_DD)。 | double |
STAT_EQUITY_DDREL_PERCENT | 以百分比计算最大净值跌幅。在交易处理过程中,净值可能有大幅度下跌,每次相关的下跌值都以百分比计算返回最大的值 | double |
STAT_EQUITY_DD_RELATIVE | 以货币计算净值下跌,记录于百分比计算的最大净值跌幅时期(STAT_EQUITY_DDREL_PERCENT)。 | double |
STAT_EXPECTED_PAYOFF | 期望收益 | double |
STAT_PROFIT_FACTOR | 利润因子,等于STAT_GROSS_PROFIT/STAT_GROSS_LOSS比率。如果STAT_GROSS_LOSS=0, 利润因子就等于 DBL_MAX | double |
STAT_RECOVERY_FACTOR | 采收率,等于 STAT_PROFIT/STAT_BALANCE_DD的比率 | double |
STAT_SHARPE_RATIO | 夏普比率 | double |
STAT_MIN_MARGINLEVEL | 保证金水平的最小值 | double |
STAT_CUSTOM_ONTESTER | 由OnTester()函数返回的计算自定义优化标准的值。 | double |
STAT_DEALS | 成交数量 | int |
STAT_TRADES | 交易的数量 | int |
STAT_PROFIT_TRADES | 获利交易 | int |
STAT_LOSS_TRADES | 亏损交易 | int |
STAT_SHORT_TRADES | 做空交易 | int |
STAT_LONG_TRADES | 做多交易 | int |
STAT_PROFIT_SHORTTRADES | 获利的做空交易 | int |
STAT_PROFIT_LONGTRADES | 获利的做多交易 | int |
STAT_PROFITTRADES_AVGCON | 一组获利交易的平均长度 | int |
STAT_LOSSTRADES_AVGCON | 一组亏损交易的平均长度 | int |
# 2.5 交易常量
用于规划交易策略的各种常量分为以下几组:
• 历史数据库属性 —— 接收一般信息; • 订单属性 —— 获得交易订单信息; • 仓位属性 —— 获得当前仓位价格信息; • 交易属性 —— 获得交易信息; • 交易操作类型 —— 交易可行性描述; • 交易事务类型 —— 描述可能的交易事务类型; • DOM(市场深度)交易订单 —— 按照要求操作的方向,在DOM(Depth of the market)中交易订单。
# 2.5.1 历史数据库属性
当访问时间序列时,函数SeriesInfoInteger() 用来获得额外 交易品种信息。作为函数参数传递所需属性的标识符是枚举型常量 ENUM_SERIES_INFO_INTEGER中的一个。
ENUM_SERIES_INFO_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
SERIES_BARS_COUNT | 交易品种 当前时间框架中K线柱的数量 | long |
SERIES_FIRSTDATE | 当前 交易品种 时间框架 中第一根K线的时间 | datetime |
SERIES_LASTBAR_DATE | 当前 交易品种 时间框架 中最后一根K线的开盘时间 | datetime |
SERIES_SERVER_FIRSTDATE | 服务器上该 交易品种 的历史数据中第一根K线的日期时间,无论 时间框架 。 | datetime |
SERIES_TERMINAL_FIRSTDATE | 客户端上该 交易品种 的历史数据中第一根K线的日期时间,无论 时间框架 。 | datetime |
SERIES_SYNCHRONIZED | 当前 交易品种 的时间框架图表 数据同步标帜 | bool |
# 2.5.2 订单属性
执行交易操作的请求被正式化为订单。每个订单都有各种各样的属性以供阅读。可以通过函数OrderGet.()和HistoryOrderGet…()获得关于它们的信息。
用于函数OrderGetInteger()和HistoryOrderGetInteger()
ENUM_ORDER_PROPERTY_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
ORDER_TICKET | 订单编号。每个订单分配一个唯一的号码 | long |
ORDER_TIME_SETUP | 订单设置时间 | datetime |
ORDER_TYPE | 订单类型 | ENUM_ORDER_TYPE |
ORDER_STATE | 订单状态 | ENUM_ORDER_STATE |
ORDER_TIME_EXPIRATION | 订单过期时间 | datetime |
ORDER_TIME_DONE | 订单 执行 或 取消 的时间 | datetime |
ORDER_TIME_SETUP_MSC | 01.01.1970以来订单设置的时间,单位: ms | long |
ORDER_TIME_DONE_MSC | 01.01.1970以来订单 执行 或 取消 的时间,单位: ms | long |
ORDER_TYPE_FILLING | 订单填充(成交手数计算)类型 | ENUM_ORDER_TYPE_FILLING |
ORDER_TYPE_TIME | 订单存活周期 | ENUM_ORDER_TYPE_TIME |
ORDER_MAGIC | EA交易安置在订单之中的ID(为确保每个EA交易的订单都有一个唯一的魔术识别码) | long |
ORDER_REASON | 下单的原因 或 来源 | ENUM_ORDER_REASON |
ORDER_POSITION_ID | 仓位标识符,当它被执行时,它将被设置为一个订单。每一个执行的订单都会导致一笔 交易 打开 或 修改已经存在的仓位。此时,该位置的标识符将被设置为已执行的订单。 | long |
ORDER_POSITION_BY_ID | 反向持仓标识符,用于关闭订单ORDER_TYPE_CLOSE_BY | long |
函数 OrderGetDouble() 和 HistoryOrderGetDouble()
ENUM_ORDER_PROPERTY_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
ORDER_VOLUME_INITIAL | 订单最初交易量 | double |
ORDER_VOLUME_CURRENT | 订单当前交易量 | double |
ORDER_PRICE_OPEN | 订单开仓价格 | double |
ORDER_SL | 止损位 | double |
ORDER_TP | 止盈位 | double |
ORDER_PRICE_CURRENT | 交易品种订单的当前价格 | double |
ORDER_PRICE_STOPLIMIT | 追损和限价订单的限制价格 | double |
函数 OrderGetString() 和 HistoryOrderGetString()
ENUM_ORDER_PROPERTY_STRING
标识符 | 描述 | 类型 |
---|---|---|
ORDER_SYMBOL | 订单的交易品种 | string |
ORDER_COMMENT | 订单的注释 | string |
当使用OrderSend()函数发送交易请求时,一些操作需要指示订单类型。订单类型在特殊结构MqlTradeRequest的 类型(type) 字段中指定,并且可以接受ENUM_ORDER_TYPE枚举的值。
标识符 | 描述 |
---|---|
ORDER_TYPE_BUY | 做多订单 |
ORDER_TYPE_SELL | 做空订单 |
ORDER_TYPE_BUY_LIMIT | 限价挂多单 |
ORDER_TYPE_SELL_LIMIT | 限价挂空单 |
ORDER_TYPE_BUY_STOP | 到达指定价格之上,挂限价多单 |
ORDER_TYPE_SELL_STOP_LIMIT | 到达指定价格之上,挂限价空单 |
ORDER_TYPE_CLOSE_BY | 通过反向持仓单平仓的订单 |
每个订单都有描述其状态的标识符。要获取订单的状态信息,请使用ORDER_STATE修饰符来使用 OrderGetInteger() 或 HistoryOrderGetInteger()。 可使用的取值范围存储在ENUM_ORDER_STATE枚举中。
标识符 | 描述 |
---|---|
ORDER_STATE_STARTED | 订单已被选中,但经纪平台未接收 |
ORDER_STATE_PLACED | 订单已被接受 |
ORDER_STATE_CANCELED | 客户撤销订单 |
ORDER_STATE_PARTIAL | 订单部分成交 |
ORDER_STATE_FILLED | 订单全部成交 |
ORDER_STATE_REJECTED | 驳回订单 |
ORDER_STATE_EXPIRED | 订单过期 |
ORDER_STATE_REQUEST_ADD | 注册订单(已放置到交易系统) |
ORDER_STATE_REQUEST_MODIFY | 更改订单(改变其参数) |
ORDER_STATE_REQUEST_CANCEL | 删除订单(从交易系统中删除) |
标识符 | 描述 |
---|---|
ORDER_FILLING_FOK | FOK(Fill or Kill)类型成交策略意味着订单只能按指定的交易量(手数)执行。如果当前市场无法提供 金融工具 需要的交易量(手数),则订单将无法成交。需要的交易量可以使用市场此刻提供的几种可用来源来执行。 |
ORDER_FILLING_IOC | IOC(Immediate or Cancel)该类型意味着交易者同意在订单指定范围内,以市场可用的最大交易量执行交易。如果无法执行全部订单交易量,那么剩下的交易量将被取消。 |
ORDER_FILLING_RETURN | 该类型只用于市场订单 (ORDER_TYPE_BUY 和 ORDER_TYPE_SELL),限价和追损限价订单 (ORDER_TYPE_BUY_LIMIT,ORDER_TYPE_SELL_LIMIT,ORDER_TYPE_BUY_STOP_LIMIT 和 ORDER_TYPE_SELL_STOP_LIMIT ) 并且只用于 市场执行 或 外汇交易 执行的交易品种。如果部分执行市场或剩下交易量的限价订单没有取消,则仍会进一步处理。 为了激活ORDER_TYPE_BUY_STOP_LIMIT 和 ORDER_TYPE_SELL_STOP_LIMIT 订单,将会创建ORDER_FILLING_RETURN执行类型相应的限价订单 ORDER_TYPE_BUY_LIMIT/ORDER_TYPE_SELL_LIMIT 。 |
当使用OrderSend() 函数发送交易请求时,订单有效期设置在特殊结构MqlTradeRequest 中的type_time字段,允许使用枚举ENUM_ORDER_TYPE_TIME的值之一,使用ORDER_TYPE_TIME修饰符和OrderGetInteger() 或 HistoryOrderGetInteger() 函数可以获得该属性的值。
标识符 | 描述 |
---|---|
ORDER_TIME_GTC | (Good Till Cancel)一直持有只到取消订单 |
ORDER_TIME_DAY | 当前交易日结束时取消订单 |
ORDER_TIME_SPECIFIED | 到指定的过期时间即取消订单 |
ORDER_TIME_SPECIFIED_DAY | 订单将生效直至指定日期的23:59:59。如果该时间超出了交易期,那么该订单会在最近的交易时间内到期。 该订单的有效期为指定日期的23:59:59。如果这个时间是在交易时段之外(休市时间),该订单将在最近的交易日结束时到期。 |
订单放置的原因包含在ORDER_REASON属性中。一个订单可能来自一个MQL5程序,或一个移动应用程序,或 作为强制平仓的结果,等等。ORDER_REASON的可能值在ENUM_ORDER_REASON枚举中描述。
标识符 | 描述 |
---|---|
ORDER_REASON_CLIENT | 从PC桌面客户端下单 |
ORDER_REASON_MOBILE | 从移动端(iPhone 或 安卓)下单 |
ORDER_REASON_WEB | 从网页端下单 |
ORDER_REASON_EXPERT | 从MQL5程序下单,例如EA 或 脚本 |
ORDER_REASON_SL | 因激活止损而下单 |
ORDER_REASON_TP | 因激活止赢而下单 |
ORDER_REASON_SO | 因强制平仓事件而下单 |
# 2.5.3 仓位属性
执行交易操作,如 交易手数的变化 和/或 改变下单方向(做多 或 做空)的结果,会导致一个 仓位 的 出现 或 消失。交易操作以 订单为基础管理,由OrderSend()函数以交易请求的形式发送。对于每个 金融工具(交易品种),一个时刻只有一个持有的 仓位。仓位具有一组属性,可以通过PositionGet…()函数来获取。
函数 PositionGetInteger()
ENUM_POSITION_PROPERTY_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
POSITION_TICKET | 仓位的编号。分配给每个新打开的仓位的唯一编号。它通常与打开该位置的订单的编号相匹配,除非由于服务器上的服务操作而更改了编号,例如,当计算隔夜利息而重新打开订单时。要查找用于打开订单价位的命令,请应用POSITION_IDENTIFIER属性。 POSITION_TICKET值对应于MqlTradeRequest::position | long |
POSITION_TIME | 仓位打开时间 | datetime |
POSITION_TIME_MSC | 自01.01.1970以来持仓的时间,单位:ms | long |
POSITION_TIME_UPDATE | 自01.01.1970以来最近更新持仓后的时间,单位:秒 | long |
POSITION_TIME_UPDATE_MSC | 自01.01.1970以来最近更新持仓后的时间,单位:ms | long |
POSITION_TYPE | 仓位类型 | ENUM_POSITION_TYPE |
POSITION_MAGIC | 仓位保证一识别魔术号码(参考 ORDER_MAGIC ) | long |
POSITION_IDENTIFIER | 仓位标识符 是分配给每个重新打开的仓位的唯一数字编号。在仓位的整个生命周期中它不会发生变化,它对应于一个用来打开一个价位的订单的编号。 仓位标识符在每个订单 (ORDER_POSITION_ID)和交易 (DEAL_POSITION_ID)中指定,用于打开、修改或关闭它。使用此属性搜索与该仓位相关的订单和交易。 当在 净值模式 (netting mode)中反转一个仓位时(使用单向交易 买入/售出 ), POSITION_IDENTIFIER不会改变。然而,POSITION_TICKET被替换为导致反转的订单的编号。在对冲(锁仓)模式下不支持仓位反转。 | long |
POSITION_REASON | 持仓的原因 | ENUM_POSITION_REASON |
函数 PositionGetDouble()
ENUM_POSITION_PROPERTY_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
POSITION_VOLUME | 仓位成交量 | double |
POSITION_PRICE_OPEN | 仓位价格 | double |
POSITION_SL | 仓位止损价位 | double |
POSITION_TP | 仓位止盈价位 | double |
POSITION_PRICE_CURRENT | 仓位当前价位 | double |
POSITION_SWAP | 隔夜利息 | double |
POSITION_PROFIT | 当前利润 | double |
函数 PositionGetString()
ENUM_POSITION_PROPERTY_STRING
标识符 | 描述 | 类型 |
---|---|---|
POSITION_SYMBOL | 仓位的交易品种 | string |
POSITION_COMMENT | 仓位注释文本 | string |
标识符 | 描述 |
---|---|
POSITION_TYPE_BUY | 做多(买入) |
POSITION_TYPE_SELL | 做空(售出) |
打开一个仓位的原因包含在POSITION_REASON属性中。一个打开的仓位可能来自,桌面客户端、移动应用程序、专家顾问EA等的订单被激活。POSITION_REASON的取值范围在ENUM_POSITION_REASON枚举值中描述。
标识符 | 描述 |
---|---|
POSITION_REASON_CLIENT | 来自桌面客户端的订单被激活 |
POSITION_REASON_MOBILE | 来自移动端的订单被激活 |
POSITION_REASON_WEB | 来自网页端的订单被激活 |
POSITION_REASON_EXPERT | 来自MQL程序的订单被激活 |
# 2.5.4 交易属性
一笔交易的执行是基于一个订单的交易请求,反映实际执行的结果。每个交易(请求)都具有一组属性来描述,可以获取其属性信息。为了读取属性的值,可以使用HistoryDealGet…()类型的函数,从对应的枚举值中返回结果值。
函数 HistoryDealGetInteger()
ENUM_DEAL_PROPERTY_INTEGER
标识符 | 描述 | 类型 |
---|---|---|
DEAL_TICKET | 交易的编号。分配给每笔交易的唯一号码 | long |
DEAL_ORDER | 交易订单号 | long |
DEAL_TIME_MSC | 交易时间 | datetime |
DEAL_TIME_MSC | 自01.01.1970以来交易执行的时间,单位:ms | long |
DEAL_TYPE | 交易类型 | ENUM_DEAL_TYPE |
DEAL_ENTRY | 交易记录条目 ---- 记录进入,记录输进,反向记录。 | ENUM_DEAL_ENTRY |
DEAL_MAGIC | 订单唯一识别魔术号(参见 ORDER_MAGIC ) | long |
DEAL_REASON | 交易执行的原因或来源 | ENUM_DEAL_REASON |
DEAL_POSITION_ID | 一笔正在执行的交易,在开始、修改或结束时,分配的仓位的标识符。每个仓位都有一个唯一的标识符,该标识符被分配给在该交易品种的所有的仓位的整个生命周期中。 | long |
函数 HistoryDealGetDouble()
ENUM_DEAL_PROPERTY_DOUBLE
标识符 | 描述 | 类型 |
---|---|---|
DEAL_VOLUME | 成交量 | double |
DEAL_PRICE | 成交价格 | double |
DEAL_COMMISSION | 订单佣金(手续费) | double |
DEAL_SWAP | 平仓时的隔夜利息 | double |
DEAL_PROFIT | 交易利润 | double |
函数 HistoryDealGetString()
ENUM_DEAL_PROPERTY_STRING
标识符 | 描述 | 类型 |
---|---|---|
DEAL_SYMBOL | 交易品种 | string |
DEAL_COMMENT | 交易注释 | string |
DEAL_EXTERNAL_ID | 在 外部 交易系统中的交易标识符(在外汇交易中) | string |
每笔交易的特征是一个类型,其取值范围ENUM_DEAL_TYPE中枚举。为了获得关于交易类型的信息,可以使用DEAL_TYPE修饰符来使用HistoryDealGetInteger()函数。
标识符 | 描述 |
---|---|
DEAL_TYPE_BUY | 做多 |
DEAL_TYPE_SELL | 做空 |
DEAL_TYPE_BALANCE | 余额 |
DEAL_TYPE_CREDIT | 信用额 |
DEAL_TYPE_CHARGE | 额外的费用 |
DEAL_TYPE_CORRECTION | 修正 |
DEAL_TYPE_BONUS | 奖金 |
DEAL_TYPE_COMMISSION | 额外手续费 |
DEAL_TYPE_COMMISSION_DAILY | 日手续费 |
DEAL_TYPE_COMMISSION_MONTHLY | 月手续费 |
DEAL_TYPE_COMMISSION_AGENT_DAILY | 日代理手续费 |
DEAL_TYPE_COMMISSION_AGENT_MONTHLY | 月代理手续费 |
DEAL_TYPE_INTEREST | 利率 |
DEAL_TYPE_BUY_CANCELED | 取消的 做多 交易。可能会有之前执行的 做多 交易被取消的情况。这样的话,之前执行的交易类型 (DEAL_TYPE_BUY) 会被改为 DEAL_TYPE_BUY_CANCELED,并且其 利润/亏损 归零。执行获得的 利润/亏损 会使用单独的结余操作被 收取/取出。 |
DEAL_TYPE_SELL_CANCELED | 取消的 做空 交易。可能会有之前执行的 做空 交易被取消的情况。这样的话,之前执行的交易类型 (DEAL_TYPE_SELL)会被改为 DEAL_TYPE_SELL_CANCELED,并且其利润/亏损归零。执行获得的 利润/亏损 会使用单独的结余操作被 收取/取出。 |
DEAL_DIVIDEND | 股息操作 |
DEAL_DIVIDEND_FRANKED | 税务减免(免税)股息操作 |
DEAL_TAX | 税费 |
交易的差别不仅在于它们在ENUM_DEAL_TYPE中设置的类型,还包括它们改变价位的方式。这可以是一个简单的开仓价位,或一个先前打开的订单(头寸)(市场进入)的积加量,与相反的交易订单(头寸)相应的成交量(市场退出)的相差量,或 仓位(头寸)反转,如果相反方向的交易订单(头寸)的成交量(手数)覆盖了先前打开的订单(头寸)的成交量。
所有这些情况都是由ENUM_DEAL_ENTRY枚举中的值来描述的。为了获得有关交易的信息,可以使用DEAL_ENTRY修饰符,来使用HistoryDealGetInteger()函数。
标识符 | 描述 |
---|---|
DEAL_ENTRY_IN | 交易记录进入 |
DEAL_ENTRY_OUT | 交易记录出场 |
DEAL_ENTRY_INOUT | 交易记录累积 |
DEAL_ENTRY_OUT_BY | 交易通过反向持仓来出场 |
交易执行的原因包含在DEAL_REASON属性中。一笔交易的执行,可能是来自触发了 移动应用程序或 MQL5程序中 的订单,以及在强制平仓事件、变更保证金计算等方面的结果。对于由于余额、信用、佣金和其他操作而导致的非订单交易的交易,DEAL_REASON_CLIENT被指定为原因。
ENUM_DEAL_REASON
标识符 | 描述 |
---|---|
DEAL_REASON_CLIENT | 因来自桌面客户端的订单被激活执行交易 |
DEAL_REASON_MOBILE | 因来自移动程序端的订单被激活执行交易 |
DEAL_REASON_WEB | 因来自网页平台的订单被激活执行交易 |
DEAL_REASON_EXPERT | 因激活从MQL5程序下单的订单来执行交易,例如EA交易或脚本 |
DEAL_REASON_SL | 因激活止损来执行交易 |
DEAL_REASON_TP | 因激活止赢来执行交易 |
DEAL_REASON_SO | 因强制止损平仓事件来执行交易 |
DEAL_REASON_ROLLOVER | 因三日翻转来执行交易 |
DEAL_REASON_VMARGIN | 因收取变动预付款后执行交易 |
DEAL_REASON_SPLIT | 宣布分割期间拥有持仓的品种进行分割(价格降低)后执行交易 |
# 2.5.5 交易操作类型
通过使用OrderSend()函数可以进行交易,发送一个价位,可以打开一个订单,同样的,也可以用来放置、修改 或 删除一个挂单。每个订单都提交一个的交易操作类型。在枚举常量ENUM_TRADE_REQUEST_ACTIONS中描述了交易操作类型。
ENUM_TRADE_REQUEST_ACTIONS
标识符 | 描述 |
---|---|
TRADE_ACTION_DEAL | 以指定的参数立即执行交易订单(市场订单) |
TRADE_ACTION_PENDING | 在指定的条件下(挂单)执行交易订单 |
TRADE_ACTION_SLTP | 修改已持有订单的止损和止盈 |
TRADE_ACTION_MODIFY | 修改先前放置的订单的参数 |
TRADE_ACTION_REMOVE | 删除先前放置的挂单 |
TRADE_ACTION_CLOSE_BY | 通过反向持仓来平仓 |
打开 做多(Buy) 订单TRADE_ACTION_DEAL 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 打开 做多(Buy) 持仓订单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 请求的参数
request.action =TRADE_ACTION_DEAL; // 交易操作类型
request.symbol =Symbol(); // 交易品种
request.volume =0.1; // 交易量0.1手
request.type =ORDER_TYPE_BUY; // 订单类型
request.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // 持仓价格
request.deviation=5; // 允许价格偏差(滑点)
request.magic =EXPERT_MAGIC; // 订单唯一识别魔术号
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果发送订单请求出错,输出错误代码
//--- 输出操作信息,可在 EA 日志中看到这条信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
打开 做空(Sell) 订单TRADE_ACTION_DEAL 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 打开 做空(Sell) 持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 请求参数
request.action =TRADE_ACTION_DEAL; // 交易操作类型
request.symbol =Symbol(); // 交易品种
request.volume =0.2; // 交易量0.2 手
request.type =ORDER_TYPE_SELL; // 订单类型
request.price =SymbolInfoDouble(Symbol(),SYMBOL_BID); // 持仓价格
request.deviation=5; // 允许价格偏差(滑点)
request.magic =EXPERT_MAGIC; // 订单唯一识别魔术号
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果发送订单请求出错,输出错误代码
//--- 输出操作信息,可在 EA 日志中看到这条信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
平仓TRADE_ACTION_DEAL 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 关闭全部持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // 持仓数
//--- 循环遍历所有持仓
for(int i=total-1; i>=0; i--)
{
//--- 订单的参数
ulong position_ticket=PositionGetTicket(i); // 持仓价格
string position_symbol=PositionGetString(POSITION_SYMBOL); // 交易品种
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // 小数位数
ulong magic=PositionGetInteger(POSITION_MAGIC); // 持仓的唯一识别魔术号
double volume=PositionGetDouble(POSITION_VOLUME); // 持仓交易量
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // 持仓类型
//--- 输出持仓信息
PrintFormat("#%I64u %s %s %.2f %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
magic);
//--- 如果唯一识别魔术号匹配
if(magic==EXPERT_MAGIC)
{
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置操作参数
request.action =TRADE_ACTION_DEAL; // 交易操作类型
request.position =position_ticket; // 持仓价格
request.symbol =position_symbol; // 交易品种
request.volume =volume; // 持仓交易量
request.deviation=5; // 允许价格偏差
request.magic =EXPERT_MAGIC; // 持仓幻数
//--- 根据持仓类型设置价格和订单类型
if(type==POSITION_TYPE_BUY)
{
request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
request.type =ORDER_TYPE_SELL;
}
else
{
request.price=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
request.type =ORDER_TYPE_BUY;
}
//--- 输出平仓关闭信息
PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
//---
}
}
}
//+------------------------------------------------------------------+
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
挂单 TRADE_ACTION_PENDING 交易操作的示例:
#property description "Example of placing pending orders"
#property script_show_inputs
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT; // 订单类型
//+------------------------------------------------------------------+
//| 下挂单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 下挂单的参数
request.action =TRADE_ACTION_PENDING; // 交易操作类型
request.symbol =Symbol(); // 交易品种
request.volume =0.1; //0.1手交易量
request.deviation=2; // 允许价格偏差
request.magic =EXPERT_MAGIC; // 订单幻数
int offset = 50; // 以点数从当前价抵消下单
double price; // 订单触动价
double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT); // value of point
int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); // 小数位数 (精确度)
//--- 检查操作类型
if(orderType==ORDER_TYPE_BUY_LIMIT)
{
request.type =ORDER_TYPE_BUY_LIMIT; // 订单类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; // 持仓价格
request.price =NormalizeDouble(price,digits); //正常开盘价
}
else if(orderType==ORDER_TYPE_SELL_LIMIT)
{
request.type =ORDER_TYPE_SELL_LIMIT; // 挂单的类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // 持仓价
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else if(orderType==ORDER_TYPE_BUY_STOP)
{
request.type =ORDER_TYPE_BUY_STOP; // 订单类型
price =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // 开盘价
request.price=NormalizeDouble(price,digits); // 正常开盘价
}
else if(orderType==ORDER_TYPE_SELL_STOP)
{
request.type =ORDER_TYPE_SELL_STOP; // 订单类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; // 开盘价
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else Alert("本例仅用于挂单"); // 如果没有挂单被选择
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
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
修改持仓止损和止赢值的 TRADE_ACTION_SLTP 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 修改持仓的止损和止赢 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // 持仓数
//--- 循环遍历所有持仓
for(int i=0; i<total ; i++)
{
//--- 订单的参数
ulong position_ticket=PositionGetTicket(i);// 持仓价格
string position_symbol=PositionGetString(POSITION_SYMBOL); // 交易品种
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // 小数位数
ulong magic=PositionGetInteger(POSITION_MAGIC); // 持仓的幻数
double volume=PositionGetDouble(POSITION_VOLUME); // 持仓交易量
double sl=PositionGetDouble(POSITION_SL); // 持仓止损
double tp=PositionGetDouble(POSITION_TP); // 持仓止赢
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// 挂仓订单的类型
//--- 输出持仓信息
PrintFormat("#%I64u %s %s %.2f %s sl: %s tp: %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
DoubleToString(sl,digits),
DoubleToString(tp,digits),
magic);
//--- 如果唯一识别魔术号匹配,则不修改止损和止赢
if(magic==EXPERT_MAGIC && sl==0 && tp==0)
{
//--- 计算当前价格水平
double price=PositionGetDouble(POSITION_PRICE_OPEN);
double bid=SymbolInfoDouble(position_symbol,SYMBOL_BID);
double ask=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
int stop_level=(int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL);
double price_level;
//--- 如果最小值被接受,那么当前平仓价的点数偏距不设置
if(stop_level<=0)
stop_level=150; // 设置当前平仓价的150点偏距
else
stop_level+=50; // 为了可靠性而设置偏距到(SYMBOL_TRADE_STOPS_LEVEL + 50) 点
//--- 计算并凑整止损和止赢值
price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
if(type==POSITION_TYPE_BUY)
{
sl=NormalizeDouble(bid-price_level,digits);
tp=NormalizeDouble(ask+price_level,digits);
}
else
{
sl=NormalizeDouble(ask+price_level,digits);
tp=NormalizeDouble(bid-price_level,digits);
}
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置操作参数
request.action =TRADE_ACTION_SLTP; // 交易操作类型
request.position=position_ticket; // 持仓价格
request.symbol=position_symbol; // 交易品种
request.sl =sl; // 持仓止损
request.tp =tp; // 持仓止赢
request.magic=EXPERT_MAGIC; // 持仓的唯一识别魔术号
//--- 输出更改信息
PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
//+------------------------------------------------------------------+
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
删除挂单的TRADE_ACTION_REMOVE 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 删除挂单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
int total=OrdersTotal(); // 下挂单的总数
//--- 循环遍历所有的挂单
for(int i=total-1; i>=0; i--)
{
ulong order_ticket=OrderGetTicket(i); // 订单的编号
ulong magic=OrderGetInteger(ORDER_MAGIC); // 订单的唯一识别魔术号
//--- 如果唯一识别魔术号匹配
if(magic==EXPERT_MAGIC)
{
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置持仓参数
request.action=TRADE_ACTION_REMOVE; // 交易操作的类型
request.order = order_ticket; // 订单价格
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
//+------------------------------------------------------------------+
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
关闭反向持仓的TRADE_ACTION_CLOSE_BY 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 关闭所有反向持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // 持仓数
//--- 循环遍历所有持仓
for(int i=total-1; i>=0; i--)
{
//--- 订单的参数
ulong position_ticket=PositionGetTicket(i); // 持仓价格
string position_symbol=PositionGetString(POSITION_SYMBOL); // 交易品种
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // 持仓价格
ulong magic=PositionGetInteger(POSITION_MAGIC); // 持仓的幻数
double volume=PositionGetDouble(POSITION_VOLUME); // 持仓交易量
double sl=PositionGetDouble(POSITION_SL); // 持仓的止损
double tp=PositionGetDouble(POSITION_TP); // 持仓的止赢
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// 持仓类型
//--- 输出持仓信息
PrintFormat("#%I64u %s %s %.2f %s sl: %s tp: %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
DoubleToString(sl,digits),
DoubleToString(tp,digits),
magic);
//--- 如果唯一识别魔术号匹配
if(magic==EXPERT_MAGIC)
{
for(int j=0; j<i; j++)
{
string symbol=PositionGetSymbol(j); // 反向持仓交易品种
//--- 如果反向持仓交易品种和初始交易品种匹配
if(symbol==position_symbol && PositionGetInteger(POSITION_MAGIC)==EXPERT_MAGIC)
{
//--- 设置反向持仓类型
ENUM_POSITION_TYPE type_by=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
//--- 离开,如果初始持仓和反向持仓类型匹配
if(type==type_by)
continue;
//--- 归零请求 和 结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置操作参数
request.action=TRADE_ACTION_CLOSE_BY; // 交易操作类型
request.position=position_ticket; // 持仓价格
request.position_by=PositionGetInteger(POSITION_TICKET); // 反向持仓价格
//request.symbol =position_symbol;
request.magic=EXPERT_MAGIC; // 持仓的幻数
//--- 输出反向持仓平仓的信息
PrintFormat("Close #%I64d %s %s by #%I64d",position_ticket,position_symbol,EnumToString(type),request.position_by);
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());// 如果发送失败,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
}
}
//+------------------------------------------------------------------+
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
# 2.5.6 交易事件(务)类型
当在交易账户上执行一些明确的操作动作时,它的状态会发生变化。这些操作动作包括: • 使用 OrderSend 和 OrderSendAsync 函数在客户端从任何MQL5应用发送交易请求及其进一步执行: • 通过程序端图形界面发送交易请求及其进一步执行; • 在服务器上激活挂单和止损订单; • 在交易服务器上执行操作。
这些操作的结果会执行以下交易事件(务): • 处理交易请求; • 改变持仓订单; • 改变订单历史记录; • 改变交易历史记录; • 改变仓位。
例如,当发送一个 做多(Buy) 市场订单,它会被这样处理,在帐户中创建一个适当的 做多(Buy) 订单,然后执行该订单,执行成功后,从打开订单的列表将其删除,后将其添加到订单历史列表中,一个合适的交易被添加到历史记录中,并且创建一个新的仓位。所有这些操作行动都是交易事件(务)。
若要让程序员跟踪交易账户相关执行的操作,MQL语言提供了OnTradeTransaction 函数。该处理程序允许MQL5应用程序获得账户中的 交易事务 的相关信息。交易事件(务) 描述使用MqlTradeTransaction 结构,以第一个参数OnTradeTransaction提交。
交易事件(务)类型以MqlTradeTransaction结构的类型参数提交。可能的交易事件(务)类型通过以下枚举值予以说明:
ENUM_TRADE_TRANSACTION_TYPE
标识符 | 描述 |
---|---|
TRADE_TRANSACTION_ORDER_ADD | 添加新的持仓订单。 |
TRADE_TRANSACTION_ORDER_UPDATE | 更新一个持仓订单。更新不仅包括明显的客户端 或 交易服务器的变化,还包括设置时的订单状态的变化(例如, 从 ORDER_STATE_STARTED 转换到 ORDER_STATE_PLACED 或 从 ORDER_STATE_PLACED 转换到 ORDER_STATE_PARTIAL等等) |
TRADE_TRANSACTION_ORDER_DELETE | 从打开的订单列表中删除一个订单。可能的原因是:设置了适当的请求 或 执行成交(填充)并移动到了历史订单记录,可以导致从打开的订单中删除订单。 |
TRADE_TRANSACTION_DEAL_ADD | 添加一笔交易到历史记录。订单执行操作 或 执行账户余额操作。 |
TRADE_TRANSACTION_DEAL_UPDATE | 更新历史记录中的一笔交易。在服务器上更改以前执行的交易时可能会出现这种情况。例如,交易在外部交易系统(外汇交易)上发生了变化,在此之前,该笔交易是由经纪平台转移到外部服务器的。 |
TRADE_TRANSACTION_DEAL_DELETE | 删除历史记录的一笔交易。可能会有之前执行的交易从服务器删除的情况。例如,交易在外部交易系统(外汇交易)上被删除,在此之前,该笔交易是由经纪平台转移到外部服务器的。 |
TRADE_TRANSACTION_HISTORY_ADD | 由于执行 或 取消 而向历史记录添加订单 |
TRADE_TRANSACTION_HISTORY_UPDATE | 更改订单历史记录中的订单。这个类型用于加强交易服务器的功能。 |
TRADE_TRANSACTION_HISTORY_DELETE | 删除订单历史记录中的订单。这个类型用于加强交易服务器的功能。 |
TRADE_TRANSACTION_POSITION | 改变与交易执行无关的持仓。这种事务类型表示持仓可以在交易服务器上改变。持仓交易量,开盘价,止损和止盈价位可以改变。更改的数据以 MqlTradeTransaction 结构通过 OnTradeTransaction 处理器来提交。持仓变化(添加,更改或关闭),作为交易执行的结果,不会引起 TRADE_TRANSACTION_POSITION 事务的出现。 |
TRADE_TRANSACTION_REQUEST | 服务器处理交易请求和处理结果的通知已经收到。只有 type(类型) 字段(交易事务类型)必须以MqlTradeTransaction 结构分析该事务。 OnTradeTransaction (请求和结果)的 第二 和 第三 参数必须分析额外的数据。 |
当在交易账户上执行一些明确的操作动作时,它的状态会发生变化。这些操作动作包括: •使用 OrderSend 和 OrderSendAsync 函数在客户端从任何MQL5应用发送交易请求及其进一步执行: •通过程序端图形界面发送交易请求及其进一步执行; •在服务器上激活挂单和止损订单; •在交易服务器上执行操作。
这些操作的结果会执行以下交易事件(务): •处理交易请求; •改变持仓订单; •改变订单历史记录; •改变交易历史记录; •改变仓位。
例如,当发送一个 做多(Buy) 市场订单,它会被这样处理,在帐户中创建一个适当的 做多(Buy) 订单,然后执行该订单,执行成功后,从打开订单的列表将其删除,后将其添加到订单历史列表中,一个合适的交易被添加到历史记录中,并且创建一个新的仓位。所有这些操作行动都是交易事件(务)。
若要让程序员跟踪交易账户相关执行的操作,MQL语言提供了OnTradeTransaction 函数。该处理程序允许MQL5应用程序获得账户中的 交易事务 的相关信息。交易事件(务) 描述使用MqlTradeTransaction 结构,以第一个参数OnTradeTransaction提交。
交易事件(务)类型以MqlTradeTransaction结构的类型参数提交。可能的交易事件(务)类型通过以下枚举值予以说明:
ENUM_TRADE_TRANSACTION_TYPE
标识符 | 描述 |
---|---|
TRADE_TRANSACTION_ORDER_ADD | 添加新的持仓订单。 |
TRADE_TRANSACTION_ORDER_UPDATE | 更新一个持仓订单。更新不仅包括明显的客户端 或 交易服务器的变化,还包括设置时的订单状态的变化(例如, 从 ORDER_STATE_STARTED 转换到 ORDER_STATE_PLACED 或 从 ORDER_STATE_PLACED 转换到 ORDER_STATE_PARTIAL等等) |
TRADE_TRANSACTION_ORDER_DELETE | 从打开的订单列表中删除一个订单。可能的原因是:设置了适当的请求 或 执行成交(填充)并移动到了历史订单记录,可以导致从打开的订单中删除订单。 |
TRADE_TRANSACTION_DEAL_ADD | 添加一笔交易到历史记录。订单执行操作 或 执行账户余额操作。 |
TRADE_TRANSACTION_DEAL_UPDATE | 更新历史记录中的一笔交易。在服务器上更改以前执行的交易时可能会出现这种情况。例如,交易在外部交易系统(外汇交易)上发生了变化,在此之前,该笔交易是由经纪平台转移到外部服务器的。 |
TRADE_TRANSACTION_DEAL_DELETE | 删除历史记录的一笔交易。可能会有之前执行的交易从服务器删除的情况。例如,交易在外部交易系统(外汇交易)上被删除,在此之前,该笔交易是由经纪平台转移到外部服务器的。 |
TRADE_TRANSACTION_HISTORY_ADD | 由于执行 或 取消 而向历史记录添加订单 |
TRADE_TRANSACTION_HISTORY_UPDATE | 更改订单历史记录中的订单。这个类型用于加强交易服务器的功能。 |
TRADE_TRANSACTION_HISTORY_DELETE | 删除订单历史记录中的订单。这个类型用于加强交易服务器的功能。 |
TRADE_TRANSACTION_POSITION | 改变与交易执行无关的持仓。这种事务类型表示持仓可以在交易服务器上改变。持仓交易量,开盘价,止损和止盈价位可以改变。更改的数据以 MqlTradeTransaction 结构通过 OnTradeTransaction 处理器来提交。持仓变化(添加,更改或关闭),作为交易执行的结果,不会引起 TRADE_TRANSACTION_POSITION 事务的出现。 |
TRADE_TRANSACTION_REQUEST | 服务器处理交易请求和处理结果的通知已经收到。只有 type(类型) 字段(交易事务类型)必须以MqlTradeTransaction 结构分析该事务。 OnTradeTransaction (请求和结果)的 第二 和 第三 参数必须分析额外的数据。 |
根据 交易事件(务)类型 的不同,在描述它的MqlTradeTransaction结构中填充了各种参数。提交数据的详细描述请参考“交易事件(务)结构”。
相关参考
交易事件(务)结构,OnTradeTransaction
# 2.5.7 市场深度(DOM)的交易订单
对股票来说,深度市场(DOM----Depth Of Market)窗口是可用的,你能看到当前 买入 和 卖出 的订单。交易操作的期望目标,要求数量和要求价格对每个订单都是指定的。
通过MQL5为获得现行状态的DOM信息,可以使用 MarketBookGet() 函数,它在DOM 目录"screen shot"下的MqlBookInfo 结构数组中。
为了通过MQL5获取关于 市场深度 当前状态的信息,可以使用MarketBookGet()函数,将市场深度“屏幕快照(screen shot)”放置到结构的MqlBookInfo数组中。Type(类型) 字段中数组的每个元素都包含关于订单的方向的信息——ENUM_BOOK_TYPE枚举值。
ENUM_BOOK_TYPE
标识符 | 描述 |
---|---|
BOOK_TYPE_SELL | 卖出订单(Offer) |
BOOK_TYPE_BUY | 买入订单(Bid) |
BOOK_TYPE_SELL_MARKET | 市场的卖出订单 |
BOOK_TYPE_BUY_MARKET | 市场的买入订单 |
相关参考
结构和类 , DOM结构 , 交易操作类型 , 市场信息
# 2.5.8 信号属性
使用交易信号和信号复制设置时会使用以下枚举。
双精度(double)类型的交易信号类型属性的枚举:
ENUM_SIGNAL_BASE_DOUBLE
ID | 描述 |
---|---|
SIGNAL_BASE_BALANCE | 账户余额 |
SIGNAL_BASE_EQUITY | 账户净值 |
SIGNAL_BASE_GAIN | 账户获利 |
SIGNAL_BASE_MAX_DRAWDOWN | 账户最大跌幅 |
SIGNAL_BASE_PRICE | 信号订阅价格 |
SIGNAL_BASE_ROI | 投资利润率(%) |
整数型(integer) 交易信号类型属性的枚举:
ENUM_SIGNAL_BASE_INTEGER
ID | 描述 |
---|---|
SIGNAL_BASE_DATE_PUBLISHED | 发布日期 (提供订阅的日期) |
SIGNAL_BASE_DATE_STARTED | 监控起始日期 |
SIGNAL_BASE_DATE_UPDATED | 信号交易统计的最近更新日期 |
SIGNAL_BASE_ID | 信号 ID |
SIGNAL_BASE_LEVERAGE | 账户杠杆 |
SIGNAL_BASE_PIPS | 利润点 |
SIGNAL_BASE_RATING | 持仓评级 |
SIGNAL_BASE_SUBSCRIBERS | 订阅人数量 |
SIGNAL_BASE_TRADES | 交易数量 |
SIGNAL_BASE_TRADE_MODE | 账户类型 (0----真实,1----模拟,2----竞赛) |
字符串型(string) 交易信号类型属性的枚举:
ENUM_SIGNAL_BASE_STRING
ID | 描述 |
---|---|
SIGNAL_BASE_AUTHOR_LOGIN | 发布者登录 |
SIGNAL_BASE_BROKER | 交易商名称(公司名) |
SIGNAL_BASE_BROKER_SERVER | 交易商服务器 |
SIGNAL_BASE_NAME | 信号名称 |
SIGNAL_BASE_CURRENCY | 信号基础货币 |
双精度(double)信号复制设置类型属性的枚举:
ENUM_SIGNAL_INFO_DOUBLE
ID | 描述 |
---|---|
SIGNAL_INFO_EQUITY_LIMIT | 净值限制 |
SIGNAL_INFO_SLIPPAGE | 滑点(用于下市价单时同步持仓和复制交易) |
SIGNAL_INFO_VOLUME_PERCENT | 最大的使用入金百分比(%), r/o |
整数型(integer) 信号复制设置类型属性的枚举:
ENUM_SIGNAL_INFO_INTEGER
描述 | |
---|---|
SIGNAL_INFO_CONFIRMATIONS_DISABLED | 确认禁用标识 |
SIGNAL_INFO_COPY_SLTP | 复制止损和止盈标识 |
SIGNAL_INFO_DEPOSIT_PERCENT | 入金比例 (%) |
SIGNAL_INFO_ID | 信号 ID, r/o |
SIGNAL_INFO_SUBSCRIPTION_ENABLED | 订阅启用标识 |
SIGNAL_INFO_TERMS_AGREE | "同意信号服务使用条款" 标识, r/o |
字符串型(string) 信号复制设置类型属性的枚举:
ENUM_SIGNAL_INFO_STRING
ID | 描述 |
---|---|
SIGNAL_INFO_NAME | 信号名称,r/o |
相关参考
交易信号
# 2.6 命名常量
所有在MQL5中使用的常量被分成如下几组:
• 预定义的宏替换 —— 在编译过程中值被替换; • 数学常量 —— 一些数学表达式的值 • 数值类型常量 —— 一些简单类型的限制约束 • 不能初始化原因代码 —— 不能初始化原因的描述 • 检测对象指针 —— 由CheckPointer()函数返回的指针类型的枚举值; • 其他常量 —— 所有其他常量
# 2.6.1 预定义的宏替换
(大量代替值......用机器翻译的鬼佬要死吧? —— 智能交易*姚 提示)
为了简化调试过程并获取关于mql5程序的操作的信息,有一个特殊的宏常量,在编译时设置了这些值。使用这些常量的最简单方法是通过Print()函数输出值,如示例中所示。
常量 | 描述 |
---|---|
DATE | 文件编译日期,无时间(小时,分钟,秒的值等于0) |
DATETIME | 文件编译日期和时间 |
LINE | 源代码文件中宏的位置的代码行号 |
FILE | 当前编译文件的名称 |
PATH | 当前正在编译的文件的绝对路径 |
FUNCTION | 宏所在的函数主体的名称 |
FUNCSIG | 函数的形式参数,其主体是宏所在的位置。对函数的完整描述的日志记录可以用于识别重载函数。 |
MQLBUILD, MQL5BUILD | 编译器构造版本号 |
示例:
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net"
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- EA交易初始化输出信息示例
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
//--- 设置定时器事件间的间隔
EventSetTimer(5);
//---
}
//+------------------------------------------------------------------+
//| EA无法初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- EA交易无法初始化输出信息示例
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
//---
}
//+------------------------------------------------------------------+
//| EA订单号函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 订单收据输出信息
Print(" __MQLBUILD__ = ",__MQLBUILD__," __FILE__ = ",__FILE__);
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
test1(__FUNCTION__);
test2();
//---
}
//+------------------------------------------------------------------+
//| test1 |
//+------------------------------------------------------------------+
void test1(string par)
{
//--- 函数内部信息输出
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__," par = ",par);
}
//+------------------------------------------------------------------+
//| test2 |
//+------------------------------------------------------------------+
void test2()
{
//--- 函数内部信息输出
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
}
//+------------------------------------------------------------------+
//| OnTimer 事件处理 |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
test1(__FUNCTION__);
}
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
# 2.6.2 数学常量
包含具体数值的一些特殊常量保留给一些数学表达式。这些常量数值可以在程序的任何地方使用,而不必使用数学函数来计算它们。
常量 | 描述 | 值 |
---|---|---|
M_E | e | 2.71828182845904523536 |
M_LOG2E | log2(e) | 1.44269504088896340736 |
M_LOG10E | log10(e) | 0.434294481903251827651 |
M_LN2 | ln(2) | 0.693147180559945309417 |
M_LN10 | ln(10) | 2.30258509299404568402 |
M_PI | pi | 3.14159265358979323846 |
M_PI_2 | pi/2 | 1.57079632679489661923 |
M_PI_4 | pi/4 | 0.785398163397448309616 |
M_1_PI | 1/pi | 0.318309886183790671538 |
M_2_PI | 2/pi | 0.636619772367581343076 |
M_2_SQRTPI | 2/sqrt(pi) | 1.12837916709551257390 |
M_SQRT2 | sqrt(2) | 1.41421356237309504880 |
M_SQRT1_2 | 1/sqrt(2) | 0.707106781186547524401 |
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 打印常量值
Print("M_E = ",DoubleToString(M_E,16));
Print("M_LOG2E = ",DoubleToString(M_LOG2E,16));
Print("M_LOG10E = ",DoubleToString(M_LOG10E,16));
Print("M_LN2 = ",DoubleToString(M_LN2,16));
Print("M_LN10 = ",DoubleToString(M_LN10,16));
Print("M_PI = ",DoubleToString(M_PI,16));
Print("M_PI_2 = ",DoubleToString(M_PI_2,16));
Print("M_PI_4 = ",DoubleToString(M_PI_4,16));
Print("M_1_PI = ",DoubleToString(M_1_PI,16));
Print("M_2_PI = ",DoubleToString(M_2_PI,16));
Print("M_2_SQRTPI = ",DoubleToString(M_2_SQRTPI,16));
Print("M_SQRT2 = ",DoubleToString(M_SQRT2,16));
Print("M_SQRT1_2 = ",DoubleToString(M_SQRT1_2,16));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.6.3 数值类型的常量
每个简单的数值类型用于特定类型的任务,并允许在正确使用时优化mql5程序的操作。为了更好的代码可读性和正确处理计算结果,有一些常量允许接收关于特定类型的简单数据的限制信息。
常量 | 描述 | 值 |
---|---|---|
CHAR_MIN | 最小值,可以用char类型表示。 | -128 |
CHAR_MAX | 最大值,可以用char类型表示。 | 127 |
UCHAR_MAX | 最大值,可以用uchar类型表示。 | 255 |
SHORT_MIN | 最小值,可以用short类型表示。 | -32768 |
SHORT_MAX | 最大值,可以用short类型表示。 | 32767 |
USHORT_MAX | 最大值,可以用ushort类型表示。 | 65535 |
INT_MIN | 最小值,可以用int类型表示。 | -2147483648 |
INT_MAX | 最大值,可以用int类型表示。 | 2147483647 |
UINT_MAX | 最大值,可以用uint类型表示。 | 4294967295 |
LONG_MIN | 最小值,可以用 long类型表示。 | -9223372036854775808 |
LONG_MAX | 最大值,可以用 long类型表示。 | 9223372036854775807 |
ULONG_MAX | 最大值,可以用 ulong类型表示。 | 18446744073709551615 |
DBL_MIN | 最小正值,可以用 double类型表示。 | 2.2250738585072014e-308 |
DBL_MAX | 最大值,可以用 double类型表示。 | 1.7976931348623158e+308 |
DBL_EPSILON | 最小值,满足条件 1.0+DBL_EPSILON != 1.0(双精度类型) | 2.2204460492503131e-016 |
DBL_DIG | 双精度型有效小数位数字 | 15 |
DBL_MANT_DIG | 双精度型尾数算在内的二进制 | 53 |
DBL_MAX_10_EXP | 双精度型指数角度最大小数值 | 308 |
DBL_MAX_EXP | 双精度型指数角度最大二进制值 | 1024 |
DBL_MIN_10_EXP | 双精度型指数角度最小小数 | (-307) |
DBL_MIN_EXP | 双精度型指数角度最小二进制值 | (-1021) |
FLT_MIN | 最小正值,可以用 float类型表示。 | 1.175494351e-38 |
FLT_MAX | 最大值,可以用 float类型表示。 | 3.402823466e+38 |
FLT_EPSILON | 最小值,满足因素: 1.0+DBL_EPSILON != 1.0 (浮点类型) | 1.192092896e?C07 |
FLT_DIG | 浮点型有效角度数位 | 6 |
FLT_MANT_DIG | 浮点型二进制计算点数 | 24 |
FLT_MAX_10_EXP | 浮点型指数角度最大小数值 | 38 |
FLT_MAX_EXP | 浮点型最大二进制值 | 128 |
FLT_MIN_10_EXP | 浮点型指数角度最小小数值 | -37 |
FLT_MIN_EXP | 浮点型指数角度最小二进制值 | (-125) |
示例:
void OnStart()
{
//--- 打印常量值
printf("CHAR_MIN = %d",CHAR_MIN);
printf("CHAR_MAX = %d",CHAR_MAX);
printf("UCHAR_MAX = %d",UCHAR_MAX);
printf("SHORT_MIN = %d",SHORT_MIN);
printf("SHORT_MAX = %d",SHORT_MAX);
printf("USHORT_MAX = %d",USHORT_MAX);
printf("INT_MIN = %d",INT_MIN);
printf("INT_MAX = %d",INT_MAX);
printf("UINT_MAX = %u",UINT_MAX);
printf("LONG_MIN = %I64d",LONG_MIN);
printf("LONG_MAX = %I64d",LONG_MAX);
printf("ULONG_MAX = %I64u",ULONG_MAX);
printf("EMPTY_VALUE = %.16e",EMPTY_VALUE);
printf("DBL_MIN = %.16e",DBL_MIN);
printf("DBL_MAX = %.16e",DBL_MAX);
printf("DBL_EPSILON = %.16e",DBL_EPSILON);
printf("DBL_DIG = %d",DBL_DIG);
printf("DBL_MANT_DIG = %d",DBL_MANT_DIG);
printf("DBL_MAX_10_EXP = %d",DBL_MAX_10_EXP);
printf("DBL_MAX_EXP = %d",DBL_MAX_EXP);
printf("DBL_MIN_10_EXP = %d",DBL_MIN_10_EXP);
printf("DBL_MIN_EXP = %d",DBL_MIN_EXP);
printf("FLT_MIN = %.8e",FLT_MIN);
printf("FLT_MAX = %.8e",FLT_MAX);
printf("FLT_EPSILON = %.8e",FLT_EPSILON);
}
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
# 2.6.4 不能初始化原因代码
使用 UninitializeReason() 函数可以返回初始化错误代码,可能值如下:
常量 | 值 | 描述 |
---|---|---|
REASON_PROGRAM | 0 | 调用ExpertRemove()函数终止了EA操作 |
REASON_REMOVE | 1 | 程序从图表中删除 |
REASON_RECOMPILE | 2 | 程序重新编译 |
REASON_CHARTCHANGE | 3 | 更改了交易品种或图表时间周期框架 |
REASON_CHARTCLOSE | 4 | 图表关闭 |
REASON_PARAMETERS | 5 | 用户改变了输入参数 |
REASON_ACCOUNT | 6 | 由于账户设置的改变,如激活了另一个账户或者重新连接交易服务器的情况。 |
REASON_TEMPLATE | 7 | 应用了新模板 |
REASON_INITFAILED | 8 | 此值表示OnInit()处理器,返回了一个非零值 |
REASON_CLOSE | 9 | 程序端已关闭 |
无法初始化的错误原因代码通过预定义函数 OnDeinit(整数常量错误代码)传递参数。
示例:
//+------------------------------------------------------------------+
//| 获得文本描述 |
//+------------------------------------------------------------------+
string getUninitReasonText(int reasonCode)
{
string text="";
//---
switch(reasonCode)
{
case REASON_ACCOUNT:
text="帐号已改变Account was changed";break;
case REASON_CHARTCHANGE:
text="交易品种 或 时间框架改变Symbol or timeframe was changed";break;
case REASON_CHARTCLOSE:
text="图表已关闭Chart was closed";break;
case REASON_PARAMETERS:
text="输入参数改变Input-parameter was changed";break;
case REASON_RECOMPILE:
text="程序文件 "+__FILE__+" 重编译";break;
case REASON_REMOVE:
text="程序文件 "+__FILE__+" 已从图表移除";break;
case REASON_TEMPLATE:
text="图表上应用了新的模版New template was applied to chart";break;
default:text="其它原因Another reason";
}
//---
return text;
}
//+------------------------------------------------------------------+
//| EA无法初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- 获得无法初始化原因代码的第一种方法
Print(__FUNCTION__,"_Uninitalization reason code = ",reason);
//--- 获得无法初始化原因代码的第二种方法
Print(__FUNCTION__,"_UninitReason = ",getUninitReasonText(_UninitReason));
}
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
# 2.6.5 检测对象指针
CheckPointer() 函数用于检测对象指针类型。返回值为 ENUM_POINTER_TYPE 枚举值之一。如果使用了不正确的指针,程序将立即终止执行。
由 new() 操作符创建的对象属于POINTER_DYNAMIC类型。delete()操作符可以而且应该只用于这些指针。
所有POINTER_AUTOMATIC类型的其它指针,表示该对象由MQL5程序环境自动创建,在使用后自动删除。
ENUM_POINTER_TYPE
常量 | 描述 |
---|---|
POINTER_INVALID | 错误指针 |
POINTER_DYNAMIC | new() 操作符创建的对象指针 |
POINTER_AUTOMATIC | 任意自动创建的对象指针(非new()创建) |
相关参考
运行错误 , 对象删除操作符删除 , 检测指针
# 2.6.6 其它常量
CLR_NONE常量用于描述没有指定颜色的情况,这意味着图形对象或一个指标的图形序列不会被绘制出来。这个常量不包含在web颜色常量列表中,但是它可以应用到需要颜色参数的任何地方。
INVALID_HANDLE 常数能用来检测处理文件 (参见 FileOpen() 和 FileFindFirst() )。
常量 | 描述 | 值 |
---|---|---|
CHARTS_MAX | 在客户终端中同时打开图表的最大可能数量。 | >100 |
clrNONE | 未指定颜色 | -1 |
EMPTY_VALUE | 指标缓冲区的空值 | DBL_MAX |
INVALID_HANDLE | 错误处理 | -1 |
IS_DEBUG_MODE | MQL5程序运行的 调试方式 标帜 | 非零值 ---- 调试模式, 其它模式为 0 |
IS_PROFILE_MODE | MQL5程序运行 分析模式 的标帜 | 非零值 ---- 分析模式, 其它模式为 0 |
NULL | 任意类型的零(空)值 | 0 |
WHOLE_ARRAY | 表示直到数组末尾,还剩余的项目数量。即,整个数组将被遍历处理。 | -1 |
WRONG_VALUE | 常量可以 隐式 地转换为任何枚举类型。 | -1 |
EMPTY_VALUE常量通常对应于图表中不需要显示的指标的值。例如,对于内置的标准差(Standard Deviation)指标,周期为20,即表示在历史数据图表中的前19根K线(柱)对应的指标线并没有显示在图表中。如果使用iStdDev()函数创建此指标,并通过CopyBuffer()将这些K线(柱对应的指标缓冲区数组中的值复制到另一个数组中,那么将会发现这些值等于EMPTY_VALUE。
可以为 自定义指标 选择空值,用于当不需要该指标在图表中显示时,可以使用函数 PlotIndexSetDouble() 的修饰符 PLOT_EMPTY_VALUE 。
可以将NULL常量分配给任何简单类型的变量 或 对象结构 或 类指针。字符串变量的空(NULL)赋值意味着该变量的全部初始化。
当有必要返回枚举值时,WRONG_VALUE常量即是为这种情况准备的,并且这必须是一个错误值。例如,当我们需要告知返回值是该枚举的值时。让我们以一个函数CheckLineStyle()为例,它返回以其名称指定的对象的行样式。如果由ObjectGetInteger()检查结果为真,则返回ENUM_LINE_STYLE的值;否则WRONG_VALUE返回。
void OnStart()
{
if(CheckLineStyle("MyChartObject")==WRONG_VALUE)
printf("Error line style getting.");
}
//+------------------------------------------------------------------+
//| 为名称指定物件返回线型 |
//+------------------------------------------------------------------+
ENUM_LINE_STYLE CheckLineStyle(string name)
{
long style;
//---
if(ObjectGetInteger(0,name,OBJPROP_STYLE,0,style))
return((ENUM_LINE_STYLE)style);
else
return(WRONG_VALUE);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WHOLE_ARRAY常量用于需要指定处理数组中元素数量的函数:
• ArrayCopy(); • ArrayMinimum(); • ArrayMaximum(); • FileReadArray(); • FileWriteArray().
如果想要列举,指定位置中的所有数组值从头到尾都是需要处理的,你应该指定WHOLE_ARRAY值。
IS_PROFILE_MODE常量允许在 分析模式 中更改程序操作,以便正确地收集数据。分析允许度量单个程序片段(通常包含函数)的执行时间,以及计算此类调用的数量。在分析模式下,可能会禁止Sleep(),以在 分析模式 中确定执行时间,比如在这个例子中:
//--- Sleep 可能大大影响(改变)分析结果
if(!IS_PROFILE_MODE) Sleep(100); // 在分析模式禁用 Sleep() 调用
2
IS_PROFILE_MODE常量值由编译器在编译期间设置,而在常规模式下设置为零。当在 分析模式 下启动一个程序时,将执行一个特殊的编译,并将IS_PROFILE_MODE替换为非零值。
当您需要在 调试模式 中稍微更改mql5程序的操作时,IS_DEBUG_MODE常量会非常有用。例如,在 调试模式 中,您可能需要在终端日志中显示额外的调试信息,或者在图表中创建附加的图形对象。
下面的示例创建一个标签(Label)对象,并根据脚本运行模式设置了描述和颜色。为了从MetaEditor中运行 调试模式 的脚本,请按F5键。如果您从客户端的浏览窗口运行脚本,那么对象标签的颜色和文本将会不同。
示例:
//+------------------------------------------------------------------+
//| Check_DEBUG_MODE.mq5 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| https://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net"
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//---
string label_name="invisible_label";
if(ObjectFind(0,label_name)<0)
{
Print("Object",label_name,"not found. Error code = ",GetLastError());
//--- 创建标签
ObjectCreate(0,label_name,OBJ_LABEL,0,0,0);
//--- 设置 X 坐标
ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200);
//--- 设置 Y 坐标
ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300);
ResetLastError();
if(IS_DEBUG_MODE) // 调试方式
{
//--- 显示脚本执行模式信息
ObjectSetString(0,label_name,OBJPROP_TEXT,"DEBUG MODE");
//--- 设置文本颜色成红色
if(!ObjectSetInteger(0,label_name,OBJPROP_COLOR,clrRed))
Print("Unable to set the color. Error",GetLastError());
}
else // 操作模式
{
ObjectSetString(0,label_name,OBJPROP_TEXT,"RELEASE MODE");
//--- 设置文本颜色为不可见
if(!ObjectSetInteger(0,label_name,OBJPROP_COLOR,CLR_NONE))
Print("Unable to set the color. Error ",GetLastError());
}
ChartRedraw();
DebugBreak(); // 如果处于调试模式,则会终止
}
}
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
Crypt 方法
ENUM_CRYPT_METHOD枚举用于指定在CryptEncode()和CryptDecode()函数中使用的数据转换方法。
ENUM_CRYPT_METHOD
常量 | 描述 |
---|---|
CRYPT_BASE64 | BASE64 |
CRYPT_AES128 | AES 128位密钥加密(16字节) |
CRYPT_AES256 | AES 256位密钥加密(32 字节) |
CRYPT_DES | DES 56位密钥加密(7字节) |
CRYPT_HASH_SHA1 | SHA1 哈希计算 |
CRYPT_HASH_SHA256 | SHA256 哈希计算 |
CRYPT_HASH_MD5 | MD5 哈希计算 |
CRYPT_ARCH_ZIP | ZIP 归档 |
相关参考
DebugBreak, 执行MQL程序属性, CryptEncode(), CryptDecode()
# 2.7 数据结构
MQL5语言提供9种预定义的 结构 :
• MqlDateTime 用于处理 日期和时间; • MqlParam 用于IndicatorCreate()函数创建指标的句柄时,可以传送输入参数; • MqlRates 用于操作历史数据,它包含关于价格、交易量 和 点差; • MqlBookInfo 用于获取DOM市场深度信息(Depth of Market); • MqlTradeRequest 用于创建交易操作的交易请求; • MqlTradeCheckResult 用于在发送之前检查已准备好的交易请求; • MqlTradeResult 通过OrderSend()函数,获得交易服务器回应交易请求的信息; • MqlTradeTransaction 包括交易事务的描述; • MqlTick 是为快速检索当前价格中最需要的信息而设计的。
# 2.7.1 MqlDateTime
数据类型结构。 用于处理 日期和时间。数据类型结构包括int的8个字段 :
struct MqlDateTime
{
int year; // 年
int mon; // 月
int day; // 日
int hour; // 小时
int min; // 分钟
int sec; // 秒
int day_of_week; // 一周内的星期几 (0-星期天, 1-星期一, ... ,6-星期六)
int day_of_year; // 一年内的第几天 (0 表示 1月1 日)
};
2
3
4
5
6
7
8
9
10
11
注意
字段day_of_year,如果是闰年,则从三月开始,该数字就会与非闰年的相应天数有所不同。
示例
void OnStart()
{
//---
datetime date1=D'2008.03.01';
datetime date2=D'2009.03.01';
MqlDateTime str1,str2;
TimeToStruct(date1,str1);
TimeToStruct(date2,str2);
printf("%02d.%02d.%4d, day of year = %d",str1.day,str1.mon,
str1.year,str1.day_of_year);
printf("%02d.%02d.%4d, day of year = %d",str2.day,str2.mon,
str2.year,str2.day_of_year);
}
/* Result:
01.03.2008, day of year = 60
01.03.2009, day of year = 59
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
相关参考
TimeToStruct, 结构和类
# 2.7.2 MqlParam
输入参量结构。 指标输入参数的结构。当使用 IndicatorCreate() 函数创建技术指标的句柄时, MqlParam结构是专门设计用来提供 输入参数的。
struct MqlParam
{
ENUM_DATATYPE type; // 输入参数 类型, ENUM_DATATYPE 枚举值
long integer_value; // 存储 整数类型 字段
double double_value; // 存储 双精度类型 字段
string string_value; // 存储 字符串类型 字段
};
2
3
4
5
6
7
一个指标所有的输入参数都以MqlParam类型的数组的形式来传递,该数组每个元素的”type类型”字段指定了按元素传递的参数的数据类型。必须首先将指标的值放在每个元素的适当字段中(即integer_value,double_value或string_value中),这取决于在”type(类型)”字段中指定的ENUM_DATATYPE枚举的值。
如果IND_CUSTOM的值以第三个指标类型传递到IndicatorCreate()函数中,输入参数数组中的第一个元素(type)的值一定是 ENUM_DATATYPE 枚举值中的TYPE_STRING ,而string_value字段中一定包含自定义指标的名称。
# 2.7.3 MqlRates
历史数据结构。 此结构存储有关报价、交易量和点差的信息。
struct MqlRates
{
datetime time; // 周期开始时间
double open; // 开盘价
double high; // 周期内的最高价
double low; // 周期内的最低价
double close; // 收盘价
long tick_volume; // 跳价数量
int spread; // 点差
long real_volume; // 真实交易量
};
2
3
4
5
6
7
8
9
10
11
示例:
void OnStart()
{
MqlRates rates[];
int copied=CopyRates(NULL,0,0,100,rates);
if(copied<=0)
Print("Error copying price data ",GetLastError());
else Print("Copied ",ArraySize(rates)," bars");
}
2
3
4
5
6
7
8
相关参考
复制比率(CopyRates) , 接入时间序列
# 2.7.4 MqlBookInfo
DOM结构,此结构提供市场深度信息。
struct MqlBookInfo
{
ENUM_BOOK_TYPE type; // 订单类型 取值范围为 ENUM_BOOK_TYPE 枚举值之一
double price; // 价格
long volume; // 交易量
};
2
3
4
5
6
注意
MqlBookInfo 结构是预定义的,因此它不需要任何声明和描述。若要使用该结构,只需声明此类型的变量即可。
DOM仅在有限的一些 交易品种 中可以适用。
示例
MqlBookInfo priceArray[];
bool getBook=MarketBookGet(NULL,priceArray);
if(getBook)
{
int size=ArraySize(priceArray);
Print("MarketBookInfo about ",Symbol());
}
else
{
Print("Failed to receive DOM for the symbol ",Symbol());
}
2
3
4
5
6
7
8
9
10
11
相关参考
MarketBookAdd,MarketBookRelease, MarketBookGet, DOM中交易订单 , 数据类型
# 2.7.5 MqlTradeRequest
交易请求结构 客户端为执行下单动作需要与交易服务器互动通讯,这是由交易请求来执行的。交易请求由特殊的预定义的MqlTradeRequest结构类型来表示,该结构包含执行交易协议所需的所有字段。请求处理结果由MqlTradeResult类型的结构表示。
struct MqlTradeRequest
{
ENUM_TRADE_REQUEST_ACTIONS action; // 交易操作类型,取值范围为枚举值之一
ulong magic; // EA交易 ID (唯一识别魔术号)
ulong order; // 订单号
string symbol; // 交易品种
double volume; // 交易量
double price; // 价格
double stoplimit; // 止损限价点位
double sl; // 止损
double tp; // 止盈
ulong deviation; // 允许滑点的偏差范围
ENUM_ORDER_TYPE type; // 订单类型
ENUM_ORDER_TYPE_FILLING type_filling; // 订单交易量(手数)执行类型
ENUM_ORDER_TYPE_TIME type_time; // 订单执行时间
datetime expiration; // 订单过期时间 (为 ORDER_TIME_SPECIFIED 类型订单)
string comment; // 订单注释
ulong position; // 仓位价格
ulong position_by; // 反向仓位价格
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
字段描述
字段 | 描述 |
---|---|
action | 交易操作类型,取值范围是 ENUM_TRADE_REQUEST_ACTIONS 枚举值之一 |
magic | EA交易订单的ID。它允许组织分析处理交易订单。每个EA在发送交易请求时都可以设置自己独特的唯一识别魔术号ID。 |
order | 订单编号。通常用于修改挂单。 |
symbol | 订单的交易品种,不需要对订单进行修改和关闭平仓操作。 |
volume | 交易请求订单的成交量(手数),注意每笔订单的真实成交量取决于订单执行类型。 |
price | 价格,订单执行必须达到的价格。交易品种的市场定单 ,即执行类型是“市场执行”TRADE_ACTION_DEAL类型的的订单(SYMBOL_TRADE_EXECUTION_MARKET),不需要指定价格。 |
stoplimit | 这里是一个 价格,当市场报价达到指定的 价格price 时(必要条件),将放置一个限价挂单。在此之前,不挂单。 |
sl | 在价格向不利的方向运动时,停止损失,平仓出场。即,止损 |
tp | 在价格向有利的方向运动时,停止盈利,平仓出场。即,止盈 |
deviation | 最大价格偏差范围,以 points 为单位指定 |
type | 订单类型,取值范围是 ENUM_ORDER_TYPE枚举值之一 |
type_filling | 订单成交量执行类型,取值范围是 ENUM_ORDER_TYPE_FILLING 枚举值之一 |
type_time | 订单过期类型,取值范围是 ENUM_ORDER_TYPE_TIME 枚举值之一 |
expiration | 订单过期时间(ORDER_TIME_SPECIFIED 类型的订单) |
comment | 订单注解文本 |
position | 仓位的编号。当一个仓位被 修改 或 关闭一个确定的仓位时,将被填写。一般来说,它等于订单的编号,基于这个价位打开仓位。 |
Position_by | 相反仓位的编号。当同一个 交易品种 中,一个仓位因一个相反方向的仓位打开,而被平仓时使用。 |
当在锁仓系统更改持仓或平仓时,要确保指明其单号(MqlTradeRequest::position)。而在单边系统,虽然是通过交易品种名称来确定持仓,也可以指明订单号。
发送订单 执行 交易操作 需要使用 OrderSend() 函数。对于每个 交易操作 来说都需要指定强制字段;也需要填满可选字段。有7个可能的案例发送交易订单:
请求执行 这是在 请求执行 模式下打开一个交易订单的指令(按请求的价格进行交易)。它需要指定以下9个字段:
• action 执行 • symbol 交易品种 • volume 交易量 • price 价格 • sl止损水平 • tp 盈利水平 • deviation 误差 • type 类型 • type_filling 成交量(手数)类型
也有可能指定“magic”和“comment” 字段的值
立即执行 这是一个在 即时执行 模式下(按当前价格进行交易)打开一个交易订单的指令。它需要指定以下9个字段:
• action 执行 • symbol 交易品种 • volume 交易量 • price 价格 • sl止损水平 • tp 盈利水平 • deviation 误差 • type 类型 • type_filling 成交量(手数)类型
也有可能指定“magic”和“comment” 字段的值
市场执行 这是一个在 市场执行 模式下打开一个交易订单的指令。它需要指定以下5个字段:
• action 执行 • symbol 交易品种 • volume 交易量 • type 类型 • type_filling 成交量(手数)类型
交换执行(外汇)
这是一个在 交换执行(外汇) 模式中打开一个交易订单的指令。它需要指定以下5个字段:
• action 执行 • symbol 交易品种 • volume 交易量 • type 类型 • type_filling 成交量(手数)类型
也有可能指定“magic”和“comment” 字段的值
TRADE_ACTION_DEAL交易操作打开 做多(Buy) 持仓 的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 打开买入持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 请求的参数
request.action = TRADE_ACTION_DEAL; // 交易操作类型
request.symbol = Symbol(); // 交易品种
request.volume = 0.1; // 0.1手交易量
request.type = ORDER_TYPE_BUY; // 订单类型
request.price = SymbolInfoDouble(Symbol(),SYMBOL_ASK); // 持仓价格
request.deviation = 5; // 允许价格偏差
request.magic = EXPERT_MAGIC; // 订单唯一识别魔术号
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TRADE_ACTION_DEAL交易操作打开 做空(Sell) 持仓 的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 打开卖出持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 请求参数
request.action = TRADE_ACTION_DEAL; // 交易操作类型
request.symbol = Symbol(); // 交易品种
request.volume = 0.2; // 0.2 手交易量
request.type = ORDER_TYPE_SELL; // 订单类型
request.price = SymbolInfoDouble(Symbol(),SYMBOL_BID); // 持仓价格
request.deviation = 5; // 允许价格偏差
request.magic = EXPERT_MAGIC; // 订单唯一识别魔术号
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
平仓TRADE_ACTION_DEAL 交易操作的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 关闭全部持仓 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // 持仓数
//--- 重做所有持仓
for(int i=total-1; i>=0; i--)
{
//--- 订单的参数
ulong position_ticket=PositionGetTicket(i); // 持仓价格
string position_symbol=PositionGetString(POSITION_SYMBOL); // 交易品种
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // 小数位数
ulong magic=PositionGetInteger(POSITION_MAGIC); // 持仓的唯一识别魔术号
double volume=PositionGetDouble(POSITION_VOLUME); // 持仓交易量
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // 持仓类型
//--- 输出持仓信息
PrintFormat("#%I64u %s %s %.2f %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
magic);
//--- 如果唯一识别魔术号匹配
if(magic==EXPERT_MAGIC)
{
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置操作参数
request.action =TRADE_ACTION_DEAL; // 交易操作类型
request.position =position_ticket; // 持仓价格
request.symbol =position_symbol; // 交易品种
request.volume =volume; // 持仓交易量
request.deviation=5; // 允许价格偏差
request.magic =EXPERT_MAGIC; // 持仓唯一识别魔术号
//--- 根据持仓类型设置价格和订单类型
if(type==POSITION_TYPE_BUY)
{
request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
request.type =ORDER_TYPE_SELL;
}
else
{
request.price=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
request.type =ORDER_TYPE_BUY;
}
//--- 输出关闭信息
PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
//---
}
}
}
//+------------------------------------------------------------------+
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
SL & TP修正
交易订单在StopLoss 和/或 TakeProfit 价格上做修改,要求指定如下5个字段: • action 执行 • symbol 交易品种 • sl 止损水平 • tp 盈利水平 • postition 仓位
TRADE_ACTION_SLTP 交易操作更改持仓订单 止损 和 止赢 的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 更改持仓的止损和止赢 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // 持仓数
//--- 重做所有持仓
for(int i=0; i<total ; i++)
{
//--- 订单的参数
ulong position_ticket=PositionGetTicket(i);// 持仓价格
string position_symbol=PositionGetString(POSITION_SYMBOL); // 交易品种
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // 小数位数
ulong magic=PositionGetInteger(POSITION_MAGIC); // 持仓的唯一识别魔术号
double volume=PositionGetDouble(POSITION_VOLUME); // 持仓交易量
double sl=PositionGetDouble(POSITION_SL); // 持仓止损
double tp=PositionGetDouble(POSITION_TP); // 持仓止赢
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // 仓位的类型
//--- 输出持仓信息
PrintFormat("#%I64u %s %s %.2f %s sl: %s tp: %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
DoubleToString(sl,digits),
DoubleToString(tp,digits),
magic);
//--- 如果唯一识别魔术号匹配,不定义止损和止赢
if(magic==EXPERT_MAGIC && sl==0 && tp==0)
{
//--- 计算当前价格水平
double price=PositionGetDouble(POSITION_PRICE_OPEN);
double bid=SymbolInfoDouble(position_symbol,SYMBOL_BID);
double ask=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
int stop_level=(int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL);
double price_level;
//--- 如果最小值被接受,那么当前平仓价的点数偏距不设置
if(stop_level<=0)
stop_level=150; // 设置当前平仓价的150点偏距
else
stop_level+=50; // 为了可靠性而设置偏距到(SYMBOL_TRADE_STOPS_LEVEL + 50) 点
//--- 计算并凑整止损和止赢值
price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
if(type==POSITION_TYPE_BUY)
{
sl=NormalizeDouble(bid-price_level,digits);
tp=NormalizeDouble(ask+price_level,digits);
}
else
{
sl=NormalizeDouble(ask+price_level,digits);
tp=NormalizeDouble(bid-price_level,digits);
}
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置操作参数
request.action =TRADE_ACTION_SLTP; // 交易操作类型
request.position=position_ticket; // 持仓价格
request.symbol=position_symbol; // 交易品种
request.sl =sl; // 持仓止损
request.tp =tp; // 持仓止赢
request.magic=EXPERT_MAGIC; // 持仓的唯一识别魔术号
//--- 输出更改信息
PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());// 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
//+------------------------------------------------------------------+
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
挂单
交易操作放置一个挂单,要求指定如下11个字段: • action 行动 • symbol 交易品种 • volume 交易量 • price 价格 • stoplimit 限制价格 • sl 止损 • tp 止盈 • type 类型 • type_filling 成交量(手数)类型 • type_time 过期时间类型 • expiration 过期时间
也有可能指定“magic” 和“comment”域值。
交易操作 TRADE_ACTION_PENDING 挂单的示例:
#property description "Example of placing pending orders"
#property script_show_inputs
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT; // 订单类型
//+------------------------------------------------------------------+
//| 挂单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- 下挂单的参数
request.action =TRADE_ACTION_PENDING; // 交易操作类型
request.symbol =Symbol(); // 交易品种
request.volume =0.1; //0.1手交易量
request.deviation=2; // 允许价格偏差
request.magic =EXPERT_MAGIC; // 订单唯一识别魔术号
int offset = 50; // 以点数从当前价抵消下单
double price; // 订单触动价
double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT); // 交易品种 的点值
int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); // 小数位数 (精确度)
//--- 检查操作类型
if(orderType==ORDER_TYPE_BUY_LIMIT)
{
request.type =ORDER_TYPE_BUY_LIMIT; // 订单类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; // 持仓价格
request.price =NormalizeDouble(price,digits); //正常开盘价
}
else if(orderType==ORDER_TYPE_SELL_LIMIT)
{
request.type =ORDER_TYPE_SELL_LIMIT; // 订单类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // 持仓价
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else if(orderType==ORDER_TYPE_BUY_STOP)
{
request.type =ORDER_TYPE_BUY_STOP; // 订单类型
price =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // 开盘价
request.price=NormalizeDouble(price,digits); // 正常开盘价
}
else if(orderType==ORDER_TYPE_SELL_STOP)
{
request.type =ORDER_TYPE_SELL_STOP; // 订单类型
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; // 开盘价
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else Alert("This example is only for placing pending orders"); // 如果没有挂单被选择
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
//+------------------------------------------------------------------+
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
修改挂单
交易操作在修改挂单时,要求指定如下7个字段: • action 行动 • order 订单 • price 价格 • sl 止损 • tp 止盈 • type_time 过期时间类型 • expiration 过期时间
TRADE_ACTION_MODIFY 交易操作更改挂单价格的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 更改挂单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
int total=OrdersTotal(); // 已下挂单的总数
//--- 重做所有已下的挂单
for(int i=0; i<total; i++)
{
//--- 订单参数
ulong order_ticket=OrderGetTicket(i); // 订单价格
string order_symbol=Symbol(); // 交易品种
int digits=(int)SymbolInfoInteger(order_symbol,SYMBOL_DIGITS); // 小数位数
ulong magic=OrderGetInteger(ORDER_MAGIC); // 订单的幻数
double volume=OrderGetDouble(ORDER_VOLUME_CURRENT); // 订单的当前交易量
double sl=OrderGetDouble(ORDER_SL); // 订单的当前止损
double tp=OrderGetDouble(ORDER_TP); // 订单的当前止赢
ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); // 订单类型
int offset = 50; // 以点数从当前价抵消下单
double price; // 订单触动价
double point=SymbolInfoDouble(order_symbol,SYMBOL_POINT); // 点值
//--- 输出订单信息
PrintFormat("#%I64u %s %s %.2f %s sl: %s tp: %s [%I64d]",
order_ticket,
order_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
DoubleToString(sl,digits),
DoubleToString(tp,digits),
magic);
//--- 如果幻数匹配,不定义止损和止赢
if(magic==EXPERT_MAGIC && sl==0 && tp==0)
{
request.action = TRADE_ACTION_MODIFY; // 交易操作类型
request.order = OrderGetTicket(i); // 订单价格
request.symbol = Symbol();// 交易品种
request.deviation = 5; // 允许价格偏差
//--- 根据持仓类型设置价格水平,订单的止损和止赢
if(type==ORDER_TYPE_BUY_LIMIT)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;
request.tp = NormalizeDouble(price+offset*point,digits);
request.sl = NormalizeDouble(price-offset*point,digits);
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else if(type==ORDER_TYPE_SELL_LIMIT)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point;
request.tp = NormalizeDouble(price-offset*point,digits);
request.sl = NormalizeDouble(price+offset*point,digits);
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else if(type==ORDER_TYPE_BUY_STOP)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point;
request.tp = NormalizeDouble(price+offset*point,digits);
request.sl = NormalizeDouble(price-offset*point,digits);
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
else if(type==ORDER_TYPE_SELL_STOP)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;
request.tp = NormalizeDouble(price-offset*point,digits);
request.sl = NormalizeDouble(price+offset*point,digits);
request.price =NormalizeDouble(price,digits); // 正常开盘价
}
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());// 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
}
}
}
//+------------------------------------------------------------------+
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
删除挂单
交易操作删除一个挂单,要求指定如下2个字段 • action 行动 • order 命令
TRADE_ACTION_REMOVE 交易操作删除挂单的示例:
#define EXPERT_MAGIC 123456 // EA交易的唯一识别魔术号
//+------------------------------------------------------------------+
//| 删除挂单 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 声明并初始化交易请求和交易请求结果
MqlTradeRequest request={0};
MqlTradeResult result={0};
int total=OrdersTotal(); // 下挂单的总数
//--- 重做所有已下的挂单
for(int i=total-1; i>=0; i--)
{
ulong order_ticket=OrderGetTicket(i); // 订单编号
ulong magic=OrderGetInteger(ORDER_MAGIC); // 订单的幻数
//--- 如果唯一识别魔术号匹配
if(magic==EXPERT_MAGIC)
{
//--- 归零请求和结果值
ZeroMemory(request);
ZeroMemory(result);
//--- 设置持仓参数
request.action=TRADE_ACTION_REMOVE; // 交易操作的类型
request.order = order_ticket; // 订单价格
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
//+------------------------------------------------------------------+
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
相关参考 结构和类, 交易函数,订单属性
# 2.7.6 MqlTradeCheckResult
检查交易请求测试结果的结构......用于发送前自检。
在向交易服务器发送交易请求操作之前,建议先检查一遍。执行检查可以使用OrderCheck()函数,检查请求后,将会传递一个 MqlTradeCheckResult结构类型的变量。检查结果将写入保存在这个变量中。
struct MqlTradeCheckResult
{
uint retcode; // 回应码
double balance; // 执行交易后的余额
double equity; // 执行交易后的净值
double profit; // 浮动盈利
double margin; // 需求保证金
double margin_free; // 自由保证金
double margin_level; // 保证金比例水平
string comment; // 回应码的注释(错误原因的描述)
};
2
3
4
5
6
7
8
9
10
11
字段描述
字段 | 描述 |
---|---|
retcode | 返回代码 |
balance | 在执行交易操作后账户的余额 |
equity | 在执行交易操作后帐户的净值 |
profit | 在执行交易操作后的浮动利润 |
margin | 为执行交易操作要求的保证金 |
margin_free | 在执行交易操作后的可用保证金 |
margin_level | 在执行交易操作后的保证金水平 |
comment | 注解文本回应代码,描述错误原因 |
相关参考
交易请求结构 , 当前价格结构 , 发送订单 , 订单检测
# 2.7.7 MqlTradeResult
交易请求结果结构 作为一个交易请求的结果,交易服务器会返回有关交易请求处理结果的数据,作为一个特殊预定义的 结构MqlTradeResult类型。
struct MqlTradeResult
{
uint retcode; // 操作返回码
ulong deal; // 如果成交的话,这里是 交易单的编号
ulong order; // 如果是放置订单成功,这里是挂单的编号
double volume; // 交易量手数, 由平台确认
double price; // 成交的价格, 由平台确认
double bid; // 当前 Bid 价格
double ask; // 当前 Ask 价格
string comment; // 平台对这次交易操作的注释(默认情况下,是由交易服务器返回代码的描述)
uint request_id; // 在调度期间由客户终端设置的请求ID。
uint retcode_external; // 外部交易系统的操作返回码
};
2
3
4
5
6
7
8
9
10
11
12
13
字段描述
字段 | 描述 |
---|---|
retcode | 交易服务器的返回代码 |
deal | 交易编号,如果交易已执行,会产生一个 TRADE_ACTION_DEAL 类型的交易操作 |
order | 订单编号,如果是放置订单,会产生一个 TRADE_ACTION_PENDING 类型的交易操作 |
volume | 交易成交量,由平台商确认,取决于 订单成交量(手数)填充类型 |
price | 订单价格,由平台商确认,取决于交易请求 和/或 交易操作的 deviation 字段 |
bid | 当前市场Bid买入价(请求报价) |
ask | 当前市场Ask卖出价(请求报价) |
comment | 此次操作的平台注释文本(默认情况下,是由交易服务器返回代码的描述) |
request_id | 发送到交易服务器时,由客户终端设置的请求ID。 |
retcode_external | 由外部交易系统返回的错误代码。当交易操作被发送后,这些错误代码的使用和类型取决于平台和外部交易系统。 |
交易操作结果返回到MqlTradeResult类型的变量,该变量作为第二个参数传递给OrderSend()以执行交易操作。
当使用OrdersSend()和OrderSendAsync()函数将其发送到交易服务器时,客户终端在request_id字段中修复请求ID。终端接收来自交易服务器的执行事务的消息,并通过OnTradeTransaction()函数将其提交给处理,该函数包含以下组件作为参数:
• MqlTradeTransaction结构中交易事务的描述; • 从OrderSend()或OrdersSendAsync()函数发送的交易请求的描述。请求ID由客户终端发送到交易服务器,而请求本身及其request_id存储在客户终端的内存中; • 交易请求执行结果为MqlTradeResult结构,其中包含该请求ID的request_id字段。
OnTradeTransaction()函数接收三个输入参数,但最后两个参数只对具有TRADE_TRANSACTION_REQUEST类型的交易事务进行分析。在所有其他情况下,交易请求的数据和它的执行结果都没有填写。在交易请求的结构中可以找到参数分析的例子。
在发送到服务器时,由客户终端为交易请求来设置request_id,主要是为使用OrderSendAsync()异步函数而引入的。这个标识符可以将执行的操作(OrderSend或OrderSendAsync函数调用)与发送给OnTradeTransaction()的结果关联起来。
示例:
//+------------------------------------------------------------------+
//| 随着处理结果发送交易请求 |
//+------------------------------------------------------------------+
bool MyOrderSend(MqlTradeRequest request,MqlTradeResult result)
{
//--- 重置最后一个错误代码为零
ResetLastError();
//--- 发送请求
bool success=OrderSend(request,result);
//--- 如果结果为失败----找出为什么
if(!success)
{
int answer=result.retcode;
Print("TradeLog: Trade request failed. Error = ",GetLastError());
switch(answer)
{
//--- 重新报价
case 10004:
{
Print("TRADE_RETCODE_REQUOTE");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- 订单没有被服务器接受
case 10006:
{
Print("TRADE_RETCODE_REJECT");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- 无效价格
case 10015:
{
Print("TRADE_RETCODE_INVALID_PRICE");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- 无效 止损 和/或 止盈
case 10016:
{
Print("TRADE_RETCODE_INVALID_STOPS");
Print("request.sl = ",request.sl," request.tp = ",request.tp);
Print("result.ask = ",result.ask," result.bid = ",result.bid);
break;
}
//--- 无效交易量
case 10014:
{
Print("TRADE_RETCODE_INVALID_VOLUME");
Print("request.volume = ",request.volume," result.volume = ",
result.volume);
break;
}
//--- 无足够的钱进行交易操作
case 10019:
{
Print("TRADE_RETCODE_NO_MONEY");
Print("request.volume = ",request.volume," result.volume = ",
result.volume," result.comment = ",result.comment);
break;
}
//--- 一些其他的原因, 输出服务器响应码
default:
{
Print("Other answer = ",answer);
}
}
//--- 返回false,通知交易请求的失败结果。
return(false);
}
//--- OrderSend() 返回值为 真 - 重复 answer
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
# 2.7.8 MqlTradeTransaction
交易事务结构。
当在交易账户上执行一些明确的操作时,它的状态会发生变化。这些操作包括:
• 在客户端从任何MQL5应用使用 OrderSend 和 OrderSendAsync 函数发送交易请求及其进一步执行: • 通过程序端图形界面发送交易请求及其进一步执行; • 在服务器上激活挂单和止损订单; • 在交易服务器上执行操作。
这些操作的结果会执行以下交易事务:
•处理交易请求; •改变持仓订单; •改变订单历史记录; •改变交易历史记录; •改变持仓。
例如,当发送一个市场买入订单时,它会被处理,为账户创建相应的买入订单,然后执行订单并从持仓列表中移除,添加到历史订单,而相应的交易也会添加到历史记录并创建新的持仓。所有这些操作都是交易事务。
在MQL5中提供了特殊的处理程序OnTradeTransaction(),以获取应用于帐户的交易事务。处理程序的第一个参数是描述交易事务的MqlTradeTransaction结构。
struct MqlTradeTransaction
{
ulong deal; // 交易编号
ulong order; // 订单编号
string symbol; // 交易品种 名称
ENUM_TRADE_TRANSACTION_TYPE type; // 交易事务类型
ENUM_ORDER_TYPE order_type; // 订单类型
ENUM_ORDER_STATE order_state; // 订单状态
ENUM_DEAL_TYPE deal_type; // 成交类型
ENUM_ORDER_TYPE_TIME time_type; // 操作期内订单的类型
datetime time_expiration; // 订单过期时间
double price; // 价格
double price_trigger; // 限价追损订单激活价格
double price_sl; // 止损价格
double price_tp; // 止盈价格
double volume; // 交易量(手数)
ulong position; // 仓位编号
ulong position_by; // 反向仓位编号
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
字段描述
字段 | 描述 |
---|---|
deal | 交易单编号。 |
order | 订单编号。 |
symbol | 执行交易事务的 交易品种 的名称。 |
type | 交易事务类型。取值范围是枚举型值 ENUM_TRADE_TRANSACTION_TYPE |
order_type | 交易订单类型。取值范围是枚举型值 ENUM_ORDER_TYPE |
order_state | 交易订单状态。取值范围是枚举型值 ENUM_ORDER_STATE |
deal_type | 成交类型。取值范围是枚举型值 ENUM_DEAL_TYPE |
type_time | 订单过期类型。取值范围是枚举型值 ENUM_ORDER_TYPE_TIME |
time_expiration | 挂单到期期限 (用于 ORDER_TIME_SPECIFIED 和 ORDER_TIME_SPECIFIED_DAY订单类型)。 |
price | 价格。取决于 交易事务类型,它可能是订单价格,成交价格 或 仓位价格。 |
price_trigger | 限价止损订单,止损(激活)价格 (ORDER_TYPE_BUY_STOP_LIMIT 和 ORDER_TYPE_SELL_STOP_LIMIT)。 |
price_sl | 止损价。根据交易事务类型,它可能涉及订单,交易或持仓。 |
price_tp | 止盈价。根据交易事务类型,它可能涉及订单,交易或持仓。 |
volume | 交易量手数。根据交易事务类型,它可能涉及订单,交易或持仓的当前交易量。 |
position | 被交易事务影响的仓位的编号 |
position_by | 相反方向的仓位的编号。当以相反的方向关闭某一仓位时,即以相反方向打开的同一 交易品种 的仓位 |
接收 交易事务 分析的基本参数是在 type 字段中指定的类型。例如,如果一个 交易事务是TRADE_TRANSACTION_REQUEST类型(由服务器处理一个交易请求的结果),那么该结构只有一个完全填充的字段 ---- type 。其他字段没有分析。在这种情况下,我们可以分析提交给OnTradeTransaction()处理程序的两个额外参数 request 和 result,如下所示。
有了交易操作类型的数据,您可以决定对交易帐户的订单、仓位和交易的当前状态进行分析。记住,从客户终端发送到服务器的一个交易请求可以生成几个新的交易事务。他们到达终点站的优先权没有得到保证。
根据交易类型(ENUM_TRADE_TRANSACTION_TYPE), MqlTradeTransaction结构以不同的方式填充:
TRADE_TRANSACTION_ORDER_* 和 TRADE_TRANSACTION_HISTORY_*
填充MqlTradeTransaction结构中的以下字段,其中处理持有开放订单相关的有TRADE_TRANSACTION_ORDER_ADD,
TRADE_TRANSACTION_ORDER_UPDATE,
TRADE_TRANSACTION_ORDER_DELETE
处理历史订单的有
TRADE_TRANSACTION_HISTORY_ADD,
TRADE_TRANSACTION_HISTORY_UPDATE,
TRADE_TRANSACTION_HISTORY_DELETE
• order ---- 订单编号; • symbol ---- 订单 交易品种 的名称。 • type ---- 交易事务的类型; • order_type ---- 订单类型; • orders_state ---- 订单当前状态; • time_type ---- 订单过期类型; • time_expiration ---- 订单过期时间(用于 ORDER_TIME_SPECIFIED 和 ORDER_TIME_SPECIFIED_DAY 过期类型); • price ---- 由客户端指定的订单价格; • price_trigger ---- 限价止损订单的止损价格 (仅用于 ORDER_TYPE_BUY_STOP_LIMIT 和 ORDER_TYPE_SELL_STOP_LIMIT); • price_sl ---- 订单止损价格 (填写,如果在订单中已指明); • price_tp ---- 订单止盈价格 (填写,如果在订单中已指明); • volume ---- 订单当前成交量手数 (未执行成交的手数).订单的初始交易量可以使用 HistoryOrders* 函数在历史订单中找到。 • position ----由于执行打开、修改或关闭订单而影响的仓位的编号。它只用于成交市场订单,而不是成交TRADE_TRANSACTION_ORDER_ADD • position_by ---- the ticket of the opposite position. It is only filled for the close by orders (to close a position by an opposite one).相反仓位的编号。只用于成交平仓订单(用一个相反的仓位关闭一个仓位)。
TRADE_TRANSACTION_DEAL_*
填充MqlTradeTransaction结构的以下字段用于交易相关的交易事务,处理 TRADE_TRANSACTION_DEAL_ADD,
TRADE_TRANSACTION_DEAL_UPDATE
TRADE_TRANSACTION_DEAL_DELETE:
• deal ---- 交易编号; • order ---- 订单编号,基于已执行的交易; • symbol ---- 交易品种名称; • type ---- 交易事务类型; • deal_type ---- 交易类型; • price ---- 交易价格; • price_sl ---- 止损价(填写,在订单中指定的,根据已执行的交易而填写); • price_tp ---- 获利价(填写,在订单中指定的,根据已执行的交易而填写); • volume ---- 交易量手数。 • position ----由于执行打开、修改或关闭订单而影响的仓位的编号。它只用于成交市场订单,而不是成交TRADE_TRANSACTION_ORDER_ADD • position_by ---- the ticket of the opposite position. It is only filled for the close by orders (to close a position by an opposite one).相反仓位的编号。只用于成交平仓订单(用一个相反的仓位关闭一个仓位)。
TRADE_TRANSACTION_POSITION
填充 MqlTradeTransaction 结构的以下字段用于改变与执行交易 (TRADE_TRANSACTION_POSITION) 无关联的持仓的相关交易事务:
• symbol ---- 仓位 交易品种 名称; • type ---- 交易事务类型; • deal_type ---- 持仓类型(DEAL_TYPE_BUY 或DEAL_TYPE_SELL); • price ---- 仓位加权平均持仓价; • price_sl ---- 止损价; • price_tp ---- 止盈价; • volume ---- 仓位持仓交易量手数,如果已经改变。
TIP
仓位改变(添加,修改 或 关闭订单),如执行交易的结果,不会导致发生TRADE_TRANSACTION_POSITION 交易事务。
TRADE_TRANSACTION_REQUEST
在MqlTradeTransaction结构中,只填充一个字段用于描述交易请求已被服务器处理的交易事务,并收到了处理结果(TRADE_TRANSACTION_REQUEST):
• type ---- 交易事务类型;
TIP
只有 type 字段(交易事务类型)必须对此类事务进行分析。必须对OnTradeTransaction函数的第二个和第三个参数(request 和 result)进行分析,以获得额外的数据。
示例
input int MagicNumber=1234567;
//--- 启用CTrade 交易类并声明这种类的变量
#include <Trade /Trade.mqh >
CTrade trade;
//--- 安装和删除挂单的标识
bool pending_done=false;
bool pending_deleted=false;
//--- 挂单将被存储在这里
ulong order_ticket;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 设置MagicNumber 标记EA的所有订单
trade.SetExpertMagicNumber(MagicNumber);
//--- 交易请求将通过OrderSendAsync() 函数以非同步的模式发送
trade.SetAsyncMode(true);
//--- 初始化变量为零
order_ticket=0;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA订单函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//---安装挂单
if(!pending_done)
{
double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
//--- 如果BuyStop()函数成功执行
if(res)
{
pending_done=true;
//--- 获取从ctrade发送的请求的结果
MqlTradeResult trade_result;
trade.Result(trade_result);
//--- 获得发送请求的request_id
uint request_id=trade_result.request_id;
Print("Request has been sent to set a pending order. Request_ID=",request_id);
//--- 存储订单 (如果使用非同步模式发送到CTrade,则将为零)
order_ticket=trade_result.order;
//--- 全部完成后,提前从OnTick() 处理程序退出
return;
}
}
//--- 删除挂单
if(!pending_deleted)
//--- 附加检查
if(pending_done && (order_ticket!=0))
{
//--- 尝试删除挂单
bool res=trade.OrderDelete(order_ticket);
Print("OrderDelete=",res);
//--- 删除请求发送成功
if(res)
{
pending_deleted=true;
//--- 得到请求执行结果
MqlTradeResult trade_result;
trade.Result(trade_result);
//--- 获得来自结果的 request ID
uint request_id=trade_result.request_id;
//--- 在日志中显示
Print("The request has been sent to delete a pending order #",order_ticket,
". Request_ID=",request_id,
"\r\n");
//--- 修正来自请求结果的订单
order_ticket=trade_result.order;
}
}
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction 函数 |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- 获取事务类型作为枚举值
ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- 如果事务是请求处理结果,那么只显示它的名称
if(type==TRADE_TRANSACTION_REQUEST)
{
Print(EnumToString(type));
//--- 显示已处理的 request 字符串名称
Print("------------RequestDescription\r\n",RequestDescription(request));
//--- 显示request 结果描述
Print("------------ResultDescription\r\n",TradeResultDescription(result));
//--- 存储用于下一个OnTick()处理的删除的订单
if(result.order!=0)
{
//--- 通过在next OnTick() 调用的标识删除该订单
order_ticket=result.order;
Print(" Pending order ticket ",order_ticket,"\r\n");
}
}
else // 显示另一事务类型的完整描述
//--- 在日志中显示已接收事务的描述
Print("------------TransactionDescription\r\n",TransactionDescription(trans));
//---
}
//+------------------------------------------------------------------+
//| 返回事务文本描述 |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
{
//---
string desc=EnumToString(trans.type)+"\r\n";
desc+="Symbol: "+trans.symbol+"\r\n";
desc+="Deal ticket: "+(string)trans.deal+"\r\n";
desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
desc+="Order ticket: "+(string)trans.order+"\r\n";
desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
//--- 返回获得的字符串
return desc;
}
//+------------------------------------------------------------------+
//| 返回交易请求文本描述 |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
{
//---
string desc=EnumToString(request.action)+"\r\n";
desc+="Symbol: "+request.symbol+"\r\n";
desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
desc+="Order ticket: "+(string)request.order+"\r\n";
desc+="Order type: "+EnumToString(request.type)+"\r\n";
desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
desc+="Comment: "+request.comment+"\r\n";
//--- 返回获得的字符串
return desc;
}
//+------------------------------------------------------------------+
//| 返回请求处理结果的文本描述 |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
{
//---
string desc="Retcode "+(string)result.retcode+"\r\n";
desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
desc+="Order ticket: "+(string)result.order+"\r\n";
desc+="Deal ticket: "+(string)result.deal+"\r\n";
desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
desc+="Comment: "+result.comment+"\r\n";
//--- 返回获得的字符串
return desc;
}
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
170
171
172
173
174
相关参考
交易事务类型,OnTradeTransaction()
# 2.7.9 MqlTick
返回当前价格的结构。
这是一种存储最新价格的结构。它是为快速检索当前价格的最需要的信息而设计的。
struct MqlTick
{
datetime time; // 价格更新的最后时间
double bid; // 当前买入价Bid
double ask; // 当前卖出价Ask
double last; // 上一次的交易价格 (Last)
ulong volume; // 上一次价格交易量
long time_msc; // 价格更新的最后时间,单位:毫秒
uint flags // 报价标帜
};
2
3
4
5
6
7
8
9
10
MqlTick类型的变量允许在SymbolInfoTick()函数的单个调用中获取Ask、Bid、Last和Volume的值。
无论与之前报价相比是否有变化都会填充每个报价参数。因此,可以找出过去任何时刻的正确价格,无需在报价历史中搜索之前的值。例如,即使报价到达期间只有 Ask 变化,该结构仍然包含其他参数,包括之前的Ask price、volume等等。
您可以分析报价标帜,找出具体更改了哪个数据: • TICK_FLAG_BID —— 跳价更新了 Bid • TICK_FLAG_ASK —— 跳价更新了 Ask • TICK_FLAG_LAST —— 跳价更新了最终成交价 Last • TICK_FLAG_VOLUME —— 跳价更新了交易量 • TICK_FLAG_BUY —— 跳价是 做多交易 的结果 • TICK_FLAG_SELL —— 跳价是 做空交易 的结果
示例:
void OnTick()
{
MqlTick last_tick;
//---
if(SymbolInfoTick(Symbol(),last_tick))
{
Print(last_tick.time,": Bid = ",last_tick.bid,
" Ask = ",last_tick.ask," Volume = ",last_tick.volume);
}
else Print("SymbolInfoTick() failed, error = ",GetLastError());
//---
}
2
3
4
5
6
7
8
9
10
11
12
相关参考
结构和类, CopyTicks(), SymbolInfoTick()
# 2.8 错误和警告代码
本章内容包括如下描述:
• 交易服务器返回的错误代码 —— 分析通过OrderSend() 函数发送的交易请求的结果; • 编辑器警告 —— 在编辑器中出现的警告信息代码(不是错误代码); • 编译错误 —— 尝试编译失败后的错误信息代码; • 运行时间(Runtime errors)错误 —— MQL5程序的属性错误代码,可以通过使用 GetLastError() 函数获得。
# 2.8.1 交易服务器返回代码
所有执行交易操作的请求都是使用OrderSend()函数作为MqlTradeRequest 结构来发送的。 函数执行结果被放置到结构MqlTradeResult中,字段retcode中包含交易服务器返回的代码。
ENUM_TRADE_RETURN_CODES
代码 | 常量 | 描述 |
---|---|---|
10004 | TRADE_RETCODE_REQUOTE | 重新报价 |
10006 | TRADE_RETCODE_REJECT | 拒绝请求 |
10007 | TRADE_RETCODE_CANCEL | 交易者取消请求 |
10008 | TRADE_RETCODE_PLACED | 放置订单 |
10009 | TRADE_RETCODE_DONE | 交易请求完成 |
10010 | TRADE_RETCODE_DONE_PARTIAL | 交易请求部分成交完成 |
10011 | TRADE_RETCODE_ERROR | 请求处理错误 |
10012 | TRADE_RETCODE_TIMEOUT | 请求超时,已被取消 |
10013 | TRADE_RETCODE_INVALID | 无效请求 |
10014 | TRADE_RETCODE_INVALID_VOLUME | 无效成交量(手数) |
10015 | TRADE_RETCODE_INVALID_PRICE | 无效价格 |
10016 | TRADE_RETCODE_INVALID_STOPS | 无效止损 |
10017 | TRADE_RETCODE_TRADE_DISABLED | 禁止交易 |
10018 | TRADE_RETCODE_MARKET_CLOSED | 休市 |
10019 | TRADE_RETCODE_NO_MONEY | 没有足够的钱实现交易请求 |
10020 | TRADE_RETCODE_PRICE_CHANGED | 价格已改变 |
10021 | TRADE_RETCODE_PRICE_OFF | 没有报价来处理交易请求 |
10022 | TRADE_RETCODE_INVALID_EXPIRATION | 订单过期时间无效 |
10023 | TRADE_RETCODE_ORDER_CHANGED | 订单状态改变 |
10024 | TRADE_RETCODE_TOO_MANY_REQUESTS | 太频繁的交易请求 |
10025 | TRADE_RETCODE_NO_CHANGES | 没有更改交易请求 |
10026 | TRADE_RETCODE_SERVER_DISABLES_AT | 服务器禁止自动交易 |
10027 | TRADE_RETCODE_CLIENT_DISABLES_AT | 客户端禁止自动交易 |
10028 | TRADE_RETCODE_LOCKED | 处理锁定交易请求 |
10029 | TRADE_RETCODE_FROZEN | 冻结订单 或 放置订单 |
10030 | TRADE_RETCODE_INVALID_FILL | 无效的成交量(手数)类型 |
10031 | TRADE_RETCODE_CONNECTION | 与服务器断开无连接 |
10032 | TRADE_RETCODE_ONLY_REAL | 仅允许实盘帐户操作 |
10033 | TRADE_RETCODE_LIMIT_ORDERS | 挂单数量达到限制 |
10034 | TRADE_RETCODE_LIMIT_VOLUME | 订单成交量 和 交易品种 订单数量达到限制 |
10035 | TRADE_RETCODE_INVALID_ORDER | 错误或禁止的 订单类型 |
10036 | TRADE_RETCODE_POSITION_CLOSED | 指定 POSITION_IDENTIFIER的持仓订单已关闭 |
10038 | TRADE_RETCODE_INVALID_CLOSE_VOLUME | 平仓交易量(手数)超出当前持仓交易量(手数) |
10039 | TRADE_RETCODE_CLOSE_ORDER_EXIST | 已经存在一个指定仓位的平仓订单。这种情况可能发生在对冲系统中: • 当试图以相反订单的方式关闭某一仓位时,该仓位的平仓订单已经存在。 • 当试图完全或部分关闭一个仓位时,如果已经存在的订单的总量和新放置的订单量超过了当前的仓位成交量(手数)。 |
10040 | TRADE_RETCODE_LIMIT_POSITIONS | 在帐户上同时打开的订单的数量可以通过服务器的设置来限定。在到达一个限制之后,当试图下订单时,服务器将返回trade_retcode_limit_position错误。限定操作的差异取决于账户持仓类型: • 净持仓模式(单边做多) —— 仅考虑持有打开订单的数量。当达到一个限制时,平台不允许放置新订单(挂单),因其执行可能会增加持有订单的数量。事实上,该平台只允许对已经持有的仓位的交易品种下单。而挂单则未考虑,因为它们的执行可能导致当前仓位的变化,但不能增加它们的数量。• 对冲模式(双向交易 )—— 挂单与持有的订单一起被考虑,因为一个挂单激活总是导致打开一个新的仓位。当达到一个限制时,平台不允许同时发布新的 市场订单 和 挂单。 |
10041 | TRADE_RETCODE_REJECT_CANCEL | 挂单激活请求被拒绝,订单被取消 |
10042 | TRADE_RETCODE_LONG_ONLY | 因为交易品种(POSITION_TYPE_BUY)设置了"只允许做多"的规则,所以请求被拒绝 |
10043 | TRADE_RETCODE_SHORT_ONLY | 因为交易品种 (POSITION_TYPE_SELL)设置了"只允许做空"的规则,所以请求被拒绝 |
10044 | TRADE_RETCODE_CLOSE_ONLY | 因为交易品种设置了"只允许平仓"的规则,所以请求被拒绝 |
# 2.8.2 编译器警告
编译器警告仅用于提示信息目的,并不是错误消息。
代码 | 描述 |
---|---|
21 | datetime字符串中的日期记录不完整。 |
22 | 在datetime字符串中使用了错误的日期数字,正确要求如下 年 1970 <= X <= 3000 月 0 <X <= 12 日 0 <X <= 31/30/28 (29 ).... |
23 | 在datetime字符串中使用了错误的时间数字,正确要求如下 小时 0 <= X <24 分钟 0 <= X <60 |
24 | 在RGB格式中使用了无效的颜色值,RGB元素中的值应该在0到255之间 |
25 | 未知的转义序列字符。 可用的转义符 : \n \r \t \ " ' \X \x |
26 | 函数的局部变量(> 512Kb)太大,减少这个数字。 |
29 | 枚举已定义(副本)---- 成员将被添加到第一个定义中。 |
30 | 主要宏 |
31 | 变量已声明但在任何地方都没使用 |
32 | 构造函数必须是void(空)类型。 |
33 | 解构函数必须是void(空)类型。 |
34 | 常量不在整数范围内 (X> _UI64_MAX | | X <_I64_MIN),并且转变为双精度型函数 |
35 | 太长的HEX —— 超过16个有意义的字符(高位的半字节被切除) |
36 | 在HEX字符串"0x"中没有半字节 |
37 | 无功能函数 —— 没有执行任何命令 |
38 | 使用了一个未初始化的变量 |
41 | 函数没有主体,不被调用 |
43 | 在类型转换中可能丢失的数据。示例: int x = (double) z; |
44 | 当转换一个常数时,(数据)精度的损失。示例: int x = M_PI。 |
45 | 比较的操作数存在正负符号(+-)差异。示例: (char) c1> (uchar) c2。 |
46 | 函数导入问题 —— #import声明是必需的,或者函数的导入是隐式的 |
47 | 描述文本太大 —— 额外超出的字符将不会包含在可执行文件中。 |
48 | 指标缓冲区的数量比所要求的少 |
49 | 在指标中绘图图解无颜色 |
50 | 指标中无图解系列 |
51 | 在脚本中找不到'OnStart' 函数句柄 |
52 | 'OnStart' 函数参数错误 |
53 | 只在脚本中定义'OnStart' 函数 |
54 | 'OnInit' 函数参数错误 |
55 | 在脚本中不使用'OnInit'函数 |
56 | 以错误参量定义'OnDeinit'函数 |
57 | 在脚本中不使用'OnDeinit'函数 |
58 | 定义了两个'OnCalculate'函数。价格数组的'OnCalculate'函数被使用。 |
59 | 在计算复杂的整数常量时检测到的溢出。 |
60 | 或许,变量没有初始化 |
61 | 该声明可能导致无法引用在指定行上声明的局部变量。 |
62 | 该声明可能导致无法引用在指定行上声明的全局变量。 |
63 | 不能用于静态分配的数组。 |
64 | 这个变量声明隐藏了预定义的变量。 |
65 | 表达式的值始终为 true/false |
66 | 在数学运算中使用变量或bool型表达式是不安全的。 |
67 | 将一元 负算子 应用于无符号ulong类型的结果是未定义的。 |
68 | 在#property version属性中指定的版本对于市场部分来说是不可接受的; #property version id“XXX.YYY”的正确格式 |
69 | 发现 空 控制语句 |
70 | 在事件处理函数的声明中,函数返回类型无效 或 不正确的参数。 |
71 | 需要对一种类型的 结构 进行隐式转换。 |
72 | 该声明使得不能直接访问指定字符串中声明的类成员。只能通过 范围解析操作 :: 进行访问。 |
73 | 二进制常量太大,高位的数字将被截断 |
74 | 继承类方法中的参数有一个不同的const修饰符,派生函数已经重载了父函数。 |
75 | 在 移位位操作中,移位值为 负 或 过大,则执行结果未定义。 |
76 | 函数必须 返回一个值 |
77 | void(空)类型 函数返回了一个值 |
78 | 不是所有的控制路径都返回一个值。 |
79 | 在 全局范围 内不允许表达式。 |
80 | 检查 操作符优先级 的可能错误;使用括号来阐明这个优先 |
81 | 定义了两个 OnCalCulate() 。将使用OHLC 版本 |
82 | Struct 结构 没有成员,大小被分配1字节 |
83 | 函数的返回值应该被检查 |
84 | 为调试编译资源指标。这会降低性能。请重新编译指标以提高性能。 |
85 | 字符串中的字符代码太大,必须在0到65535之间。 |
86 | 字符串中未识别的字符 |
87 | 没有指定指标窗口属性( 主窗口 或 子窗口 )。属性 #property indicator_chart_window (使用主窗口)被应用. |
# 2.8.3 编译错误
在编辑代码过程中,MetaEdtior 5会通过内置的编译器检测程序错误,并将错误消息显示出来。这些错误列举在下表中。要将源代码编译成可执行文件,请按F7。包含错误的程序不能编译,直到编译器识别出的错误被消除为止。
代码 | 描述 |
---|---|
>100 | 文件读取错误 |
101 | 打开 *. EX5文件试图写入错误 |
103 | 没有足够内存完成编译 |
104 | 编译器不能识别的空语法单元 |
105 | #include文件中的错误文件名 |
106 | #include 包含文件中的文件访问错误(也许因为文件不存在) |
108 | 与 #define不匹配的名称 |
109 | 预处理器的未知命令(有效的命令为 #include, #define, #property, #import) |
110 | 编译器无法识别的符号 |
111 | 无法实施的函数(只有描述,却没有主体) |
112 | 双引号 (") 省略 |
113 | 尖角括号 (<) 或 双引号 (") 省略 |
114 | 单引号(')省略 |
115 | 反尖括号">"省略 |
116 | 声明中未指定的类型 |
117 | 无返回(return)操作 或者 在实施的所有分支中没发现返回操作符(return)。 |
118 | 预期调用参数的开启括号。 |
119 | 写入EX5 错误 |
120 | 对数组的访问无效 |
121 | 函数不是 空(void)类型,返回操作符(return)必须返回一个值 |
122 | 析构函数的错误声明。 |
123 | 冒号":"缺失 |
124 | 变量已声明 |
125 | 标识符变量已声明 |
126 | 变量名称太长(>250字符) |
127 | 已经定义了该标识符的 结构 |
128 | 结构 未定义 |
129 | 同名结构成员已被定义 |
130 | 没有相关 结构 成员 |
131 | 违反了配对的括号 |
132 | 需要一个开(左)括号 "(" |
133 | 不对称的括号(不是 "}") |
134 | 难以编译(过多的分支,内部堆栈级别被过度填充) |
135 | 打开文件读取错误 |
136 | 没有足够内存下载源文件 |
137 | 预期变量 |
138 | 引用不能初始化 |
140 | 预期任务(出现在声明中) |
141 | 需要开()左括号"{" |
142 | 参数仅用于 动态数组 |
143 | 不能接受使用"void"类型 |
144 | 没有成对的 ")" 或者 "]", 例如 缺少 "(" 或 " [ " |
145 | 没有成对的 ")" 或者 "]", 例如 缺少 ")" 或 " ] " |
146 | 数组大小错误 |
147 | 太多参数(> 64) |
149 | 该标记不是预期的 |
150 | 无效使用操作(无效操作数) |
151 | 表达式不允许 空(void) 型 |
152 | 需要操作符 |
153 | 滥用终止 |
154 | 需要分号";" |
155 | 需要逗号"," |
156 | 必须是一个 类 ,而不是 结构 |
157 | 需要表达式 |
158 | 在十六进制或太长(数字> 511)中发现“非十六进制字符” |
>159 | 字符串常数有超过65534个字符 |
160 | 此处的函数定义无法接受 |
161 | 不是预期的程序结尾 |
162 | 禁止 结构 的前置声明 |
163 | 函数名称已定义并有另一个返回类型 |
164 | 函数名称已定义并有不同的形式参数 |
165 | 函数名称已定义并已实施 |
166 | 调用时未发现 函数重载 |
167 | 具有void类型返回值的函数不能返回值 |
168 | 函数不能定义 |
170 | 需要一个值 |
171 | case 表达式中只有整数常量是有效的 |
172 | switch中的case值已经被使用 |
173 | 需要整数 |
174 | 需要 #import表达式文件名称 |
175 | 在全局范围上,不允许使用表达式 |
176 | 在 ";" 前省略了圆括号")" |
177 | 等号左边需要一个变量 |
178 | 不能使用表达式结果 |
179 | 在 case 中,不允许声明变量。 |
180 | 从字符串到数字的隐式转换 |
181 | 从数字到字符串的隐式转换 |
182 | 重载函数 的模糊调用(同时有几个重载匹配) |
183 | 不包含if的非法else |
184 | 没有switch的无效case或者default |
185 | 省略号的不恰当使用 |
186 | 初始化序列比初始化的变量具有更多的元素。 |
187 | 需要case常数 |
188 | 需要表达式常数 |
>189 | 常量不能改变 |
190 | 需要 反括号 或 逗号(声明数组成员) |
191 | 枚举标识符已经定义 |
192 | 枚举不能有访问修饰符(const, extern, static) |
193 | 枚举成员已经声明了不同的值 |
194 | 有一个用相同名称定义的变量 |
195 | 有一个用相同名称定义的结构 |
196 | 需要列举成员名称 |
197 | 需要整数表达式 |
198 | 常数表达式中除以0(分母为0) |
199 | 函数参数数量错误 |
200 | 参数的引用必须是一个变量 |
201 | 相同类型的变量,通过引用来传递。 |
202 | 常量不能通过非常量引用传递 |
203 | 需要正整数常量 |
204 | 访问 类 的保护成员失败 |
205 | 导入 已使用另一种方式定义 |
208 | 未生成可执行文件 |
209 | 指标中未发现 'OnCalculate' 入口点 |
210 | 只有在 循环中 才能执行 continue 操作 |
211 | 访问 私有(关闭) 类 成员 错误 |
213 | 结构 或 类 的方法没有声明 |
214 | 访问 私有 (关闭) 类 的方法错误 |
216 | 不允许复制带有对象的结构 |
218 | 数组索引超出范围 |
219 | 不允许在 结构 或 类 声明中进行数组初始化。 |
220 | 类 构造函数不能有参数 |
221 | 类 析构函数不能有参数 |
222 | 已经声明了具有相同名称和参数的 类方法 或 结构 |
223 | 需要一个操作数 |
224 | 具有相同名称的 类方法 或 结构 存在,但具有不同的参数 (声明 != 实现) |
225 | 未声明实施函数 |
226 | ZeroMemory()不允许有受保护成员 或 继承 的对象。 |
227 | 重载函数的模糊调用(几个重载的参数的精确匹配) |
228 | 需要变量名称 |
229 | 此处不能声明引用。 |
230 | 枚举名称已经使用 |
232 | 需要 类 或 结构 |
235 | 不能调用 'delete' 操作去删除数组 |
236 | 需要' while'操作符 |
237 | 'delete'操作需要指针 |
238 | 'switch' 已经有 'default' |
239 | 语法错误 |
240 | 转码序列符只能在字符串中(以“\”开头) |
241 | 需要数组 —— 方括号'['不应用于数组,或者将 非数组 作为 数组参数 传递 |
242 | 不能通过初始化序列初始化 |
243 | 导入 (import) 不能定义 |
244 | 语法树优化器错误 |
245 | 声明太多结构(尝试简化程序) |
246 | 不允许参数转换 |
247 | 使用“删除”操作错误 |
248 | 不允许声明引用指针 |
249 | 不允许声明引用的引用 |
250 | 不允许声明指针的指针 |
251 | 不允许在参数列表中的声明结构 |
252 | 类型转换(Type Casting)过程中的无效操作 |
253 | 指针只能为 类 或 结构 声明 |
256 | 未声明的标识符 |
257 | 可执行代码优化程序出错 |
258 | 可执行代码生成错误 |
260 | “switch”指令的无效表达式 |
261 | 字符串常量溢出,请简化程序 |
262 | 不能转换为枚举类型 |
263 | 不能使用“virtual虚拟”数据(类 或 结构 的成员) |
264 | 不能调用 类 的 保护方法 |
265 | 拒绝虚拟函数返回不同类型的值 |
266 | 类 不能从 结构 继承 |
267 | 结构 不能从 类 继承 |
268 | 构造函数不能是虚拟的(不允许使用virtual说明符) |
269 | 结构 不能有virtual(虚拟) 方法 |
270 | 函数必须有主体 |
271 | 禁止重载系统函数(终端函数) |
272 | Const说明符对于不属于 类 或 结构 的函数是无效的 |
274 | 在常量方法中不允许改变 类 成员 |
276 | 不适当的初始化顺序 |
277 | 参数没有默认值(特定的默认参数声明) |
278 | 覆盖默认参数(声明和实现中的不同值) |
279 | 不允许为 对象常量 调用 非常量方法 |
280 | 对象 访问 成员 是必需的(用 .(点) 来标识 类/结构 和 非类/结构 ) |
281 | 已声明的结构名称不能在声明中使用 |
284 | 未经授权的转换(在封闭的继承中) |
285 | 结构 和 数组 不能用作输入变量(外部参数) |
286 | Const说明符对 构造函数/析构函数 无效 |
287 | 不正确的字符串表达式用于datetime类型 |
288 | 未知的属性 (#property) |
289 | 属性值错误 |
290 | #property中的属性值为无效索引 |
291 | 调用省略参数 - <func (x,)> |
293 | 对象必须通过引用传递 |
294 | 数组必须通过引用传递 |
295 | 函数被声明为可导出的 |
296 | 函数被声明为不可导出的 |
297 | 导入的函数禁止导出 |
298 | 导入的函数不能有此参数(禁止传递一个指针、包含动态数组的类 或 结构,指针、类等) |
299 | 必需是 类 |
300 | #import 没有关闭 |
302 | 类型不匹配 |
>303 | 外部变量已经初始化 |
304 | 没有导出函数 或者 没有找到 事件处理函数的 进入点 |
305 | 不允许直接调用 显式构造函数 |
306 | 方法 被声明为常数 |
307 | 方法 没有被声明为常数 |
308 | 资源文件大小不正确 |
309 | 资源名称不正确 |
310 | 资源文件打开错误 |
311 | 资源文件读取错误 |
312 | 未知的资源文件类型 |
313 | 资源文件路径错误 |
314 | 指定的资源文件名称已经被使用 |
315 | 函数需要变量,类似宏 |
316 | 意外的宏 定义符号 |
317 | 宏的形式参数错误 |
318 | 宏的形式参数数量无效 |
319 | 宏的参数太多 |
320 | 太复杂,请简化 宏 |
321 | EnumToString()的参数只能是一个枚举型 |
322 | 资源名称太长 |
323 | 不支持的图片格式(只支持24/32位色深的BMP格式) |
324 | 数组不能以操作符声明 |
325 | 函数只能在 全局 范围被声明 |
326 | 不允许在当前范围声明 |
327 | 不允许使用局部变量的值初始化静态变量 |
328 | 非法声明一个没有默认构造函数 的 对象数组 |
329 | 初始化列表 只允许用于 构造函数 |
330 | 初始化列表后无定义函数 |
331 | 初始化列表 为空 |
332 | 不允许在构造函数中初始化数组 |
333 | 不允许在初始化列表中的初始化父类的成员 |
334 | 期望 整数类型 的表达式 |
335 | 数组 所需的内存超过最大值 |
336 | 结构 所需的内存超过最大值 |
337 | 声明的全局变量所需的内存超过最大值 |
338 | 局部变量所需的内存超过最大值 |
339 | 构造函数 未定义 |
340 | 图标文件的名称无效 |
341 | 不能在指定路径打开图标文件 |
342 | 图标文件不正确,不是 ICO 格式 |
343 | 使用初始化列表重新初始化 类/结构 构造函数的成员 |
344 | 不允许在 构造函数 初始化列表 中 初始化 静态 成员 |
345 | 不允许在 类/结构 的全局范围上初始化 非静态 成员 |
346 | 类/结构 的方法名称与前面声明的成员的名称相匹配 |
347 | 类/结构 的成员名称与前面声明的成员的名称相匹配 |
348 | 虚函数不能声明为静态 |
349 | const 修饰符不允许用于静态函数 |
350 | 构造函数 或 析构函数 不能是静态的 |
351 | 类 或 结构 的 非静态成员/方法 不能从静态函数访问 |
352 | 重载操作(+,-,[],++,等等)在操作符关键字之后。 |
353 | 并非所有操作都可以在MQL5 重载 |
354 | 定义与声明不匹配 |
355 | 为 操作符 指定的参数数量无效 |
356 | 未发现事件处理函数 |
357 | 方法 无法导出 |
358 | 常量对象的指针不能通过非常量对象格式化 |
359 | 还不支持类的模板 |
360 | 还不支持函数模板重载 |
361 | 不能应用函数模板 |
362 | 函数模板的不明确参数(可以应用几种参数类型) |
363 | 无法确定参数类型,函数模板参数应该被格式化 |
364 | 函数模板中的参数数量不正确 |
365 | 函数模板不能是 虚拟(virtual)的 |
366 | 函数模板不能导出 |
367 | 函数模板不能导入 |
368 | 不允许包含 对象 的 结构 |
369 | 不允许包含对象的字符串数组和 结构 |
370 | 静态 类/结构 成员 必须被显式初始化 |
371 | 编译器限制:字符串不能包含超过65 535个字符 |
372 | #ifdef/#endif 相悖 |
373 | 不能返回 类 的 对象,复制构造函数没有找到 |
374 | 不能使用 非静态成员 和 方法 |
375 | 没有OnTesterDeinit() 不能使用OnTesterInit() |
376 | 重新定义形式参数 '%s' |
377 | 宏 FUNCSIG 和 FUNCTION 不能出现在函数主体之外 |
378 | 无效返回类型。例如,从DLL输入的函数返回 结构 或 指针 将会产生这种错误 |
379 | 模板使用错误 |
380 | 未使用 |
381 | 声明纯粹(pure)的虚拟(virtual)函数时语法出错,只允许 "=NULL" 或 "=0" |
382 | 只有虚拟(virtual)函数可以使用纯粹(pure说明符进行声明 ("=NULL" 或 "=0") |
383 | 抽象类不能被实例化 |
384 | 使用dynamic_cast操作符将一个指向用户定义类型的指针作为动态转换的目标类型 |
385 | 需要"函数指针" 类型 |
386 | 不支持 指向方法的指针 |
387 | 错误 —— 不能定义函数指针类型 |
388 | 类型转换不可用,由于private 继承 |
389 | const 修饰符变量应在声明期间初始化 |
393 | 只有具有公共访问的 方法 才能在接口中声明 |
394 | 无效界面 嵌入另一个界面中 |
395 | 界面只能由另一个界面衍生 |
396 | 期待一个界面 |
397 | 界面仅支持公共继承 |
398 | 一个界面不能包括成员 |
399 | 界面对象不可直接创建,只能通过继承方式 |
# 2.8.4 运行时间错误
GetLastError() 函数是用来返回储存在预定义变量 _LastError中的上一个错误的代码。该值可以通过 ResetLastError() 函数重置为0
常量 | 代码 | 描述 |
---|---|---|
ERR_SUCCESS | 0 | 操作成功完成 |
ERR_INTERNAL_ERROR | 4001 | 意外内部错误 |
ERR_WRONG_INTERNAL_PARAMETER | 4002 | 客户端函数内部调用的参数错误 |
ERR_INVALID_PARAMETER | 4003 | 当调用系统函数时参数错误 |
ERR_NOT_ENOUGH_MEMORY | 4004 | 没有足够的内存空间执行系统函数 |
ERR_STRUCT_WITHOBJECTS_ORCLASS | 4005 | 该结构包含 字符串 和/或 动态数组 的对象 和/或 此 对象的类 和/或 结构。 |
ERR_INVALID_ARRAY | 4006 | 数组类型错误,大小错误,或者 动态数组 中有一个已损害的对象 |
ERR_ARRAY_RESIZE_ERROR | 4007 | 没有足够的内存来重新定位一个数组,或者尝试改变一个静态数组的大小 |
ERR_STRING_RESIZE_ERROR | 4008 | 没有足够内存重置字符串 |
ERR_NOTINITIALIZED_STRING | 4009 | 没有初始化字符串 |
ERR_INVALID_DATETIME | 4010 | 无效人 日期 和/或 时间 |
ERR_ARRAY_BAD_SIZE | 4011 | 要求的数组大小超过2GB |
ERR_INVALID_POINTER | 4012 | 无效指针 |
ERR_INVALID_POINTER_TYPE | 4013 | 指针类型错误 |
ERR_FUNCTION_NOT_ALLOWED | 4014 | 函数不允许调用 |
ERR_RESOURCE_NAME_DUPLICATED | 4015 | 动态名称 和 静态资源 匹配 |
ERR_RESOURCE_NOT_FOUND | 4016 | 该名称的资源在EX5文件中没有找到 |
ERR_RESOURCE_UNSUPPOTED_TYPE | 4017 | 不支持的资源类型 或 其大小超过 16 Mb |
ERR_RESOURCE_NAME_IS_TOO_LONG | 4018 | 资源名称超过 63 个字符 |
ERR_MATH_OVERFLOW | 4019 | 计算数学函数时产生溢值(超出计算范围) |
图表 | ||
ERR_CHART_WRONG_ID | 4101 | 错误的图表ID编号 |
ERR_CHART_NO_REPLY | 4102 | 图表没有响应 |
ERR_CHART_NOT_FOUND | 4103 | 图表未找到 |
ERR_CHART_NO_EXPERT | 4104 | 在图表中没有任何EA处理这个事件 |
ERR_CHART_CANNOT_OPEN | 4105 | 图表打开错误 |
ERR_CHART_CANNOT_CHANGE | 4106 | 改变图表交易品种 或 周期 失败 |
ERR_CHART_WRONG_PARAMETER | 4107 | 使用图表函数的参数错误 |
ERR_CHART_CANNOT_CREATE_TIMER | 4108 | 创建定时器失败 |
ERR_CHART_WRONG_PROPERTY | 4109 | 错误图表属性ID |
ERR_CHART_SCREENSHOT_FAILED | 4110 | 生成截屏错误 |
ERR_CHART_NAVIGATE_FAILED | 4111 | 图表导航操作错误 |
ERR_CHART_TEMPLATE_FAILED | 4112 | 应用模板错误 |
ERR_CHART_WINDOW_NOT_FOUND | 4113 | 未找到子窗口(副图窗口)包含的指标 |
ERR_CHART_INDICATOR_CANNOT_ADD | 4114 | 添加指标到图表错误 |
ERR_CHART_INDICATOR_CANNOT_DEL | 4115 | 删除图表指标错误 |
ERR_CHART_INDICATOR_NOT_FOUND | 4116 | 指定图表上未发现指标 |
图解对象 | ||
ERR_OBJECT_ERROR | 4201 | 图解对象的错误 |
ERR_OBJECT_NOT_FOUND | 4202 | 未发现图解对象 |
ERR_OBJECT_WRONG_PROPERTY | 4203 | 图解对象属性ID错误 |
ERR_OBJECT_GETDATE_FAILED | 4204 | 无法获得与值对应的日期时间 |
ERR_OBJECT_GETVALUE_FAILED | 4205 | 无法获得与日期时间对应的值 |
市场信息 | ||
ERR_MARKET_UNKNOWN_SYMBOL | 4301 | 未知交易品种 |
ERR_MARKET_NOT_SELECTED | 4302 | 市场报价中未选中该交易品种 |
ERR_MARKET_WRONG_PROPERTY | 4303 | 交易品种的属性标识符错误 |
ERR_MARKET_LASTTIME_UNKNOWN | 4304 | 最后一个跳价的时间是未知的(没有收到报价) |
ERR_MARKET_SELECT_ERROR | 4305 | 在 市场报价 窗口中 添加 或 删除 交易品种错误 |
历史访问 | ||
ERR_HISTORY_NOT_FOUND | 4401 | 请求查看的历史记录未找到 |
ERR_HISTORY_WRONG_PROPERTY | 4402 | 历史记录属性ID错误 |
ERR_HISTORY_TIMEOUT | 4403 | 历史请求超时过多 |
ERR_HISTORY_BARS_LIMIT | 4404 | 请求K柱的数量受到程序端设置的限制 |
ERR_HISTORY_LOAD_ERRORS | 4405 | 加载历史数据时发生多个错误 |
ERR_HISTORY_SMALL_BUFFER | 4407 | 接受数组太小,无法存储所有请求的历史数据 |
全局变量 | ||
ERR_GLOBALVARIABLE_NOT_FOUND | 4501 | 客户端全局变量未找到 |
ERR_GLOBALVARIABLE_EXISTS | 4502 | 相同名称的客户端全局变量已经存在 |
ERR_GLOBALVARIABLE_NOT_MODIFIED | 4503 | 全局变量未被修改 |
ERR_GLOBALVARIABLE_CANNOTREAD | 4504 | 无法通过全局变量值读取文件 |
ERR_GLOBALVARIABLE_CANNOTWRITE | 4505 | 无法通过全局变量值写入文件 |
ERR_MAIL_SEND_FAILED | 4510 | 发送邮件失败 |
ERR_PLAY_SOUND_FAILED | 4511 | 声音播放失败 |
ERR_MQL5_WRONG_PROPERTY | 4512 | 程序属性标识符错误 |
ERR_TERMINAL_WRONG_PROPERTY | 4513 | 客户端属性标识符错误 |
ERR_FTP_SEND_FAILED | 4514 | 通过ftp发送文件失败 |
ERR_NOTIFICATION_SEND_FAILED | 4515 | 发送 通知(短消息,需要 google 框架支持) 失败 |
ERR_NOTIFICATION_WRONG_PARAMETER | 4516 | 发送通知的无效参数 —— 空字符串或 NULL 被传递到 SendNotification() 函数 |
ERR_NOTIFICATION_WRONG_SETTINGS | 4517 | 错误的程序端通知设置(未指定ID或未设置权限) |
ERR_NOTIFICATION_TOO_FREQUENT | 4518 | 发送通知过于频繁 |
ERR_FTP_NOSERVER | 4519 | 未指定FTP 服务器 |
ERR_FTP_NOLOGIN | 4520 | 未指定FTP登录名 |
ERR_FTP_FILE_ERROR | 4521 | 在MQL5\Files目录未找到发送至FTP服务器的文件 |
ERR_FTP_CONNECT_FAILED | 4522 | FTP 连接失败 |
ERR_FTP_CHANGEDIR | 4523 | 在服务器上未找到FTP路径 |
ERR_FTP_CLOSED | 4524 | FTP 连接关闭 |
自定义指标缓冲区 | ||
ERR_BUFFERS_NO_MEMORY | 4601 | 没有足够内存建立指标缓冲区 |
ERR_BUFFERS_WRONG_INDEX | 4602 | 错误指标缓冲区索引值 |
自定义指标属性 | ||
ERR_CUSTOM_WRONG_PROPERTY | 4603 | 自定义指标的错误ID |
账户 | ||
ERR_ACCOUNT_WRONG_PROPERTY | 4701 | 账户属性ID错误 |
ERR_TRADE_WRONG_PROPERTY | 4751 | 交易属性ID错误 |
ERR_TRADE_DISABLED | 4752 | EA交易被禁止 |
ERR_TRADE_POSITION_NOT_FOUND | 4753 | 未找到仓位 |
ERR_TRADE_ORDER_NOT_FOUND | 4754 | 未找到订单 |
ERR_TRADE_DEAL_NOT_FOUND | 4755 | 未找到交易单 |
ERR_TRADE_SEND_FAILED | 4756 | 交易需求发送失败 |
ERR_TRADE_CALC_FAILED | 4758 | 计算利润或保证金(预付款)失败 |
指标 | ||
ERR_INDICATOR_UNKNOWN_SYMBOL | 4801 | 未知交易品种 |
ERR_INDICATOR_CANNOT_CREATE | 4802 | 不能创建指标 |
ERR_INDICATOR_NO_MEMORY | 4803 | 没有足够内存添加指标 |
ERR_INDICATOR_CANNOT_APPLY | 4804 | 指标不能应用于另一指标 |
ERR_INDICATOR_CANNOT_ADD | 4805 | 指标应用到图表错误 |
ERR_INDICATOR_DATA_NOT_FOUND | 4806 | 需求数据未找到 |
ERR_INDICATOR_WRONG_HANDLE | 4807 | 指标句柄处理错误 |
ERR_INDICATOR_WRONG_PARAMETERS | 4808 | 创建指标时使用的参数数量错误 |
ERR_INDICATOR_PARAMETERS_MISSING | 4809 | 创建指标时没有参数 |
ERR_INDICATOR_CUSTOM_NAME | 4810 | 数组中的第一个参数必须是自定义指标的名称 |
ERR_INDICATOR_PARAMETER_TYPE | 4811 | 创建指标时,数组中参数类型无效 |
ERR_INDICATOR_WRONG_INDEX | 4812 | 请求的指标缓冲区索引错误 |
市场深度 | ||
ERR_BOOKS_CANNOT_ADD | 4901 | 不能添加市场深度 |
ERR_BOOKS_CANNOT_DELETE | 4902 | 不能移动市场深度 |
ERR_BOOKS_CANNOT_GET | 4903 | 市场深度数据未获得 |
ERR_BOOKS_CANNOT_SUBSCRIBE | 4904 | 从市场深度接收新数据时出错 |
文件操作 | ||
ERR_TOO_MANY_FILES | 5001 | 不能同时打开超过64个文件 |
ERR_WRONG_FILENAME | 5002 | 无效文件名 |
ERR_TOO_LONG_FILENAME | 5003 | 太长文件名 |
ERR_CANNOT_OPEN_FILE | 5004 | 文件打开错误 |
ERR_FILE_CACHEBUFFER_ERROR | 5005 | 读取文件缓冲区没有足够内存 |
ERR_CANNOT_DELETE_FILE | 5006 | 文件删除错误 |
ERR_INVALID_FILEHANDLE | 5007 | 文件句柄关闭,或者根本没打开 |
ERR_WRONG_FILEHANDLE | 5008 | 文件句柄处理错误 |
ERR_FILE_NOTTOWRITE | 5009 | 文件必须打开后写入 |
ERR_FILE_NOTTOREAD | 5010 | 文件必须打开后读取 |
ERR_FILE_NOTBIN | 5011 | 文件必须以二进制打开 |
ERR_FILE_NOTTXT | 5012 | 文件必须以文本形式打开 |
ERR_FILE_NOTTXTORCSV | 5013 | 文件必须以文本或者CSV打开 |
ERR_FILE_NOTCSV | 5014 | 文件必须以CSV格式打开 |
ERR_FILE_READERROR | 5015 | 文件读取错误 |
ERR_FILE_BINSTRINGSIZE | 5016 | 字符串大小必须制定,因为文件以二进制打开 |
ERR_INCOMPATIBLE_FILE | 5017 | 文本文件必须以字符串数组打开,或其他数组-二进制 |
ERR_FILE_IS_DIRECTORY | 5018 | 没有文件,只有目录 |
ERR_FILE_NOT_EXIST | 5019 | 文件不存在 |
ERR_FILE_CANNOT_REWRITE | 5020 | 文件不能覆盖写入 |
ERR_WRONG_DIRECTORYNAME | 5021 | 错误的目录名称 |
ERR_DIRECTORY_NOT_EXIST | 5022 | 目录不存在 |
ERR_FILE_ISNOT_DIRECTORY | 5023 | 只有文件,没有目录 |
ERR_CANNOT_DELETE_DIRECTORY | 5024 | 目录不能更改 |
ERR_CANNOT_CLEAN_DIRECTORY | 5025 | 清除目录失败(或许一个或多个文件阻止了清除操作,导致失败) |
ERR_FILE_WRITEERROR | 5026 | 将资源写入文件失败 |
ERR_FILE_ENDOFFILE | 5027 | 已到文件末端,不能阅读CSV文件的下一片数据(FileReadString, FileReadNumber,FileReadDatetime,FileReadBool) |
字符串转换 | ||
ERR_NO_STRING_DATE | 5030 | 字符串中无日期 |
ERR_WRONG_STRING_DATE | 5031 | 字符串日期错误 |
ERR_WRONG_STRING_TIME | 5032 | 字符串时间错误 |
ERR_STRING_TIME_ERROR | 5033 | 转变字符串到日期错误 |
ERR_STRING_OUT_OF_MEMORY | 5034 | 没有足够空间建立字符串 |
ERR_STRING_SMALL_LEN | 5035 | 字符串太短 |
ERR_STRING_TOO_BIGNUMBER | 5036 | 太大的数,比ULONG_MAX还大 |
ERR_WRONG_FORMATSTRING | 5037 | 字符串格式无效 |
ERR_TOO_MANY_FORMATTERS | 5038 | 格式说明符数量比参数多 |
ERR_TOO_MANY_PARAMETERS | 5039 | 参数多于格式说明符 |
ERR_WRONG_STRING_PARAMETER | 5040 | 字符串类型参数损坏 |
ERR_STRINGPOS_OUTOFRANGE | 5041 | 位置在字符串之外 |
ERR_STRING_ZEROADDED | 5042 | 字符串末尾添加0,无用操作 |
ERR_STRING_UNKNOWNTYPE | 5043 | 当转换字符串时,数据类型未知 |
ERR_WRONG_STRING_OBJECT | 5044 | 损坏的字符串对象 |
数组操作 | ||
ERR_INCOMPATIBLE_ARRAYS | 5050 | 复制不兼容数组,字符串数组只能复制成字符串数组,数字数组 ---- 只能复制数字数组 |
ERR_SMALL_ASSERIES_ARRAY | 5051 | 接收数组被声明为AS_SERIES,它的大小不够。 |
ERR_SMALL_ARRAY | 5052 | 太小的数组,起始位置在数组的之外 |
ERR_ZEROSIZE_ARRAY | 5053 | 长度数组为0 |
ERR_NUMBER_ARRAYS_ONLY | 5054 | 必须是数字数组 |
ERR_ONEDIM_ARRAYS_ONLY | 5055 | 必须是一维数组 |
ERR_SERIES_ARRAY | 5056 | 不能使用时间序列 |
ERR_DOUBLE_ARRAY_ONLY | 5057 | 必须是双精度类型数组 |
ERR_FLOAT_ARRAY_ONLY | 5058 | 必须是浮点型数组 |
ERR_LONG_ARRAY_ONLY | 5059 | 必须是长型数组 |
ERR_INT_ARRAY_ONLY | 5060 | 必须是整型数组 |
ERR_SHORT_ARRAY_ONLY | 5061 | 必须是短型数组 |
ERR_CHAR_ARRAY_ONLY | 5062 | 必须是字符型数据 |
ERR_STRING_ARRAY_ONLY | 5063 | 仅字符串数组 |
OpenCL操作 | ||
ERR_OPENCL_NOT_SUPPORTED | 5100 | 该计算机不支持OpenCL 函数 |
ERR_OPENCL_INTERNAL | 5101 | 运行 OpenCL 时发生的内部错误 |
ERR_OPENCL_INVALID_HANDLE | 5102 | 无效的 OpenCL 句柄 |
ERR_OPENCL_CONTEXT_CREATE | 5103 | 创建 OpenCL 语境 的错误 |
ERR_OPENCL_QUEUE_CREATE | 5104 | 在OpenCL创建运行队列失败 |
ERR_OPENCL_PROGRAM_CREATE | 5105 | 编译 OpenCL 程序 时发生的错误 |
ERR_OPENCL_TOO_LONG_KERNEL_NAME | 5106 | 过长的内核名称 (OpenCL kernel) |
ERR_OPENCL_KERNEL_CREATE | 5107 | 创建 OpenCL kernel 错误 |
ERR_OPENCL_SET_KERNEL_PARAMETER | 5108 | 当为OpenCL kernel设置参数 时发生的错误 |
ERR_OPENCL_EXECUTE | 5109 | OpenCL 程序 运行时间错误 |
ERR_OPENCL_WRONG_BUFFER_SIZE | 5110 | 无效的 OpenCL 缓存大小 |
ERR_OPENCL_WRONG_BUFFER_OFFSET | 5111 | 无效的 OpenCL 缓存补偿 |
ERR_OPENCL_BUFFER_CREATE | 5112 | 创建 OpenCL 缓存 失败 |
ERR_OPENCL_TOO_MANY_OBJECTS | 5113 | OpenCL 对象过多 |
ERR_OPENCL_SELECTDEVICE | 5114 | OpenCL 设备选择错误 |
WebRequest操作 | ||
ERR_WEBREQUEST_INVALID_ADDRESS | 5200 | 无效 URL |
ERR_WEBREQUEST_CONNECT_FAILED | 5201 | 连接指定URL失败 |
ERR_WEBREQUEST_TIMEOUT | 5202 | 超时 |
ERR_WEBREQUEST_REQUEST_FAILED | 5203 | HTTP 请求失败 |
自定义交易品种 | ||
ERR_NOT_CUSTOM_SYMBOL | 5300 | 必须指定一个自定义交易品种 |
ERR_CUSTOM_SYMBOL_WRONG_NAME | 5301 | 自定义交易品种名称无效。交易品种名称只能包含拉丁字母不可含有标点符号,空格或特殊字符(仅可以包含".","_","&" 和 "#"符号)。不建议使用下列字符<,>,:,",/,\,|,?,*。 |
ERR_CUSTOM_SYMBOL_NAME_LONG | 5302 | 自定义交易品种的名称过长。交易品种名称的总长度不可超过32个字符,包括末位的0字符 |
ERR_CUSTOM_SYMBOL_PATH_LONG | 5303 | 自定义交易品种的路径过长。路径长度不应超过128个字符,包括"Custom\",交易品种名称,组分隔符和末位的0字符 |
ERR_CUSTOM_SYMBOL_EXIST | 5304 | 已存在同名的自定义交易品种 |
ERR_CUSTOM_SYMBOL_ERROR | 5305 | 创建,删除或更改自定义交易品种时出现错误 |
ERR_CUSTOM_SYMBOL_SELECTED | 5306 | 您正在试图删除市场报价中选定的自定义交易品种 |
ERR_CUSTOM_SYMBOL_PROPERTY_WRONG | 5307 | 无效的自定义交易品种属性 |
ERR_CUSTOM_SYMBOL_PARAMETER_ERROR | 5308 | 设置自定义交易品种属性时的参数错误 |
ERR_CUSTOM_SYMBOL_PARAMETER_LONG | 5309 | 设置自定义交易品种属性时过长的字符串参数 |
ERR_CUSTOM_TICKS_WRONG_ORDER | 5310 | 数组中的跳价不是按时间顺序排列的 |
自定义错误 | ||
ERR_USER_ERROR_FIRST | 65536 | 用户自定义 错误起始于该代码 |
相关参考
交易服务器返回代码
# 2.9 输入和输出常量
常量:
•文件打开标帜 •文件属性 •文件内部(指针)位置 •使用字符编码集 •消息盒子(对话框)
# 2.9.1 文件打开标帜
文件打开标帜的 值 指定了文件访问模式。标帜的定义如下:
标识符 | 值 | 描述 |
---|---|---|
FILE_READ | 1 | 打开文件用于读取,在 FileOpen() 中使用此标签。 打开文件时,标帜FILE_WRITE 和/或FILE_READ 模式是必需之一 |
FILE_WRITE | 2 | 打开文件用于写入,在 FileOpen() 中使用此标签。 打开文件时,标帜FILE_WRITE 和/或FILE_READ 模式是必需之一 |
FILE_BIN | 4 | 二进制 读/书 模式(不需要转换字符串),在 FileOpen() 中使用此标签 |
FILE_CSV | 8 | CSV文件(所有元素转换到恰当的字符串类型,Unicode 或者ANSI,并用分隔符分开)在 FileOpen() 中使用此标签 |
FILE_TXT | 16 | 简单文本文件(与CSV文件相同,但不考虑分隔符),在 FileOpen() 中使用此标签 |
FILE_ANSI | 32 | ANSI类型字符串(单字节的字符),在 FileOpen() 中使用此标签 |
FILE_UNICODE | 64 | UNICODE类型字符串(双字节的字符),在 FileOpen() 中使用此标签 |
FILE_SHARE_READ | 128 | 多个程序共享读取,在 FileOpen() 中使用此标签, 但是当打开文件时,此标签不能替代必要的 FILE_WRITE 和/或 FILE_READ 标帜 |
FILE_SHARE_WRITE | 256 | 多个程序共享写入,在 FileOpen() 中使用此标签, 但是当打开文件时,此标签不能替代必要的 FILE_WRITE 和/或 FILE_READ 标帜 |
FILE_REWRITE | 512 | 使用 FileCopy() 和 FileMove() 函数可以重新写入文件,文件应该在打开时,用于 写入(FILE_WRITE),否则不能打开文件。 |
FILE_COMMON | 4096 | 所有客户端在共用文件夹中的文件路径 \Terminal\Common\Files, 此标签在FileIsExist(),,FileOpen() , FileCopy() , FileMove() 函数中使用。 |
打开文件时可以指定一个或多个标帜。这是标帜的组合。标帜的组合使用逻辑 或(|) 的符号,它位于枚举标帜之间。例如,打开CSV格式的文件同时指定 读取 和 写入模式,请指定标帜组合FILE_READ|FILE_WRITE|FILE_CSV
示例:
int filehandle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_CSV);
当指定 读取 和 写入 标帜时,有几种特性: • 如果只指定了FILE_READ,表示尝试打开一个现有的文件。如果文件不存在,文件打开失败,就不会创建新文件。 • FILE_READ|FILE_WRITE —— 如果指定的文件名称不存在,则会创建一个新文件。 • 如果只指定了 FILE_WRITE —— 该文件会被再次创建,其大小为零。
打开文件时,需要指定FILE_WRITE 和/或 FILE_READ。 打开文件时定义读取类型的标帜具有优先级。最高优先级的标帜是FILE_CSV,然后是FILE_BIN,而FILE_TXT最低。因此,如果同时指定了多个标帜(FILE_TXT|FILE_CSV或FILE_TXT FILE_BIN或FILE_BIN|FILE_CSV),那么将使用具有最高优先级的标帜。
定义编码类型的标帜也具有优先级。FILE_UNICODE比FILE_ANSI具有更高的优先级。因此,如果指定组合FILE_UNICODE|FILE_ANSI,将会使用标记FILE_UNICODE。
如果没有显示FILE_UNICODE或FILE_ANSI,那么就默认隐含了FILE_UNICODE。如果不指定FILE_CSV、FILE_BIN或FILE_TXT,则会默认隐含FILE_CSV。
如果一个文件作为文本文件(FILE_TXT或FILE_CSV)打开,并且在文件开头发现了一个特殊的双字节指标 0xff,0xfe,即使在打开时使用了FILE_ANSI编码标帜,该文件的编码也会被指定为FILE_UNICODE。
相关参考 文件函数
# 2.9.2 文件属性
FileGetInteger() 函数用于获取文件属性。在调用期间,从ENUM_FILE_PROPERTY_INTEGER 枚举请求所需的属性标识符传递给它。
ENUM_FILE_PROPERTY_INTEGER
ID | ID 描述 |
---|---|
FILE_EXISTS | 检查文件是否存在 |
FILE_CREATE_DATE | 创建日期 |
FILE_MODIFY_DATE | 最近的更改日期 |
FILE_ACCESS_DATE | 最后访问文件的日期 |
FILE_SIZE | 文件的字节大小 |
FILE_POSITION | 文件指针的位置 |
FILE_END | 获取文件结束标志 |
FILE_LINE_END | 获取行结束标志 |
FILE_IS_COMMON | 该文件在所有终端的共享文件夹中打开(请参考FILE_COMMON) |
FILE_IS_TEXT | 文件打开为文本文件 (请参考 FILE_TXT) |
FILE_IS_BINARY | 文件打开为二进制文件 (请参考 FILE_BIN) |
FILE_IS_CSV | 文件打开为 CSV 文件(请参考 FILE_CSV) |
FILE_IS_ANSI | 文件打开为 ANSI 文件(请参考 FILE_ANSI) |
FILE_IS_READABLE | 打开文件为可读文件 (请参考 FILE_READ) |
FILE_IS_WRITABLE | 打开文件为可写入文件 (请参考 FILE_WRITE) |
调用FileGetInteger() 函数有两个不同的选项。第一个选项,用于获取文件属性,指定使用FileOpen()函数打开文件时获得的句柄。该选项允许获得文件的全部属性。
FileGetInteger() 函数的第二个选项通过文件名称返回文件属性的值。使用该选项,只能获得下面的一般属性:
•FILE_EXISTS —— 指定名称的文件存在 •FILE_CREATE_DATE —— 带有指定名称的文件的创建日期 •FILE_MODIFY_DATE —— 带有指定名称的文件的修改日期 •FILE_ACCESS_DATE —— 带有指定名称的文件的最近访问日期 •FILE_SIZE —— 带有指定名称的文件的大小 当尝试获取超出上述指定的其它属性时,FileGetInteger()调用的第二个选项将返回一个错误。
# 2.9.3 文件内部(指针)位置
大多数文件函数都与数据 读/写 操作相关。同时,使用FileSeek()可以指定文件指针在文件内的位置,然后执行下一个 读或写 操作。ENUM_FILE_POSITION枚举包含有效的指针位置,相对于您可以指定下一个操作的字节转换。
ENUM_FILE_POSITION
标识符 | 描述 |
---|---|
SEEK_SET | 文件起点 |
SEEK_CUR | 文件指针的当前位置 |
SEEK_END | 文件末尾 |
相关参考
文件结束 , 文件结束行
# 2.9.4 使用字符编码集
(在字符串转换操作时使用的字符编码集) 当转换 字符串 变量到 字符型数组 中时,MQL5使用的字符编码集对应的是当前Windows操作系统默认的ANSI (CP_ACP)。如果指定不同类型的字符编码集,可以将它设置为CharArrayToString()、StringToCharArray()和FileOpen()函数的附加参数。
下表列出了一些最流行的编码集的内置常量。没有提到的字符编码集可以通过相对应的代码来指定。
内置字符编码集常量
常量 | 值 | 描述 |
---|---|---|
CP_ACP | 0 | 当前Windows操作系统ANSI字符编码集 |
CP_OEMCP | 1 | 当前系统OEM字符编码集 |
CP_MACCP | 2 | 当前Macintosh系统的字符编码集。 注释:这个值主要在早期创建的程序代码中使用,现在没用了,新的Macintosh电脑使用Unicode编码集。 |
CP_THREAD_ACP | 3 | 当前线程的Windows ANSI字符编码集 |
CP_SYMBOL | 42 | 符号字符编码集 |
CP_UTF7 | 65000 | UTF-7字符编码集 |
CP_UTF8 | 65001 | UTF-8字符编码集 |
相关参考
客户端属性
# 2.9.5 对话框常量
此部分包含MessageBox()函数的返回代码。如果消息窗口有一个 取消 按钮,则该函数将返回IDCANCEL,表示 ESC键 或 取消按钮被按下。如果消息窗口中没有 取消 按钮,按ESC也不会产生任何效果。
常量 | 值 | 描述 |
---|---|---|
IDOK | 1 | 按“确认”键 |
IDCANCEL | 2 | 按“取消”键 |
IDABORT | 3 | 按“停止”键 |
IDRETRY | 4 | 按“重试”键 |
IDIGNORE | 5 | 按“忽略”键 |
IDYES | 6 | 按“是”键 |
IDNO | 7 | 按“否”键 |
IDTRYAGAIN | 10 | 按“再试一次”键 |
IDCONTINUE | 11 | 按“继续”键 |
MessageBox()函数的主标帜定义了对话框窗口的内容和行为。这个值可以是下列标帜的组合:
常量 | 值 | 描述 |
---|---|---|
MB_OK | 0x00000000 | 对话框只包括一个按钮:确定OK 默认 |
MB_OKCANCEL | 0x00000001 | 对话框包括两个按钮:确定OK和 取消 Cancel |
MB_ABORTRETRYIGNORE | 0x00000002 | 对话框包括三个按钮:停止Abort,重试Retry 和 忽略Ignore |
MB_YESNOCANCEL | 0x00000003 | 对话框包括三个按钮:是Yes, 否No 和 取消 Cancel |
MB_YESNO | 0x00000004 | 对话框包括两个按钮:是Yes 和 否No |
MB_RETRYCANCEL | 0x00000005 | 对话框包括两个按钮:重试Retry 和 取消Cancel |
MB_CANCELTRYCONTINUE | 0x00000006 | 对话框包括三个按钮:取消Cancel, 再试一次Try Again, 继续 Continue |
在消息对话框窗口中显示图标icon,必需指定额外的符加标签:
常量 | 值 | 描述 |
---|---|---|
MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND | 0x00000010 | STOP停止标志图标 |
MB_ICONQUESTION | 0x00000020 | 疑问标志图标 |
MB_ICONEXCLAMATION, MB_ICONWARNING | 0x00000030 | 惊叹/警示 标志图标 |
MB_ICONINFORMATION, MB_ICONASTERISK | 0x00000040 | 包围标志图标 |
如下标签定义默认按钮:
常量 | 值 | 描述 |
---|---|---|
MB_DEFBUTTON1 | 0x00000000 | 第一个按钮MB_DEFBUTTON1 -是默认的,如果没有指定其他按钮MB_DEFBUTTON2、 MB_DEFBUTTON3或 MB_DEFBUTTON4。 |
MB_DEFBUTTON2 | 0x00000100 | 默认第二按钮 |
MB_DEFBUTTON3 | 0x00000200 | 默认第三按钮 |
MB_DEFBUTTON4 | 0x00000300 | 默认第四按钮 |