保持敬畏之心
交易是一场持久战

​MQL4(13):OrderSend() - 下单函数详解

在讲解下单函数之前,我们先了解下单流程。在EA程序中提交一个交易订单,通常需要经过以下准备步骤,确定好所有必要信息:

  1. 订单类型:确定是买单 (Buy) 还是卖单 (Sell),是市价单还是挂单,如果是挂单,是止损挂单 (Stop) 还是限价挂单 (Limit)
  2. 交易品种:确定要交易哪个货币对。通常是EA当前所附加的图表对应的品种。
  3. 交易手数:确定下单量。可以是固定的手数,也可以是根据资金管理规则动态计算得出。
  4. 开仓价格:
    • 市价单:通常使用当前的Bid或Ask价格。
    • 挂单:必须指定一个具体的触发价格,该价格需要满足与当前市场价格有最小距离的要求(由经纪商设定,可通过 MarketInfo(Symbol(), MODE_STOPLEVEL) 查询),并且其位置(高于或低于当前价)必须符合所选挂单类型的规则。
  5. 止损价格:设定风险控制的止损位。可以是预设的固定价格,某个技术指标的计算值,距离开仓价固定点数,或者是通过风险管理算法动态计算的价格。止损可以在提交订单时一同设置,也可以在订单成交后通过修改订单的方式添加。
  6. 止盈价格:设定盈利目标位。通常是距离开仓价固定点数,但也可以基于其他逻辑计算。止盈同样可以在下单时设置,或之后再添加。
  7. 订单标识:
    • 订单注释:可选的文本信息,会显示在交易终端的订单列表中,可用于记录下单原因等。
    • 魔术数字:一个整数值,强烈建议使用。它用于区分由不同EA或同一EA的不同策略所下的订单,是管理订单的关键。
  8. 订单到期时间:对于挂单,如果经纪商支持且策略需要,可以设置一个可选的到期时间。

OrderSend() 函数

EA中用于执行开仓和平仓操作的核心函数是 OrderSend()。其完整的语法结构如下:

int OrderSend(
   string symbol,           // 交易品种名称 ("EURUSD")
   int    cmd,              // 订单类型 (OP_BUY, OP_SELL)
   double volume,           // 交易手数
   double price,            // 开仓价格 (市价单用 Ask/Bid, 挂单用指定价)
   int    slippage,         // 最大允许滑点
   double stoploss,         // 止损价格 (0 表示不设置)
   double takeprofit,       // 止盈价格 (0 表示不设置)
   string comment=NULL,     // 订单注释 (可选)
   int    magic=0,          // 魔术数字 (可选, 但强烈建议EA使用)
   datetime expiration=0,   // 订单到期时间 (挂单可选, 0表示不过期)
   color  arrow_color=clrNONE // 开仓箭头颜色 (可选, clrNONE表示不绘制)
);
  • symbol: 字符串类型,指定要交易的品种,例如 "GBPUSD"。通常使用 Symbol() 内置函数获取当前图表的品种。
  • cmd: 整数类型,指定订单的类型。必须使用预定义的常量,如下:
    • OP_BUY (0): 买入市价单
    • OP_SELL (1): 卖出市价单
    • OP_BUYSTOP (2): 买入止损挂单
    • OP_SELLSTOP (3): 卖出止损挂单
    • OP_BUYLIMIT (4): 买入限价挂单
    • OP_SELLLIMIT (5): 卖出限价挂单
  • volume: 双精度浮点数类型,指定交易手数。
  • price: 双精度浮点数类型,指定订单的开仓价格。
    • 买入市价单 (OP_BUY): 用当前的 Ask 价格。
    • 卖出市价单 (OP_SELL): 用当前的 Bid 价格。
    • 挂单 (OP_BUYSTOP 等): 设定的挂单触发价格。
  • slippage: 整数类型,指定允许的最大滑点,建议设置一个合理的值。不支持滑点的经纪商会忽略此参数。
  • stoploss: 双精度浮点数类型,指定止损价格。买单的止损价必须低于开仓价,卖单的止损价必须高于开仓价。0 表示不设置止损。
  • takeprofit: 双精度浮点数类型,指定止盈价格。买单的止盈价必须高于开仓价,卖单的止盈价必须低于开仓价。0 表示不设置止盈。
  • comment: 字符串类型,可选参数,用于添加订单注释。
  • magic: 整数类型,可选参数,但对于EA交易极其重要。用于为订单打上一个独特的标识号(魔术数字),以便 EA 能够区分哪些订单是由自己下的,从而进行后续管理。
  • expiration: datetime 类型,可选参数,用于设置挂单的到期时间。0 表示挂单永不过期。
  • arrow_color: color 类型,可选参数,指定在图表上标记开仓位置的箭头颜色。 clrNONE(默认值)则不绘制箭头。

