《MQL4实用编程》读书笔记(3) - 交易操作的编程:建仓和挂单

本章解决2个编程问题:现价交易和挂单交易。

原文讲得很详细,但我只译出两个例程。我觉得,这是高效率学习编程的最好办法。

先看几个相关函数:

函数OrderSend

int OrderSend (string symbol, int cmd, double volume, double price, 
               int slippage, double stoploss,double takeprofit, 
               string comment=NULL, int magic=0, datetime expiration=0, 
               color arrow_color=CLR_NONE)

OrderSend 返回定单的编号。编号由交易服务器给出,独一无二。若编号为-1,则定单被服务器或客户端拒绝。可通过函数GetLastError()查看拒绝的原因。

symbol 交易对象的名称,用字符串,如"EURUSD",表示“欧元/美元”货币对。在“操盘手”中,可用函数 Symbol()得到交易对象的名称。

cmd 交易操作的类型,分别以内建常量表示。

volume 交易手数。现价交易,必须检查帐户资金是否充足;挂单交易,手数不受限制。

price 建仓(开单)价格。它由定单特点和交易规则确定。

slippage 滑点。能够接受的建仓报价与成交价之间的最大点差。挂单不处理这一参数。

stoploss 止损价(点位)。

takeprofit 止盈价(点位)。

comment 对定单的文字说明。

magic 汇客自定义的定单标识。

expiration 定单期限。

arrow_color 在主图中,标示建仓位置的箭头颜色。若无此参数或其值为 CLR_NONE,则不显示该箭头。

函数MarketInfo

double MarketInfo(string symbol, int type)

它返回的信息,是MT4终端窗口"Market Watch"中的数据。而当前交易对象的另外一些信息,则保存在预定义变量中。

参数:

symbol - 交易对象的名称;

type - 所要返回的信息类别代号。(参见Function MarketInfo Identifier)。

为了程序运行稳定,最大限度减少交易请求被拒绝,在执行函数OrderSend()之前,应当先用函数MarketInfo()和RefreshRates(),更新相关交易数据。

函数AccountFreeMargin

double  AccountFreeMargin();

返回当前帐户可用的保证金数额。

函数MathFloor

double  MathFloor(
   double  val     // 数字
   );

参数

val 数值

返回值 小于或等于val的最大整数

注意 可用函数floor()代替MathFloor()

函数RefreshRates

bool  RefreshRates();

返回值 数据得到更新返回True,否则,返回false。

说明 在“操盘手”或脚本中,刷新预定义变量和时序数组。

函数GetLastError

int GetLastError();

返回值 返回MQL4程序运行时,最新发生的错误。

说明 本函数被调用后,内建变量 _LastError 没有重设。若需重设,调用函数ResetLastError()。

函数WindowPriceOnDropped

double  WindowPriceOnDropped();

返回值 “操盘手”或脚本运行的主图窗口价格点位。只有用鼠标将它俩拖拉到主图中,数值才为有效。

说明 外建指标没有此值。

一、现价交易

//-------------------------------------------------------------------------------
// openbuy.mq4 
// 代码仅用于教学
//-------------------------------------------------------------------------- 1 --
int start()                                     // 特别函数 start
  {
   int Dist_SL =10;                             // 设定止损价位 10 点
   int Dist_TP =3;                              // 设定止盈价位 3 点
   double Prots=0.35;                           // 使用 35% 的保证金
   string Symb=Symbol();                        // 交易对象名称
//-------------------------------------------------------------------------- 2 --
   while(true)                                  // 建仓过程的循环
     {
      int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// 交易允许的止损/止盈最小点位
      double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// 交易允许的最小手数
      double Step   =MarketInfo(Symb,MODE_LOTSTEP);//交易允许的手数变化幅度
      double Free   =AccountFreeMargin();       // 保证金
      double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//每买进一手所需保证金
      //-------------------------------------------------------------------- 3 --
      double Lot=MathFloor(Free*ProtsOne_LotStep)*Step;// 总手数
      if (Lot < Min_Lot)                        // 若总手数小于允许的下限
        {
         Alert(" Not enough money for ", Min_Lot," lots");
         break;                                 // 退出循环
        }
      //-------------------------------------------------------------------- 4 --
      if (Dist_SL < Min_Dist)                   // 止损点位小于允许的最小值
        {
         Dist_SL=Min_Dist;                      // 设定最小止损位
         Alert(" Increased the distance of SL = ",Dist_SL," pt");
        }
      double SL=Bid - Dist_SL*Point;            // 确定交易的止损价位
                                                // Bid 系统内建变量:当前交易品种的最新买价
                                                // Point 系统内建变量:报价小数部分的值

      //-------------------------------------------------------------------- 5 --  
      if (Dist_TP < Min_Dist)                   // 止盈点位小于允许的最小值
      {   
         Dist_TP=Min_Dist;                      // 设定最小止盈位
         Alert(" Increased the distance of TP = ",Dist_TP," pt");
      }
         double TP=Bid + Dist_TP*Point;            // 确定交易的止盈价位                                            

                                                // Bid 系统内建变量:当前交易品种的最新买价

                                                // Point 系统内建变量:报价小数部分的值

     //-------------------------------------------------------------------- 6 --
      Alert("The request was sent to the server. Waiting for reply..");      
      int ticket=OrderSend(Symb, OP_BUY, Lot, Ask, 2, SL, TP);         

     //-------------------------------------------------------------------- 7 --
      if (ticket>0)                             // 交易成功! :)
      { 
        Alert ("Opened order Buy ",ticket);
        break;                                 // 退出循环
      }   
      //-------------------------------------------------------------------- 8 --
      int Error=GetLastError();                 // 交易失败 :(
      switch(Error)                             // 可以克服的错误
      {
         case 135:Alert("The price has changed. Retrying..");             
            RefreshRates();                     // 更新数据
            continue;                           // 继续循环
         case 136:
            Alert("No prices. Waiting for a new tick..");
            while(RefreshRates()==false)        // 获得新报价
               Sleep(1);                        // 延迟循环
            continue;                           // 继续循环
         case 146:Alert("Trading subsystem is busy. Retrying..");          
            Sleep(500);                         // 简单处理方案
            RefreshRates();                     // 更新数据
            continue;                           // 继续循环
      }
      switch(Error)                             // 致命错误
      {
         case 2 : 
             Alert("Common error.");
             break;                              // 退出本 'switch'
         case 5 : 
             Alert("Outdated version of the client terminal.");
             break;                              // 退出本 'switch'
         case 64:
             Alert("The account is blocked.");
             break;                              // 退出本 'switch'
         case 133:
             Alert("Trading forbidden");
             break;                              // 退出本 'switch'
         default:
             Alert("Occurred error ",Error);// 其他错误           
      }
      break;                                    // 退出循环
   }
    //-------------------------------------------------------------------------- 9 --
   Alert ("The script has completed its operations ---------------------------");
   return;                                      // 退出 start()
  }
