网格制作者1.1 - 页 4

 
对不起,我对任何给定的网格位置只有一个订单,而且我已经测试了几乎所有的变化--超过几个星期。

我偶尔会删除所有未结订单,这样我们的MT4朋友就不会不高兴了。

,你在回测中会遇到这个问题,但这不是一个脚本问题,而是一个MT4回测 问题。

如果它继续下去,请让我知道或给我发送一些显示问题的报告...

谢谢和回复,

hugues
 
我已经发现了它。我对这个问题感到不高兴。

顾问用我给的注释 "GridEURUSD "创建网格。只要订单在等待,这个评论就会出现在评论栏里。如果订单被激活,评论将变为 "激活/自动"。很明显,这种行为导致了所描述的问题。

我在Alpari交易。他们在模拟账户 中支持MT4

我将检查,如果我可以绕过这种行为,即使用订单的魔法作为网格的标识符,并让你知道结果。

在测试的同时,我也对网格的清理脚本进行了修改。我也增加了关闭未结订单的功能。不幸的是,如果我试图关闭一个未结订单,我得到了错误129,这意味着订单被锁定。但它却删除了给定网格的所有挂单。

//+------------------------------------------------------------------+ //| RemoveGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" extern string GridName = "Grid"; extern bool closeOpen = false; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { #property show_inputs // displays the parameters - thanks Slawa... 

//---- int total = OrdersTotal(); int i ; for(i=total-1; i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if ( OrderSymbol()==Symbol() && OrderComment() == GridName ) { bool result = false; switch(type) { case OP_BUY :if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Ask, 0, Blue ) ; } break; case OP_SELL :if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Bid, 0, Blue ); } break; //Close pending orders case OP_BUYLIMIT : result = OrderDelete( OrderTicket() ) ; break; case OP_BUYSTOP :result = OrderDelete( OrderTicket() ); break; case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); break; case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); break; } if(result == false) { Print( "Order " , OrderTicket() , " failed to close.Error:" , GetLastError() ); // Sleep(3000); }  
        } //---- return(0); } //+------------------------------------------------------------------+




cori

 
好的,科里,谢谢...

让我知道它是否起作用,我将使用这个魔法......因为我不知道经纪人会做这样的怪事!!!。

谢谢和问候。

胡戈斯
 
现在,就这样了。

我已经把gridMaker改成了使用OrderMagicNumber而不是注释。我还做了一些关于建立注释的小修改。

下面是结果。

