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

​MQL4(15):MarketInfo() - 检索信息函数

我们在前面讨论计算 PipPointGetSlippage 时用到了 MarketInfo() 函数来获取交易品种的 Point 值(最小价格变动单位)和报价小数位数 (Digits)。MarketInfo() 是一个非常有用的函数,在MQL4编程中会经常使用它来获取各种必要的市场实时或历史信息。

其函数语法如下:

double MarketInfo(string symbol, int type);
  • symbol (字符串类型): 指定想查询哪个交易品种的信息。
    • 若要查询当前 EA/指标所在图表的品种信息,可以直接使用内置函数 Symbol()
    • 若要查询其他品种(例如,进行跨品种分析或交易),则需要明确提供该品种的名称字符串,如 "EURJPY"
  • type (整数类型): 通过传入预定义的常量,指定您想获取哪一类信息。该函数的返回值类型是double,但根据请求的 type 不同,返回值的实际含义也不同(有时需要强制转换为 intdatetime)。

MarketInfo() 参数中常用的常量 (type): (完整列表请查阅官方参考文档 -> 标准常量 -> 市场信息)

  • MODE_POINT: 获取该品种价格的最小变动单位。例如,EURUSD (5位报价) 返回 0.00001,USDJPY (3位报价) 返回 0.001。
  • MODE_DIGITS: 获取该品种报价的小数位数。例如,EURUSD 返回 5,USDJPY 返回 3。
  • MODE_SPREAD: 获取当前的实时点差。注意:返回值单位是points (即 Point 的整数倍)。例如,若点差为 3 pips,对于 5 位报价的 EURUSD,此模式返回 30;对于 3 位报价的 USDJPY,也返回 30。
  • MODE_STOPLEVEL: 获取经纪商设置的最小止损和挂单距离,单位也是points。您设置的止损价或挂单价与当前市价的距离必须大于等于这个值。例如,若最小距离为 3 pips,对于 5 位报价的 EURUSD,此模式返回 30。
  • MODE_BID: 获取指定品种当前的买价 (Bid)。
  • MODE_ASK: 获取指定品种当前的卖价 (Ask)。
  • MODE_LOW: 获取指定品种当前 K 线 (Bar 0,即正在形成的 K 线) 的最低价 (Low)。
  • MODE_HIGH: 获取指定品种当前 K 线 (Bar 0) 的最高价 (High)。

基于前面讨论并计算得到的UsePoint (代表 1 pip 的价格值),我们可以精确地计算止损价格。回顾一下基本原则:买单止损在开仓价之下,卖单止损在开仓价之上。

买单止损计算 (基于 StopLossPips 点数):

double openPrice = Ask; // 市价买单开仓价
double buyStopLossPrice = 0.0;

if (StopLossPips > 0)
{
    // 止损价格 = 开仓价 - (止损点数 * 每 pip 的价格值)
    buyStopLossPrice = openPrice - (StopLossPips * UsePoint);
    // 规范化价格,确保符合精度要求
    buyStopLossPrice = NormalizeDouble(buyStopLossPrice, Digits);
}

卖单止损计算 (基于 StopLossPips 点数):

double openPrice = Bid; // 市价卖单开仓价
double sellStopLossPrice = 0.0;

if (StopLossPips > 0)
{
    // 止损价格 = 开仓价 + (止损点数 * 每 pip 的价格值)
    sellStopLossPrice = openPrice + (StopLossPips * UsePoint);
    // 规范化价格
    sellStopLossPrice = NormalizeDouble(sellStopLossPrice, Digits);
}

对于挂单,计算逻辑完全相同,只需将 openPrice 替换为您的挂单价格即可。

计算止盈价格

计算止盈价格 (Take Profit, TP) 的逻辑与止损类似,只是加减方向相反:

  • 买单:止盈价 = 开仓价 + (止盈点数 * 每 pip 的价格值)
  • 卖单:止盈价 = 开仓价 – (止盈点数 * 每 pip 的价格值)
// 买单止盈计算 (假设 TakeProfitPips 为止盈点数)
double buyTakeProfitPrice = 0.0;
if (TakeProfitPips > 0)
{
    buyTakeProfitPrice = openPrice + (TakeProfitPips * UsePoint);
    buyTakeProfitPrice = NormalizeDouble(buyTakeProfitPrice, Digits);
}

