乐于分享
好东西不私藏

一款双向加仓策略EA源码

一款双向加仓策略EA源码

今天是准备继续发布一些以前的源码,今天是一款双向加仓策略的EA,具体是这样的:典型的双向网格马丁格尔策略,通过同时持有多空双向订单、在价格波动中不断加仓,最终利用整体浮盈达到目标后一键平仓来获利

一、策略核心玩法

初始开仓

当没有任何订单时,EA会同时开出一张多单和一张空单(手数=初始手数,如0.01),形成对冲底仓。

双向加仓规则

多单加仓:当Ask价格 – 最后一笔多单开仓价 >= 加仓间距时,且当前多单数量 ≤ 空单数量+1(差值<2),则加仓多单。

空单加仓:当最后一笔空单开仓价 – Bid价格 >= 加仓间距时,且当前空单数量 ≤ 多单数量+1,则加仓空单。

加仓手数 = 上一轮手数 × 加仓倍数(如1.2倍),并受“最大手数”限制。

整体止盈

实时计算所有持仓订单的总浮动盈亏(多空盈亏对冲后的净值)。一旦该值 ≥ 整体止盈金额(如40美元),立即全部平仓,完成一轮交易循环。

风险控制

限制多空订单数量差 ≤ 2,避免单方向过度暴露。

最大手数封顶,防止无限倍增。

每次加仓间距固定(200小点),确保加仓节奏清晰。

EA做单有风险,不可商用

当然,不会编译的可以联系我

源码:

