MT4订单相关上下文
2025-03-05 本文已影响0人
AI_Finance
在 MQL4 中,OrderSelect() 并不会返回一个订单对象,而是通过选择一个订单,将其信息加载到全局的订单上下文中。换句话说,MQL4 的订单操作是基于全局状态的,必须通过 OrderSelect() 将某个订单选中后,才能使用其他订单相关的函数(例如 OrderOpenTime()、OrderSymbol() 等)来获取当前选中的订单的信息。
关于 OrderSelect() 和订单上下文
OrderSelect() 的作用
OrderSelect() 的作用是选择一个订单,并将其信息加载到订单上下文中。之后,所有订单相关的函数(如 OrderOpenTime()、OrderSymbol() 等)都会基于当前选中的订单返回数据。
关键点
-
OrderSelect()的返回值:- 返回
true表示选择成功(即订单存在并被选中)。 - 返回
false表示选择失败(如订单索引无效或订单不存在)。
- 返回
-
选中订单后,如何获取信息:
- 选中订单后,调用函数如
OrderOpenTime()、OrderSymbol()等,都会返回当前选中的订单的信息。
- 选中订单后,调用函数如
-
OrderSelect()的参数:- 第一个参数:订单索引(
i)。 - 第二个参数:选择方式(
SELECT_BY_POS按索引选择,SELECT_BY_TICKET按订单编号选择)。 - 第三个参数:订单池类型(
MODE_TRADES表示未平仓订单,MODE_HISTORY表示历史订单)。
- 第一个参数:订单索引(
代码中的问题
在你的代码中,OrderSelect() 使用了如下代码:
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) // 选择订单
{
// 检查订单是否是新订单
if (OrderOpenTime() > TimeCurrent() - 10) // 假设订单在最近 10 秒内打开
{
// 获取订单信息
string symbol = OrderSymbol();
double lotSize = OrderLots();
double price = OrderOpenPrice();
string orderType = (OrderType() == OP_BUY) ? "BUY" : "SELL";
// 打印日志(可选)
Print("New Order Detected: ", orderType, " ", symbol, " Lot: ", lotSize, " Price: ", price);
}
}
问题解释
-
OrderSelect()的用法:-
OrderSelect(i, SELECT_BY_POS, MODE_TRADES)中,i是订单的索引,表示选择第i个未平仓订单。 - 如果
OrderSelect()返回true,则说明第i个订单被成功选中。
-
-
未显式指定订单对象:
- MQL4 没有显式的订单对象概念,订单信息是通过全局上下文管理的。
- 一旦使用
OrderSelect()成功选中某个订单,所有订单相关函数(如OrderOpenTime()、OrderSymbol()等)都会基于当前选中的订单返回值。
-
如何知道
OrderOpenTime()是哪个订单的:-
OrderSelect(i, SELECT_BY_POS, MODE_TRADES)成功后,OrderOpenTime()返回的就是第i个订单的开仓时间。
-
改进建议
虽然代码逻辑是正确的,但为了更清晰地表达选中订单的流程,可以在代码中添加注释或结构化代码,明确说明 OrderSelect() 的作用和其与订单相关函数的关系。例如:
// 遍历所有未平仓订单
for (int i = 0; i < OrdersTotal(); i++)
{
// 选择第 i 个订单
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// 现在,订单上下文已经切换到第 i 个订单
// 检查订单是否是新订单(假设订单在最近 10 秒内打开)
if (OrderOpenTime() > TimeCurrent() - 10)
{
// 获取当前选中订单的信息
string symbol = OrderSymbol(); // 当前订单的交易品种
double lotSize = OrderLots(); // 当前订单的手数
double price = OrderOpenPrice(); // 当前订单的开仓价格
string orderType = (OrderType() == OP_BUY) ? "BUY" : "SELL"; // 当前订单类型
// 打印日志(可选)
Print("New Order Detected: ", orderType, " ", symbol, " Lot: ", lotSize, " Price: ", price);
// 将订单信息发送到 HTTP API
string apiUrl = "http://127.0.0.1:8000/api/ainance/mt/receive_order";
SendOrderToAPI(apiUrl, symbol, lotSize, price, orderType);
}
}
else
{
// 如果订单选择失败,打印错误信息(可选)
Print("OrderSelect failed for index: ", i);
}
}
补充说明
关于订单上下文的全局性
-
订单上下文是全局的:
- 一旦调用
OrderSelect()成功,所有订单相关函数(如OrderOpenTime()、OrderSymbol()等)都会基于当前选中的订单返回值。 - 如果没有调用
OrderSelect()或调用失败,这些订单函数将返回无效值。
- 一旦调用
-
避免混淆:
- 在遍历订单时,确保每次调用
OrderSelect()成功后,才使用订单相关函数。 - 如果在某些地方调用了另一个
OrderSelect(),可能会改变订单上下文,导致之前的订单信息失效。
- 在遍历订单时,确保每次调用
总结
-
OrderSelect()不会返回订单对象,而是通过成功选中某个订单,将其信息加载到全局订单上下文中。 - 选中订单后,所有订单相关函数(如
OrderOpenTime())都会基于当前选中的订单返回值。 - 在代码中,
OrderOpenTime()是针对当前选中的订单(即通过OrderSelect()选中的订单)返回开仓时间的。 - 在遍历订单时,确保正确调用
OrderSelect()并检查其返回值,避免使用无效的订单上下文。