网格制作者1.1 - 页 4 123456 新评论 Forex Trader 2005.07.18 17:33 #31 对不起,我对任何给定的网格位置只有一个订单,而且我已经测试了几乎所有的变化--超过几个星期。 我偶尔会删除所有未结订单,这样我们的MT4朋友就不会不高兴了。 ,你在回测中会遇到这个问题,但这不是一个脚本问题,而是一个MT4回测 问题。 如果它继续下去,请让我知道或给我发送一些显示问题的报告... 谢谢和回复, hugues Forex Trader 2005.07.18 20:34 #32 我已经发现了它。我对这个问题感到不高兴。 顾问用我给的注释 "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 如何编码? 新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 在MT4,可以实现一键平仓吗? Forex Trader 2005.07.18 22:01 #33 好的,科里,谢谢... 让我知道它是否起作用,我将使用这个魔法......因为我不知道经纪人会做这样的怪事!!!。 谢谢和问候。 胡戈斯 Forex Trader 2005.07.18 23:09 #34 现在,就这样了。 我已经把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); } //+------------------------------------------------------------------+ 致以敬意,科里 Grid maker 1.1 Help: How to write 如何编码? Forex Trader 2005.07.19 02:11 #35 谢谢 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); } //+------------------------------------------------------------------+ Grid maker 1.1 如何编码? 新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 Forex Trader 2005.07.19 09:59 #36 嗨,hdb, ,似乎可以。但你应该把GridName定义为extern,我改了,因为我不需要它作为参数。 greetings, cori Forex Trader 2005.07.21 00:03 #37 注意所有GridMaker的用户--在函数 IsPosition中存在一个错误--其结果是,并非所有的网格槽都被填满。 你可以改变这一行: if (MathAbs( OrderOpenPrice() - atRate ) < inRange) //不寻找确切的价格,但价格接近(小于网格大小) to if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9))//不寻找准确的价格,而是价格接近(小于gridsize)--因为浮动的pont错误而增加了0.9 ,这样就纠正了问题。 很抱歉给您带来不便... hugues Forex Trader 2005.07.21 01:09 #38 你好,hugues。 这个问题已经存在了吗? 在旧的MQL2中发现了类似的问题。 绕过这个问题的真正确定的方法是做这样的事情。 int intOOP = MathRound( OrdeOpenPrice() / Point ) 。 为你所有的双倍变量。然后你就有了所有直接的int变量,这些变量是可以比较的,没有错误。 为了保持清晰易懂,它要多写一点,但它的错误较少。 问候。 cori Forex Trader 2005.07.21 14:51 #39 你是对的,科里,这更优雅!只是我太懒了! 问候。 hugues Forex Trader 2005.07.29 13:33 #40 这里是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); } //+------------------------------------------------------------------+ 123456 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
我偶尔会删除所有未结订单,这样我们的MT4朋友就不会不高兴了。
,你在回测中会遇到这个问题,但这不是一个脚本问题,而是一个MT4回测 问题。
如果它继续下去,请让我知道或给我发送一些显示问题的报告...
谢谢和回复,
hugues
顾问用我给的注释 "GridEURUSD "创建网格。只要订单在等待,这个评论就会出现在评论栏里。如果订单被激活,评论将变为 "激活/自动"。很明显,这种行为导致了所描述的问题。
我在Alpari交易。他们在模拟账户 中支持MT4
我将检查,如果我可以绕过这种行为,即使用订单的魔法作为网格的标识符,并让你知道结果。
在测试的同时,我也对网格的清理脚本进行了修改。我也增加了关闭未结订单的功能。不幸的是,如果我试图关闭一个未结订单,我得到了错误129,这意味着订单被锁定。但它却删除了给定网格的所有挂单。
cori
让我知道它是否起作用,我将使用这个魔法......因为我不知道经纪人会做这样的怪事!!!。
谢谢和问候。
胡戈斯
我已经把gridMaker改成了使用OrderMagicNumber而不是注释。我还做了一些关于建立注释的小修改。
下面是结果。
致以敬意,科里
因为我自己已经做了一些改动,所以我把你的改动整合到了较新的版本中。
我做了一个小小的改动:为了保持我当前的网格处于活动状态,我在magic OR gridname上做了一个测试......
,你能检查一下 我的做法是否正确吗?
,似乎可以。但你应该把GridName定义为extern,我改了,因为我不需要它作为参数。
greetings, cori
你可以改变这一行:
if (MathAbs( OrderOpenPrice() - atRate ) < inRange) //不寻找确切的价格,但价格接近(小于网格大小)
to
if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9))//不寻找准确的价格,而是价格接近(小于gridsize)--因为浮动的pont错误而增加了0.9
,这样就纠正了问题。
很抱歉给您带来不便...
hugues
这个问题已经存在了吗?
在旧的MQL2中发现了类似的问题。
绕过这个问题的真正确定的方法是做这样的事情。
int intOOP = MathRound( OrdeOpenPrice() / Point ) 。
为你所有的双倍变量。然后你就有了所有直接的int变量,这些变量是可以比较的,没有错误。
为了保持清晰易懂,它要多写一点,但它的错误较少。
问候。
cori
问候。
hugues
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的代码: