新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 861

 

嗨,你能告诉我为什么它不工作吗?没有错误,但订单在测试器中没有打开。我正在尝试编写一个EA,用于突破日线蜡烛图的高点和低点,作为训练工具。


extern int      TimeCandle   = 1440;      //таймфрейм свечи, которую пробиваем 
extern int      HourStart=10; // час начала торговли
extern double   Lots=0.1;     // лот торговли   
extern int      StopLoss=100; // стоплосс
extern int      TakeProfit=100; // тайкпрофит
extern int      znak=5;     // количество знаков котировки
extern int      magik=54321;     // магик 

double minprice; // минимальная цена
double maxprice;// максимальная цена


void OnTick()
  {
  double SL, TP;
  int ticket;
 
   minprice = iLow(Symbol(),TimeCandle,1);
   maxprice = iHigh(Symbol(),TimeCandle,1);   
   
   if (TimeHour(TimeCurrent()==HourStart))
   { 
    if (BuyLimitCount()==0 && BuyCount()==0) //если нет ордера то пытаться открыть
    { 
    SL = NormalizeDouble(maxprice - StopLoss*Point,znak);
    TP = NormalizeDouble(maxprice + TakeProfit*Point,znak);
    ticket = OrderSend(Symbol(), OP_BUYLIMIT,Lots,maxprice, 10, SL,TP,"", magik,0,Blue);
    
    if (ticket <0)
    Print ("Не удалось открыть ордер на покупку");
    }
    
    
     if (SellLimitCount()==0 && SellCount()==0) //если нет ордера то пытаться открыть
    { 
    SL = NormalizeDouble(minprice + StopLoss*Point,znak);
    TP = NormalizeDouble(minprice - TakeProfit*Point,znak);
    ticket = OrderSend(Symbol(), OP_SELLLIMIT,Lots,minprice,10, SL,TP,"", magik,0,Red);
        
    if (ticket <0)
    Print ("Не удалось открыть ордер на продажу");
    }
    
    }
    Comment ("Минимальная цена:" + DoubleToStr(minprice,znak) + "\n" + "Максимальная цена:"+ DoubleToStr(maxprice, znak)); 
  }
   
  // проверяем есть ли байлимит ордера с конца
  int BuyLimitCount()
  {
  int count = 0;
  for (int i=OrdersTotal()-1;i>=0;i--)
  {
    if (OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == true && 
        OrderMagicNumber()== magik &&                        
        OrderType() == OP_BUYLIMIT )                        
        {
        count ++;
        }
    }
    return(count);  
    
  }
   // проверяем есть ли селллимит ордера с конца
  int SellLimitCount()
  {
  int count = 0;
  for (int i=OrdersTotal()-1;i>=0;i--)
  {
    if (OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == true && 
        OrderMagicNumber()== magik &&                        
        OrderType() == OP_SELLLIMIT )                        
        {
        count ++;
        }
    }
    return(count);      
  }
  
   // проверяем есть ли бай ордера с конца
  int BuyCount()
  {
  int count = 0;
  for (int i=OrdersTotal()-1;i>=0;i--)
  {
    if (OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == true && 
        OrderMagicNumber()== magik &&                        
        OrderType() == OP_BUY )                        
        {
        count ++;
        }
    }
    return(count);      
  }
  
  // проверяем есть ли селл ордера с конца
  int SellCount()
  {
  int count = 0;
  for (int i=OrdersTotal()-1;i>=0;i--)
  {
    if (OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == true &&         
        OrderMagicNumber()== magik &&                        
        OrderType() == OP_SELL )                        
        {
        count ++;
        }
    }
    return(count);      
  }
Как самому создать советника или индикатор - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
Как самому создать советника или индикатор - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
  • www.metatrader5.com
Для разработки торговых систем в платформу встроен собственный язык программирования MetaQuotes Language 5 (MQL5), среда разработки MetaEditor и инструменты тестирования стратегий. Любую информацию о разработке торговых стратегий на языке MQL5 можно найти на официальном сайте MQL5.community. На этом же сайте в разделе Code Base могут быть...
 
nelenaby:

嗨,你能告诉我为什么它不工作吗?没有错误,但订单在测试器中没有打开。我正在尝试编写一个EA,用于突破日线蜡烛图的高点和低点,作为一个训练工具。


它没有打开,也就是说,它没有尝试,或者它尝试了但失败了?他们在日志中是怎么说的?

 
nelenaby:

嗨,你能告诉我为什么它不工作吗?没有错误,但订单在测试器中没有打开。我正在尝试编写一个EA,用于分解每日蜡烛图的高点和低点,作为培训工具。


分析一下你的这种表达方式

if (TimeHour(TimeCurrent()==HourStart))
        {
          ........
        }

我不明白这个表达式的意思,也许我错了。 但你至少应该把"(TimeCurrent()==HourStart)"改为"(TimeCurrent()-HourStart)"。

 

接下来,如果我理解正确的话--你试图在没有BuyLimitOrder和BuyPosition的情况下下达一个BuyLimit订单。注意确切的 "和 "字。也就是说,任何一个单独的存在都适合你,因此,在当前价格的 理想位置,你会得到无限多的ByLimits,每个tick上都有一个,直到至少有一个触发,第一个位置打开。另外,你并不关心现在的价格在哪里。只要满足了关于时间的奇怪条件(就在帖子上面),我想就会出现错误,但不要紧。总之,如果你不考虑这一点,EA将在第一个刻度开始下错订单,直到价格达到昨天的高点,因为你是用昨天的高点作为下单的价格。买入限价被设置在当前价格之下,这意味着当前价格应该高于昨天的高点,但在此之前,订单将失败。

