MT4订单相关上下文

2025-03-05  本文已影响0人  AI_Finance

在 MQL4 中,OrderSelect() 并不会返回一个订单对象,而是通过选择一个订单,将其信息加载到全局的订单上下文中。换句话说,MQL4 的订单操作是基于全局状态的,必须通过 OrderSelect() 将某个订单选中后,才能使用其他订单相关的函数(例如 OrderOpenTime()OrderSymbol() 等)来获取当前选中的订单的信息。


关于 OrderSelect() 和订单上下文

OrderSelect() 的作用

OrderSelect() 的作用是选择一个订单,并将其信息加载到订单上下文中。之后,所有订单相关的函数(如 OrderOpenTime()OrderSymbol() 等)都会基于当前选中的订单返回数据。

关键点

  1. OrderSelect() 的返回值

    • 返回 true 表示选择成功(即订单存在并被选中)。
    • 返回 false 表示选择失败(如订单索引无效或订单不存在)。
  2. 选中订单后,如何获取信息

    • 选中订单后,调用函数如 OrderOpenTime()OrderSymbol() 等,都会返回当前选中的订单的信息。
  3. 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);
    }
}

问题解释

  1. OrderSelect() 的用法

    • OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 中,i 是订单的索引,表示选择第 i 个未平仓订单。
    • 如果 OrderSelect() 返回 true,则说明第 i 个订单被成功选中。
  2. 未显式指定订单对象

    • MQL4 没有显式的订单对象概念,订单信息是通过全局上下文管理的。
    • 一旦使用 OrderSelect() 成功选中某个订单,所有订单相关函数(如 OrderOpenTime()OrderSymbol() 等)都会基于当前选中的订单返回值。
  3. 如何知道 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);
    }
}

补充说明

关于订单上下文的全局性

  1. 订单上下文是全局的

    • 一旦调用 OrderSelect() 成功,所有订单相关函数(如 OrderOpenTime()OrderSymbol() 等)都会基于当前选中的订单返回值。
    • 如果没有调用 OrderSelect() 或调用失败,这些订单函数将返回无效值。
  2. 避免混淆

    • 在遍历订单时,确保每次调用 OrderSelect() 成功后,才使用订单相关函数。
    • 如果在某些地方调用了另一个 OrderSelect(),可能会改变订单上下文,导致之前的订单信息失效。

总结

上一篇 下一篇

猜你喜欢

热点阅读