ea/martine.mq4 at master · Goleo8/ea
2018-03-05 22:23:55 Author: github.com(查看原文) 阅读量:64 收藏

//可以调整参数:EAType:决定是否单向开仓|起始手数0.02 or 0.05|加仓间距100 or 150|isSafeMode:向下取整
//1.同时开多单和空单的EA
//2.程序可以初始化
//3.200点顺势平仓
//4.追踪止损
//5.处理跳空|Fix跳空bug
//6.多空分开处理
//7.安全模式1.5倍时向下取整
//8.加上顺势加强逻辑震荡超过0.9手趋势初始仓位为0.05
//9.可以挂多个货币对
//10.跳空方法处理扛单问题——rollback无法解决问题
//11.加上了逻辑
//Modification:
//1. only open one direction
//2. close position when detect there is an 0.01 order opened in opposite direction
int minTrailingStop=10; //初始化追踪止损点数
int maxTrailingStop=50; //最大追踪止损点数
int deltaPoint=10; //用来覆盖手续费
//Tuning Parameters EA调整是可以调整的参数
bool isAggressive=False; //when order number is illegal like 0.013, whether use math.floor or math.ceiling
double initialisedOrderCount=0.02; //起始仓位大小
double orderIncreaseFactor=1.5; //加仓倍数
int increaseOrderDeltaStep=150; //间隔多少点加仓
int pointToCloseAntiTrendOrder=deltaPoint+increaseOrderDeltaStep/(orderIncreaseFactor-1);//多少点平掉震荡型仓位
int pointToCloseTrendOrder=200; //多少点平掉趋势型仓位
//Final Parameters
double minOrderNumber=0.01;//The minimum order number allowed by platform
int jumpUpFactor=3;
int placeOrderDelta=5;
double increaseTrendThreshold=0.9;
int enlargedInitialisedOrderFactor=5;
//EA Parameters
bool isInitialised=False;
int valueOfLastBuyOrder=0;
int valueOfLastSellOrder=0;
int currentAskValue=0;
int currentBidValue=0;
double numberOfLastBuyOrder=0.0;
double numberOfLastSellOrder=0.0;
ulong buyOrderIdArray[100];//Hold order ticket
int buyOrderIdArrayIndex=0;
ulong sellOrderIdArray[100];
int sellOrderIdArrayIndex=0;
bool isAutoPlaceOrder=True;
bool isBuyIsTrend=True;
bool isSellIsTrend=True;
int orderDirection=0; //1 means long and -1 means short 0 means both direction
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick(void)
{
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external
// variables (Lots, StopLoss, TakeProfit,
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
if(Bars<100)
{
Print("bars less than 100");
return;
}
if(!isInitialised)
{
initialise();
}
int cnt=OrdersTotal()-1;
int totalBuyOrders=0;
int totalSellOrders=0;
isAutoPlaceOrder=True;
for(;cnt>=0;cnt--)
{
if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
Print("Cannot select ",cnt+1," order!");
continue;
}
else
{
if(OrderType()==OP_BUY&&OrderSymbol()==Symbol())
totalBuyOrders++;
if(OrderType()==OP_SELL&&OrderSymbol()==Symbol())
totalSellOrders++;
if((OrderType()==OP_BUYLIMIT||OrderType()==OP_SELLLIMIT)&&OrderSymbol()==Symbol())
{
isAutoPlaceOrder=False;
Print("Order Type: ",OrderType());
Print("Close autoplace order");
}
}
}
Print("Autoplace order",isAutoPlaceOrder);
if(totalBuyOrders!=0)
{
processor(OP_BUY);
}
if(totalSellOrders !=0)
{
processor(OP_SELL);
}
if(totalBuyOrders==0&&isLongDirection()&&isAutoPlaceOrder)
{
buyOrderIdArrayIndex=0;
isBuyIsTrend=True;
placeOrder(OP_BUY,initialisedOrderCount);
}
if(totalSellOrders==0&&isShortDirection()&&isAutoPlaceOrder)
{
sellOrderIdArrayIndex=0;
isSellIsTrend=True;
placeOrder(OP_SELL,initialisedOrderCount);
}
}
bool isLongDirection()
{
if(orderDirection==1||orderDirection==0)
return True;
else
return False;
}
bool isShortDirection()
{
if(orderDirection==-1||orderDirection==0)
return True;
else
return False;
}
double adjustOrderCount(double lots)
{
double tmpLots=lots/minOrderNumber;
if(isAggressive)
return MathCeil(tmpLots)*minOrderNumber;
else
return MathFloor(tmpLots)*minOrderNumber;
}
void placeOrder(int orderType,double lots)
{
double tmpLots=lots/minOrderNumber;
lots=MathFloor(tmpLots)*minOrderNumber;
int ticket;
ticket=OrderSend(Symbol(),orderType,NormalizeDouble(lots,2),orderType==OP_BUY?Ask:Bid,3,0,0,"dl combine sample",16384,0,orderType==OP_BUY?Red:Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
if(orderType==OP_BUY)
{
Print("Buy order opened : ",OrderOpenPrice());
valueOfLastBuyOrder=OrderOpenPrice()/Point();
numberOfLastBuyOrder=OrderLots();
buyOrderIdArray[buyOrderIdArrayIndex]=ticket;
buyOrderIdArrayIndex++;
}
else if(orderType==OP_SELL)
{
Print("Sell order opened : ",OrderOpenPrice());
valueOfLastSellOrder=OrderOpenPrice()/Point();
numberOfLastSellOrder=OrderLots();
sellOrderIdArray[sellOrderIdArrayIndex]=ticket;
sellOrderIdArrayIndex++;
}
}
else
{
Print("Log: Cannot get the exist order!",Symbol());
return;
}
}
}
void processor(int orderType)
{
double orderCount = initialisedOrderCount;
int delta;
currentAskValue=Ask/Point();
currentBidValue=Bid/Point();
if(orderType==OP_BUY)
{
delta=currentAskValue-valueOfLastBuyOrder;
if(isBuyIsTrend&&(currentBidValue-valueOfLastBuyOrder)>pointToCloseTrendOrder)
{
closeAllOrders(buyOrderIdArray,OP_BUY);
if(numberOfLastSellOrder>increaseTrendThreshold)
{
orderCount=initialisedOrderCount*enlargedInitialisedOrderFactor;
}
placeOrder(OP_BUY,orderCount);
}
else if(delta<0&&MathAbs(delta)>increaseOrderDeltaStep&&MathAbs(delta)<increaseOrderDeltaStep+placeOrderDelta)
{
placeOrder(OP_BUY,numberOfLastBuyOrder*orderIncreaseFactor);
isBuyIsTrend=False;
}
else if(delta<0&&MathAbs(delta)>increaseOrderDeltaStep*jumpUpFactor)
{
double jumpGap=MathAbs(delta);
double tmpOrderIncreaseFactor=orderIncreaseFactor;
while(jumpGap/(double)increaseOrderDeltaStep>=1)
{
tmpOrderIncreaseFactor+=orderIncreaseFactor;
jumpGap=jumpGap-increaseOrderDeltaStep;
}
placeOrder(OP_BUY,numberOfLastBuyOrder*tmpOrderIncreaseFactor);
isBuyIsTrend=False;
}
if(!isBuyIsTrend&&(Bid/Point()-valueOfLastBuyOrder>pointToCloseAntiTrendOrder+minTrailingStop))
{
int tmpTrailingStop=MathMax((Bid/Point()-valueOfLastBuyOrder-pointToCloseAntiTrendOrder),minTrailingStop);
tmpTrailingStop=MathMin(tmpTrailingStop,maxTrailingStop);
modifyAllOrders(buyOrderIdArray,OP_BUY,tmpTrailingStop);
}
}
else if(orderType==OP_SELL)
{
delta=currentBidValue-valueOfLastSellOrder;
if(isSellIsTrend&&(valueOfLastSellOrder-currentAskValue)>pointToCloseTrendOrder)
{
closeAllOrders(sellOrderIdArray,OP_SELL);
if(numberOfLastBuyOrder>increaseTrendThreshold)
{
orderCount=initialisedOrderCount*enlargedInitialisedOrderFactor;
}
placeOrder(OP_SELL,orderCount);
}
else if(delta>increaseOrderDeltaStep&&delta<increaseOrderDeltaStep+placeOrderDelta)
{
placeOrder(OP_SELL,numberOfLastSellOrder*orderIncreaseFactor);
isSellIsTrend=False;
}
else if(delta>increaseOrderDeltaStep*jumpUpFactor)
{
jumpGap=MathAbs(delta);
tmpOrderIncreaseFactor=orderIncreaseFactor;
while(jumpGap/increaseOrderDeltaStep>1)
{
tmpOrderIncreaseFactor+=orderIncreaseFactor;
jumpGap=jumpGap-increaseOrderDeltaStep;
}
placeOrder(OP_SELL,numberOfLastSellOrder*tmpOrderIncreaseFactor);
isSellIsTrend=False;
}
if(!isSellIsTrend&&(valueOfLastSellOrder-Ask/Point()>pointToCloseAntiTrendOrder+minTrailingStop))
{
tmpTrailingStop=MathMax((valueOfLastSellOrder-Ask/Point()-pointToCloseAntiTrendOrder),minTrailingStop);
tmpTrailingStop=MathMin(tmpTrailingStop,maxTrailingStop);
modifyAllOrders(sellOrderIdArray,OP_SELL,tmpTrailingStop);
}
}
}
void closeAllOrders(ulong &orderIdArray[],int orderType)
{
int cnt;
int index=(orderType==OP_BUY)?buyOrderIdArrayIndex:sellOrderIdArrayIndex;
for(cnt=0;cnt<index;cnt++)
{
ulong orderId=orderIdArray[cnt];
if(!OrderSelect(orderId,SELECT_BY_TICKET,MODE_TRADES))
{
Print("Cannot select ",orderId," order!");
continue;
}
else
{
if(OrderType()==OP_BUY)
if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
Print("OrderClose error ",GetLastError());
if(OrderType()==OP_SELL)
if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))
Print("OrderClose error ",GetLastError());
}
}
if(orderType==OP_BUY)
{
buyOrderIdArrayIndex=0;
}
else if(orderType==OP_SELL)
{
sellOrderIdArrayIndex=0;
}
}
void modifyAllOrders(ulong &orderIdArray[],int orderType,int tmpTrailingStop)
{
int cnt;
int index=(orderType==OP_BUY)?buyOrderIdArrayIndex:sellOrderIdArrayIndex;
for(cnt=0;cnt<index;cnt++)
{
ulong orderId=orderIdArray[cnt];
if(!OrderSelect(orderId,SELECT_BY_TICKET,MODE_TRADES))
{
Print("Cannot select ",orderId," order!");
continue;
}
else
{
if(OrderType()==OP_BUY)
if(OrderStopLoss()<Bid-Point*tmpTrailingStop)
{
if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*tmpTrailingStop,OrderTakeProfit(),0,Red))
Print("OrderModify error ",GetLastError());
}
if(OrderType()==OP_SELL)
if((OrderStopLoss()>(Ask+Point*tmpTrailingStop))|| (OrderStopLoss()==0))
{
if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*tmpTrailingStop,OrderTakeProfit(),0,Green))
Print("OrderModify error ",GetLastError());
}
}
}
}
void initialise()
{
int cnt=OrdersTotal()-1;
for(;cnt>=0;cnt--)
{
if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
Print("Cannot select ",cnt+1," order!");
continue;
}
else
{
if(OrderType()==OP_BUY && OrderSymbol()==Symbol())
{
double buyOrderLots=OrderLots();
if(buyOrderLots>numberOfLastBuyOrder)
{
numberOfLastBuyOrder=buyOrderLots;
valueOfLastBuyOrder=OrderOpenPrice()/Point();
}
buyOrderIdArray[buyOrderIdArrayIndex]=OrderTicket();
buyOrderIdArrayIndex++;
}
if(OrderType()==OP_SELL && OrderSymbol()==Symbol())
{
double sellOrderLots=OrderLots();
if(sellOrderLots>numberOfLastSellOrder)
{
numberOfLastSellOrder=sellOrderLots;
valueOfLastSellOrder=OrderOpenPrice()/Point();
}
sellOrderIdArray[sellOrderIdArrayIndex]=OrderTicket();
sellOrderIdArrayIndex++;
}
}
}
if(buyOrderIdArrayIndex>2)
{
isBuyIsTrend=False;
}
if(sellOrderIdArrayIndex>2)
{
isSellIsTrend=False;
}
isInitialised=True;
}

文章来源: https://github.com/Goleo8/ea/blob/master/martine.mq4
如有侵权请联系:admin#unsafe.sh