// 卖单止盈计算
double sellTakeProfitPrice = 0.0;
if (TakeProfitPips > 0)
{
    sellTakeProfitPrice = openPrice - (TakeProfitPips * UsePoint);
    sellTakeProfitPrice = NormalizeDouble(sellTakeProfitPrice, Digits);
}

其他止损设置方法

除了使用固定的 pips 数,还可以采用更动态的方法来设置止损或止盈,常见的有:

  1. 基于K线高低点: 例如,将买单止损设置在上一根 K 线 (Bar 1) 的最低价下方 2 pips。 MQL4提供了预定义的价格时间序列数组,如 Low[](最低价)、High[](最高价)。数组索引代表 K 线的偏移量Low[0] 是当前 K 线 (Bar 0, 正在形成中) 的最低价,Low[1] 是上一根已完成 K 线 (Bar 1) 的最低价,以此类推。

    // 获取上一根 K 线的最低价
    double prevBarLow = Low[1];
    // 计算 2 pips 的价格距离
    double offset = 2 * UsePoint;
    // 计算止损价
    double buyStopLossPrice = NormalizeDouble(prevBarLow - offset, Digits);
    
  2. 基于过去N 根K线的极值: 例如,将买单止损设置在过去 10 根 K 线(包括当前 K 线)的最低最低价。可以使用 MQL4内置函数 iLowest() (查找最低值) 或 iHighest() (查找最高值)。 iLowest(symbol, timeframe, type, count, start) 返回指定范围内具有最低值的 K 线相对于当前 K 线 (Bar 0) 的索引 (index or shift)。

    示例:买单止损设在过去 10 根 K 线的最低价下方一定距离

    int lookbackPeriod = 10; // 回看周期
    int startBar = 0;      // 从当前 K 线开始 (索引 0)
    // 查找最低价(MODE_LOW)在过去10根K线(从Bar 0 到 Bar 9)中的 K 线索引
    int lowestBarIndex = iLowest(NULL, 0, MODE_LOW, lookbackPeriod, startBar);
    
    // 获取该 K 线的最低价
    double lowestLowPrice = Low[lowestBarIndex];
    // 设置止损价 (例如,在最低价下方再加一个缓冲 pips)
    double bufferPips = 1;
    double buyStopLossPrice = NormalizeDouble(lowestLowPrice - (bufferPips * UsePoint), Digits);
    

    iHighest() 函数用法类似,配合 MODE_HIGH 来查找区间的最高价,常用于设置卖单的止损。

  3. 基于技术指标值: 例如,将止损设置在某条移动平均线 (MA) 的当前值下方。

    // 假设已用 iMA() 计算出 MA 值并存入 maValue
    double maValue = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0); // 示例: 20周期SMA
    // 设置买单止损在 MA 值下方一定距离 (例如 3 pips)
    double bufferPips = 3;
    double buyStopLossPrice = NormalizeDouble(maValue - (bufferPips * UsePoint), Digits);
    

这些只是设定止损止盈的一些常用思路。您可以结合您的交易策略、风险偏好以及对技术分析的理解,设计出更多样化的动态止损止盈机制。

获取订单信息

当一个订单成功下达后(无论是市价单还是挂单),在后续的程序运行中,我们常常需要获取这个订单的详细信息,以便进行状态跟踪、修改(如调整 SL/TP)或最终平仓/删除。这个“获取信息”的过程,第一步是选中目标订单,这需要用到 OrderSelect() 函数。

OrderSelect() 函数允许我们通过两种方式定位并选中订单:一是使用订单独一无二的订单号;二是通过遍历当前订单池(所有持仓订单和挂单的集合),按其在池中的位置索引 来逐个选中。

一旦通过 OrderSelect() 成功选中了一个订单,MQL4就会将该订单的全部信息加载到一块临时内存区域。之后,我们就可以调用一系列以 Order 开头的特定函数(如 OrderType(), OrderOpenPrice(), OrderStopLoss() 等)来读取这块内存区域中的信息,从而获得关于当前选中订单的各种属性。