返回值: OrderSend() 函数执行后会返回一个整数值。

  • 成功: 返回新创建订单的订单号,这是一个正整数。
  • 失败: 返回 -1。如果返回 -1,可以通过调用 GetLastError() 函数获取具体的错误代码,以分析失败原因。

建议将 OrderSend() 返回的订单号保存到一个变量中(如全局变量或静态变量),以便后续需要对该订单进行修改或查询。同时,检查返回值是否为 -1 是处理下单失败情况(如网络问题、参数错误、保证金不足等)的标准做法。

下市价单示例

以下是一个下达买入市价单的示例代码。假设变量 LotSize, Slippage , BuyStopLoss (止损价格), BuyTakeProfit (止盈价格) 和 MagicNumber 都已经被正确计算或赋值。

int ticket = OrderSend(
    Symbol(),           // 当前图表品种
    OP_BUY,             // 买入市价单
    LotSize,            // 交易手数
    Ask,                // 使用当前卖价作为开仓价格
    Slippage,           // 允许的最大滑点 (points)
    BuyStopLoss,        // 止损价格
    BuyTakeProfit,      // 止盈价格
    "My EA Buy Order",  // 订单注释
    MagicNumber,        // 魔术数字
    0,                  // 市价单无到期时间
    Green               // 在图表上绘制绿色开仓箭头
);

if (ticket < 0)
  {
    Print("买入市价单失败,错误代码: ", GetLastError());
  }
else
  {
    Print("成功下达买入市价单,订单号: ", ticket);
  }
  • Symbol(): 获取当前图表的交易品种名称。绝大多数情况下,EA 都是在当前图表对应的品种上进行交易。
  • OP_BUY: 指定订单类型为买入市价单。
  • Ask: MQL 内置的预定义变量,实时存储当前最新的卖价。切记:买单是在 Ask 价开仓!
  • Slippage:Slippage参数表示下单时可接受的最大价格滑动范围,单位为点(Points),即“最小价格变动单位”。在 MQL4 中Point 是价格的最小单位,对于使用 5位小数报价的品种(如 EURUSD 报价为 1.12345),1pip = 10points。对于使用 3位小数报价的日元对(如 USDJPY 报价为 123.456),同样 1pip = 10points。因此如果你希望允许的滑点为3个pip:5位报价的EURUSD,应设置 Slippage = 30;对于3位报价的 USDJPY,同样 Slippage=30;
  • "My EA Buy Order": 自定义订单注释。
  • Expiration = 0: 市价单不需要设置到期时间。
  • Green: 内置颜色常量 Green,在图表上标记买单开仓位置。
以下是一个类似的卖出市价单示例:
int ticket = OrderSend(
    Symbol(),           // 当前图表品种
    OP_SELL,            // 卖出市价单
    LotSize,            // 交易手数
    Bid,                // 使用当前买价作为开仓价格
    Slippage,           // 允许的最大滑点 (points)
    SellStopLoss,       // 止损价格 (卖单止损价 > 开仓价)
    SellTakeProfit,     // 止盈价格 (卖单止盈价 < 开仓价)
    "My EA Sell Order", // 订单注释
    MagicNumber,        // 魔术数字
    0,                  // 市价单无到期时间
    Red                 // 在图表上绘制红色开仓箭头
);

