龙听期货论坛's Archiver

龙听 发表于 2017-10-30 15:25

[转载]MetaTrader编程中级(0)--一个EA练习

[code] MetaTrader编程中级(0)--一个EA练习

这里提供配套的一个指标和一个EA,
从中可以学会,1 EA的文件结构, 2 指标的文件结构 巩固和发展前面的入门材料.

进一步可以分析这个EA的表现,来认识 (1) 这个EA有哪些"诡异"的想象,原因是什么? (2)这个指标和EA可以使用吗?如何使用? (3)EA是如何优化的? (4) 不同公司不同数据,不同时间段 表现如何? 分析原因?(5)如何改进?
声明,这个EA是学习编程用的, 若你要使用,当然后果自负. 有关问题我可能选择回答.
这时最近偶然设计的一个EA, 内容很简单, 但我认为分析它 有很好的学习价值.

我初步的测试结果最好时, 5.13~5.24十天从10000到18000, EUR, 目前的缺省参数就是,使用了MT自己的数据MetaQuotes-Demo. 但是却可能不能用.


指标文件: 存为0meme.mq4


#property indicator_chart_window

//#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Aqua//Lime
#property indicator_color2 Red


double buffer10[];
double buffer20[];
extern int period=79;//10;
extern int price=5; // 0 or other = (H+L)/2
            // 1 = Open
            // 2 = Close
            // 3 = High
            // 4 = Low
            // 5 = (H+L+C)/3
            // 6 = (O+C+H+L)/4
            // 7 = (O+C)/2
extern double lwei= 0.67;
bool Mode_Fast= False;

int init()
{
  SetIndexArrow(0,67);//200);
  SetIndexArrow(1,68);//202);  
  SetIndexBuffer(0,buffer10);
  SetIndexBuffer(1,buffer20);
return(0);
}


int deinit()
{
int i;
return(0);
}


double Value=0,Value1=0,Value2=0,Fish=0,Fish1=0,Fish2=0;

double _price;
double MinL=0;
double MaxH=0;            


void getprice0(int i)
{
MaxH = High[iHighest(NULL,0,MODE_HIGH,period,i)];
  MinL = Low[iLowest(NULL,0,MODE_LOW,period,i)];
  switch (price)
  {
  case 1: _price = Open[i]; break;
  case 2: _price = Close[i]; break;
  case 3: _price = High[i]; break;
  case 4: _price = Low[i]; break;
  case 5: _price = (High[i]+Low[i]+Close[i])/3; break;
  case 6: _price = (Open[i]+High[i]+Low[i]+Close[i])/4; break;
  case 7: _price = (Open[i]+Close[i])/2; break;
  default: _price = (High[i]+Low[i])/2; break;
  }

}
datetime lasttime = NULL;
int start()
{

int i;
int barras;
if ((lasttime != NULL ) && ((Time[0] - lasttime) < Period( ) )) return;
lasttime = Time[0];
SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,3);
  SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,3);

barras = Bars;
if (Mode_Fast)
  barras = 100;
i = 0;
while(i<barras)
  {
  getprice0(i);
// Value = 0.33*2*((_price-MinL)/(MaxH-MinL)-0.5) + 0.67*Value1;  
  Value = (1-lwei)*2*((_price-MinL)/(MaxH-MinL)-0.5) + lwei*Value1;  
  Value=MathMin(MathMax(Value,-0.999),0.999);
  Fish = 0.5*MathLog((1+Value)/(1-Value))+0.5*Fish1;

   
  buffer10[i] = EMPTY_VALUE;
  buffer20[i] = EMPTY_VALUE;

  if ( (Fish<0) && (Fish1>0))
  {
  buffer10[i] = Low[i];

  }  
  if ((Fish>0) && (Fish1<0))
  { buffer20[i] = High[i];

  }   
  Value1 = Value;
  Fish2 = Fish1;
  Fish1 = Fish;
i++;
  }
return(0);
}
//+------------------------------------------------------------------+




EA文件: 存为你喜欢的名字

CODE:


//+------------------------------------------------------------------+
//|                           Designed by OKwh, China   |
//|                   Copyright 2006, OKwh |
//|                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2006, OKwh "
#property link     ""
#define MAGICMA 200610011231
//本程序适合200603-04-05, 07-08

extern int whichmethod = 3;//1;//4;   //1~4 select no T/P no S/L,has T/P no S/L, no T/P has S/L, has T/P has S/L,
extern double TakeProfit = 51;//104;   //point 方法2时无效
extern   double StopLoss = 20;//25;   //point
extern double Lots = 1;     // default lots
extern double MaximumRisk     = 0.3;   //0.1,or 0.8   0.3
extern double DecreaseFactor   = 8; // factor if many lose 8* 3 5
extern double TrailingStop =13;//10~14 15;// 60;   // T/S

