下载MetaTrader 5

MQL5 Cookbook: 获取仓位属性

18 十月 2013, 09:45
Anatoli Kazharski
0
746

简介

前一篇文章:"MQL5 Cookbook: 使用不同的打印模式" 向我们展示了如何快速写一个脚本来使用三种不同模式打印所需的信息,现在让我们创建一个脚本来向用户显示所有的仓位属性。

我们需要允许用户从脚本的外部参数中选择对应的选项,如下实现:或者只取得一个(当前)交易品种的仓位属性,或者一个接一个地遍历所有交易品种的所有持仓。这一次,我们会在对话框中查看所需的信息,这非常方便,你们中的一些人可能会觉得这种方法更为有用。

写脚本

程序的开头部分和前一篇文章多少类似 (参见下面的代码)。我们从程序的属性开始,它们之后是使用#define的预定义代码,我们可以使用MQL5InfoString()函数并指定MQL5_PROGRAM_NAME常量为参数,赋值给SCRIPT_NAME变量来为脚本命名,更多有关MQL5InfoString() 函数所有可能值的信息可以在MQL5参考中找到。

我们继续看模式的枚举,如果您为每个标识符写了注释,这些注释的文本将在外部参数的下拉列表中显示。我们将实现两个选项:

  • 当前交易品种 - 只显示当前交易品种的仓位属性,还有
  • 所有交易品种 - 显示所有交易品种的仓位信息。

这里将会有一个唯一的外部参数(mode)用于选择对应的模式。外部参数之后的注释也会在外部参数窗口上显示出来,这使我们能够创建更有含义的参数名称,同时,短一点的变量名在代码中使用更加方便。

#property copyright   "Copyright 2012, http://tol64.blogspot.com"
#property link        "http://tol64.blogspot.com"
#property description "email: hello.tol64@gmail.com"
#property version     "1.0"
#property script_show_inputs
//---
#define SCRIPT_NAME MQL5InfoString(MQL5_PROGRAM_NAME) // 脚本名称
//---
// 模式枚举
enum ENUM_SYMBOLS_MODE
  {
   CURRENT_SYMBOL =0,                     // 当前交易品种
   ALL_SYMBOLS    =1                      // 所有交易品种
  };
//---
// 输入参数
input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL;     // 模式

代码之后是全局变量,为了使全局变量能够在脚本的任何部分都可以访问,它们应该被放置在函数之外(通常在程序的最前面)。

// 全局变量
long                 pos_magic=0;         // 幻数
string               pos_symbol="";       // 交易品种
string               pos_comment="";      // 注释
double               pos_swap=0.0;        // 库存费
double               pos_commission=0.0;  // 手续费
double               pos_price=0.0;       // 仓位的当前价格
double               pos_cprice=0.0;      // 仓位的当前价格
double               pos_profit=0.0;      // 仓位的利润/亏损
double               pos_volume=0.0;      // 仓位交易量
double               pos_sl=0.0;          // 仓位止损价位
double               pos_tp=0.0;          // 仓位获利价位
datetime             pos_time=NULL;       // 仓位建仓时间
long                 pos_id=0;            // 仓位编号
ENUM_POSITION_TYPE   pos_type=NULL;       // 仓位类型
//---

在程序的主函数中,我们只调用一个用户定义的函数,PrintPositionProperties(), 它将进行所有所需的操作:

//+------------------------------------------------------------------+
//| 主函数                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   PrintPositionProperties();
  }

现在让我们分步看一下用户定义的PrintPositionProperties() 函数的结构。我们要先为未来工作打好基础,它非常简单,实现上看起来如下:

//+------------------------------------------------------------------+
//| 打开对话框并显示交易品种数据                            |
//+------------------------------------------------------------------+
void PrintPositionProperties()
  {
   int err=0; // 处理错误的变量
//---
// 如果您只需要获取当前交易品种的仓位属性
   if(mode==CURRENT_SYMBOL)
     {
 
     }
//---
// 如果您需要获取全部交易品种的仓位属性
   if(mode==ALL_SYMBOLS)
     {
 
     }
  }

我们只有两个分支和一个局部变量err,它用于错误处理并且在函数的开始部分声明。现在我们需要写下每个选项的用例,让我们从第一个开始,也就是"如果您只需要获取当前交易品种的仓位信息"。

它非常简单,首先,我们需要检查当前交易品种是否有持仓,这可以通过MQL5中的PositionSelect()函数实现,其唯一参数为交易品种的名称。为了传入当前交易品种的名称,我们需要使用Symbol() 函数或者已经包含当前交易品种名称的预定义变量 _Symbol。如果此交易品种已有持仓,PositionSelect() 将返回一个正值, 如果没有持仓或者出错,则会返回负值。