//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.4beta" // modified by cori.使用OrderMagicNumber来识别网格的交易 extern int uniqueGridMagic = 11111; // 交易的魔法号码。必须是唯一的,以识别//一个网格的交易 extern double Lots = 0.1; // extern double GridSize = 6; // pips between orders - grid or mesh size extern double GridSteps = 12; // total number of orders to place extern double TakeProfit = 6 ; // number of ticks to take profit. 通常是=网格大小,但是你可以覆盖 extern double StopLoss = 0; // if you want to add a stop loss.正常的网格不使用止损,外部 double UpdateInterval = 1; // 每x分钟更新一次订单 外部 bool wantLongs = true; // 我们是否需要多头头寸 外部 bool wantShorts = true; // 我们是否需要空头头寸 外部 bool wantBreakout = true;       羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true; // 羊毛羊毛 = true仅限内部变量 double LastUpdate = 0; // 用于记录最后一次更新时间的计数器 double GridMaxOpen = 0; // 最大开仓数 string GridName = "Grid"; // 标识网格。允许几个共存的网格 //+------------------------------------------------------------------+ //| 专家初始化函数 | //+------------------------------------------------------------------+ int init() { //---- #属性 show_inputs // 显示参数 - 谢谢 Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- GridName = StringConcatenate( "Grid", Symbol() ) ; return(0);
  } //+------------------------------------------------------------------------+ //|测试在atRate区域是否有未结头寸或订单|//|如果checkLongs为真,将检查长线,否则将检查|//|短线|//+------------------------------------------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal(); for(int j=0;j<totalorders;j++) // 扫描所有订单和头寸。... { OrderSelect(j, SELECT_BY_POS); // 由cori修改。使用OrderMagicNumber来识别网格的交易 if ( OrderSymbol()==Symbol() && OrderMagicNumber() == uniqueGridMagic )  //只看mygrid和符号...... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) //不看确切的价格,但价格接近(小于网格大小) { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) { return(true); } } } 

   return(false); } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // we update the first time it is called and every UpdateInterval minutes { LastUpdate = CurTime();
   Print("Updating"); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // 取整为可被GridSize划分的点数 k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point 。          //计算最低进入点 double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && ( !limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false )           // 测试我是否有接近我的价格的未结订单:如果有,就放一个 { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              否则 { entermode = OP_BUYLIMIT ; } 
              
              如果((traderate > Ask ) && (wantBreakout))|| ((traderate <= Ask ) && (wantCounter)) ) 

              { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize, false)== false )           //测试我是否有接近我的价格的未平仓订单:如果有,就放一个 { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              否则 { entermode = OP_SELLSTOP ; } 
              
              如果 ( ( (traderate < Bid ) && (wantBreakout) )|| ((traderate >= Bid ) && (wantCounter)) ) 
               { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+



致以敬意,科里

 
谢谢 Cori...

因为我自己已经做了一些改动,所以我把你的改动整合到了较新的版本中。

我做了一个小小的改动:为了保持我当前的网格处于活动状态,我在magic OR gridname上做了一个测试......

,你能检查一下 我的做法是否正确吗?



//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.6beta" // modified by cori.使用OrderMagicNumber来识别网格的交易 extern int uniqueGridMagic = 11111; // 交易的魔法号码。必须是唯一的,以识别//一个网格的交易 extern double Lots = 0.1; // extern double GridSize = 6; // pips between orders - grid or mesh size extern double GridSteps = 12; // total number of orders to place extern double TakeProfit = 12 ; // number of ticks to take profit. 通常是=网格大小,但你可以覆盖 extern double StopLoss = 0; // if you want to add a stop loss.正常的网格不使用止损,外部 double UpdateInterval = 1; // 每x分钟更新一次订单 外部 bool wantLongs = true; // 我们是否需要多头头寸 外部 bool wantShorts = false; // 我们是否需要空头头寸 外部 bool wantBreakout = true;     //我们是否需要高于价格的多头,低于价格的空头 extern bool wantCounter = true; //我们是否需要低于价格的多头,高于价格的空头 extern bool limitEMA34 = true; //我们是否需要仅高于ema的多头,仅低于ema的空头 extern double GridMaxOpen = 0; //最大开仓数:还没有实现。外部 bool UseMACD = true; // 如果为真,只对多头使用macd >0,只对空头使用macd >0 // 在交叉点上,将取消所有挂单。外部 bool CloseOpenPositions = false;// 如果 UseMACD,我们是否也要关闭亏损的未平仓头寸?允许几个并存的网格 double LastUpdate = 0; // 用于记录最后更新时间的计数器 //+------------------------------------------------------------------+ //| 专家初始化函数 | //+------------------------------------------------------------------+ int init() { //---- #属性 show_inputs // 显示参数 - 谢谢 Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- // 添加了我的corri,被hdb删除了!!笑了。只是为了与开放网格保持兼容。
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| 测试在atRate区域是否有未结头寸或订单 | //| 如果checkLongs为真将检查多头,否则将检查 | //| 短头 | /+------------------------------------------------------------------------+ bool IsPosition( double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal( ) 。
     for(int j=0;j<totalorders;j++) // 扫描所有订单和仓位。... { OrderSelect(j, SELECT_BY_POS); // 由cori修改。使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看mygrid和符号...... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) //不看确切的价格,而是看价格的接近程度(小于网格大小) { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) { return(true); } } } 
   return(false); } //+------------------------------------------------------------------------+ //|取消所有挂单 | //+------------------------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) //扫描所有订单和头寸... { OrderSelect(j, SELECT_BY_POS); //按照cori修改。使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看mygrid和符号的情况。
         { int type = OrderType(); bool result = false; switch(type) { case OP_BUY : result = true ; case OP_SELL : result = true ; //close pending orders case OP_BUYLIMIT :result = OrderDelete( OrderTicket() ); case OP_BUYSTOP : result = OrderDelete( OrderTicket() ); case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); case OP_SELLSTOP : result = OrderDelete( OrderTicket( ) ); } } } 
   return; } //+------------------------------------------------------------------------+ //|取消所有挂单并关闭未结头寸 | //+------------------------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // modified by cori.使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看是否有mygrid和符号...
     { // Print("Closing 2",type); switch(type) { //Close opened long positions case OP_BUY : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ) ; break; //Close opened short positions case OP_SELL :result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); break; //Close pending orders case OP_BUYLIMIT : case OP_BUYSTOP :
           case OP_SELLLIMIT : case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); } } if(result == false) { // Alert("Order " , OrderTicket() , " failed to close.错误:" , GetLastError() ); // Sleep(3000); } return; } //+。  
  } return; } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // we update the first time it is called and every UpdateInterval minutes { LastUpdate = CurTime() ;
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // 取整为可被GridSize划分的点数 k = startrate ; k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ; //计算最低进入点 double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0) 。
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // cross up { CloseAllPendingOrders() 。
         if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // cross down { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders();} wantLongs = false; wantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0) //远高于零 { wantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0) //远低于零 { wantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false )           // 测试我是否有接近我的价格的未结订单:如果有,就放一个 { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              否则 { entermode = OP_BUYLIMIT ; } 
              如果((traderate > Ask ) && (wantBreakout))|| ((traderate <= Ask ) && (wantCounter)) ) 
              { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize, false) == false )           //测试我是否有接近我的价格的未平仓订单:如果有,就放一个 { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              否则 { entermode = OP_SELLSTOP ; } 
              
              如果 ( ( (traderate < Bid ) && (wantBreakout) )|| ((traderate >= Bid ) && (wantCounter)) ) 
                { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+
 
嗨,hdb,

,似乎可以。但你应该把GridName定义为extern,我改了,因为我不需要它作为参数

greetings, cori
 
注意所有GridMaker的用户--在函数 IsPosition中存在一个错误--其结果是,并非所有的网格槽都被填满。

你可以改变这一行:

if (MathAbs( OrderOpenPrice() - atRate ) < inRange) //不寻找确切的价格,但价格接近(小于网格大小)

to

if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9))//不寻找准确的价格,而是价格接近(小于gridsize)--因为浮动的pont错误而增加了0.9