if (ticket < 0)
  {
    Print("卖出市价单失败,错误代码: ", GetLastError());
  }
else
  {
    Print("成功下达卖出市价单,订单号: ", ticket);
  }

和多单主要区别在于:

  • OP_SELL: 指定为卖出市价单。
  • Bid: 使用内置变量 Bid(当前买价)。切记:卖单是在 Bid 价开仓!
  • "My EA Sell Order": 不同的注释。
  • Red: 使用红色箭头标记卖单。
下止损挂单(突破单)示例

挂单与市价单的区别在于,其开仓价格 (Price 参数) 不是当前的市价,而是您预先设定的未来某个价位。同时,止损和止盈价格的计算也必须相对于这个挂单价格,而不是当前市价。

在以下示例中,我们假设变量 PendingPrice 存储了计算好的挂单触发价格。

  • 对于买入止损单 (Buy Stop)PendingPrice 必须设置在当前Ask价之上。假设 BuyStopLossBuyTakeProfit 已根据 PendingPrice 正确计算。

    int ticket = OrderSend(
        Symbol(),
        OP_BUYSTOP,
        LotSize,
        PendingPrice,
        Slippage,
        BuyStopLoss,
        BuyTakeProfit,
        "My EA Buy Stop",
        MagicNumber,
        0,
        Green
    );
    // ... 错误检查 ...
    

    注意:订单类型为 OP_BUYSTOP,开仓价格为 PendingPrice。此例中未设置到期时间 (Expiration = 0)。

  • 对于卖出止损单 (Sell Stop)PendingPrice 必须设置在当前 Bid 价之下。假设 SellStopLossSellTakeProfit 已根据 PendingPrice 正确计算。此例中我们还加入了一个到期时间,存储在 Expiration 变量中(其值必须晚于当前服务器时间 TimeCurrent())。

    datetime expirationTime = TimeCurrent() + (60 * 60 * 24); // 例如,设置 24 小时后到期
    int ticket = OrderSend(
        Symbol(), 
        OP_SELLSTOP,
        LotSize,
        PendingPrice, 
        Slippage,
        SellStopLoss, 
        SellTakeProfit,
        "My EA Sell Stop",
        MagicNumber, 
       expirationTime, 
       Red
    );
    // ... 错误检查 ...
    

    注意:订单类型为 OP_SELLSTOP,开仓价格为 PendingPrice,并提供了 expirationTime

下限价单(低买高卖)示例

限价挂单与止损挂单类似,但挂单价格相对于当前市价的位置要求是相反的。

  • 对于买入限价单 (Buy Limit)PendingPrice 必须设置在当前 Bid 价之下

    int ticket = OrderSend(
        Symbol(),
        OP_BUYLIMIT,
        LotSize, 
        PendingPrice,
        Slippage,
        BuyStopLoss,
        BuyTakeProfit,
        "My EA Buy Limit",
        MagicNumber, 
        0,
        Green
    );
    // ... 错误检查 ...
    

    注意:订单类型为 OP_BUYLIMIT

  • 对于卖出限价单 (Sell Limit)PendingPrice 必须设置在当前 Ask 价之上

    datetime expirationTime = TimeCurrent() + (60 * 60 * 24); // 例如,设置 24 小时后到期
    int ticket = OrderSend(
        Symbol(), 
        OP_SELLLIMIT, 
        LotSize, 
        PendingPrice, 
        Slippage,
        SellStopLoss,
        SellTakeProfit, 
        "My EA Sell Limit",
        MagicNumber, 
        expirationTime, 
        Red
    );
    // ... 错误检查 ...
    

    注意:订单类型为 OP_SELLLIMIT

借用前一篇教学的一段话,买入止损单 (Buy Stop)是向上做突破单,卖出止损单 (Sell Stop)是向下做下破单;买入限价单 (Buy Limit)是低买,卖出限价单 (Sell Limit)是高卖;而是市价单是现在就进场。理解了这句话就会明白什么情况下价格设置市价之上,什么情况下价格设置市价之下。

赞(0)
未经允许不得转载:图道交易 » ​MQL4(13):OrderSend() - 下单函数详解