[转载]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]