#property copyright "华尔街狼人ea"#property link      ""#property version   "1.10"#property strict//授权开始#define 有效结束时间 "2123.03.20"//结束时间限制#define 有效账号 0  //使用账号限制//+------------------------------------------------------------------+//| Expert initialization function                                   |//+------------------------------------------------------------------+input int Magic = 118;input double     初始手数=0.01;input int        加仓间距=200//加仓间距(小点)input double     加仓倍数=1.2;    input double     最大手数=1;input int        整体止盈金额=40;intOnInit()  {   return(INIT_SUCCEEDED);  }//+------------------------------------------------------------------+//| Expert deinitialization function                                 |//+------------------------------------------------------------------+voidOnDeinit(constint reason)  {//---  }intgetSumOrders(int type){   int orders = 0;   for(int i=OrdersTotal()-1;i>=0;i--)   {      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))      {       if (OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue;       if(OrderType()==type || type == 2)       {         orders+=1;       }      }      else      {         i=OrdersTotal()-1;      }   }   return orders;}doublegetSumProfit(int type){   double profit = 0;   for(int i=OrdersTotal()-1;i>=0;i--)   {      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))      {       if (OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue;       if (OrderType()<=1)       {          if(OrderType()==type || type == 2)          {            profit+=OrderProfit();          }       }      }      else      {         i=OrdersTotal()-1;      }   }   return profit;}voidcheckToOpen(){   double sl,tp;   int ret;   sl = 0;   tp = 0;   if((ret=OrderSend(Symbol(),OP_BUY,初始手数,Ask,10,sl,tp,"首单多*1",Magic,0,clrRed))<0)   {      Print(Symbol()+"做多OpenErr:",GetLastError()," bid=",Bid," ask=",Ask," lot=",初始手数);   }   else   {      int errCnt=0;      while(true)      {         ret=OrderSend(Symbol(),OP_SELL,初始手数,Bid,10,sl,tp,"首单空*1",Magic,0,clrLime);         if (ret>0         {            break;         }         else         {            errCnt++;            Print(Symbol()+"做空OpenErr:",GetLastError()," bid=",Bid," ask=",Ask," lot=",初始手数);            if (errCnt>=100)            {               Alert("开仓失败,先退出程序,请检查!");               AllClose();               ExpertRemove();               break;            }            Sleep(100);         }      }         }}boolgetLastOrderInfo(double& lastBuyPrice,double& lastSellPrice,int& lastBuyCnt,int& lastSellCnt){      lastBuyPrice = 0;   lastSellPrice = 0;   lastBuyCnt = 0;   lastSellCnt = 0;   string retStr[5];   for(int i=OrdersTotal()-1;i>=0;i--)   {      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))      {       if (OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue;       if (lastBuyCnt<=0)       {          if (OrderType()==OP_BUY)          {             lastBuyPrice = OrderOpenPrice();             StringSplit(OrderComment(),'*',retStr);             lastBuyCnt = (int)StringToInteger(retStr[1]);          }       }       if (lastSellCnt<=0)       {          if (OrderType()==OP_SELL)          {             lastSellPrice = OrderOpenPrice();             StringSplit(OrderComment(),'*',retStr);             lastSellCnt = (int)StringToInteger(retStr[1]);          }       }      }      else      {         i=OrdersTotal()-1;      }   }   return true;}voidcheckToAdd(){   int ret;   double lastBuyPrice;   double lastSellPrice;   int lastBuyCnt;   int lastSellCnt;   double addLot;   getLastOrderInfo(lastBuyPrice, lastSellPrice, lastBuyCnt, lastSellCnt);   double lotStep = MarketInfo(NULL,MODE_LOTSTEP);   //printf("Bid:%f %f %d %f %f %f %d",Bid,lastBuyPrice,lastBuyCnt,加仓间距*Point(),Ask,lastSellPrice,lastSellCnt);        if(NormalizeDouble(Ask - lastBuyPrice,Digits)>=加仓间距*Point())   {      if (lastBuyCnt-lastSellCnt>=2)      {         return;      }      addLot = (int)(MathPow(加仓倍数,(lastBuyCnt))*初始手数/lotStep)*lotStep;      if (addLot >= 最大手数)      {         addLot = 最大手数;      }      if((ret=OrderSend(Symbol(),OP_BUY,addLot,Ask,5,0,0,"加仓买*"+IntegerToString(lastBuyCnt+1),Magic,0,clrRed))<0)      {         printf("Fail to buy:%f,%d",addLot,GetLastError());      }        }   if(NormalizeDouble(lastSellPrice-Bid,Digits)>=加仓间距*Point())   {      if (lastSellCnt-lastBuyCnt>=2)      {         return;      }      addLot = (int)(MathPow(加仓倍数,(lastSellCnt))*初始手数/lotStep)*lotStep;      if (addLot >= 最大手数)      {         addLot = 最大手数;      }      if((ret=OrderSend(Symbol(),OP_SELL,addLot,Bid,5,0,0,"加仓卖*"+IntegerToString(lastSellCnt+1),Magic,0,clrLime))<0)      {         printf("Fail to sell:%f,%d",addLot,GetLastError());      }        }   return;}voidOnTick(){   if(TimeCurrent()>=StringToTime(有效结束时间)) 	{   	Alert("使用期限已到!");    	return;	}	if (有效账号!=0 && AccountInfoInteger(ACCOUNT_LOGIN)!=有效账号)	{	   Alert("无效账户!"); 	   return;	int orderCnt=0;   checkClose();   orderCnt=getSumOrders(2);   if (orderCnt == 0)      {      checkToOpen();   }   else   {      checkToAdd();   }   }voidAllClose(){   for(int i=OrdersTotal()-1;i>=0;i--)   {      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))      {         if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic)         continue;         if(OrderType()<=1)         {            if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),300,clrGray))            {               Print("close erro:"GetLastError());               i = OrdersTotal() - 1;            }         }         else          {            if(!OrderDelete(OrderTicket()))            {               Print("delete erro");               i = OrdersTotal() - 1;            }         }      }      else      {         i = OrdersTotal() - 1;      }   }}boolcheckClose(){      double sumProfit;   sumProfit = getSumProfit(2);   if (sumProfit >= 整体止盈金额)   {      AllClose();   }      return true;}