有什么帮助吗?

 

所以我在学习了一些其他语言之后,正在学习mql4,我(或者说我认为)刚刚完成了我的第一个EA的第一版,一个简单的移动平均线 交易者。我让它在昨天一直运行,没有任何顾虑,进入和退出都符合预期,我认为它已经准备好了。今天早上,我遇到了各种各样的问题,首先,当我重新运行时,代码只卖出,而不考虑位置,现在,经过一点摆弄,它将在正确的位置买入和卖出,但当买入时,交易将在下一个点关闭,无论如何。尽管我持有相同的格式,但卖出时却没有发生这种情况--谁能给我指出原因?

(顺便提一下,我的电脑昨天一整天都能运行代码,没有更多的嗡嗡声(CPU平均为12%),今天它像地狱钟一样运行代码(~60-90%))

代码。

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

我还没有深入研究你的代码

为什么要刷新速率,然后休眠1秒,当市场快速移动 时,数据就会过时了!?

你是按点计算的,而不是按条计算的,所以一个点可以通过一个MA高于/低于另一个MA的最小量来触发一个订单。如果接下来的tick(睡眠后)发生逆转,MAs再次交叉,订单将被关闭。

 

我们的想法是简单地保持循环,同时等待条件,直到收盘条件出现(也就是SMA的切换)--诚然,这不是最好的方法,但却是计算上最便宜的方法之一。

均线迅速地在彼此上方/下方移动是代码的问题之一--但我认为没有理由,当我正在运行的两个均线之间目前有10-15点时,会导致关闭?

 
j.w.msb:

我们的想法是简单地保持循环,同时等待条件,直到收盘条件出现(也就是SMA的转换)--诚然,这不是最好的方法,但在计算上是最便宜的方法之一。

均线迅速地在彼此上方/下方移动是代码的问题之一--但我认为没有理由,当我正在运行的两个均线之间目前有10-15个点时,会导致关闭?


如果你只检查 一个MA是否高于/低于另一个,我怀疑它通常是10到15个点的差异,它可能是0.1个点,所以下一个刻度可以很容易地扭转它。

这只是我的观点,但在处理交叉盘时,我认为最好只在收盘时计算,以避免太多的相反信号。

 

另外,在你的启动程序中

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

你的else只适用于最后一个if,所以如果EA没有关闭一个未平仓的卖单,总数将增加1。 你为什么要这样?

 
GumRai:


如果你只检查一个MA是否高于/低于另一个,我怀疑它通常是10到15个点的差异,它可能是0.1个点,所以下一个点可以很容易地扭转它。

这只是我的看法,但在处理交叉盘时,我认为最好只在关闭的条形图上计算,以避免过多的相反信号。


这是我在计算点数方面的一个错误!我的错但问题是这两者之间肯定有喘息的空间,所以没有交叉信号来强制卖出。用while (TimeSecond(TimeCurrent)!=59){Sleep(1000)}代替Sleep(1000)可以确保在蜡烛收盘时才测试交叉信号?


我已经去掉了买入部分的OrderClose,订单仍然在运行时被打开,然后在下一个点上关闭 :s


接下来,我切换了OP_BUY和OP_SELL,当6SMA高于21SMA时,卖盘如期而至--我在等待下一个交叉点,看看会发生什么(显然,我暂时是在一分钟的时间框架内测试的)。

 

有很多需要改变的地方.....,需要努力的地方。

你的EA创建的交易有什么神奇的数字......

你为什么不把它作为一个外部输入变量,这样你就可以使它成为一个唯一的数字,而且它不会关闭其他EA的交易。

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

这里发生了什么...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

如果你像现在这样在循环中关闭交易,那么不要计算检查交易,会失败的。

看一下这里,看看你为什么要工作,以及如何倒数。

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

当每笔交易都有新的点数出现时,这个条件可以在片刻间改变几次,你要支付点差

条件不总是改变一次....,在一个单一的酒吧

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

什么总是运行你让它睡觉

在正常情况下,当嘀嗒声结束,新的嘀嗒声出现时,会再次调用start()

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

这样一来,只在秒数为0时运行代码,往往会失败。

因为经常会发生这样的情况:在一秒钟内没有新的tick出现。

如果一分钟的第一个刻度线在1秒时出现,你就必须等待新的一分钟,并希望新的刻度线在下一分钟的第0秒出现。

查看RefreshRates() 函数

还有更多的事情,比如让它像4位和5位经纪人一样工作。

检查returncodes....

滑点你的值是0,为什么需要它?

 
deVries:

有很多需要改变的地方.....,需要努力的地方。

你的EA创建的交易有什么神奇的数字......

你为什么不把它作为一个外部输入变量,这样你就可以使它成为一个唯一的数字,而且它不会关闭其他EA的交易。

这里发生了什么...

如果你像现在这样在循环中关闭交易,那么不要计算检查交易,会失败的。

看一下这里,看看你为什么要工作,以及如何倒数。

https://www.mql5.com/en/forum/139654

当每笔交易都有新的点数出现时,这个条件可以在片刻间改变几次,你要支付点差

条件不总是改变一次....,在一个单一的酒吧

什么总是运行你让它睡觉

在正常情况下,当嘀嗒声结束,新的嘀嗒声出现时,会再次调用start()

这样一来,只在秒数为0时运行代码,往往会失败。

因为经常会发生这样的情况:在一秒钟内没有新的tick出现。

如果一分钟的第一个刻度线在1秒时出现,你就必须等待新的一分钟,并希望新的刻度线在下一分钟的第0秒出现。

查看RefreshRates() 函数

还有更多的事情,比如让它像4位和5位经纪人一样工作。

检查returncodes....

滑点你的值是0,为什么需要它?

谢谢你的帮助,我现在正在进行修改,我会看看效果如何!"。愚蠢的错误加上我的愚蠢错误!它几乎是一个奇迹,为什么它首先运行!
 

所以,我把代码剥离出来,以最简单的能力运行(即交叉=反向头寸)--当两个SMAs接近时,它导致大量的买/卖订单,但我不担心(目前),在模拟账户上运行良好。现在让我担心的是,如果我在策略测试器上 运行我的代码,它会正确地打开第一个头寸,但随后未能在时间上向前推进,所以SMA从未交叉。我做错了什么?我的打印列表是。

2013.10.22 23:41:26 2013.09.18 00:41 测试员:订单#1已关闭

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY, M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1:加载成功

代码。



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: 现在让我担心的是,如果我在策略测试器上运行我的代码,它能正确地打开第一个位置,但在时间上却不能向前移动。
  1. int start(){
       while (AccountBalance()>50){
          :
    当然不是。准确地说,是 "RTFM"。你只有在从开始返回时才能得到一个新的勾。
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM和测试器的限制,你不能在测试器中睡觉。
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    什么是函数的返回值?我如何使用它们?- MQL4论坛
 
RefreshRates不会改变测试器中的任何值,所以你被困在一个while循环中,因为它没有任何新值可以使用。