OrderSelect() 函数详解

OrderSelect() 函数是用于访问和操作现有订单(包括持仓订单和挂单)的核心入口。它的主要作用是在当前的订单池中选中一个特定的订单,以便后续可以通过一系列 Order*() 函数来读取该订单的详细信息,或者调用 OrderClose(), OrderDelete(), OrderModify() 等函数来对其进行平仓、删除或修改操作。

语法:

bool OrderSelect(int index, int select_by, int pool=MODE_TRADES);
  • index (整数): 用于定位订单的标识符。其具体含义由 select_by 参数决定。
  • select_by (整数): 指定 index 参数的类型:
    • SELECT_BY_TICKET: 表示 index 是一个订单号 (Ticket Number)。这是最常用的方式,因为订单号是唯一的。
    • SELECT_BY_POS: 表示 index 是订单在 pool 指定的订单池中的位置索引,从 0 开始计数。这种方式通常用于循环遍历订单池中的所有订单(例如,使用 for 循环配合 OrdersTotal())。
  • pool (整数, 可选): 指定要搜索哪个订单池:
    • MODE_TRADES (默认值): 在当前持仓订单和未成交挂单池中搜索。
    • MODE_HISTORY: 在已平仓或已取消的订单历史记录池中搜索。

返回值 (bool 类型):

  • true: 函数成功找到了 index 指定的订单并将其选中。此时,MQL4内部环境已准备好该订单的信息供 Order*() 函数读取。
  • false: 未能找到或选中订单(例如,订单号无效,或索引超出范围)。如果返回 false,调用 GetLastError() 可以获取失败原因。

示例 (按订单号选择):

假设变量 myOrderTicket 存储了一个您想查询的订单号。

if (OrderSelect(myOrderTicket, SELECT_BY_TICKET, MODE_TRADES))
{
    // 订单成功选中!现在可以安全地调用 Order*() 函数获取它的信息了
    Print("订单 #", myOrderTicket, " 类型: ", OrderType(), ", 手数: ", OrderLots());
}
else
{
    Print("无法选中订单 #", myOrderTicket, ", 错误代码: ", GetLastError());
}

核心要点: 必须先成功调用 OrderSelect() (即其返回值为 true),然后才能使用下面的 Order*() 函数来获取当前选中订单的信息。

常用的订单信息函数 (在 OrderSelect() 成功后调用): (完整列表请查阅参考文档 -> 交易函数)

  • OrderSymbol(): 返回订单的交易品种名称 (string)。
  • OrderType(): 返回订单类型 (int, 对应 OP_BUY, OP_SELL, OP_BUYSTOP 等常量)。
  • OrderOpenPrice(): 返回订单的开仓价格 (double)。
  • OrderLots(): 返回订单的交易手数 (double)。
  • OrderStopLoss(): 返回订单设置的止损价格 (double, 未设置则为 0)。
  • OrderTakeProfit(): 返回订单设置的止盈价格 (double, 未设置则为 0)。
  • OrderTicket(): 返回当前选中订单的订单号 (int)。(在使用 SELECT_BY_POS 遍历时特别有用)。
  • OrderMagicNumber(): 返回订单的魔术数字 (int)。(EA 管理自身订单的关键)。
  • OrderComment(): 返回订单的注释 (string)。
  • OrderClosePrice(): 返回已平仓订单的平仓价格 (double, 必须在 MODE_HISTORY 池中选择)。
  • OrderOpenTime(): 返回订单的开仓时间 (datetime)。
  • OrderCloseTime(): 返回订单的关闭/取消时间 (datetime, 对于未关闭的订单返回 0)。
  • OrderProfit(): 返回订单当前的浮动盈亏或已实现盈亏 (double, 以账户基础货币计)。
  • OrderSwap(): 返回订单的隔夜利息 (double)。
  • OrderCommission(): 返回订单的手续费 (double)。

在执行平仓或修改订单的操作之前,通常都需要先调用 OrderSelect() 选中目标订单,并可能需要调用上述函数获取一些必要信息(如手数、类型等)以进行判断或作为后续操作的参数。

赞(0)
未经允许不得转载:图道交易 » ​MQL4(15):MarketInfo() - 检索信息函数