检查蜡烛是否打开 - 页 3

 
  1. 这段代码是建国前600年写的。自2014年2月起,不能在变量名中使用点。只是用下划线代替。
  2. 这里有一个独立于方向的代码的例子
    double DIR, OOP, OCP, ISL;  int OP;
    
    if(     Bid > High[1]){
       DIR = +1; OOP = Ask; OCP = Bid; OP = OP_BUY;
    }
    else if(Bid <  Low[1]){
       DIR = -1; OOP = Bid; OCP = Ask; OP = OP_BUY;
    }
    else return;
    
    ISL = OCP -DIR* pips_to_change( extISL_Pips );
    ... OrderSend(...);
    你只要把Ask/Bid换成开盘价/收盘价,其他都写成买入。ISL低于OCP(OCP-ISL),-DIR*改变符号为卖出。
    如果你需要一个比较(A>B) ,使用(A-B)*DIR>0 来扭转卖出的比较。
 
GumRai:

似乎你有这个想法。

修改并发布你的代码,我或其他人会对它进行评论。

嘿,GumRai。

我已经有一段时间没有在这里发布更新了,但是我一直在努力学习代码,并最终完成了它--在每天工作10小时的情况下,这很痛苦。然而,我有两个主要问题。1)无论我做什么,它都会产生一个错误代码。"2)我做了一个文件的保存,(调用了一个USDCAD,另一个EURUSD),使用了不同的magicnumbers等,但它仍然每次只做一个交易--并没有独立处理这些交易。事实上,它还产生了一个 "OrderCloseFunction无效票 "的错误。

我试着在谷歌上搜索这个问题,但无济于事。如果你能在这个问题上为我提供正确的指导,我将非常感激。我做错了什么?

#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//part with the extern int stating the terms of the MA removed to reduce space.

int MagicNumber = 1234;
int MagicNumber2 = 2345;
double Pips;
int BuyTicket;
int SellTicket;
int CloseTicket;
int CloseSellTicket;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   double Ticksize = MarketInfo(Symbol(), MODE_TICKSIZE);
   if (Ticksize == 0.00001 || Ticksize == 0.001)
   Pips = Ticksize*10;
   else Pips = Ticksize;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
  {
//---

   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);
      double PreviousPriceClose2=iClose(NULL,0,2);
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      for(int i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(iClose(NULL, 0,0)<PreviousSlow)
        {
          CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         }
         }
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
      for(i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if(iClose(NULL, 0,1)>PreviousSlow)
        {
          CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              }
     }
     }
    return(0);
    return(0); 
    }
//--------------

  

预先感谢!

 

永远不要使用OrdersTotal()==0 作为交易的条件

这意味着,如果一个交易已经被手动打开,或被另一个EA打开,或同一EA连接到另一个图表符号,只能打开一个交易。

你有全局变量BuyTicket,把它初始化为-1。

int BuyTicket=-1;

      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),
                                "Main Entry EA",MagicNumber,0,clrLimeGreen);
        }

在平仓前不要对订单进行循环,这没有必要。

else
if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
  {
   if(OrderCloseTime()==0)
     {
      if(Close[0]<PreviousSlow)
        {
         bool  CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         if(CloseTicket)
            BuyTicket=-1;
        }
     }
   else
      BuyTicket=-1;  //Order has closed so reset variable
  }

现在,当使用全局声明的票号变量时,如果终端因某种原因被关闭并重新启动,可能会出现问题。

所以要声明一个新的全局范围变量

 bool Recovery=true;

  
  if(Recovery)
     {
     //loop through open orders and check for magic number, symbol and type
     //if you find a buy order with the magic number and symbol
     BuyTicket=OrderTicket();
     //if you find a sell order with the magic number and symbol
     SellTicket=OrderTicket();
     Recovery=false;
     }

我打得很快,所以我可能有错误,但足以给你一个概念。

 
GumRai:


非常感谢!我之所以把这个循环放在那里,是因为我注意到,当它关闭卖出时,由于某种原因,它不会触发买入。

我已经做了必要的修改......但似乎还是有些不对劲。它现在不进行任何长线交易,并产生无效票据的错误代码,以及OrderClose错误4051。对这里的问题有什么建议吗?

