MQL5 Cookbook: 获取仓位属性(基础篇)
📘

MQL5 Cookbook: 获取仓位属性(基础篇)

第 1/2 篇

◍ 在 MT5 里读出持仓的真实属性

做价格行为分析时,很多人只盯着图表上的 K 线,却忽略了终端里已经算好的仓位元数据。MT5 的 MQL5 通过 PositionGet 系列函数,可以直接取到当前选中账户的持仓属性,不用自己从成交记录里反推。 关键入口是 PositionSelect():先用它按 ticket 或 symbol 锁定一条持仓,失败返回 false,之后才能安全地调用 PositionGetInteger()、PositionGetDouble()、PositionGetString()。比如持仓量、开仓价、止损止盈、注释字段,分别对应不同的标识符常量。 下面这段演示了如何选出 EURUSD 的持仓并打印手数与开仓价。注意 PositionSelect(_Symbol) 只选当前图表品种的第一条持仓,若同一品种有多条独立持仓需循环遍历 ticket。外汇与贵金属杠杆高,持仓属性随时受点差和强制平仓影响,读数仅反映查询瞬间的账户状态。

MQL5 / C++
if(PositionSelect(_Symbol))
{
   class="type">class="kw">double volume = PositionGetDouble(POSITION_VOLUME);
   class="type">class="kw">double open_price = PositionGetDouble(POSITION_PRICE_OPEN);
   Print("Volume: ", volume, " Open: ", open_price);
}

用脚本把持仓属性一次性翻出来

上篇讲了三种打印模式快速输出信息,这一节把目标换成持仓属性:写个脚本,把当前账户里所有持仓的关键字段直接弹窗列给你看。 脚本要留一个外部输入项,让用户二选一:只抓当前图表品种的那一笔持仓,还是按交易品种逐个把全部持仓扫一遍。弹窗比终端日志更适合临场核对,尤其是你同时盯几个品种时,不用去‘交易’标签里手动翻。 外汇和贵金属保证金交易杠杆高、滑点不可控,脚本只做属性读取不替你下单,但账户若开了自动交易,任何脚本运行都先把EA总开关确认好再跑。

「把仓位属性读出来:MT5脚本骨架」

做这类小工具,开头先声明脚本属性,再用 #define 把程序名绑到 SCRIPT_NAME 上,后续弹窗和日志都能直接复用。模式用枚举区分:CURRENT_SYMBOL=0 只看当前品种,ALL_SYMBOLS=1 扫全部品种;input 里只暴露一个 mode 参数,下拉文字就是枚举注释,写代码时变量名短、窗口里名字直观。 全局变量必须写在函数外,pos_magic、pos_symbol、pos_volume 这类字段放最前面,PrintPositionProperties() 在任何分支都能直接填。主函数只调这一用户函数,逻辑全收在里面,避免 OnStart 越写越肿。 当前品种分支先用 PositionSelect(_Symbol) 探持仓:返回真值才有后续,否则弹「无持仓」提醒。把属性抓取抽成 GetPositionProperties(),类型转换交给 PositionTypeToString(),同样的逻辑在「所有品种」模式还要跑一遍,抽函数能少复制几十行。 验证路径很直接:MT5 里按 F9 开订单窗口,下个 AUDUSD 或 EURUSD 的真实仓位(外汇/贵金属杠杆高,先用模拟盘跑)。把脚本拖进图表,mode 选「当前交易品种」确定后,对话框会列出成交量、库存费、SL/TP 等 11 个字段;切到「所有交易品种」就能一次看跨品种仓位。下面是从原文扒出的声明段,逐行都是后续函数的地基。

MQL5 / C++
class="macro">#class="kw">property copyright   "Copyright class="num">2012, http:class=class="str">"cmt">//tol64.blogspot.com"
class="macro">#class="kw">property link         "http:class=class="str">"cmt">//tol64.blogspot.com"
class="macro">#class="kw">property description "email: hello.tol64@gmail.com"
class="macro">#class="kw">property version      "class="num">1.0"
class="macro">#class="kw">property script_show_inputs
class=class="str">"cmt">//---
class="macro">#define SCRIPT_NAME MQL5InfoString(MQL5_PROGRAM_NAME) class=class="str">"cmt">// 脚本名称
class=class="str">"cmt">//---
class=class="str">"cmt">// 模式枚举
enum ENUM_SYMBOLS_MODE
  {
   CURRENT_SYMBOL =class="num">0,                          class=class="str">"cmt">// 当前交易品种
   ALL_SYMBOLS   =class="num">1                            class=class="str">"cmt">// 所有交易品种
  };
class=class="str">"cmt">//---
class=class="str">"cmt">// 输入参数
input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL;     class=class="str">"cmt">// 模式
class=class="str">"cmt">// 全局变量
class="type">long                pos_magic=class="num">0;                class=class="str">"cmt">// 幻数
class="type">class="kw">string              pos_symbol="";              class=class="str">"cmt">// 交易品种
class="type">class="kw">string              pos_comment="";             class=class="str">"cmt">// 注释
 class="type">class="kw">double              pos_swap=class="num">0.0;               class=class="str">"cmt">// 库存费
