第十九章 交易函数
这是用于管理交易活动的一组函数。
交易函数在EA程序 或 脚本 中使用,只有在EA交易的属性 或 脚本中勾选启用了“允许实时自动交易”复选框,交易函数才能被调用。
根据“交易权限”部分中描述的各种因素,交易可以被允许或禁止。
函数 | 功能 |
---|---|
OrderCalcMargin | 以存款货币为单位计算指定订单类型所需的保证金 |
OrderCalcProfit | 以存款货币为单位,根据传递的形式参数计算利润 |
OrderCheck | 检测是否有足够资金执行所请求的交易操作. |
OrderSend | 发送 交易请求 到服务器 |
OrderSendAsync | 异步发送交易请求,意即无需等待交易服务器的响应 |
PositionsTotal | 返回持仓头寸仓位的总数量 |
PositionGetSymbol | 返回与相应持仓头寸仓位的交易品种 |
PositionSelect | 选中一个仓位以便进行下一步工作 |
PositionSelectByTicket | 通过指定的单号选中一个仓位以便下一步工作 |
PositionGetDouble | 请求返回一个仓位的(双精度类型)属性 |
PositionGetInteger | 请求返回一个仓位的(日期时间 或 整型)属性 |
PositionGetString | 请求返回一个仓位的(字符串型)属性 |
PositionGetTicket | 返回仓位列表中指定索引编号的订单号 |
OrdersTotal | 返回订单总数量 |
OrderGetTicket | 返回相应订单的订单号 |
OrderSelect | 选中一个订单以便进行下一步工作 |
OrderGetDouble | 请求返回一个订单的(双精度类型)属性 |
OrderGetInteger | 请求返回一个订单的(日期时间 或 整型)属性 |
OrderGetString | 请求返回一个订单的(字符串型)属性 |
HistorySelect | 检索服务器上指定时间段内的交易事务和订单历史记录 |
HistorySelectByPosition | 请求指定仓位标识符交易的历史记录 |
HistoryOrderSelect | 选中一个历史订单以便进行下一步工作 |
HistoryOrdersTotal | 返回历史记录中订单总数 |
HistoryOrderGetTicket | 返回历史记录中相关订单的订单号 |
HistoryOrderGetDouble | 请求返回一个历史订单的(双精度类型)属性 |
HistoryOrderGetInteger | 请求返回一个历史订单的(日期时间 或 整型)属性 |
HistoryOrderGetString | 请求返回一个历史订单的(字符串型)属性 |
HistoryDealSelect | 在历史记录中选中一笔交易,以便通过适当的函数进一步调用 |
HistoryDealsTotal | 返回历史记录中的交易总数量 |
HistoryDealGetTicket | 返回历史记录中相关交易的订单号 |
HistoryDealGetDouble | 请求返回历史记录中一笔交易的(双精度类型)属性 |
HistoryDealGetInteger | 请求返回历史记录中一笔交易的(日期时间 或 整型)属性 |
HistoryDealGetString | 请求返回历史记录中一笔交易的(字符串型)属性 |
# 19.1 OrderCalcMargin
该函数计算当前市场环境下当前账户中指定定单类型所需的保证金,但不考虑当前挂单和未平仓头寸。它允许为计划的交易事务评估保证金。该值以账户货币单位返回。
bool OrderCalcMargin(
ENUM_ORDER_TYPE action, // 订单类型
string symbol, // 交易品种名称
double volume, // 交易量
double price, // 开盘价
double& margin // 为获取保证金值的值
);
2
3
4
5
6
7
参数
action
[in] 订单类型,取值范围是 ENUM_ORDER_TYPE 枚举值之一。
symbol
[in] 交易品种名称。
volume
[in] 成交量。
price
[in] 打开订单的价格。
margin
[out] 保存保证金数值的变量。在函数执行成功的情况下将写入所需的保证金的值。计算过程就好像当前账户没有 挂单 和 持有仓位一样。保证金的值取决于许多因素,并且可能在不同的市场环境中有所不同。
返回值
如果成功,函数返回true,否则返回false,如果想要获得有关的错误信息,请调用 GetLastError() 函数。
相关参考
OrderSend(), 订单属性, 交易操作类型
# 19.2 OrderCalcProfit
该函数根据传递的形式参数计算当前市场状况下,当前账户的利润。 该函数用于交易操作结果的预评估。返回值以账户货币为单位。
bool OrderCalcProfit(
ENUM_ORDER_TYPE action, // 订单类型 (ORDER_TYPE_BUY 或者 ORDER_TYPE_SELL)
string symbol, // 交易品种名称
double volume, // 交易量
double price_open, // 开盘价
double price_close, // 收盘价
double& profit // 为获得利润值的变量
);
2
3
4
5
6
7
8
参数
action
[in] 订单类型,取值范围是 ENUM_ORDER_TYPE 枚举的ORDER_TYPE_BUY 或 ORDER_TYPE_SELL值中之一。
symbol
[in] 交易品种名称。
volume
[in] 成交量。
price_open
[in] 打开订单的价格。
price_close
[in] 关闭平仓时的价格。
profit
[out] 保存计算得出的利润值的变量,在函数成功执行后写入,估计利润值取决于许多因素,并且可能在不同的市场环境中有所不同。
返回值
如果成功,函数返回true,否则返回false。如果指定无效订单类型,函数返回false。如果想要获得有关的错误信息,请调用 GetLastError() 函数。
相关参考
OrderSend(), 订单属性, 交易操作类型
# 19.3 OrderCheck
OrderCheck()函数检测是否有足够的资金执行请求的交易操作。检测结果会保存在MqlTradeCheckResult结构的字段域中。
bool OrderCheck(
MqlTradeRequest& request, // 请求结构
MqlTradeCheckResult& result // 结果结构
);
2
3
4
参数
request
[in] 指向MqlTradeRequest类型的结构的指针,它描述了所请求的交易操作。
result
[in,out] 指向保存检查结果的MqlTradeCheckResult类型的结构的指针。
返回值
如果资金不足以完成操作,或者参数填写不正确,则该函数返回false。如果对结构进行了成功的基本检查(检查指针),则返回true。 但是,这并不表示所请求的交易操作肯定会成功执行。有关函数执行结果的更详细描述,请分析结果结构的字段。
如果想要获得有关的错误信息,请调用 GetLastError() 函数。
相关参考
OrderSend(), 交易操作类型, 交易请求结构, 检测结果请求结构, 交易请求结果结构
# 19.4 OrderSend
发送 交易请求 到服务器,OrderSend()函数用来执行交易操作。
bool OrderSend(
MqlTradeRequest& request, // query structure
MqlTradeResult& result // structure of the answer
);
2
3
4
参数
request
[in] 指向描述客户端交易活动的MqlTradeRequest类型结构的指针。
result
[in,out] 指向MqlTradeResult类型结构的指针,描述成功完成交易操作的结果(如果返回true)。
返回值
成功的基础检查结构(索引检查)返回true。 然而,这并不是成功执行交易事务的标志。有关函数执行结果的更详细描述,请分析结果结构的字段。
注意
交易请求需要经过交易服务器上的多个步骤检查。第一,它检查请求参数的所有必填字段是否正确填写。如果没有错误,则服务器接受订单以进一步处理。如果交易服务器成功接受订单,则OrderSend()函数返回true。
建议在将 交易请求 发送到交易服务器之前先检查交易请求。要检查交易请求,请使用OrderCheck()函数。它检查是否有足够的资金来执行交易操作,并在交易请求检查结果中返回许多有用的参数:
• 返回码 在检测请求中包含的错误信息;
• 在交易操作执行后显示账户 余额;
• 在交易操作执行后显示帐户 净值;
• 在交易操作执行后显示 浮点值;
• 交易操作所需保证金;
• 在交易操作执行后可用的净值数量;
• 在交易操作执行后设定的保证金比例;
• 注释回应代码,描述错误信息。
在发送市场订单(MqlTradeRequest.action = TRADE_ACTION_DEAL)时,OrderSend()函数的成功结果并不意味着该订单已被执行(适当的交易已执行)。在这种情况下,“TRUE”只意味着订单已成功放入交易系统以供进一步执行。交易服务器可能在返回的 交易请求结果结构 (MqlTradeResult) 中填写 ‘deal’(交易) 或 ‘order’(定单) 字段的值,如果它在形成对OrderSend()调用的响应时感知到这些数据。通常,在发送对OrderSend()调用的响应之后,可能发生执行与订单相对应的交易的事件。因此,对于任何类型的交易请求,当接收到OrderSend()执行结果时,我们应该首先检查获得的 结果结构 中可用的 交易服务器响应代码(retcode) 和 外部系统响应代码(retcode_external)(如果需要)。
应该注意的是,成功完成OrderSend()方法操作并不总是意味着在下达市价单时成功完成交易。根据返回结果中的操作类型检查包含交易服务器返回代码的交易码值,以及 ‘deal’(交易) 或 ‘order’(定单) 字段的值。
每个接收到的订单都存储在交易服务器中排队处理,直到可以执行的条件发生: • 到达过期时间, 出现相反的交易请求, • 当执行价格出现时即执行订单, • 收到的取消订单的命令。
在订单处理的时刻,交易服务器向客户端发送关于交易事件发生的消息,消息可以由OnTrade()函数处理。
在通过OrderSend()函数发送的服务器上执行交易请求的结果可以通过OnTradeTransaction 处理程序跟踪。应该注意,当执行交易请求时,将会多次调用OnTradeTransaction处理程序。
例如,当发送市场买入(buy)订单时,它会被处理,为该账户创建一个适当的买入(buy)订单,然后执行订单并从持仓订单列表中移除,然后它被添加到订单历史记录中,相应的交易(deal)也被添加到历史记录中 并 创建一个新的持仓位。OnTradeTransaction函数将会为这里每个事件进行调用。
示例:
//--- ORDER_MAGIC值
input long order_magic=55555;
//+------------------------------------------------------------------+
//| 启动函数的脚本程序 |
//| 此脚本为 MQL5 专用,仅适用于 MT5 客户端 (智能交易*姚 注) |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 确保账户是样本
if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
{
Alert("Script operation is not allowed on a live account!");
return;
}
//--- 下订单或者删除订单
if(GetOrdersTotalByMagic(order_magic)==0)
{
//--- 无当前订单 - 下订单
uint res=SendRandomPendingOrder(order_magic);
Print("Return code of the trade server ",res);
}
else // 有订单 - 删除订单
{
DeleteAllOrdersByMagic(order_magic);
}
//---
}
//+------------------------------------------------------------------+
//| 接收当前带有指定的ORDER_MAGIC的订单号 |
//+------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
{
ulong order_ticket;
int total=0;
//--- 检查通过所有挂单
for(int i=0;i<OrdersTotal();i++)
if((order_ticket=OrderGetTicket(i))>0)
if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
return(total);
}
//+------------------------------------------------------------------+
//| 删除所有带有指定ORDER_MAGIC的挂单 |
//+------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
{
ulong order_ticket;
//--- 检查所有挂单
for(int i=OrdersTotal()-1;i >= 0;i--)
if((order_ticket=OrderGetTicket(i)) > 0)
//--- 带有恰当ORDER_MAGIC的订单
if(magic_number==OrderGetInteger(ORDER_MAGIC))
{
MqlTradeResult result={0};
MqlTradeRequest request={0};
request.order=order_ticket;
request.action=TRADE_ACTION_REMOVE;
OrderSend(request,result);
//--- 编写服务器回复到日志
Print(__FUNCTION__,": ",result.comment," reply code ",result.retcode);
}
//---
}
//+------------------------------------------------------------------+
//| 随机设置挂单 |
//+------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
{
//--- 准备请求
MqlTradeRequest request={0};
request.action=TRADE_ACTION_PENDING; // 设置挂单
request.magic=magic_number; // ORDER_MAGIC
request.symbol=_Symbol; // 交易品种
request.volume=0.1; // 0.1为单位的交易量
request.sl=0; // 没有指定止损价位
request.tp=0; // 没有指定盈利价位
//--- 形成订单类型
request.type=GetRandomType(); // 订单类型
//--- 形成挂单价格
request.price=GetRandomPrice(request.type); // 开盘价
//--- 发送交易请求
MqlTradeResult result={0};
OrderSend(request,result);
//--- 编写服务器回复到日志
Print(__FUNCTION__,":",result.comment);
if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- 返回交易服务器回复的代码
return result.retcode;
}
//+------------------------------------------------------------------+
//| 返回随机挂单类型 |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE GetRandomType()
{
int t=MathRand()%4;
//--- 0<=t<4
switch(t)
{
case(0):return(ORDER_TYPE_BUY_LIMIT);
case(1):return(ORDER_TYPE_SELL_LIMIT);
case(2):return(ORDER_TYPE_BUY_STOP);
case(3):return(ORDER_TYPE_SELL_STOP);
}
//--- 不正确值
return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| 返回随机价格 |
//+------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
{
int t=(int)type;
//--- 交易品种止损水平
int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- 接收上一个订单号数据
MqlTick last_tick={0};
SymbolInfoTick(_Symbol,last_tick);
//--- 按照类型计算价格
double price;
if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT or ORDER_TYPE_SELL_STOP
{
price=last_tick.bid; // 不同于卖价
price=price-(distance+(MathRand()%10)*5)*_Point;
}
else // ORDER_TYPE_SELL_LIMIT or ORDER_TYPE_BUY_STOP
{
price=last_tick.ask; // 不同于买价
price=price+(distance+(MathRand()%10)*5)*_Point;
}
//---
return(price);
}
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
相关参考
交易操作类型, 交易请求结构, 请求检测结果结构, 交易请求结果结构
# 19.5 OrderSendAsync
OrderSendAsync()函数用于执行异步 交易操作,意即,无需等待 交易服务器 对 发送的交易请求的 响应。 该函数专为高频交易而设计,在交易算法条款下,浪费时间等待服务器的响应是不可接受的。
bool OrderSendAsync(
MqlTradeRequest& request, // 请求架构
MqlTradeResult& result // 请求架构
);
2
3
4
参数
request
[in] 指向描述客户端交易行为的MqlTradeRequest类型结构的指针。
result
[in,out] 一个指向MqlTradeResult类型的结构的指针,该类型描述成功执行函数(如果返回true)时交易操作的结果。
返回值
如果请求被发送到交易服务器,则返回true。如果请求未被发送,则返回false。在发送请求的情况下,在结果变量中,响应代码包含TRADE_RETCODE_PLACED值(代码10008) —— “已下单”。成功执行意味着只是发送的事实,但是不保证请求到达交易服务器和已被接受处理。当处理接收的请求时,交易服务器向客户端发送回应,通知引起生成交易事件的持仓当前状态,订单和交易的变化。
在通过OrderSendAsync()函数发送的服务器上执行交易请求的结果可以通过OnTradeTransaction处理程序跟踪。应该注意,当执行交易请求时,将会多次调用OnTradeTransaction处理程序。
例如,当发送市场买入(buy)订单时,它会被处理,为该账户创建一个适当的买入(buy)订单,然后执行订单并从持仓订单列表中移除,然后它被添加到订单历史记录中,相应的交易(deal)也被添加到历史记录中 并 创建一个新的持仓位。OnTradeTransaction函数将会为这里每个事件进行调用。若要获得这种数据,应该分析函数参数: • trans —— 该参数获取描述应用到交易账户的交易事务的 MqlTradeTransaction 结构; • request —— 该参数获取描述一个交易事务得出的交易请求的 MqlTradeRequest 结构; • result —— 该参数获取描述交易请求执行结果的 MqlTradeResult 结构。
注意
在 目的 和 参数 方面,该函数与OrderSend()类似,但与其不同的是,它是异步(非同步)的,即在等待函数执行结果时不保存程序操作。您可以使用示例EA比较这两个函数的交易操作的比率。
示例:
#property description "Expert Advisor for sending trade requests "
" using OrderSendAsync() function.\r\n"
#property description "Handling trading events using"
" OnTrade() and OnTradeTransaction() handler functions is displayed\r\n"
#property description "Expert Advisor parameters allow setting Magic Number"
" (unique ID) "
#property description "and the mode of displaying messages in Experts log. All details are displayed by default.\r\n"
//--- 输入参数
input int MagicNumber=1234567; // EA交易 ID
input bool DescriptionModeFull=true; // 详细的输出模式
//--- HistorySelect()调用使用的变量
datetime history_start;
//+------------------------------------------------------------------+
//| 专家初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 检查是否允许自动交易
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
Alert("Autotrading in the terminal is disabled, Expert Advisor will be removed.");
ExpertRemove();
return(-1);
}
//--- 不能交易真实账户
if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
{
Alert("Expert Advisor cannot trade on a real account!");
ExpertRemove();
return(-2);
}
//--- 检查是否可以在该账户交易(例如,使用只读密码时不能交易)
if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
{
Alert("Trading on this account is disabled");
ExpertRemove();
return(-3);
}
//--- 节省启动EA交易的时间来接收交易历史记录
history_start=TimeCurrent();
//---
CreateBuySellButtons();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 专家去初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- 删除所有图形对象
ObjectDelete(0,"Buy");
ObjectDelete(0,"Sell");
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction 函数 |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- 标题命名在交易事件处理程序函数之后
Print("=> ",__FUNCTION__," at ",TimeToString(TimeCurrent(),TIME_SECONDS));
//--- 接收事务类型作为枚举值
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- 如果事务是请求处理的结果
if(type==TRADE_TRANSACTION_REQUEST)
{
//--- 显示事务名称
Print(EnumToString(type));
//--- 然后显示已处理请求的字符串描述
Print("------------RequestDescription\r\n",
RequestDescription(request,DescriptionModeFull));
//--- 并显示请求结果的描述
Print("------------ ResultDescription\r\n",
TradeResultDescription(result,DescriptionModeFull));
}
else // 显示另一类型事务的完整描述
{
Print("------------ TransactionDescription\r\n",
TransactionDescription(trans,DescriptionModeFull));
}
//---
}
//+------------------------------------------------------------------+
//| 交易函数 |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- 存储交易账户状态的静态成员
static int prev_positions=0,prev_orders=0,prev_deals=0,prev_history_orders=0;
//--- 请求交易历史记录
bool update=HistorySelect(history_start,TimeCurrent());
PrintFormat("HistorySelect(%s , %s) = %s",
TimeToString(history_start),TimeToString(TimeCurrent()),(string)update);
//--- 标题命名在交易事件处理程序函数之后
Print("=> ",__FUNCTION__," at ",TimeToString(TimeCurrent(),TIME_SECONDS));
//--- 显示处理程序名称和处理时期订单数量
int curr_positions=PositionsTotal();
int curr_orders=OrdersTotal();
int curr_deals=HistoryOrdersTotal();
int curr_history_orders=HistoryDealsTotal();
//--- 用括号显示订单数量,持仓,成交,以及改变
PrintFormat("PositionsTotal() = %d (%+d)",
curr_positions,(curr_positions-prev_positions));
PrintFormat("OrdersTotal() = %d (%+d)",
curr_orders,curr_orders-prev_orders);
PrintFormat("HistoryOrdersTotal() = %d (%+d)",
curr_deals,curr_deals-prev_deals);
PrintFormat("HistoryDealsTotal() = %d (%+d)",
curr_history_orders,curr_history_orders-prev_history_orders);
//--- 插入字符串断点,更便于查看日志
Print("");
//--- 保存账户状态
prev_positions=curr_positions;
prev_orders=curr_orders;
prev_deals=curr_deals;
prev_history_orders=curr_history_orders;
//---
}
//+------------------------------------------------------------------+
//| ChartEvent 函数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- 处理 CHARTEVENT_CLICK 事件 ("点击图表")
if(id==CHARTEVENT_OBJECT_CLICK)
{
Print("=> ",__FUNCTION__,": sparam = ",sparam);
//--- 成交的最小交易量
double volume_min=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
//--- 如果按下"买入"按钮,则买入
if(sparam=="Buy")
{
PrintFormat("Buy %s %G lot",_Symbol,volume_min);
BuyAsync(volume_min);
//--- 不按下该按钮
ObjectSetInteger(0,"Buy",OBJPROP_STATE,false);
}
//--- 如果按下"卖出"按钮,则卖出
if(sparam=="Sell")
{
PrintFormat("Sell %s %G lot",_Symbol,volume_min);
SellAsync(volume_min);
//--- 不按下该按钮
ObjectSetInteger(0,"Sell",OBJPROP_STATE,false);
}
ChartRedraw();
}
//---
}
//+------------------------------------------------------------------+
//| 返回交易事务的文本描述 |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans,
const bool detailed=true)
{
//--- 准备从函数返回的字符串
string desc=EnumToString(trans.type)+"\r\n";
//--- 在详细模式添加所有可能的数据
if(detailed)
{
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,
const bool detailed=true)
{
//--- 准备从函数返回的字符串
string desc=EnumToString(request.action)+"\r\n";
//--- 在详细模式添加所有可用的数据
if(detailed)
{
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,
const bool detailed=true)
{
//--- 准备从函数返回的字符串
string desc="Retcode "+(string)result.retcode+"\r\n";
//--- 在详细模式添加所有可用的数据
if(detailed)
{
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;
}
//+------------------------------------------------------------------+
//| 为买入和卖出创建两个按钮 |
//+------------------------------------------------------------------+
void CreateBuySellButtons()
{
//--- 检查名称为“买入”的对象
if(ObjectFind(0,"Buy") >= 0)
{
//--- 如果发现的对象不是按钮,请删除
if(ObjectGetInteger(0,"Buy",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Buy");
}
else
ObjectCreate(0,"Buy",OBJ_BUTTON,0,0,0); // 创建“买入”按钮
//--- 配置“买入”按钮
ObjectSetInteger(0,"Buy",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Buy",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Buy",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"Buy",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Buy",OBJPROP_YSIZE,30);
ObjectSetString(0,"Buy",OBJPROP_TEXT,"Buy");
ObjectSetInteger(0,"Buy",OBJPROP_COLOR,clrRed);
//--- 检查名称为“卖出”的对象
if(ObjectFind(0,"Sell") >= 0)
{
//--- 如果发现的对象不是按钮,请删除
if(ObjectGetInteger(0,"Sell",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Sell");
}
else
ObjectCreate(0,"Sell",OBJ_BUTTON,0,0,0); // 创建“卖出”按钮
//--- 配置“卖出”按钮
ObjectSetInteger(0,"Sell",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Sell",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_YDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Sell",OBJPROP_YSIZE,30);
ObjectSetString(0,"Sell",OBJPROP_TEXT,"Sell");
ObjectSetInteger(0,"Sell",OBJPROP_COLOR,clrBlue);
//--- 执行强制更新图表,立即查看按钮
ChartRedraw();
//---
}
//+------------------------------------------------------------------+
//| 使用OrderSendAsync()异步函数进行买入 |
//+------------------------------------------------------------------+
void BuyAsync(double volume)
{
//--- 准备请求
MqlTradeRequest req={0};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_BUY;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_ASK);
req.deviation =10;
req.comment ="Buy using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+------------------------------------------------------------------+
//| 使用OrderSendAsync()异步函数进行卖出 |
//+------------------------------------------------------------------+
void SellAsync(double volume)
{
//--- 准备请求
MqlTradeRequest req={0};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_SELL;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_BID);
req.deviation =10;
req.comment ="Sell using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+------------------------------------------------------------------+
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
在“专家”日志显示消息的示例:
12:52:52 ExpertAdvisor (EURUSD,H1) => OnChartEvent: sparam = Sell
12:52:52 ExpertAdvisor (EURUSD,H1) Sell EURUSD 0.01 lot
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTradeTransaction at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_TRANSACTION_REQUEST
12:52:52 ExpertAdvisor (EURUSD,H1) ------------RequestDescription
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_ACTION_DEAL
12:52:52 ExpertAdvisor (EURUSD,H1) Symbol: EURUSD
12:52:52 ExpertAdvisor (EURUSD,H1) Magic Number: 1234567
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Order type: ORDER_TYPE_SELL
12:52:52 ExpertAdvisor (EURUSD,H1) Order filling: ORDER_FILLING_FOK
12:52:52 ExpertAdvisor (EURUSD,H1) Order time type: ORDER_TIME_GTC
12:52:52 ExpertAdvisor (EURUSD,H1) Order expiration: 1970.01.01 00:00
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Deviation points: 10
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Loss: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Take Profit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Limit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0.1
12:52:52 ExpertAdvisor (EURUSD,H1) Comment: Sell using OrderSendAsync()
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) ------------ ResultDescription
12:52:52 ExpertAdvisor (EURUSD,H1) Retcode 10009
12:52:52 ExpertAdvisor (EURUSD,H1) Request ID: 2
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Deal ticket: 15048668
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0.1
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Ask: 1.29319
12:52:52 ExpertAdvisor (EURUSD,H1) Bid: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Comment:
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) HistorySelect( 09:34 , 09:52) = true
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTrade at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) PositionsTotal() = 1 (+1)
12:52:52 ExpertAdvisor (EURUSD,H1) OrdersTotal() = 0 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryOrdersTotal() = 2 (+2)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryDealsTotal() = 2 (+2)
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTradeTransaction at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) ------------ TransactionDescription
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_TRANSACTION_ORDER_ADD
12:52:52 ExpertAdvisor (EURUSD,H1) Symbol: EURUSD
12:52:52 ExpertAdvisor (EURUSD,H1) Deal ticket: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Deal type: DEAL_TYPE_BUY
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Order type: ORDER_TYPE_SELL
12:52:52 ExpertAdvisor (EURUSD,H1) Order state: ORDER_STATE_STARTED
12:52:52 ExpertAdvisor (EURUSD,H1) Order time type: ORDER_TIME_GTC
12:52:52 ExpertAdvisor (EURUSD,H1) Order expiration: 1970.01.01 00:00
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Price trigger: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Loss: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Take Profit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0.1
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTradeTransaction at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) ------------ TransactionDescription
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_TRANSACTION_ORDER_DELETE
12:52:52 ExpertAdvisor (EURUSD,H1) Symbol: EURUSD
12:52:52 ExpertAdvisor (EURUSD,H1) Deal ticket: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Deal type: DEAL_TYPE_BUY
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Order type: ORDER_TYPE_SELL
12:52:52 ExpertAdvisor (EURUSD,H1) Order state: ORDER_STATE_STARTED
12:52:52 ExpertAdvisor (EURUSD,H1) Order time type: ORDER_TIME_GTC
12:52:52 ExpertAdvisor (EURUSD,H1) Order expiration: 1970.01.01 00:00
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Price trigger: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Loss: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Take Profit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0.1
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) HistorySelect( 09:34 , 09:52) = true
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTrade at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) PositionsTotal() = 1 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) OrdersTotal() = 0 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryOrdersTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryDealsTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTradeTransaction at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) ------------ TransactionDescription
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_TRANSACTION_HISTORY_ADD
12:52:52 ExpertAdvisor (EURUSD,H1) Symbol: EURUSD
12:52:52 ExpertAdvisor (EURUSD,H1) Deal ticket: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Deal type: DEAL_TYPE_BUY
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Order type: ORDER_TYPE_SELL
12:52:52 ExpertAdvisor (EURUSD,H1) Order state: ORDER_STATE_FILLED
12:52:52 ExpertAdvisor (EURUSD,H1) Order time type: ORDER_TIME_GTC
12:52:52 ExpertAdvisor (EURUSD,H1) Order expiration: 1970.01.01 00:00
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Price trigger: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Loss: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Take Profit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) HistorySelect( 09:34 , 09:52) = true
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTrade at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) PositionsTotal() = 1 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) OrdersTotal() = 0 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryOrdersTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryDealsTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTradeTransaction at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) ------------ TransactionDescription
12:52:52 ExpertAdvisor (EURUSD,H1) TRADE_TRANSACTION_DEAL_ADD
12:52:52 ExpertAdvisor (EURUSD,H1) Symbol: EURUSD
12:52:52 ExpertAdvisor (EURUSD,H1) Deal ticket: 15048668
12:52:52 ExpertAdvisor (EURUSD,H1) Deal type: DEAL_TYPE_SELL
12:52:52 ExpertAdvisor (EURUSD,H1) Order ticket: 16361998
12:52:52 ExpertAdvisor (EURUSD,H1) Order type: ORDER_TYPE_BUY
12:52:52 ExpertAdvisor (EURUSD,H1) Order state: ORDER_STATE_STARTED
12:52:52 ExpertAdvisor (EURUSD,H1) Order time type: ORDER_TIME_GTC
12:52:52 ExpertAdvisor (EURUSD,H1) Order expiration: 1970.01.01 00:00
12:52:52 ExpertAdvisor (EURUSD,H1) Price: 1.29313
12:52:52 ExpertAdvisor (EURUSD,H1) Price trigger: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Stop Loss: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Take Profit: 0
12:52:52 ExpertAdvisor (EURUSD,H1) Volume: 0.1
12:52:52 ExpertAdvisor (EURUSD,H1)
12:52:52 ExpertAdvisor (EURUSD,H1) HistorySelect( 09:34 , 09:52) = true
12:52:52 ExpertAdvisor (EURUSD,H1) => OnTrade at 09:52:53
12:52:52 ExpertAdvisor (EURUSD,H1) PositionsTotal() = 1 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) OrdersTotal() = 0 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryOrdersTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1) HistoryDealsTotal() = 2 (+0)
12:52:52 ExpertAdvisor (EURUSD,H1)
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
# 19.6 PositionsTotal
返回持有仓位的总数量。
int PositionsTotal();
返回值
整数值
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
相关参考
PositionGetSymbol(), PositionSelect(), 仓位属性
# 19.7 PositionGetSymbol
根据 仓位 的索引编号位置返回相对应的 交易品种,并使用函数PositionGetDouble,PositionGetInteger,PositionGetString自动选中该 仓位 以便进一步使用它。
string PositionGetSymbol(
int index // 仓位列表中的索引编号数字
);
2
3
参数
index
[in] 持有仓位列表中的索引编号数字。
返回值
字符串 型值,如果找不到仓位,则返回 空字符串,如果想要获得 错误代码,需调用 GetLastError() 函数。
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
交易账户中 仓位 的总数不可能超过 金融工具(交易品种) 的总数量。
相关参考
PositionsTotal(), PositionSelect(), 仓位属性
# 19.8 PositionSelect
根据 交易品种 名称(代码符号)选中一个仓位,如果函数成功完成,返回true,如果失败返回false,调用 GetLastError()函数可获取错误信息。
bool PositionSelect(
string symbol // 交易品种名称
);
2
3
参数
symbol
[in] 交易品种(金融工具) 名称
返回值
布尔型值
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
函数PositionSelect()将有关 仓位 的数据复制到程序环境中,并且在进一步调用函数PositionGetDouble(),PositionGetInteger()和PositionGetString()时会返回之前已复制的数据。这意味着该 仓位 本身可能已发生变化(或其 交易量,方向等已发生变化),但仍可获得该仓位 的数据。为确保收到有关 仓位 的最新数据,建议在引用它们之前即时调用一次PositionSelect()。
相关参考
PositionGetSymbol(), PositionsTotal(), 仓位属性
# 19.9 PositionSelectByTicket
根据指定的 订单编号 选中一个仓位。如果成功,返回true。如果函数失败,返回false。调用GetLastError()获取错误细节。
bool PositionSelectByTicket(
ulong ticket // 持有 仓位 的 订单编号(不是索引位置编号)
);
2
3
参数
ticket
[in] 持有 仓位 的 订单编号(不是索引位置编号) 。
返回值
布尔 型值。
注意
函数PositionSelectByTicket() 将有关 仓位 的数据复制到程序环境中。并且在进一步调用函数PositionGetDouble(),PositionGetInteger()和PositionGetString()时会返回之前已复制的数据。这意味着该 仓位 本身可能已发生变化(或其 交易量,方向等已发生变化),但仍可获得该仓位 的数据。为确保收到有关 仓位 的最新数据,建议在引用它们之前即时调用一次PositionSelect()。
相关参考
PositionGetSymbol(),PositionsTotal(),持仓属性
# 19.10 PositionGetDouble
此函数请求返回一个持有 仓位 的属性值,仓位 是之前使用PositionGetSymbol或者 PositionSelect选中的,请求获取的 仓位属性 值必须是双精度型,此函数有两种变体。
- 直接返回属性值。
double PositionGetDouble(
ENUM_POSITION_PROPERTY_DOUBLE property_id // 属性标识符
);
2
3
- 返回true或者false,取决于函数执行成功与否,如果成功,属性值保存在形式参数中。
bool PositionGetDouble(
ENUM_POSITION_PROPERTY_DOUBLE property_id, // 属性标识符
double& double_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 仓位属性标识符。取值范围是ENUM_POSITION_PROPERTY_DOUBLE 枚举值之一。
double_var
[out] 双精度类型值,如果函数调用失败,返回0。
返回值
双精度 类型值。如果函数失败,返回0 。
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保接收到的是关于 仓位 的最新数据,在之前应该即时调用一次 PositionSelect() 函数。
相关参考
PositionGetSymbol(), PositionSelect(), 仓位属性
# 19.11 PositionGetInteger
此函数请求返回一个持有 仓位 的属性值,仓位 是之前使用PositionGetSymbol或者 PositionSelect选中的,请求获取的 仓位属性 值必须是 日期时间型,整数型,此函数有两种变体。
- 直接返回属性值
long PositionGetInteger(
ENUM_POSITION_PROPERTY_INTEGER property_id // 属性标识符
);
2
3
- 返回true或者false,取决于函数执行成功与否,如果成功,属性值保存在形式参数中。
bool PositionGetInteger(
ENUM_POSITION_PROPERTY_INTEGER property_id, // 属性标识符
long& long_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 仓位属性标识符,取值范围是 ENUM_POSITION_PROPERTY_INTEGER 枚举值之一。
long_var
[out] 用于保存 属性值的长整型数值。
返回值
长整型值。如果函数失败,返回0。
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保接收到的是关于 仓位 的最新数据,在之前应该即时调用一次 PositionSelect() 函数。
例:
//+------------------------------------------------------------------+
//| 交易函数 |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- 检查持仓是否存在并显示其变化的时间
if(PositionSelect(_Symbol))
{
//--- 接收持仓ID为进一步工作
ulong position_ID=PositionGetInteger(POSITION_IDENTIFIER);
Print(_Symbol," postion #",position_ID);
//--- 接收从1970.01.01开始的毫秒为单位的形成持仓的时间
long create_time_msc=PositionGetInteger(POSITION_TIME_MSC);
PrintFormat("Position #%d POSITION_TIME_MSC = %i64 milliseconds => %s",position_ID,
create_time_msc,TimeToString(create_time_msc/1000));
//--- 接收从1970.01.01开始的秒为单位的持仓最近变化的时间
long update_time_sec=PositionGetInteger(POSITION_TIME_UPDATE);
PrintFormat("Position #%d POSITION_TIME_UPDATE = %i64 seconds => %s",
position_ID,update_time_sec,TimeToString(update_time_sec));
//--- 接收从1970.01.01开始的毫秒为单位的持仓最近变化的时间
long update_time_msc=PositionGetInteger(POSITION_TIME_UPDATE_MSC);
PrintFormat("Position #%d POSITION_TIME_UPDATE_MSC = %i64 milliseconds => %s",
position_ID,update_time_msc,TimeToString(update_time_msc/1000));
}
//---
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
相关参考
PositionGetSymbol(), PositionSelect(), 仓位属性
# 19.12 PositionGetString
此函数请求返回一个持有 仓位 的属性值,仓位 是之前使用PositionGetSymbol或者 PositionSelect选中的,请求获取的 仓位属性 值必须是 字符串型,此函数有两种变体。
- 直接返回属性值
string PositionGetString(
ENUM_POSITION_PROPERTY_STRING property_id // 属性标识符
);
2
3
- 返回true或者false,取决于函数执行成功与否,如果成功,属性值保存在形式参数中。
bool PositionGetString(
ENUM_POSITION_PROPERTY_STRING property_id, // 属性标识符
string& string_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 仓位属性标识符,取值范围是 ENUM_POSITION_PROPERTY_STRING 枚举值之一。
long_var
[out] 用于保存 属性值 的 字符串 值。
返回值
字符串型值。如果函数失败,返回0。
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个交易的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保接收到的是关于 仓位 的最新数据,在之前应该即时调用一次 PositionSelect() 函数。
相关参考
PositionGetSymbol(), PositionSelect(), 仓位属性
# 19.13 PositionGetTicket
根据指定的索引编号返回一个持有 仓位 的订单编号,并使用函数PositionGetDouble,PositionGetInteger,PositionGetString自动选中该 仓位 以便进一步使用它。/p>
ulong PositionGetTicket(
int index // 仓位 列表中的索引编号
);
2
3
参数
index
[in] 持有 仓位 列表中的索引,编号从0开始。
返回值
仓位的订单编号。如果函数失败,返回0。
注意
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保接收到的是关于 仓位 的最新数据,在之前应该即时调用一次 PositionSelect() 函数。
相关参考
PositionGetSymbol(),PositionSelect(),Position Properties
# 19.14 OrdersTotal
返回当前订单总数。
int OrdersTotal();
返回值
整数型数值。 br>
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
相关参考
OrderSelect(), OrderGetTicket() , 订单属性
# 19.15 OrderGetTicket
根据指定的 索引编号 返回 订单编号,并自动选中该订单,以便进一步调用函数处理。
ulong OrderGetTicket(
int index // 订单列表中的数量
);
2
3
参数
index
[in] 当前订单列表中的 索引数字。
返回值
无符号长整型 值。如果函数失败,返回0。
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
函数OrderGetTicket()将有关 订单 的数据复制到程序环境中,并且在进一步调用函数OrderGetDouble(),OrderGetInteger(),OrderGetString()时会返回之前已复制的数据。这意味着订单本身可能已发生变化(或其 开仓进场的价格,止损/止盈价格 或 到期日期 已更改),但仍可获得此 订单 的数据。为确保收到有关 订单 的最新数据,建议在引用它们之前即时调用一次OrderGetTicket()。
示例:
void OnStart()
{
//--- 订单属性返回值的变量
ulong ticket;
double open_price;
double initial_volume;
datetime time_setup;
string symbol;
string type;
long order_magic;
//--- 当前挂单量
uint total=OrdersTotal();
//--- 反复检查通过订单
for(uint i=0;i<total;i++)
{
//--- 通过列表中的仓位返回订单报价
if(ticket=OrderGetTicket(i))
{
//--- 返回订单属性
open_price =OrderGetDouble(ORDER_PRICE_OPEN);
time_setup =(datetime)OrderGetInteger(ORDER_TIME_SETUP);
symbol =OrderGetString(ORDER_SYMBOL);
order_magic =OrderGetInteger(ORDER_MAGIC);
positionID =OrderGetInteger(ORDER_POSITION_ID);
initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
type =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
//--- 准备和显示订单信息
printf("#ticket %d %s %G %s at %G was set up at %s",
ticket, // 订单报价
type, // 类型
initial_volume, // 已下交易量
symbol, // 交易品种
open_price, // 规定的开盘价
TimeToString(time_setup)// 下订单时间
);
}
}
//---
}
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
相关参考
OrdersTotal(), OrderSelect(), OrderGetInteger()
# 19.16 OrderSelect
选择一个 订单。如果函数成功调用返回TRUE值,如果函数没能完成,则返回错误值,了解更多关于错误调用的信息,可以使用 GetLastError()。
bool OrderSelect(
ulong ticket // 订单编号(不是索引位置编号)
);
2
3
参数
ticket
[in] 订单编号。不是索引位置编号。
返回值
布尔型值。
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
函数OrderSelect()将有关 订单 的数据复制到程序环境中,并且在进一步调用函数OrderGetDouble(),OrderGetInteger(),OrderGetString()时会返回之前已复制的数据。这意味着订单本身可能已发生变化(或其 开仓进场的价格,止损/止盈价格 或 到期日期 已更改),但仍可获得此 订单 的数据。为确保收到有关 订单 的最新数据,建议在引用它们之前即时调用一次OrderSelect()。
相关参考
OrderGetInteger(), OrderGetDouble(), OrderGetString(), OrderCalcProfit(), OrderGetTicket(), 订单属性
# 19.17 OrderGetDouble
此函数请求返回一个 订单 的属性值,订单 是之前使用 OrderGetTicket 或者 OrderSelect选中的,请求获取的 订单属性 值必须是 双精度类型,此函数有两种变体。
- 直接返回属性值。
double OrderGetDouble(
ENUM_ORDER_PROPERTY_DOUBLE property_id // 属性标识符
);
2
3
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中。
bool OrderGetDouble(
ENUM_ORDER_PROPERTY_DOUBLE property_id, // 属性标识符
double& double_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 订单 的属性标识符,取值范围是 ENUM_ORDER_PROPERTY_DOUBLE 枚举值之一。
double_var
[out] 接收属性值的 双精度类型 变量。
返回值
双精度 值。如果函数失败,返回0。
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保获取的是关于 订单 的最新数据,推荐调用此函数之前,即时调用一次 OrderSelect() 函数。
相关参考
OrdersTotal(), OrderGetTicket(), 订单属性
# 19.18 OrderGetInteger
此函数请求返回一个 订单 的属性值,订单 是之前使用 OrderGetTicket 或者 OrderSelect选中的,请求获取的 订单属性 值必须是 日期时间型,整数型,此函数有两种变体。
- 直接返回属性值。
long OrderGetInteger(
ENUM_ORDER_PROPERTY_INTEGER property_id // 属性标识符
);
2
3
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中。
bool OrderGetInteger(
ENUM_ORDER_PROPERTY_INTEGER property_id, // 属性标识符
long& long_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 订单 的属性标识符,取值范围是ENUM_ORDER_PROPERTY_INTEGER枚举值之一。
long_var
[out] 接收属性值的 长整数类型 变量。
返回值
长整数 值。如果函数失败,返回0。
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保获取的是关于 订单 的最新数据,推荐调用此函数之前,即时调用一次 OrderSelect() 函数。
相关参考
OrdersTotal(), OrderGetTicket(), 订单属性
# 19.19 OrderGetString
此函数请求返回一个 订单 的属性值,订单 是之前使用 OrderGetTicket 或者 OrderSelect选中的,请求获取的 订单属性 值必须是 字符串类型,此函数有两种变体。
- 直接返回属性值。
string OrderGetString(
ENUM_ORDER_PROPERTY_STRING property_id // 属性标识符
);
2
3
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中。
bool OrderGetString(
ENUM_ORDER_PROPERTY_STRING property_id, // 属性标识符
string& string_var // 这里接受属性值
);
2
3
4
参数
property_id
[in] 订单 的属性标识符,取值范围是 ENUM_ORDER_PROPERTY_STRING 枚举值之一。
string_var
[out] 接收属性值的 字符串类型 变量。
返回值
字符串类型 值。如果函数失败,返回0。
注意
不要与 当前挂单 和/或 仓位 相混淆,它们也显示在客户端“工具箱”的“交易”标签中。订单是执行交易(deal)的请求,而 仓位(头寸) 是一个或多个交易的结果。
对于"单边" 持仓 (ACCOUNT_MARGIN_MODE_RETAIL_NETTING 和 ACCOUNT_MARGIN_MODE_EXCHANGE),无论任何时候一个交易品种只可能存在一个持有仓位。仓位 是一个或多个 交易 的结果。不要将 仓位 与有效的挂单相混淆,这些订单也显示在工具箱窗口的交易标签上。
如果允许单独持仓头寸(ACCOUNT_MARGIN_MODE_RETAIL_HEDGING),那么则可以为一个 交易品种 同时打开持有多个头寸。
为确保获取的是关于 订单 的最新数据,推荐调用此函数之前,即时调用一次 OrderSelect() 函数。
相关参考
OrdersTotal(), OrderGetTicket(), 订单属性
# 19.20 HistorySelect
按指定的时间段,检索服务器上的交易和订单的历史记录。
bool HistorySelect(
datetime from_date, // 开始日期
datetime to_date // 结束日期
);
2
3
4
参数
from_date
[in] 请求检索的开始日期。
to_date
[in] 请求检索的结束日期。
返回值
如果成功返回true,否则返回false。
注意
HistorySelect()在MQL5程序中创建一个订单列表和一个交易列表,以便进一步使用相应的函数引用列表中的元素。交易清单列表的大小可以使用HistoryDealsTotal()函数返回; 历史订单列表的大小可以使用HistoryOrdersTotal()函数返回。在 订单列表 中选择某一条记录,使用 HistoryOrderGetTicket()更适合。在 交易列表 中选择某一条记录,使用 HistoryDealGetTicket() 更适合。
在使用 HistoryOrderSelect()后,MQL5程序中可用的历史 订单列表 就会重设,如果成功执行了 HistoryOrderSelect()函数,则列表会被新发现的订单填满。这同样适用于MQL5程序中可用的 交易列表 —— 通过执行 HistoryDealSelect()函数重设更表并再次成功填满新发现的 交易 记录。
示例:
void OnStart()
{
color BuyColor =clrBlue;
color SellColor=clrRed;
//--- 请求交易历史记录
HistorySelect(0,TimeCurrent());
//--- 创建物件
string name;
uint total=HistoryDealsTotal();
ulong ticket=0;
double price;
double profit;
datetime time;
string symbol;
long type;
long entry;
//--- 所有交易
for(uint i=0;i<total;i++)
{
//--- 尝试获取 交易(deal) 单的编号
if((ticket=HistoryDealGetTicket(i))>0)
{
//--- 获得交易单属性
price =HistoryDealGetDouble(ticket,DEAL_PRICE);
time =HistoryDealGetInteger(ticket,DEAL_TIME);
symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);
type =HistoryDealGetInteger(ticket,DEAL_TYPE);
entry =HistoryDealGetInteger(ticket,DEAL_ENTRY);
profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
//--- 只对当前交易品种
if(price && time && symbol==Symbol())
{
//--- 创建价格对象
name="TradeHistory_Deal_"+string(ticket);
if(entry) ObjectCreate(0,name,OBJ_ARROW_RIGHT_PRICE,0,time,price,0,0);
else ObjectCreate(0,name,OBJ_ARROW_LEFT_PRICE,0,time,price,0,0);
//--- 设置物件属性
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,0);
ObjectSetInteger(0,name,OBJPROP_BACK,0);
ObjectSetInteger(0,name,OBJPROP_COLOR,type?BuyColor:SellColor);
if(profit!=0) ObjectSetString(0,name,OBJPROP_TEXT,"Profit: "+string(profit));
}
}
}
//--- 应用于图表
ChartRedraw();
}
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
相关参考
HistoryOrderSelect(), HistoryDealSelect(),HistorySelectByPosition
根据 仓位标识符 检索历史记录中的交易和订单。
bool HistorySelectByPosition(
long position_id // 仓位标识符 - POSITION_IDENTIFIER
);
2
3
参数
position_id
[in] 仓位标识符,对应每个已执行成功的交易单 和 交易。
返回值
如果成功返回TRUE值,否则返回错误值。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
HistorySelectByPosition()在MQL5程序中创建一个订单列表和一个具有指定 仓位标识符 的交易(deal)单列表,以便进一步使用相应的函数引用列表中的元素。要获取交易(deal)单列表的大小,可以使用函数HistoryDealsTotal()。要获取 历史订单列表的大小,可以使用函数HistoryOrdersTotal()。要遍历 历史订单列表 中的所有元素,请使用HistoryOrderGetTicket(),要遍历 交易(deal)单列表 中的所有元素,请使用HistoryDealGetTicket()。
在使用 HistoryOrderSelect()后,MQL5程序中可用的历史 订单列表 就会重设,如果成功执行了 HistoryOrderSelect()函数,则列表会被新发现的订单填满。这同样适用于MQL5程序中可用的 交易列表 —— 通过执行 HistoryDealSelect()函数重设更表并再次成功填满新发现的 交易 记录。
相关参考
HistorySelect(), HistoryOrderGetTicket(), 订单属性
# 19.21 HistorySelectByPosition
检索特殊位置标识符交易和订单历史记录。
bool HistorySelectByPosition(
long position_id // 仓位标识符 - POSITION_IDENTIFIER
);
2
3
参量
position_id
[in] 位置标识符设置每个已执行命令和每笔交易。
返回值
如果成功返回真值,否则返回错误值。
注释
不能把出现在客户端"工具箱"的"交易" 标签中的当前挂单和交易历史订单弄乱。取消的或者导致的交易的订单列表可以在"工具箱"客户端中的"历史记录"标签浏览。
HistorySelectByPosition()建立一系列命令列表和MQL5程序的交易,使用类似 仓位标识符 函数来执行列表元素。订单列表大小可以使用 HistoryDealsTotal(),函数返回。使用HistoryOrdersTotal()。可以显示历史订单列表的大小。使用HistoryOrderGetTicket(),运行订单列表元素,订单列表元素— HistoryDealGetTicket()。
在使用 HistoryOrderSelect(), 后,MQL5程序中的历史可用订单列表就会重设并被发现的订单填满。如果成功执行 通过报价搜索订单同样适用于MQL5程序可行性订单中-通过 HistoryDealSelect() 重设并再次成功填满。
另见
HistorySelect(), HistoryOrderGetTicket(), 订单属性
# 19.22 HistoryOrderSelect
从历史记录中选择一个订单,以便进一步使用适当的函数调用它。如果该函数操作成功,将返回true。如果函数操作失败,则返回false。 要想获取有关错误的更详细信息,可以调用GetLastError()函数。
bool HistoryOrderSelect(
ulong ticket // 订单号
);
2
3
参数
ticket
[in] 订单编号。
返回值
如果成功,返回真值,否则返回错误值。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
HistoryOrderSelect()在MQL5程序从历史记录中删除一系列订单,如果成功执行HistoryOrderSelect (),可用调用和复制的单个字节,如果需要通过 HistorySelect()运行所有订单,最好使用 HistoryOrderGetTicket()。
如果HistoryOrderSelect()的执行已成功完成,则HistoryOrderSelect()会在MQL5程序中清除历史记录中可用于调用的订单列表,并将复制其中一个订单。如果您需要遍历HistorySelect()所选择的所有交易,则最好使用HistoryOrderGetTicket()函数。
相关参考
HistorySelect(), HistoryOrderGetTicket(), 订单属性
# 19.23 HistoryOrdersTotal
返回历史记录中订单的总数量。在调用HistoryOrdersTotal()之前,首先需要使用HistorySelect()或者 HistorySelectByPosition() 函数接收 交易(deal)单 和 订单 的历史记录。
int HistoryOrdersTotal();
返回值
整数型数值。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
相关参考
HistorySelect(), HistoryOrderSelect(), HistoryOrderGetTicket(), 订单属性
# 19.24 HistoryOrderGetTicket
根据指定的 索引编号 返回历史记录中相应的订单。在调用HistoryOrderGetTicket()之前,首先需要使用HistorySelect()或者 HistorySelectByPosition() 函数接收 交易(deal)单 和 订单 的历史记录。
ulong HistoryOrderGetTicket(
int index // 订单列表中的索引编号数字 从0 开始
);
2
3
参数
index
[in] 订单列表中的索引编号数字,从0 开始。
返回值
无符号长整型数值。如果函数失败,则返回0。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
示例:
void OnStart()
{
datetime from=0;
datetime to=TimeCurrent();
//--- 要求全部历史记录
HistorySelect(from,to);
//--- 返回订单属性值变量
ulong ticket;
double open_price;
double initial_volume;
datetime time_setup;
datetime time_done;
string symbol;
string type;
long order_magic;
long positionID;
//--- 当前挂单数量
uint total=HistoryOrdersTotal();
//--- 循环检测通过订单
for(uint i=0;i < total;i++)
{
//--- 通过其列表中的位置返回订单报价
if((ticket=HistoryOrderGetTicket(i)) > 0)
{
//--- 返回订单属性
open_price= HistoryOrderGetDouble(ticket,ORDER_PRICE_OPEN);
time_setup= (datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_SETUP);
time_done= (datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_DONE);
symbol= HistoryOrderGetString(ticket,ORDER_SYMBOL);
order_magic= HistoryOrderGetInteger(ticket,ORDER_MAGIC);
positionID = HistoryOrderGetInteger(ticket,ORDER_POSITION_ID);
initial_volume= HistoryOrderGetDouble(ticket,ORDER_VOLUME_INITIAL);
type=GetOrderType(HistoryOrderGetInteger(ticket,ORDER_TYPE));
//--- 准备并显示订单信息
printf("#ticket %d %s %G %s at %G was set up at %s => done at %s, pos ID=%d",
ticket, // 订单报价
type, // 类型
initial_volume, // 已下的交易量
symbol, // 交易品种
open_price, // 规定的开盘价
TimeToString(time_setup),// 下订单时间
TimeToString(time_done), // 订单执行或者删除时间
positionID // 一个包括订单交易的仓位ID
);
}
}
//---
}
//+------------------------------------------------------------------+
//| 返回订单类型字符串名称 |
//+------------------------------------------------------------------+
string GetOrderType(long type)
{
string str_type="unknown operation";
switch(type)
{
case (ORDER_TYPE_BUY): return("buy");
case (ORDER_TYPE_SELL): return("sell");
case (ORDER_TYPE_BUY_LIMIT): return("buy limit");
case (ORDER_TYPE_SELL_LIMIT): return("sell limit");
case (ORDER_TYPE_BUY_STOP): return("buy stop");
case (ORDER_TYPE_SELL_STOP): return("sell stop");
case (ORDER_TYPE_BUY_STOP_LIMIT): return("buy stop limit");
case (ORDER_TYPE_SELL_STOP_LIMIT):return("sell stop limit");
}
return(str_type);
}
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
相关参考
HistorySelect(), HistoryOrdersTotal(), HistoryOrderSelect(), 订单属性
# 19.25 HistoryOrderGetString
此函数请求返回一个 历史订单 的属性值,请求获取的 历史订单 的属性值必须是 字符串型,此函数有两种变体。
- 直接返回属性值。
string HistoryOrderGetString(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_STRING property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryOrderGetString(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_STRING property_id, // 属性标识符
string& string_var // 这里接受属性值
);
2
3
4
5
参数
ticket_number
[in] 订单编号。
property_id
[in] 订单属性标识符。取值范围是 ENUM_ORDER_PROPERTY_STRING 枚举值之一。
string_var
[out] 字符串型变量。
返回值
字符串。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
相关参考
HistorySelect(), HistoryOrdersTotal(), HistoryOrderSelect(), 订单属性
# 19.26 HistoryOrderGetDouble
此函数请求返回一个 历史订单 的属性值,请求获取的 历史订单 的属性值必须是 双精度类型,此函数有两种变体。
- 直接返回属性值。
double HistoryOrderGetDouble(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_DOUBLE property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryOrderGetDouble(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_DOUBLE property_id, // 属性标识符
double& double_var // 这里接受属性值
);
2
3
4
5
参数
ticket_number
[in] 订单编号。
property_id
[in] 订单属性标识符。取值范围是 ENUM_ORDER_PROPERTY_DOUBLE 枚举值之一。
string_var
[out] 双精度类型变量。
返回值
双精度型数值。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
相关参考
HistorySelect(), HistoryOrdersTotal(), HistoryOrderSelect(), 订单属性
# 19.27 HistoryOrderGetInteger
此函数请求返回一个 历史订单 的属性值,请求获取的 历史订单 的属性值必须是 整数型,此函数有两种变体。
- 直接返回属性值。
long HistoryOrderGetInteger(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_INTEGER property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryOrderGetInteger(
ulong ticket_number, // 订单号
ENUM_ORDER_PROPERTY_INTEGER property_id, // 属性标识符
long& long_var // 这里接受属性值
);
2
3
4
5
参数
ticket_number
[in] 订单编号。
property_id
[in] 订单属性标识符。取值范围是 ENUM_ORDER_PROPERTY_INTEGER 枚举值之一。
string_var
[out] 整数型变量。
返回值
整数型数值。
注意
不要将 出现在客户端"工具箱"的"交易"标签中的 当前挂单 与 历史交易(deal)单 混为一谈。可以在客户终端的“工具箱”的“历史记录”标签中查看已被取消 或 已成交的订单列表。
例如:
//+------------------------------------------------------------------+
//| 交易函数 |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- 从周交易历史记录接收最后订单的标签
ulong last_order=GetLastOrderTicket();
if(HistoryOrderSelect(last_order))
{
//--- 从1970.01.01起以毫秒为单位下单的时间
long time_setup_msc=HistoryOrderGetInteger(last_order,ORDER_TIME_SETUP_MSC);
PrintFormat("Order #%d ORDER_TIME_SETUP_MSC=%i64 => %s",
last_order,time_setup_msc,TimeToString(time_setup_msc/1000));
//--- 从1970.01.01起以毫秒为单位执行/取消订单的时间
long time_done_msc=HistoryOrderGetInteger(last_order,ORDER_TIME_DONE_MSC);
PrintFormat("Order #%d ORDER_TIME_DONE_MSC=%i64 => %s",
last_order,time_done_msc,TimeToString(time_done_msc/1000));
}
else // 通知失败
PrintFormat("HistoryOrderSelect() failed for #%d. Eror code=%d",
last_order,GetLastError());
//---
}
//+------------------------------------------------------------------+
//| 返回历史记录中最后订单的标签或-1 |
//+------------------------------------------------------------------+
ulong GetLastOrderTicket()
{
//--- 请求最近7天的历史记录
if(!GetTradeHistory(7))
{
//--- 通知不成功的调用和返回-1
Print(__FUNCTION__," HistorySelect() returned false");
return -1;
}
//---
ulong first_order,last_order,orders=HistoryOrdersTotal();
//--- 如果有,从事订单工作
if(orders>0)
{
Print("Orders = ",orders);
first_order=HistoryOrderGetTicket(0);
PrintFormat("first_order = %d",first_order);
if(orders>1)
{
last_order=HistoryOrderGetTicket((int)orders-1);
PrintFormat("last_order = %d",last_order);
return last_order;
}
return first_order;
}
//--- 未发现订单,返回 -1
return -1;
}
//+--------------------------------------------------------------------------+
//| 请求最近几日的历史记录,如果失败,则返回false |
//+--------------------------------------------------------------------------+
bool GetTradeHistory(int days)
{
//--- 设置一个星期的周期请求交易历史记录
datetime to=TimeCurrent();
datetime from=to-days*PeriodSeconds(PERIOD_D1);
ResetLastError();
//--- 发出请求检察结果
if(!HistorySelect(from,to))
{
Print(__FUNCTION__," HistorySelect=false. Error code=",GetLastError());
return false;
}
//--- 成功接收历史记录
return true;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
相关参考
HistorySelect(), HistoryOrdersTotal(), HistoryOrderSelect(), 订单属性
# 19.28 HistoryDealSelect
从历史记录中选择一个 交易(deal)单,以便进一步使用适当的函数调用它。如果该函数操作成功,将返回true。如果函数操作失败,则返回false。要想获取有关错误的更详细信息,可以调用GetLastError()函数。
bool HistoryDealSelect(
ulong ticket // 交易订单号
);
2
3
参数
ticket
[in] 交易订单号。
返回值
如果成功返回TRUE值,否则返回错误值。
注释
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
如果HistoryDealSelect的执行已成功完成,则HistoryDealSelect会在MQL5程序中清除历史记录中可用于调用的 交易(deal)单 列表,并将复制其中一条交易单的记录。如果您需要遍历HistorySelect()所选择的所有交易,则最好使用HistoryDealGetTicket函数。
相关参考
HistorySelect(), HistoryDealGetTicket(), 交易属性
# 19.29 HistoryDealsTotal
返回历史 交易(deal) 总数量。在调用HistoryDealsTotal之前,首先需要使用HistorySelect()或者 HistorySelectByPosition() 函数接收 交易(deal)单 和 订单 的历史记录。
int HistoryDealsTotal();
返回值
整数型数值。
注意
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
相关参考
HistorySelect(), HistoryDealGetTicket(), 交易属性
# 19.30 HistoryDealGetTicket
根据指定的 索引编号 返回历史记录中相应的 交易(deal)单。在调用HistoryDealGetTicket()之前,首先需要使用HistorySelect()或者 HistorySelectByPosition() 函数接收 交易(deal)单 和 订单 的历史记录。
ulong HistoryDealGetTicket(
int index // 交易单的索引编号
);
2
3
参数
index
[in] 交易单列表中的索引编号。
返回值
无符号长整型数值。如果函数失败,则返回0。
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
示例:
void OnStart()
{
ulong deal_ticket; // 交易订单号
ulong order_ticket; // 执行交易的订单的订单号
datetime transaction_time; // 交易执行时间
long deal_type ; // 交易操作类型
long position_ID; // 仓位ID
string deal_description; // 操作描述
double volume; // 操作交易量
string symbol; // 交易的交易品种
//--- 设置交易历史记录请求的起止时间
datetime from_date=0; // 从最开始
datetime to_date=TimeCurrent();// 到当前时间
//--- 特定周期中请求交易历史记录
HistorySelect(from_date,to_date);
//--- 交易列表中的全部数量
int deals=HistoryDealsTotal();
//--- 现在处理每一个交易
for(int i=0;i<deals;i++)
{
deal_ticket= HistoryDealGetTicket(i);
volume= HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
transaction_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
order_ticket= HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
deal_type= HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
symbol= HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
position_ID= HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
deal_description= GetDealDescription(deal_type,volume,symbol,order_ticket,position_ID);
//--- 为交易号执行格式化
string print_index=StringFormat("% 3d",i);
//--- 显示交易信息
Print(print_index+": deal #",deal_ticket," at ",transaction_time,deal_description);
}
}
//+------------------------------------------------------------------+
//| 返回操作的字符串描述 |
//+------------------------------------------------------------------+
string GetDealDescription(long deal_type,double volume,string symbol,long ticket,long pos_ID)
{
string descr;
//---
switch(deal_type)
{
case DEAL_TYPE_BALANCE: return ("balance");
case DEAL_TYPE_CREDIT: return ("credit");
case DEAL_TYPE_CHARGE: return ("charge");
case DEAL_TYPE_CORRECTION: return ("correction");
case DEAL_TYPE_BUY: descr="buy"; break;
case DEAL_TYPE_SELL: descr="sell"; break;
case DEAL_TYPE_BONUS: return ("bonus");
case DEAL_TYPE_COMMISSION: return ("additional commission");
case DEAL_TYPE_COMMISSION_DAILY: return ("daily commission");
case DEAL_TYPE_COMMISSION_MONTHLY: return ("monthly commission");
case DEAL_TYPE_COMMISSION_AGENT_DAILY: return ("daily agent commission");
case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: return ("monthly agent commission");
case DEAL_TYPE_INTEREST: return ("interest rate");
case DEAL_TYPE_BUY_CANCELED: descr="cancelled buy deal"; break;
case DEAL_TYPE_SELL_CANCELED: descr="cancelled sell deal"; break;
}
descr=StringFormat("%s %G %s (order #%d, position ID %d)",
descr, // 当前描述。
volume, // 交易的交易量。
symbol, // 交易的交易品种。
ticket, // 引起交易的订单的订单号。
pos_ID // 仓位交易执行的ID号。
);
return(descr);
//---
}
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
相关参考
HistorySelect(), HistoryDealsTotal(), HistoryDealSelect(), 交易属性
# 19.31 HistoryDealGetDouble
此函数请求返回一个 历史交易(deal)单 的属性值,请求获取的属性值必须是 双精度类型,此函数有两种变体。
- 直接返回属性值。
double HistoryDealGetDouble(
ulong ticket_number, // 订单号
ENUM_DEAL_PROPERTY_DOUBLE property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryDealGetDouble(
ulong ticket_number, // 订单号
ENUM_DEAL_PROPERTY_DOUBLE property_id, // 属性标识符
double& double_var // 这里接受属性值
);
2
3
4
5
参量
ticket_number
[in] 交易单编号。
property_id
[in] 交易属性标识符。取值范围是 ENUM_DEAL_PROPERTY_DOUBLE 枚举值之一。
double_var
[out] 接收属性值的双精度类型变量。
返回值
双精度型数值。
注意
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
相关参考
HistorySelect(), HistoryDealsTotal(), HistoryDealGetTicket(), 交易属性
# 19.32 HistoryDealGetInteger
此函数请求返回一个 历史交易(deal)单 的属性值,请求获取的属性值必须是 整数型,此函数有两种变体。
- 直接返回属性值。
long HistoryDealGetInteger(
ulong ticket_number, // 订单号
ENUM_DEAL_PROPERTY_INTEGER property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryDealGetInteger(
ulong ticket_number, // 订单号
ENUM_DEAL_PROPERTY_INTEGER property_id, // 属性标识符
long& long_var // 这里接受属性值
);
2
3
4
5
参量
ticket_number
[in] 交易单编号。
property_id
[in] 交易属性标识符。取值范围是 ENUM_DEAL_PROPERTY_INTEGER 枚举值之一。
long_var
[out] 接收属性值的长整型变量。
返回值
长整型数值。
注意
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
示例:
//+------------------------------------------------------------------+
//| 交易函数 |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- 从周交易历史记录接收最后订单的标签
ulong last_deal=GetLastDealTicket();
if(HistoryDealSelect(last_deal))
{
//--- 从1970.01.01起以毫秒为单位的交易执行的时间
long deal_time_msc=HistoryDealGetInteger(last_deal,DEAL_TIME_MSC);
PrintFormat("Deal #%d DEAL_TIME_MSC=%i64 => %s",
last_deal,deal_time_msc,TimeToString(deal_time_msc/1000));
}
else
PrintFormat("HistoryDealSelect() failed for #%d. Eror code=%d",
last_deal,GetLastError());
//---
}
//+------------------------------------------------------------------+
//| 返回历史记录中最后交易的标签或-1 |
//+------------------------------------------------------------------+
ulong GetLastDealTicket()
{
//--- 请求最近7天的历史记录
if(!GetTradeHistory(7))
{
//--- 通知不成功的调用和返回-1
Print(__FUNCTION__," HistorySelect() returned false");
return -1;
}
//---
ulong first_deal,last_deal,deals=HistoryOrdersTotal();
//--- 如果有,从事订单工作
if(deals>0)
{
Print("Deals = ",deals);
first_deal=HistoryDealGetTicket(0);
PrintFormat("first_deal = %d",first_deal);
if(deals>1)
{
last_deal=HistoryDealGetTicket((int)deals-1);
PrintFormat("last_deal = %d",last_deal);
return last_deal;
}
return first_deal;
}
//--- 未发现成交,返回 -1
return -1;
}
//+--------------------------------------------------------------------------+
//| 请求最近几日的历史记录,如果失败,则返回false |
//+--------------------------------------------------------------------------+
bool GetTradeHistory(int days)
{
//--- 设置一个星期的周期请求交易历史记录
datetime to=TimeCurrent();
datetime from=to-days*PeriodSeconds(PERIOD_D1);
ResetLastError();
//--- 发出请求检察结果
if(!HistorySelect(from,to))
{
Print(__FUNCTION__," HistorySelect=false. Error code=",GetLastError());
return false;
}
//--- 成功接收历史记录
return true;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
相关参考
HistorySelect(), HistoryDealsTotal(), HistoryDealGetTicket(), 交易属性
# 19.33 HistoryDealGetString
此函数请求返回一个 历史交易(deal)单 的属性值,请求获取的属性值必须是 字符串型,此函数有两种变体。
- 直接返回属性值。
string HistoryDealGetString(
ulong ticket_number, // 订单号
ENUM_DEAL_PROPERTY_STRING property_id // 属性标识符
);
2
3
4
- 依据函数是否成功调用返回TRUE 或 FALSE。如果成功,属性值被保存在形式参数中
bool HistoryDealGetString(
ulong ticket_number, //订单号
ENUM_DEAL_PROPERTY_STRING property_id, // 属性标识符
string& string_var // 这里接受属性值
);
2
3
4
5
参量
ticket_number
[in] 交易单编号。
property_id
[in] 交易属性标识符。取值范围是 ENUM_DEAL_PROPERTY_STRING 枚举值之一。
string_var [out] 接收属性值的长整型变量。
返回值
字符串型数值。
注意
不要弄混 订单(orders),交易(deals) 和 仓位(positions)。每笔 交易(deal) 的结果都是执行订单(order),每个 仓位(positions) 都是一个或多个 交易(deals) 的汇总结果。
相关参考
HistorySelect(), HistoryDealsTotal(), HistoryDealGetTicket(), 交易属性