因此,唯一适合你的情况是,当价格移动到昨天的高点以上,没有补仓限制,也没有开放交易。这是一个罕见的组合。此外,它不会影响突破,但会在突破后反弹(因为有一个bylimit),而且它会给你带来很多错误,从高于昨天最大值的第一个tick开始(这是另一个错误)。条件已经满足,专家顾问抛出订单,但也有一个点差,与市场的最小允许距离,等等。

 
Sergey Voytsekhovsky:

我很难理解这个表达式的意思,也许我错了,但至少要把"(TimeCurrent()==HourStart)"改为"(TimeCurrent()-HourStart)"。

这是正确的,这里有一个错误。你需要如果(TimeHour(TimeCurrent())==HourStart)

现在订单有时会打开,但会产生更多错误(OrderSend错误130)。

这里的错误是关于限价订单的不正确。

 
nelenaby:

这是正确的,这里有一个错误。它需要如果(TimeHour(TimeCurrent())==HourStart)

现在它有时会打开交易,但会抛出更多错误(OrderSend错误130)。

关于限价单,它是不对的。

这里有一个与时间打交道的脚本。

它是旧的,但它能正常工作。

附加的文件:
 

你好。

请帮助我了解如何处理文件。

当程序运行时,我将收到的数据保存到一个文件中,并读取CSV。

文件增加,速度下降。我试图更新(覆盖)行中的一些元素。不可能!

你不能删除一个选定的行!我不能在旧的线路上添加新的元素!

这是很奇怪的事!你可以轻松地删除一个文件 或一个图形对象,等等。但是,当涉及到使用已创建的文件时,它是一个绝对的僵局。

在论坛上,只有一个建议:"将文件读入内存,改变或删除这一行,并将新文件保存在旧名称下"。

在我看来,这并不是正确的解决方案。我一定是错过了什么。请帮助我解决这个问题。

 
im-zvv:

在我看来,这似乎不是一个正确的决定。我可能错过了什么。请帮助我解决这个问题。

你应该被微软紧急聘用,以最终解决这个文件 处理的 "错误解决方案"


文件处理并不像在文件编辑器中编辑文件,它更像是用单个字母的骰子来做一个单词。
如果你需要插入一个新的字母,所有跟在它后面的方块都需要向右移动。
如果你想删除一个旧的字母,它后面的所有骰子必须移到左边。
因此,如果文件不大,而且工作不需要访问该文件,将数据写入一个新文件,删除旧文件,并将新文件重命名为旧文件的名称,确实比较容易。

如果我没有弄错的话,MQL在处理文件时唯一缺少的是将文件长度修剪到所需大小的能力。


 
Alekseu Fedotov:

这里有一个与时间打交道的脚本。

它是旧的,但它能正确工作。

我以前也用金的功能,后来我找到时间写自己的。

//_______________________________________________________________________
class CWorkTime
  {
private:
   int               mday,mstarthour,mstophour,mstartmin,mstopmin;
   datetime          mstarttime,mstoptime;
   bool              UseThisSession;
   void inittime()
     {
      mday=Day();
      MqlDateTime dtstart,dtstop;
      TimeToStruct(TimeCurrent(),dtstart);
      dtstop=dtstart;
      dtstart.hour= mstarthour;
      dtstart.min = mstartmin;
      dtstop.hour = mstophour;
      dtstop.min = mstopmin;
      mstarttime = StructToTime(dtstart);
      mstoptime=StructToTime(dtstop);
     }
public:
   void              CWorkTime(void){};
   void              ~CWorkTime(void){};
   void              CWorkTime(int hstart,int mstart,int hstop,int mstop)
     {
      mstarthour=hstart;
      mstartmin = mstart;
      mstophour=hstop;
      mstopmin=mstop;
      UseThisSession=(mstarthour<0 || mstophour<0 || mstarthour>23 || mstophour>23) ? false : true;
      UseThisSession=(mstartmin<0 || mstopmin<0 || mstartmin>59 || mstopmin>59) ? false : true;
      if(UseThisSession) inittime(); else Print("Время работы советника не используется");
     };

   bool              Disable()
     {
      bool result=false;
      if(UseThisSession)
        {
         if(mday!=Day()) inittime();
         datetime t=TimeCurrent();
         result=t>=mstarttime && t<=mstoptime ? false : true;
        }
      return(result);
     };
  }
*Work;


.....

int OnInit()
{
   Work=new CWorkTime(StartHour,StartMinute,StopHour,StopMinute);
}

.....


void OnTick()
  {

if(Work.Disable())
{
 Comment("Не торговое время!!! Сопровождение открытых ордеров");
 }
else
{......
禁用运行时间--在初始化构造器时,你必须输入无效的数据,例如25小时或70分钟。
 
Sergey Dzyublik:

你迫切需要被微软雇佣,以便他们最终解决这个文件处理的 "错误解决方案"


与文件打交道并不像在文件编辑器中编辑文件,它更像是用单个字母的骰子来做一个单词。
如果你需要插入一个新的字母,所有跟在它后面的方块都需要向右移动。
如果你想删除一个旧的字母,它后面的所有骰子必须移到左边。
因此,如果文件不大,而且工作不需要访问该文件,将数据写入一个新文件,删除旧文件,并将新文件重命名为旧文件的名称,确实比较容易。

如果我没有记错的话,MQL在处理文件时唯一缺少的是将文件长度修剪到所需大小的能力。


谢谢你。澄清得好。不幸的是,我的文件非常大,因此我将不得不用 "立方体 "来工作。