第二章 标准常量,列举和架构

为了简化编写程序的过程,以及使程序代码文本更容易理解,在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");
     }
  }          
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

对于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)); 
  }         
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

对于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  */          
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

另见

事件处理函数 ,工作事件

# 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);        
1
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); 
        } 
     }          
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

另见

使用图表示例

# 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(); 
     }          
1
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); 
     }          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

另见:

打开图表 , 图表ID

# 2.1.6 使用图表示例

本节包含使用图表属性工作的示例。每个属性显示一个或两个完整的函数。这些函数允许设置/接收属性的值。这些函数可以在自定义的mql5应用程序中使用,可以被使用"as is"。

下面的屏幕截图展示了图形面板,说明了图表属性的变化是如何改变其外观的。单击Next按钮,可以设置相应属性的新值,并查看图表窗口中的变化。

Alt text

面板的完整源代码位于 本节最后部分。

图表属性和使用它们的样本函数 •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); 
  }          
1
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); 
  }          
1
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); 
  }          
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

•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); 
  }          
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

•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); 
  }          
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

•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); 
  }
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

•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); 
  }          
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

•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         
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

•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); 
  }          
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

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); 
  }          
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

•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); 
  }          
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

•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); 
  }          
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

•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); 
  }          
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

•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); 
  }          
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
1
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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

• 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);
  }
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

• 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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
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

•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);
  }
1
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);
  }
1
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);
  }
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

•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);
  }
1
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);
  }
1
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;
     }
  }
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 Alt text 垂直线
OBJ_HLINE Alt text 水平线
OBJ_TREND Alt text 趋势线
OBJ_TRENDBYANGLE Alt text 趋势线角度
OBJ_CYCLES Alt text 周期线
OBJ_ARROWED_LINE Alt text 箭头线
OBJ_CHANNEL Alt text 等距离通道
OBJ_STDDEVCHANNEL Alt text 标准偏离通道
OBJ_REGRESSION Alt text 线形回归通道
OBJ_PITCHFORK Alt text 安德鲁分叉线
OBJ_GANNLINE Alt text 江恩线
OBJ_GANNFAN Alt text 江恩扇形线
OBJ_GANNGRID Alt text 江恩网格线
OBJ_FIBO Alt text 斐波纳契回撤
OBJ_FIBOTIMES Alt text 斐波纳契时间周期线
OBJ_FIBOFAN Alt text 斐波纳契扇形线
OBJ_FIBOARC Alt text 斐波纳契弧线
OBJ_FIBOCHANNEL Alt text 斐波纳契通道
OBJ_EXPANSION Alt text 斐波纳契扩展
OBJ_ELLIOTWAVE5 Alt text 艾略特驱动浪
OBJ_ELLIOTWAVE3 Alt text 艾略特调整浪
OBJ_RECTANGLE Alt text 矩型
OBJ_TRIANGLE Alt text 三角形
OBJ_ELLIPSE Alt text 椭圆形
OBJ_ARROW_THUMB_UP Alt text 大拇指向上
OBJ_ARROW_THUMB_DOWN Alt text 大拇指向下
OBJ_ARROW_UP Alt text 向上箭头
OBJ_ARROW_DOWN Alt text 向下箭头
OBJ_ARROW_STOP Alt text 停止标志
OBJ_ARROW_CHECK Alt text 检测标志
OBJ_ARROW_LEFT_PRICE Alt text 左侧价格标签
OBJ_ARROW_RIGHT_PRICE Alt text 右侧价格标签
OBJ_ARROW_BUY Alt text 买入(做多)箭头
OBJ_ARROW_SELL Alt text 卖出(做空)箭头
OBJ_ARROW Alt text 箭头
OBJ_TEXT Alt text 文本
OBJ_LABEL Alt text 文本标签
OBJ_BUTTON Alt text 按钮
OBJ_CHART Alt text 图表
OBJ_BITMAP Alt text 位图
OBJ_BITMAP_LABEL Alt text 位图标签
OBJ_EDIT Alt text 文本编辑框
OBJ_EVENT Alt text “事件”对象在经济日历对应一个事件
OBJ_RECTANGLE_LABEL Alt text 用于创建和设计自定义图形界面的“矩形标签”对象。

# 2.2.1.1 OBJ_VLINE垂直线

Alt text

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);
//---
  }
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

# 2.2.1.3 OBJ_TREND趋势线

Alt text

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);
//---
  }
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

# 2.2.1.4 OBJ_TRENDBYANGLE角度趋势线

Alt text

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);
//---
  }
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

# 2.2.1.5 OBJ_CYCLES循环周期线

Alt text

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);
//---
  }
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

# 2.2.1.6 OBJ_ARROWED_LINE箭头线

Alt text

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);
//---
  }
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

# 2.2.1.7 OBJ_CHANNEL等距通道

Alt text

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);
//---
  }
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

# 2.2.1.8 OBJ_STDDEVCHANNEL标准偏差通道。

Alt text

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);
//---
  }
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

# 2.2.1.9 OBJ_REGRESSION线性回归通道

Alt text

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);
//---
  }
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

# 2.2.1.10 OBJ_PITCHFORK安德鲁鱼叉线

Alt text

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);
//---
  }
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

# 2.2.1.11 OBJ_GANNLINE江恩线

Alt text

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);
//---
  }
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

# 2.2.1.12 OBJ_GANNFAN江恩扇形线

Alt text

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);
//---
  }
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

# 2.2.1.13 OBJ_GANNGRID江恩网格

Alt text

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);
//---
  }
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

# 2.2.1.14 OBJ_FIBO斐波纳契回调线

Alt text

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);
//---
  }
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

# 2.2.1.15 OBJ_FIBOTIMES斐波纳契(黄金分割)时间周期线

Alt text

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);
//---
  }
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

# 2.2.1.16 OBJ_FIBOFAN斐波纳契(黄金分割)扇形线

Alt text

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);
//---
  }
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

# 2.2.1.17 OBJ_FIBOARC斐波纳契(黄金分割)弧形线

Alt text

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);
//---
  }
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

# 2.2.1.18 OBJ_FIBOCHANNEL斐波纳契(黄金分割)通道线

Alt text

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);
//---
  }
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

# 2.2.1.19 OBJ_EXPANSION斐波纳契(黄金分割)扩展线

Alt text

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);
//---
  }
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

# 2.2.1.20 OBJ_ELLIOTWAVE5艾略特驱动浪

Alt text

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);
//---
  }
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

# 2.2.1.21 OBJ_ELLIOTWAVE3艾略特调整浪

Alt text

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);
//---
  }
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

# 2.2.1.21 OBJ_ELLIOTWAVE3艾略特调整浪

Alt text

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);
//---
  }
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

# 2.2.1.22 OBJ_RECTANGLE矩形

Alt text

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);
//---
  }
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

# 2.2.1.23 OBJ_TRIANGLE三角形

Alt text

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);
//---
  }
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

# 2.2.1.24 OBJ_ELLIPSE椭圆形

Alt text

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);
//---
  }
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

# 2.2.1.25 OBJ_ARROW_THUMB_UP拇指向上符号

Alt text

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);
//---
  }
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

# 2.2.1.26 OBJ_ARROW_THUMB_DOWN拇指向下符号

Alt text

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);
//---
  }
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

# 2.2.1.27 OBJ_ARROW_UP箭头向上符号

Alt text

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);
//---
  }
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

# 2.2.1.28 OBJ_ARROW_DOWN箭头向下符号

Alt text

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);
//---
  }
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

# 2.2.1.29 OBJ_ARROW_STOP停止符号

Alt text

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);
//---
  }
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

# 2.2.1.30 OBJ_ARROW_CHECK查验符号

Alt text

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);
//---
  }
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

# 2.2.1.31 OBJ_ARROW_LEFT_PRICE向左价格标签

Alt text

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);
//---
  }
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

# 2.2.1.32 OBJ_ARROW_RIGHT_PRICE向右价格标签

Alt text

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);
//---
  }
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

# 2.2.1.33 OBJ_ARROW_BUY买入符号

Alt text

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);
     }
//---
  }
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

# 2.2.1.34 OBJ_ARROW_SELL卖出符号

Alt text

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);
     }