,这样就纠正了问题。

很抱歉给您带来不便...

hugues
 
你好,hugues。

这个问题已经存在了吗?

在旧的MQL2中发现了类似的问题。

绕过这个问题的真正确定的方法是做这样的事情。

int intOOP = MathRound( OrdeOpenPrice() / Point ) 。

为你所有的双倍变量。然后你就有了所有直接的int变量,这些变量是可以比较的,没有错误。

为了保持清晰易懂,它要多写一点,但它的错误较少。

问候。

cori
 
你是对的,科里,这更优雅!只是我太懒了!

问候。
hugues
 
这里是GridMaker EA的一个更新。在这个版本中,我已经。

1)改变了UseMACD、wantLongs、wantShorts的逻辑。以前,如果设置了useMACD,EA就会做多和做空,与wnatLongs和wantShorts标志无关。现在,useMACD不会覆盖这些标志,所以你可以用useMACD只做多头或只做空头。

2) 我增加了一个额外的检查,以确保在设置limitEMA34的情况下,EMA的错误一侧没有未结订单。过去发生的情况是,订单被很好地放置在EMA之上或之下,但几个小时后,EMA移动了,所以EMA两边都有订单。

3) 在OrderType()的switch语句中似乎有一个错误,我不确定它是什么,但它的行为真的很奇怪。我简单地删除了switch语句,用 "if "代替......我不喜欢它,但它能起作用!

4) 我使EMA周期成为变量......对回溯测试 很有帮助。

如果有人需要,我还有一些配套的脚本:

1) 删除一个货币对的未完成的未结订单
2) 一次性删除所有货币对的所有未结订单
3) 平掉所有头寸并删除未结订单。
4)从未结头寸和历史记录中获得一些简单的网格行为统计。

以下是V1.08的代码:


//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //|
http://www.dubois1.net/hdb |//+------------------------------------------------------------------+ #属性版权 "Copyright © 2005, hdb" #属性链接 "http://www.dubois1.net/hdb" //#属性版本 "1.8" // 免责声明 ***** 重要提示 ***** 使用前请阅读 ***** //本专家顾问可以打开和关闭真实头寸,从而进行真实交易并损失真实资金。
// 这不是一个 "交易系统",而是一个简单的机器人,它根据固定的规则进行交易。 // 作者对这个系统的盈利能力没有任何预想,不建议使用这个EA,除了在模拟账户中进行测试。
// 在使用本程序之前,请与您的经纪人确认,他的系统是否适合与本专家相关的最频繁的交易。以前,如果你把UseMACD设置为 "true",//它就会做多头和空头,而忽略wantLongs和wantShorts的标志。 
// 现在,这些标志没有被忽略。//增加了一个循环,以检查在使用limitEMA34//标志时,是否有高于或低于EMA的 "非法 "开仓订单。这些订单随着时间的推移不断积累,并且从未被删除,这是由于EMA移动造成的。 // 删除了switch指令,因为它们似乎不起作用--用if语句代替//使EMA周期成为变量////由cori修改。使用OrderMagicNumber来识别网格的交易 extern int uniqueGridMagic = 11111; // 交易的魔法号码。必须是唯一的,以识别//一个网格的交易 extern double Lots = 0.1; // extern double GridSize = 6; // pips between orders - grid or mesh size extern double GridSteps = 12; // total number of orders to place extern double TakeProfit = 12 ; // number of ticks to take profit. 通常是=网格大小,但你可以覆盖 extern double StopLoss = 0; // if you want to add a stop loss.正常的网格不使用止损,外部 double UpdateInterval = 1; // 每x分钟更新一次订单 外部 bool wantLongs = true; // 我们是否需要多头头寸 外部 bool wantShorts = true; // 我们是否需要空头头寸 外部 bool wantBreakout = true;     // 我们是否希望在价格上方做多,在价格下方做空 extern bool wantCounter = true; // 我们是否希望在价格下方做多,在价格上方做空 extern bool limitEMA = true; // 我们是否希望在ema上方做多,在ema下方做空 extern int EMAperiod = 34; // EMA的长度。之前固定为34 extern double GridMaxOpen = 0; // 最大开仓数:尚未实现... extern bool UseMACD = true; // 如果为真,将只对多头使用macd >0,对空头使用macd >0 // 在交叉时,将取消所有挂单。extern bool CloseOpenPositions = false;//如果使用MACD,我们是否也要关闭亏损的开仓? extern bool doHouseKeeping = true; //只是一个测试,//由cori修改。允许几个并存的网格 double LastUpdate = 0; // 用于记录最后一次更新时间的计数器 //+------------------------------------------------------------------+ //| 专家初始化函数 | //+------------------------------------------------------------------+ int init() { //---- #property show_inputs // 显示参数 - 谢谢 Slawa...    
//---- //加入了我的corri,被hdb删除了!!笑了。只是为了保持与开放网格的兼容。
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| 测试在atRate区域是否有开仓或订单 | //| 如果checkLongs为真将检查多头,否则将检查 | //| 短头 | /+------------------------------------------------------------------------+ bool IsPosition( double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal( ) 。
     for(int j=0;j<totalorders;j++) // 扫描所有订单和仓位。... { OrderSelect(j, SELECT_BY_POS); // 由cori修改。使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看mygrid和符号... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)//不寻找准确的价格,而是价格接近(小于网格大小)--因为浮点错误而增加了0.9 { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) { return(true); } } } } 
   return(false); } //+------------------------------------------------------------------------+ //|取消所有挂单 | //+------------------------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) //扫描所有订单和头寸... { OrderSelect(j, SELECT_BY_POS); //按照cori修改。使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看mygrid和符号... { int type = OrderType(); if ( type > 1 ) bool result = OrderDelete( OrderTicket() ); } } 
   return; } //+------------------------------------------------------------------------+ //|取消所有挂单并关闭未结头寸 | //+------------------------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // modified by cori.使用OrderMagicNumber来识别网格的交易//为兼容而添加了hdb或gridname if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) )  //只看mygrid和符号...
     { //关闭已开立的多头头寸 if ( type == OP_BUY ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ) 。
           //如果(type == OP_SELL ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); //Close pending orders if ( type > 1 ) result = OrderDelete( OrderTicket( ) ) ; } } return;
} //+------------------------------------------------------------------------+ //|取消所有落在EMA错误一侧的未结订单 | //+------------------------------------------------------------------------+ void CloseOrdersfromEMA( double theEMAValue ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) //扫描所有订单和仓位。{ OrderSelect(j, SELECT_BY_POS); if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || ( OrderComment() == GridName)) )  //只看mygrid和符号的情况。
         { int type = OrderType(); bool result = false; //if (type > 1) Print(type," ",theEMAValue," ",OrderOpenPrice()); if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket( ) ) ; if ( type == OP_BUYSTOP &&OrderOpenPrice() <= theEMAValue ) 结果 = OrderDelete( OrderTicket() ); if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) 结果 = OrderDelete( OrderTicket() ); if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) 结果 = OrderDelete( OrderTicket() ) ; } } 
   return; } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- setup parameters if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } bool myWantLongs = wantLongs;
 bool myWantShorts = wantShorts; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // we update the first time it is called and every UpdateInterval minutes { LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // 取整为可被GridSize划分的点数 k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point 。          //计算最低进入点 double myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0); if ( limitEMA ) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA); } if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0) 。
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 &&Macd1>0 && Macd2<0) //交叉上升 { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) //交叉下降 { CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } myWantLongs = false; myWantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0 && wantLongs )     //远高于零 { myWantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0 && wantShorts )     //远低于零 { myWantShorts = true; } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( myWantLongs && ( ! limitEMA || traderate > myEMA)) { if ( IsPosition(traderate,point*GridSize,true) = = false )           // 测试我是否有接近我的价格的未结订单:如果有,就放一个 { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              否则 { entermode = OP_BUYLIMIT ; } 
              如果((traderate > Ask ) && (wantBreakout))|| ((traderate <= Ask ) && (wantCounter)) ) 
              { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( myWantShorts && ( ! limitEMA || traderate < myEMA)) { if (IsPosition(traderate,point*GridSize, false) == false )           //测试我是否有接近我的价格的未平仓订单:如果有,就放一个 { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              否则 { entermode = OP_SELLSTOP ; } 
              
              如果 ( ( (traderate < Bid ) && (wantBreakout) )|| ((traderate >= Bid ) && (wantCounter)) ) 
                { // 由cori修改。使用OrderMagicNumber来识别网格的交易 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+