//-------------------------------------------------------------------------- 10 --

二、挂单交易

//------------------------------------------------------------------------------------
// openbuystop.mq4 
// 代码仅用于教学
//------------------------------------------------------------------------------- 1 --
int start()                                     // 特别函数 start
  {
   int Dist_SL =10;                             // 设定止损位 10 个点
   int Dist_TP =3;                              // 设定止盈位 3 个点
   double Prots=0.35;                           // 交易使用35%的保证金
   string Symb=Symbol();                        // 交易对象名称
   double Win_Price=WindowPriceOnDropped();     // 脚本被拖拉进的窗口,价格点位
   Alert("The price is set by the mouse as Price = ",Win_Price);// 点击鼠标设定的价格
//------------------------------------------------------------------------------- 2 --
   while(true)                                  // 建仓过程循环
     {
      int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// 最小止损/止盈点位
      double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// 最小交易手数
      double Free   =AccountFreeMargin();       // 保证金
      double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//每手所需保证金
      double Lot=MathFloor(Free*ProtsOne_LotMin_Lot)*Min_Lot;// 总手数
      //------------------------------------------------------------------------- 3 --
      double Price=Win_Price;                   // 点击鼠标设定的价格
      if (NormalizeDouble(Price,Digits)<        // 若小于下限
         NormalizeDouble(Ask+Min_Dist*Point,Digits))
        {                                       // 仅可 BuyStop 挂单!
         Price=Ask+Min_Dist*Point;              // 没有平仓
         Alert("Changed the requested price: Price = ",Price);
        }
      //------------------------------------------------------------------------- 4 --
      double SL=Price - Dist_SL*Point;          // 止损报价
      if (Dist_SL < Min_Dist)                   // 若低于下限
        {
         SL=Price - Min_Dist*Point;             // 以下限为止损点位
         Alert(" Increased the distance of SL = ",Min_Dist," pt");
        }
      //------------------------------------------------------------------------- 5 --
      double TP=Price + Dist_TP*Point;          // 止盈报价
      if (Dist_TP < Min_Dist)                   // 若低于下限
        {
         TP=Price + Min_Dist*Point;             // 以下限为止盈点位
         Alert(" Increased the distance of TP = ",Min_Dist," pt");
        }
      //------------------------------------------------------------------------- 6 --
      Alert("The request was sent to the server. Waiting for reply..");
      int ticket=OrderSend(Symb, OP_BUYSTOP, Lot, Price, 0, SL, TP);
      //------------------------------------------------------------------------- 7 --
      if (ticket>0)                             // 服务器接受挂单!:)
        {
         Alert ("Placed order BuyStop ",ticket);
         break;                                 // 退出挂单
        }
      //------------------------------------------------------------------------- 8 --
      int Error=GetLastError();                 // 挂单被拒绝 :(
      switch(Error)                             // 可克服的错误
        {
         case 129:Alert("Invalid price. Retrying..");
            RefreshRates();                     // 更新数据
            continue;                           // 继续
         case 135:Alert("The price has changed. Retrying..");
            RefreshRates();                     // 更新数据
            continue;                           // 继续
         case 146:Alert("Trading subsystem is busy. Retrying..");
            Sleep(500);                         // 简单处理方案
            RefreshRates();                     // 更新数据
            continue;                           // 继续
        }
      switch(Error)                             // 致命错误
        {
         case 2 : Alert("Common error.");
            break;                              // 退出本 'switch'
         case 5 : Alert("Outdated version of the client terminal.");
            break;                              // 退出本 'switch'
         case 64: Alert("The account is blocked.");
            break;                              // 退出本 'switch'
         case 133:Alert("Trading fobidden");
            break;                              // 退出本 'switch'   
         default: Alert("Occurred error ",Error);// 其他错误
        }
      break;                                    // 退出挂单
     }
//------------------------------------------------------------------------------- 9 --
   Alert ("The script has completed its operations -----------------------------");
   return;                                      // 退出 start()
  }
//------------------------------------------------------------------------------- 10 --
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值