奇怪的是,无论是以前的代码,还是现在的代码(只针对卖出),它都能合理地进行交易(如果我只在一个图表上执行)。

我不认为这有多难,哈哈!我想我错了,我以为这是一个非常简单和直接的事情......当蜡烛穿过并开在MA之上时买入,当蜡烛穿过并低于MA时关闭并卖出。


if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
      {
      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;
            }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;
            }
            
    return(0);
    return(0); 
    }
 

很抱歉,但我真的不知道你想做什么

if(OrderSelect(SELECT_BY_POS,MODE_TRADES))

没有选择任何顺序。这段代码甚至可以编译吗?

      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;

这里的else适用于如果(OrderCloseTime()==0)为假的 情况。

       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;

这里适用于OrderSelect失败的情况,当然它也是如此。

 
GumRai:

很抱歉,但我真的不知道你想做什么

没有选择任何顺序。这段代码甚至可以编译吗?

这里的else适用于如果(OrderCloseTime()==0)为假的 情况。

这里适用于OrderSelect失败的情况,当然它也是如此。

对不起,完全是我的错。我没有正确地阅读/应用你的建议;非常感谢你指出这些建议。我在这里已经做得很正确了。报告中完全没有产生错误。唯一的问题是,现在,它有时会输入多个卖单买单,这使它不能在正确的时间关闭交易。

编辑:准确地说,它只在SL和TP处退出,而不是在价格越过MA的另一边时退出。这与bool有关系吗?

int start()
  {
   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
      else
      if(OrderSelect(BuyTicket,MODE_TRADES))
      {
         if(OrderCloseTime()==0)
         {
          if(Close[0]<PreviousSlow)
           {
             bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
             if(CloseTicket)
               BuyTicket=-1;
               }
            }
            else
               BuyTicket= -1; //Order has closed so reset variable
               }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SellTicket,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else 
            SellTicket= -1; //Order has closed so reset variable
            }
    return(0);
    return(0); 
    }
 
if(OrderSelect(BuyTicket,MODE_TRADES))
这不是选择交易,请按照我给你的例子,正确操作。
 
GumRai:
这不是选择交易,请按照我给你的例子,正确地做。

我觉得......真的很蠢。笑。谢谢你的发现!!

1)还剩下两件事......现在它产生了一个错误代码 OrderClose 4108。我应该再贴一次代码吗?它与上面的代码相同,并进行了你所说的修正。不过它是按照规则进入和退出的。

2) 它没有像图中所示,在关闭多头头寸后立即进入空头。绿色的向下箭头显示了它应该做空的地方。它买入了一个,一旦收盘低于黄色MA,它就亏损平仓。在这里,它应该做空。我怎样才能做到这一点呢?

非常感谢GumRai。说实话,如果没有你的帮助,我不会达到这么近的地方。

应该在这里做空

 
int start()
  {
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(BuyTicket==-1)
        {
         if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
           {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]<PreviousSlow)
              {
               bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
               if(CloseTicket)
                  BuyTicket=-1;
              }
           }
         else
            BuyTicket=-1; //Order has closed so reset variable
        }

      if(SellTicket==-1)
        {
         if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
           {
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(SellTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]>PreviousSlow)
              {
               bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
               if(CloseSellTicket)
                  SellTicket=-1;
              }
           }
         else
            SellTicket=-1; //Order has closed so reset variable
        }
     }
   return(0);
  }

这是个小变化,因为它正在检查 关闭一个没有的订单。

根据代码,没有理由在买入结束后立即打开卖出。

退出买入的条件与打开卖出的条件是不一样的。

请记住,由于你只检查蜡烛的开盘,Close[0]将是该蜡烛的第一个刻度的买入值。

 
GumRai:

这是个小变化,因为它正在检查关闭一个没有的订单。

根据代码,没有理由在买入结束后立即打开卖出。

退出买入的条件与打开卖出的条件是不一样的。

请记住,由于你只检查蜡烛的开盘情况,Close[0]将是该蜡烛的第一个刻度的买入值。

我的天哪!你成功了!再三感谢GumRai。你是最棒的。

现在不能向前测试,但一旦市场开放,我想我应该能够使用这个,只要我在演示上有不同的魔法#,就可以使用其他对。