以下提供了涵盖详细描述的第一个选项的代码:

//---
      // 如果已有持仓,那么...
      if(PositionSelect(_Symbol))
        {
         // ...获取它的属性
         GetPositionProperties();
         //---
         // 打开对话框显示我们获得的全部数据
         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,2)+"\n"+
                    "手续费    : "+DoubleToString(pos_commission,2)+"\n"+
                    "库存费          : "+DoubleToString(pos_swap,2)+"\n"+
                    "利润        : "+DoubleToString(pos_profit,2)+"\n"+
                    "时间          : "+TimeToString(pos_time)+"\n"+
                    "编号    : "+IntegerToString(pos_id)+"",
                    //---
                    "消息框",MB_ICONASTERISK);
         //---
         return;
        }
      // 如果没有持仓或者出错,则报告
      else
        {
         err=GetLastError(); // 获取最后注册的错误编号
         //---
         if(err>0) // 如果有错误
           {
            // 打印相关信息
            MessageBox("当选择("+_Symbol+")仓位时出错 ("+IntegerToString(err)+")  !\n\n"+
                       "也许该交易品种没有持仓. 如果不是这种情况,请重试.",
                       "错误",
                       MB_ICONWARNING);
            //---
            return; // 退出函数
           }
        }
      //---

在以上代码中,我们可以看到两个用户定义的函数-GetPositionProperties()和 PositionTypeToString()。 因为我们必须在整个程序的不同地方获取仓位属性,我们最好建立一个独立的函数以便减少代码量以及使代码有更好的可读性。以下是这个函数的代码。请确保查阅MQL5参考来了解GetPositionProperties()函数中所使用MQL5函数和标识符的更多信息。

//+------------------------------------------------------------------+
//| 获取交易品种属性                                        |
//+------------------------------------------------------------------+
void GetPositionProperties()
  {
   pos_symbol     =PositionGetString(POSITION_SYMBOL);
   pos_comment    =PositionGetString(POSITION_COMMENT);
   pos_magic      =PositionGetInteger(POSITION_MAGIC);
   pos_price      =PositionGetDouble(POSITION_PRICE_OPEN);
   pos_cprice     =PositionGetDouble(POSITION_PRICE_CURRENT);
   pos_sl         =PositionGetDouble(POSITION_SL);
   pos_tp         =PositionGetDouble(POSITION_TP);
   pos_type       =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
   pos_volume     =PositionGetDouble(POSITION_VOLUME);
   pos_commission =PositionGetDouble(POSITION_COMMISSION);
   pos_swap       =PositionGetDouble(POSITION_SWAP);
   pos_profit     =PositionGetDouble(POSITION_PROFIT);
   pos_time       =(datetime)PositionGetInteger(POSITION_TIME);
   pos_id         =PositionGetInteger(POSITION_IDENTIFIER);
  }

这个用户定义的PositionTypeToString()函数把返回的持仓类型从整数型转换为可读的字符串格式,其代码如下所示:

//+------------------------------------------------------------------+
//| 把仓位类型转换为字符串                             |
//+------------------------------------------------------------------+
string PositionTypeToString(int position_type)
  {
   string str="";
//---
   if(position_type==0) { str="买入";  }
   if(position_type==1) { str="卖出"; }
//---
   return(str);
  }

这样,第一个选项,即我们仅查看当前交易品种仓位属性的代码已经完成了。如果您按照文章描述的所有步骤做下来,它甚至可以马上测试了。使用标准工具在MetaTrader 5中建立一个仓位,为了这个目标, 按下F9 键打开订单窗口,在那里你可以在仓位建立之前看到所有必要的选项来设置仓位属性:

图 1. MetaTrader 5客户终端中的订单窗口.

图 1. MetaTrader 5客户终端中的订单窗口.

当所有属性设置完成,选择卖出或者买入,然后双击脚本或者把它拖到图表上来运行脚本,脚本窗口将会打开,模式参数的所需值 (当前交易品种)已经被默认填好了,点击“确定”按钮将会打开一个对话框,显示当前交易品种的所有仓位属性:

图 2. 显示当前交易品种仓位属性的对话框.

图 2. 显示当前交易品种仓位属性的对话框.

另一方面,假如当前交易品种没有持仓,会出现一个提醒对话框:

图 3. 提醒对话框.

图 3. 提醒对话框.

一切都和计划中一样工作正常,和我们代码中所实现的一样。

让我们回顾一下那些选择查看所有交易品种仓位属性要用到的程序代码,代码和详细的注释如下:

//---
      int digits=0; // 小数位数
      int mb_res=-1; // 对话框中选择选项的变量
      int pos_total=PositionsTotal(); // 终端中的持仓个数
      //---
      // 在循环中挨个查看所有仓位的属性
      for(int i=0; i<pos_total; i++)
        {
         ResetLastError(); // 重设最后的错误
         //---
         pos_symbol=PositionGetSymbol(i); // 读取交易品种名称
         digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS); // 取得价格的小数位数
         //---
         // 如果这个交易品种有持仓,那么...
         if(PositionSelect(pos_symbol))
           {
            // ...获取它的属性
            GetPositionProperties();
            //---
            // 打开一个对话框显示所有获得的仓位属性
            mb_res=MessageBox("全部/当前持仓: "+IntegerToString(pos_total)+"/"+IntegerToString(i+1)+"\n"+
                              "---------------------------------\n"+
                              "交易品种: "        +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,2)+"\n"+
                              "手续费: "    +DoubleToString(pos_commission,2)+"\n"+
                              "库存费: "          +DoubleToString(pos_swap,2)+"\n"+
                              "利润: "        +DoubleToString(pos_profit,2)+"\n"+
                              "时间: "          +TimeToString(pos_time)+"\n"+
                              "编号: "    +IntegerToString(pos_id)+"",
                              //---
                              "消息框",MB_CANCELTRYCONTINUE|MB_ICONASTERISK);
            //---
            if(mb_res==IDCANCEL) // 如果您点击了取消或者关闭
              { Print("程序 ("+SCRIPT_NAME+") 被用户终止!"); return; } // 退出函数
            //---
            // 如果您点击了重试   
            if(mb_res==IDTRYAGAIN) { i--; } // 重设计数器并重试
           }
         else // 如果没有持仓或者出错,则报告
           {
            err=GetLastError(); // 获取最后注册的错误编号
            //---
            if(err>0) // 如果有错误
              {
               // 打印相关信息
               MessageBox("错误 ("+IntegerToString(err)+") 当选择仓位 ("+pos_symbol+") !\n\n"+
                          "也许该交易品种没有持仓. 如果不是这种情况,请重试.",
                          "错误",
                          MB_ICONWARNING);
              }
           }
        }
      //---

现在我们只需要测试这个选项,让我们在两个交易品种上建立仓位,(比如AUDUSD和 EURUSD)。当我们运行脚本的时候,在外部参数下拉列表中选择所有交易品种模式并点击确定, 一个对话框会如下显示:

Fig. 4. 显示第二个选项仓位属性的对话框

Fig. 4. 显示第二个选项仓位属性的对话框

结论

您可以在上图中看到,对话框有三个按钮,如果您点击了重试,循环计数器会被重设,当前显示在对话框中的交易品种仓位属性会被刷新;如果您点击了继续,程序会处理下一个交易品种;取消按钮用于终止程序。

请注意,仓位属性以上的第一行包含持仓总数信息(仓位总数)和仓位计数器的当前编号(当前)。

就是这样,请随意下载附件中的源代码,它们需要在MetaQuotes语言编辑器中编译。

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/639

附加的文件 |
MQL5.community的支付系统 MQL5.community的支付系统

MQL5.community 内置服务为MQL5开发人员和普通的无编程技巧的交易者们提供了巨大了机遇。但是,所有这些功能的实现都离不开安全的内部支付系统,为买家和卖家之间的结算提供了方便的基础。在本文中,我们将展示MQL5.community支付系统的工作方式。

怎样购买一个基于MQL5或者MQL4的交易机器 怎样购买一个基于MQL5或者MQL4的交易机器

通过建立“工作”服务功能,MQL5.community 成为了一个理想的可以提供和购买编程服务的地方。这里有成千上万的交易人员和开发者每天来访问所需信息资源,也可以方便地互相帮助。对于交易人员来说,“工作”服务是轻松获得自己所需的EA智能交易程序的好机会,对于MQL5开发者来说,这也是轻松找到客户的机会。在这篇文章中,我们将领略一下此项服务的具体功能。

在外汇市场中货币篮子的运作 在外汇市场中货币篮子的运作

本文论述了如何将货币对分组 (篮子), 以及如何使用某些指标来获取它们的有关状态数据 (例如, 超买和超卖), 以及如何在交易中应用此数据。

在 MetaTrader 4 中的投资组合交易 在 MetaTrader 4 中的投资组合交易

本文揭示了投资组合交易及其在外汇市场中的应用。研究几种简单的投资组合数学模型。本文包含在 MetaTrader4 中的实际投资交易组合的实施例子: 投资组合指标和半自动化智能交易程序。交易策略的元素, 还针对它们的优点和缺陷进行了说明。