extern   int maxOpen = 4;//3;   //最多持仓限制 3* 10,9,8,6,5
extern   int maxLots = 5;   //最多单仓限制 7* 5 3 1
extern int trdTime = 2; //1 //0 一次,1 2次, 2,3次

extern int bb = 1;
datetime lasttime = NULL;
int i, res;
int init()   {     return(0); }
int deinit() {   return(0); }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                           |
double LotsOptimized()  
{
double lot=Lots;
int   orders=HistoryTotal();   // history orders total
int   losses=0;             // number of losses orders without a break
// if (AccountBalance() < 8000)     MaximumRisk = 0.1;
// else MaximumRisk = 0.3;inin = 5;inin = 10;inin = 20;inin = 20;inin = 20;inin = 20;
double fm =0;
if (AccountBalance() > 200000)   fm = AccountBalance()- 100000 ;
if (AccountBalance() < 100000)   {   MaximumRisk = 0.5;   }
if (AccountBalance() < 80000)   {   MaximumRisk = 0.5; }
if (AccountBalance() < 50000)   {   MaximumRisk = 0.5; }
if (AccountBalance() < 20000)   {   MaximumRisk = 0.4; }
if (AccountBalance() < 12000)   {   MaximumRisk = 0.2;   }
fm = AccountFreeMargin();
if(AccountLeverage()<=0)
  {
    Print("CalculateVolume: invalid AccountLeverage() [",AccountLeverage(),"]");
    return(0);
  }
  double lot_min =MarketInfo(Symbol(),MODE_MINLOT);
  double lot_max =MarketInfo(Symbol(),MODE_MAXLOT);
  double lot_step=MarketInfo(Symbol(),MODE_LOTSTEP);
if(lot_min<0 || lot_max<=0.0 || lot_step<=0.0)
  {
    Print("CalculateVolume: invalid MarketInfo() results [",lot_min,",",lot_max,",",lot_step,"]");
    return(0);
  }

  lot=NormalizeDouble(fm *MaximumRisk/MarketInfo(Symbol(), MODE_MARGINREQUIRED),1);

  if(lot<0.1) lot=0.1;
if(lot>maxLots) lot=maxLots;
// if(lot<lot_min) lot=lot_min;
//   if(lot>lot_max) lot=lot_max;
return(lot);
}

void CheckForCloseBuy()
{
//LotsOptimized();
if (OrdersTotal( ) > 0 )      
{
  //下单前先检查持有的单
  for(i=OrdersTotal()-1;i>=0;i--)
  {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)     break;
    if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
  //   if (CurTime() < (OrderOpenTime()+ Period( )*gap2*60)) break ; //10倍当前时间间隔,才可去判断是否结束或更新
  if(OrderType()==OP_BUY)
  { //if (false == OrderClose(OrderTicket(),OrderLots(),Bid,3,White)) Sleep(5000);
  OrderClose(OrderTicket(),OrderLots(),Bid,3,White); Sleep(5000);
  }
  }
}
}

void CheckForCloseSel()
{
//LotsOptimized();
if (OrdersTotal( ) > 0 )      
{
  //下单前先检查持有的单
  for(i=OrdersTotal()-1;i>=0;i--)
  {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)     break;
    if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
  // if (CurTime() < (OrderOpenTime()+ Period( )*gap2*60)) break ; //10倍当前时间间隔,才可去判断是否结束或更新
    if(OrderType()==OP_SELL)
    {
    //if (false == OrderClose(OrderTicket(),OrderLots(),Ask,3,White))   Sleep(5000);
    OrderClose(OrderTicket(),OrderLots(),Ask,3,White);   Sleep(5000);
    }
  }
}
}



extern int period=81;//79;//76;//10;
extern int price=5;//6; // 0 or other = (H+L)/2
            // 1 = Open
            // 2 = Close
            // 3 = High
            // 4 = Low
            // 5 = (H+L+C)/3
            // 6 = (O+C+H+L)/4
            // 7 = (O+C)/2
