Java教程

【漆学军】EA编程速成教程(5)增加一个下单条件:抛物线指标

本文主要是介绍【漆学军】EA编程速成教程(5)增加一个下单条件:抛物线指标,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

这次,我们在之前课程的基础上,给EA设定一个下单条件,也就是抛物线指标转向的时候,下单,去掉之前的挂上就买入一单。

具体是,抛物线从k线下面转到k线上面去之后,第二根k线开盘价卖出,如图中标记5处。

反之,抛物线从k线上面转到k线下面去之后,第二根k线开盘价买入,如图中标记1处。

一、引入抛物线指标函数 iSAR函数

double  iSAR( 
   string       symbol,            // 交易品种
   int          timeframe,         // 时间周期
   double       step,              //  步长
   double       maximum,           // 最大值
   int          shift              // 位移
   );

这个函数有5个参数,前面4个看字面意思就知道其意思了,其中最后一个比较难以理解,涉及到MT4平台的K线位移。

什么是K线位移呢?

MT4平台,对于k线图上每一个k线,都设置了个位置编号,这个编号就是位移。从右往左,从0开始。

0号k线的开盘价就是Open[0];

1号K线的最高价就是High[1]。

如果要获取3号k线对应的抛物线的值就是 iSAR(NULL,0,0.02,0.2,3)。

 

二、根据上面的知识,我们现在来写一个函数Signal(),用来定义本EA的信号,返回值为1表示买入信号,返回值为-1表示卖出信号。

int signal()
  {
   int res=0;
   double A=iSAR(NULL,0,0.02,0.2,1);
   double B=iSAR(NULL,0,0.02,0.2,2);
   if(A>Close[1] && B<Close[2])
     {
      res=1;
     }
   if(A<Close[1] && B>Close[2])
     {
      res=-1;
     }
   return(res);
  }

三、现在,我们来开始编程写EA了。

1.在程序OnTick()函数的开始,我们定义两个变量,用来记录EA的持仓状态。

顺便也定义一个变量,从信号函数中返回信号值。

   int buys=0;  //多单持仓有几笔
   int sells=0; //空单持仓有几笔
   int signal=signal();

2.然后通过for循环遍历持仓单,分别找到多单持仓几笔和空单持仓几笔,并分别赋值给变量buys和sells。

for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_BUY)
           {
            buys++;
           }

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_SELL)
           {
            sells++;
           }
        }
     }

3.然后加入开仓代码,当多单持仓数为0并且买入信号出现的时候,下多单;反之,当空单持仓数为0并且卖出信号出现的时候,下空单。

 if(signal>0 && buys==0)
     {
      int ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,0,0,"My buy order",16384,0,clrGreen);
      if(ticket<0)
        {
         Print("OrderSend failed with error #",GetLastError());
        }
      else
        {
         Print("OrderSend placed successfully");
        }
     }

   if(signal<0 && sells==0)
     {
      int ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,0,0,"My sell order",16384,0,clrRed);
      if(ticket<0)
        {
         Print("OrderSend failed with error #",GetLastError());
        }
      else
        {
         Print("OrderSend placed successfully");
        }
     }

4.下单解决了,再就是加入平仓代码。

平仓代码加入到之前的for循环里面去,这样,整个程序在每次tick里就只有一次遍历订单,让程序运行更加高效。

为了节省篇幅,顺便把修改订单止损止盈也加入进去。

 for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_BUY)
           {
            buys++;
            if(signal<0)
              {
               bool res=OrderClose(OrderTicket(),OrderLots(),Bid,0);
               if(res)
                 {
                  Print("订单平仓成功");
                 }
               return;
              }
            if(OrderStopLoss()==0)
              {
               bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-SL*Point,OrderOpenPrice()+TP*Point,0);
               if(res)
                  Print("订单修改成功");
              }
           }

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_SELL)
           {
            sells++;
            if(OrderStopLoss()==0)
              {
               bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+SL*Point,OrderOpenPrice()-TP*Point,0);
               if(res)
                  Print("订单修改成功");
              }
            if(signal>0)
              {
               bool res=OrderClose(OrderTicket(),OrderLots(),Ask,0);
               if(res)
                 {
                  Print("订单平仓成功");
                 }
               return;
              }
           }
        }
     }

这里面需要注意一点的就是,多单的止损价是开盘价-点数*Point,多单止盈价是开盘价+点数*Point;

反之,空单的止损价是开盘价+点数*Point,空单的止盈价是开盘价-点数*Point。

 

四、到此,整个程序就完全修改好了,用历史数据测试下,正常交易。

完整代码如下:

//+------------------------------------------------------------------+
//|                                                   Test_EA_05.mq4 |
//|                                                             云开 |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "http://www.forexmt4.cn"
#property link      "http://www.forexmt4.cn"

#property description "【漆天编程】 测试EA"
#property description "  "
#property description "这是一款测试EA,作者QQ:80364276"
#property description "  "
#property description "发布时间:2020.06.07"
#property strict
#property icon "//Images//sea.ico"

input double lots=0.1; //交易手数
input int SL=600;      //止损点数
input int TP=200;      //止盈点数

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int buys=0;  //多单持仓有几笔
   int sells=0; //空单持仓有几笔
   int signal=signal();
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_BUY)
           {
            buys++;
            if(signal<0)
              {
               bool res=OrderClose(OrderTicket(),OrderLots(),Bid,0);
               if(res)
                 {
                  Print("订单平仓成功");
                 }
               return;
              }
            if(OrderStopLoss()==0)
              {
               bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-SL*Point,OrderOpenPrice()+TP*Point,0);
               if(res)
                  Print("订单修改成功");
              }
           }

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_SELL)
           {
            sells++;
            if(OrderStopLoss()==0)
              {
               bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+SL*Point,OrderOpenPrice()-TP*Point,0);
               if(res)
                  Print("订单修改成功");
              }
            if(signal>0)
              {
               bool res=OrderClose(OrderTicket(),OrderLots(),Ask,0);
               if(res)
                 {
                  Print("订单平仓成功");
                 }
               return;
              }
           }
        }
     }
//---
   if(signal>0 && buys==0)
     {
      int ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,0,0,"My buy order",16384,0,clrGreen);
      if(ticket<0)
        {
         Print("OrderSend failed with error #",GetLastError());
        }
      else
        {
         Print("OrderSend placed successfully");
        }
     }

   if(signal<0 && sells==0)
     {
      int ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,0,0,"My sell order",16384,0,clrRed);
      if(ticket<0)
        {
         Print("OrderSend failed with error #",GetLastError());
        }
      else
        {
         Print("OrderSend placed successfully");
        }
     }

  }
//+------------------------------------------------------------------+
int signal()
  {
   int res=0;
   double A=iSAR(NULL,0,0.02,0.2,1);
   double B=iSAR(NULL,0,0.02,0.2,2);
   if(A>Close[1] && B<Close[2])
     {
      res=1;
     }
   if(A<Close[1] && B>Close[2])
     {
      res=-1;
     }
   return(res);
  }
//+------------------------------------------------------------------+

 

这篇关于【漆学军】EA编程速成教程(5)增加一个下单条件:抛物线指标的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!