class="type">class="kw">double              pos_commission=class="num">0.0;        class=class="str">"cmt">// 手续费
class="type">class="kw">double              pos_price=class="num">0.0;             class=class="str">"cmt">// 仓位的当前价格
class="type">class="kw">double              pos_cprice=class="num">0.0;            class=class="str">"cmt">// 仓位的当前价格
class="type">class="kw">double              pos_profit=class="num">0.0;            class=class="str">"cmt">// 仓位的利润/亏损
class="type">class="kw">double              pos_volume=class="num">0.0;            class=class="str">"cmt">// 仓位交易量
class="type">class="kw">double              pos_sl=class="num">0.0;                class=class="str">"cmt">// 仓位止损价位
class="type">class="kw">double              pos_tp=class="num">0.0;                class=class="str">"cmt">// 仓位获利价位

◍ 把持仓属性弹窗打印出来

想在 MT5 里一眼看清单前品种持仓的全部细节,可以写个脚本把 PositionSelect 选中的仓位属性用 MessageBox 弹出来。下面这段骨架已经把建仓时间、编号、类型三个变量先置空,等真正选中持仓再填值。 datetime pos_time=NULL; // 仓位建仓时间 long pos_id=0; // 仓位编号 ENUM_POSITION_TYPE pos_type=NULL; // 仓位类型 主逻辑放在 OnStart 里只调一个 PrintPositionProperties,结构很轻,适合直接拖进策略测试器跑。 void OnStart() { PrintPositionProperties(); } PrintPositionProperties 内部用 mode 变量切换:CURRENT_SYMBOL 只看当前图品种,ALL_SYMBOLS 扫全部品种。若 PositionSelect(_Symbol) 返回真,就调 GetPositionProperties 抓属性,随后用 MessageBox 把交易品种、注释、幻数、建仓价、当前价、SL、TP、类型、交易量、手续费拼成字符串弹出。 外汇与贵金属杠杆高,弹窗里的止损、手续费数字仅反映当时持仓状态,不代表任何未来走向,实际滑点可能让弹出值与成交价偏差数个点数。

MQL5 / C++
class="type">class="kw">datetime              pos_time=NULL;      class=class="str">"cmt">// 仓位建仓时间
class="type">long                  pos_id=class="num">0;           class=class="str">"cmt">// 仓位编号
class="type">ENUM_POSITION_TYPE    pos_type=NULL;      class=class="str">"cmt">// 仓位类型
class=class="str">"cmt">//---
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 主函数                                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnStart()
  {
   PrintPositionProperties();
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 打开对话框并显示交易品种数据                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void PrintPositionProperties()
  {
   class="type">int err=class="num">0; class=class="str">"cmt">// 处理错误的变量
class=class="str">"cmt">//---
class=class="str">"cmt">// 如果您只需要获取当前交易品种的仓位属性
   if(mode==CURRENT_SYMBOL)
     {
     }
class=class="str">"cmt">//---
class=class="str">"cmt">// 如果您需要获取全部交易品种的仓位属性
   if(mode==ALL_SYMBOLS)
     {
     }
  }
class=class="str">"cmt">//---
      class=class="str">"cmt">// 如果已有持仓,那么...
      if(PositionSelect(_Symbol))
        {
         class=class="str">"cmt">// ...获取它的属性
         GetPositionProperties();
         class=class="str">"cmt">//---
         class=class="str">"cmt">// 打开对话框显示我们获得的全部数据
         MessageBox("交易品种        : "+pos_symbol+"\n"+
                    "注释     : "+pos_comment+"\n"+
                    "幻数  : "+IntegerToString(pos_magic)+"\n"+
                    "建仓价位      : "+DoubleToString(pos_price,_Digits)+"\n"+
                    "当前价位 : "+DoubleToString(pos_cprice,_Digits)+"\n"+
                    "止损价位      : "+DoubleToString(pos_sl,_Digits)+"\n"+
                    "获利价位  : "+DoubleToString(pos_tp,_Digits)+"\n"+
                    "类型            : "+PositionTypeToString(pos_type)+"\n"+
                    "交易量        : "+DoubleToString(pos_volume,class="num">2)+"\n"+
                    "手续费  : "+DoubleToString(pos_commission,class="num">2)+"\n"+

常见问题

写个脚本遍历持仓,用 PositionGetDouble 读入价和浮动盈亏,再打印或弹窗即可,不用手动逐个点。
可能是没先选中对应持仓符号,PositionSelect 失败会导致读到空值,先确认选择成功再读属性。
可以,小布能直接读取并汇总你的持仓方向、手数、盈亏等,打开对应品种页就能看到整理好的诊断。
用 PositionsTotal 返回数量,若为 0 就说明无持仓,后续读取逻辑应直接跳过避免报错。
把弹窗函数换成 Print 或 FileWrite,运行后去专家日志或指定文件里查就行。