//---
  }
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

# 2.2.1.35 OBJ_ARROW箭头对象

Alt text

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);
//---
  }
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

# 2.2.1.36 OBJ_TEXT文本对象

Alt 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);
     }
//---
  }
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

# 2.2.1.37 OBJ_LABEL标签对象

Alt text

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);
  }
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

# 2.2.1.38 OBJ_BUTTON按钮对象

Alt text

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);
//---
  }
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

# 2.2.1.39 OBJ_CHART图表对象

Alt text

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);
//---
  }
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

# 2.2.1.40 OBJ_BITMAP位图对象

Alt text

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);
     }
//---
  }
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

# 2.2.1.41 OBJ_BITMAP_LABEL位图对象标签

Alt text

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);
//---
  }
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

# 2.2.1.42 OBJ_EDIT编辑对象

Alt text

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);
//---
  }
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

# 2.2.1.43 OBJ_EVENT事件对象

Alt text

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);
//---
  }
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

# 2.2.1.44 OBJ_RECTANGLE_LABEL矩形标签对象

Alt text

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);
//---
  }
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

# 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);
     }
  }
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

# 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);
     }
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

图解对象箭头(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++;
              }
           }
        }
     }
  }
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

在脚本执行完毕后,图表看起来像这样。

Alt text

# 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);
  }
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

# 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); // 强制重画图表
  }
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

# 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");
        }
     }
1
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);
     }
  }
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

# 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
1
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!");
  }
1
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);
  }
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

# 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);
1
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);
  }
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

# 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);
//--- 完成初始化
  }
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

# 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;
1
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));
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

脚本执行的结果,会在 EA 日志中,看到如下的信息:

Alt text

# 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);
     }
1
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);
  }
1
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");
//---
  }
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

为计算 交易品种 的保证金要求,可以使用枚举型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);
  }
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

# 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);
  }
//+------------------------------------------------------------------+
1
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);
  }
//+------------------------------------------------------------------+
1
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);
         //---
        }
     }
  }
//+------------------------------------------------------------------+
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

挂单 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);
  }
//+------------------------------------------------------------------+
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

修改持仓止损和止赢值的 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);
        }
     }
  }
//+------------------------------------------------------------------+
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

删除挂单的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);
        }
     }
  }
//+------------------------------------------------------------------+
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

关闭反向持仓的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);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
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

# 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__);
  }
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

# 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));
  }
1
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);
  }
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

# 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));
  }
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

# 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);
  }
1
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() 调用
1
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();    // 如果处于调试模式,则会终止
     }
  }
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

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 日)
  };
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
*/
1
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;   // 存储 字符串类型 字段
  };
1
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;  // 真实交易量
  };
1
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");
  }
1
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;     // 交易量
  };
1
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());
     }
1
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;      // 反向仓位价格
  };
1
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)。而在单边系统,虽然是通过交易品种名称来确定持仓,也可以指明订单号。
1

发送订单 执行 交易操作 需要使用 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);
  }
//+------------------------------------------------------------------+
1
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);
  }
//+------------------------------------------------------------------+
1
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);
         //---
        }
     }
  }
//+------------------------------------------------------------------+
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

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);
        }
     }
  }
//+------------------------------------------------------------------+
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

挂单

交易操作放置一个挂单,要求指定如下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);
  }
//+------------------------------------------------------------------+
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

修改挂单

交易操作在修改挂单时,要求指定如下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);
        }
     }
  }
//+------------------------------------------------------------------+
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

删除挂单

交易操作删除一个挂单,要求指定如下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);
        }
     }
  }
//+------------------------------------------------------------------+
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

相关参考 结构和类, 交易函数,订单属性

# 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;             // 回应码的注释(错误原因的描述)
  };
1
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; // 外部交易系统的操作返回码
  };
1
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);
  }
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

# 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;      // 反向仓位编号
  };
1
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;
  }
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

相关参考

交易事务类型,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          // 报价标帜
  };
1
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());
//---
  }
1
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 FUNCSIGFUNCTION 不能出现在函数主体之外
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);
1

当指定 读取 和 写入 标帜时,有几种特性: • 如果只指定了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 默认第四按钮