extern double lwei=0.69;// 0.67;//0.74;//0.67;
extern int pos = 1;
int ZigJuge()
{
double x,y;


x= iCustom(NULL,0,"0meme",period,price,lwei,0,pos);
y= iCustom(NULL,0,"0meme",period,price,lwei,1,pos);
  if ((y != EMPTY_VALUE))//1上穿2
{
//Print ("last = ",iCustom(NULL,0,"1LineCro1EA",9,3,3,17,1,9,21,17,5,5,0), " x= ",x, " y= ",y);
  return (-1);// setBuy(i);
    }
if ((x != EMPTY_VALUE))//1上穿2
{
//Print ("last = ",iCustom(NULL,0,"1LineCro1EA",9,3,3,17,1,9,21,17,5,5,0), " x= ",x, " y= ",y);
  return (1);// setBuy(i);
  }

return (0);

}
int nowZigJuge = 0;
void CheckForOpen()
{
if ((lasttime != NULL ) && ((Time[0] - lasttime) < Period( ) )) return;
lasttime = Time[0];
nowZigJuge = ZigJuge();
if (nowZigJuge == 1) //买//上穿买 先结束卖的
      CheckForCloseSel();
if (nowZigJuge == -1) //卖//下穿卖 先结束买的
CheckForCloseBuy();

if (TimeDayOfWeek(CurTime()) == 1)
  {
  if (TimeHour(CurTime()) < 3 ) return;//周一早x8点前不做
  }
  if (TimeDayOfWeek(CurTime()) == 5)
  {
  if (TimeHour(CurTime()) > 19 ) return;//周五晚x11点后不做中国时间
  }

if (((Ask-Bid)/Point)> 5) return ; //如果市场剧烈动荡,不做

if (OrdersTotal( ) >= maxOpen) return ;   //如果已持有开仓数达到,不做

  TradeOK();

if (OrdersTotal( ) >= maxOpen) return ;   //如果已持有开仓数达到,不做
TradeOK();

if (trdTime==2)
{
if (OrdersTotal( ) >= maxOpen) return ;   //如果已持有开仓数达到,不做
TradeOK();

if (OrdersTotal( ) >= maxOpen) return ;   //如果已持有开仓数达到,不做
TradeOK();
}

}
void TradeOK()
{
int error ;
if (nowZigJuge == 1) //买//上穿买 先结束卖的
// if (PriLiv() == 1) //买//上穿买 先结束卖的
  {

  // if (iOpen(NULL,PERIOD_H4,1)>iClose(NULL,PERIOD_H4,1)) return;
    switch (whichmethod)
    {
    case 1:   res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break;
    case 2:   res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,0,"",MAGICMA,0,Blue);   break;
    case 3:   res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break;
    case 4:   res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break;
    default : res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break;
    }
    if (res <=0)
    {
    error=GetLastError();
    if(error==134)Print("Received 134 Error after OrderSend() !! ");         // not enough money
    if(error==135) RefreshRates();   // prices have changed
    }
    Sleep(5000);
    return ;  
  }

if (nowZigJuge == -1) //卖//下穿卖 先结束买的
// if (PriLiv() == -1) //买//上穿买 先结束卖的
  {
//   if (iOpen(NULL,PERIOD_H4,1)<iClose(NULL,PERIOD_H4,1)) return;
    switch (whichmethod)
    {
    case 1:   res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break;
    case 2:   res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,0,"",MAGICMA,0,Red);     break;
    case 3:   res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break;
    case 4:   res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break;
    default : res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break;
    }
    if (res <=0)
    {
    error=GetLastError();
    if(error==134) Print("Received 134 Error after OrderSend() !! ");         // not enough money
    if(error==135) RefreshRates();   // prices have changed
    }
    Sleep(5000);
    return ;  
  }


}

void CTP()   //固定10点止赢
{
// Print("into CTP");
bool bs = false;
for (int i = 0; i < OrdersTotal(); i++)
{
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)     break;
  if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
  //   if (CurTime() < (OrderOpenTime()+ Period( )*gap2*2*60)) continue ;
  if (OrderType() == OP_BUY)
  {
    if (Bid - OrderOpenPrice() > TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))
    {
    if (OrderStopLoss() < Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))
    {

      bs = OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Green);
      // Print("into CTP buy ", bs);
    }
    }
  }
  else if (OrderType() == OP_SELL)
  {
    if (OrderOpenPrice() - Ask > TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))
    {
    if ((OrderStopLoss() > Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)) ||
      (OrderStopLoss() == 0))
    {   
      bs = OrderModify(OrderTicket(), OrderOpenPrice(),
        Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Tan);
    //   Print("into CTP Sell", bs);
}
    }
  }
}
}

//| expert start function                             |
//+------------------------------------------------------------------+
int start()
{
CheckForOpen();
if (bb==1)     CTP();   //bb ==1 跟踪
return(0);
}
//+------------------------------------------------------------------+[/code]

页: [1]