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

 

mashcats 的标准MT顾问中,DecreaseFactor是什么?

lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
 
Nerd Trader #:

很奇怪,这些按钮现在都在那里。还有代码的杂乱,因为这是一个草案。总之,我已经做了一个工作版本,剩下的最后一件事是删除按钮,这里又开始了这个垃圾:删除功能没有找到4个对象中的任何一个。

点击按钮就可以创建所有的线条。

如果按钮被按下--删除。

我很遗憾地说,写的都是些什么废话。

 
Artyom Trishkin #:

而且你不需要观看这些活动。它们在测试器中根本不起作用。你必须观察状态。

当然不是谦虚,但如果你能听一次我的提示,你早就把一切都做好了。适当的,没有多层楼的拐杖。

但每个人都会选择他们想要跳入 的深渊。

Mihail Matkovskij#:

要使用测试器中的调试,要学会用MQL5编写。那里的一切都很好。

没有重命名对象这种事。可以把它看作是用一个新的对象来替换一个现有的对象。

这是不可能的。你的代码看起来像一个混乱的东西。这可能是你遇到按钮滞后的原因。就像我之前告诉你的,从简单的东西开始。不要把事情过分复杂化。当简单的东西开始起作用并且你对它有信心的时候,再逐渐将它复杂化。

如果它们是由事件触发的(通过点击),我又该如何查看状态?是的,但我是用mql4写的,这和说 "学习用c#写,在那里调试工作 "是一样的。

"正确的,没有多层的拐杖。"--所以隐藏物体只是拐杖。

总的来说,我已经做了,一切都很好https://gist.github.com/satorkain/0cf7a8df8ec1f4b3191defd04c94a418
通过点击按钮,所有的线都是一次性创建的,然后它们被隐藏,只剩下一个,取决于按钮面板的位置。根据光标相对于价格的位置,更多的线条被隐藏/显示出来。

P.S.

如果不是歪打正着的mql4,我就不用想出隐藏对象的这套废话了,一切都应该在第一次删除/重命名对象时就能成功。

stop order button (public).mq4
stop order button (public).mq4
  • gist.github.com
GitHub Gist: instantly share code, notes, and snippets.
 
Nerd Trader #:

如果它们是由事件触发的(通过点击),我又该如何查看状态?是的,但我是用mql4写的,这就像说 "学习用c#写,在那里调试工作 "一样。

"正确的,没有多层的拐杖。"因此,隐藏物体只是 拐杖。

总的来说,我已经做了,一切都很好https://gist.github.com/satorkain/0cf7a8df8ec1f4b3191defd04c94a418
通过点击按钮,所有的线都是一次性创建的,然后它们被隐藏,只有一个被保留,这取决于按钮面板的位置。根据光标相对于价格的位置,更多的线条被隐藏/显示出来。

P.S.

如果不是因为歪曲的mql4,我就不会想出这种关于隐藏对象的无稽之谈,一切都应该在第一次删除/重命名对象时就能成功。

隐藏一个对象 只是开发者推荐的方法。而且有一个特殊的属性。要查看状态,你需要查看按钮的 "状态 "属性。

这里歪曲 的是你的逻辑和概念的替换--你把开发者推荐的手段当作拐杖,你把不断贪婪的对象创建/删除当作纯粹的代码,但这正是拐杖,绕过了推荐的快速方法。

顺便说一下,要想快速使一个对象位于所有其他对象的顶部,你必须使它隐形,并立即可见--这将覆盖它在对象列表中的位置,它将位于顶部。

即使在那里,在git上,你发表的代码也是C-minus。完全容易出错。只要有一条线没有被创造出来,一切都会垮掉。这一点马上就能看出来。你在事件处理程序中创建了几行--为了什么?你需要OnInit()做什么?你创建了它,检查了它的成功,设置了一个标志并隐藏了它。在OnDeinit()中,你已经删除了由你的程序创建的对象。为此你还需要名字的前缀。

你只在事件处理程序中显示和隐藏--不应该有建筑。对于你的情况--正是如此。

我会为在git上公开发表这样的东西而感到羞耻。但那是对我而言。

你呢?人们可以利用它吗?

 
Artyom Trishkin #:

隐藏一个对象 正是开发者推荐的方法。而且有一个特殊的属性。要查看状态,你需要查看按钮的 "状态 "属性。

这里歪打 正着的是你的逻辑和概念的替换--你把开发者推荐的手段当作拐杖,你把不断贪婪的对象创建/删除当作纯粹的代码,但这正是绕过推荐的快速方法的拐杖。

顺便说一下,要想快速使一个对象位于所有其他对象的顶部,你必须使它隐形,然后立即可见--这将重新定义它在对象列表中的位置,它将位于顶部。

即使在那里,在git上,你发表的代码也是C-minus。完全容易出错。一旦有一条线没有创建,你的整个事情就会崩溃。这一点马上就能看出来。你在事件处理程序中创建了几行--为了什么? 你需要OnInit()做什么?你创建它,检查它的成功,设置一个标志并隐藏它。在OnDeinit()中,你已经删除了由你的程序创建的对象。为此你还需要名字的前缀。

你只在事件处理程序中显示和隐藏--不应该有建筑。对于你的情况--正是如此。

我会为在git上公开发表这样的东西而感到羞耻。但那是对我而言。

你呢?人们可以利用它吗?

贪婪地根据需要创建1行4列?:)如果有200条线呢?按照你的逻辑,一下子把它们都创造出来会不会很经济?而开发者是如何构思的,只有他们自己知道,而且是以一种非常不直观的方式构思的。仿佛不需要什么不可思议或不合逻辑的东西。我怎么会知道我只应该以这种方式而不是其他方式来处理物体呢?也许是来自mql4的教科书?我怀疑这一点在那里得到了解释。

至少,它是按原定计划运作的 :)标题里有括号(公共),所以还没有完成,但是是的,没有检查创建对象,让我们来解决这个问题。 我把它贴在git上只是因为我不记得粘贴bin 惭愧?Git是为人们 学习、交流经验、分享代码而创建的,工作与否没有区别,任何人都可以建立一个分叉,并在他们不满意的情况下进行修改。

在这里,250个对象已经被创建并存储在内存中,供专家顾问使用。好 吧,谢谢你,我会知道的。 这就是我说的 "非直观逻辑"。例如,在关于OnInit()的教程中,你只能读到该函数在专家顾问/指标的初始化期间被处理。

 
Nerd Trader #:


让我告诉你一个秘密。你可以创建多达1000个对象或更多,只要你没有 "计算器"。但它也能做到这一点。计算器是一台拥有4GB内存的计算机。任何低于这个数字的东西都是 "奶奶的计算器"......。:)因此,你可以一次创建所有的对象,也可以一次创建一个。这没有什么区别。但是没有狂热。

这样一来,只要你明智地去做,一切都能为大家所用!...

 
Nerd Trader #:

贪婪地根据需要创建1行4列?:)如果有200条线呢?按照你的逻辑,一次性把它们都造出来会不会很经济?而开发者是如何构思的,只有他们自己知道,而且是以一种非常不直观的方式构思的。仿佛不需要什么不可思议或不合逻辑的东西。我怎么会知道我只应该以这种方式而不是其他方式来处理物体呢?也许是来自mql4的教科书?我怀疑这一点在那里得到了解释。

至少,它是按原定计划运作的 :)标题里有括号(公共),所以还没有完成,但是是的,没有检查创建对象,让我们来解决这个问题。 我把它贴在git上只是因为我不记得粘贴bin 惭愧?Git是为人们 学习、交流经验、分享代码而创建的,工作与否没有区别,任何人都可以建立一个分叉,并在他们不满意的情况下进行修改。

在这里,250个对象已经被创建并存储在内存中,供专家顾问使用。好吧,谢谢你,我就知道了。 这就是我说的 "非直观逻辑 "的意思。你可以在教程中读到,例如,关于OnInit(),该函数在EA/指标的初始化过程中被处理。

你可以在同一时间创建你需要的许多对象。当时MT在绘制指标缓冲区方面不是很发达,我们必须用趋势线绘制400个可见的蜡烛图,一个蜡烛图我们需要5条线,400*5=2000,再加上每个对象的一个对象,如此循环。我们总共得到了大约2500个物体。它的作用是没有任何沉闷的感觉。

你不太理解与物体打交道的逻辑,但你知道如何争论。最好是反其道而行之。

 
Nerd Trader #:

贪婪地根据需要创建1行4列?:)如果有200条线呢?按照你的逻辑,一次性把它们都造出来会不会很经济?而开发者是如何构思的,只有他们自己知道,而且是以一种非常不直观的方式构思的。仿佛不需要什么不可思议或不合逻辑的东西。我怎么会知道 我只应该以这种方式而不是其他方式来处理物体呢?也许是来自mql4的教科书?我怀疑这一点在那里得到了解释。

至少,它是按原定计划运作的 :)标题里有括号(公共),所以还没有完成,但是是的,没有检查创建对象,让我们来解决这个问题。 我把它贴在git上只是因为我不记得粘贴bin 惭愧?Git是为人们 学习、交流经验、分享代码而创建的,工作与否没有区别,任何人都可以建立一个分叉,并在他们不满意的情况下进行修改。

在这里,250个对象已经被创建并存储在内存中,供专家顾问使用。好吧,谢谢你,我就知道了。 这就是我说的 "非直观逻辑 "的意思。例如,你在教程中唯一能读到的关于OnInit()的内容是,该函数在专家顾问/指标的初始化过程中被处理。

欢迎。我将尝试用简单的俄语来解释它。

你要去钓鱼了。

  1. 在家里,你打开储藏室,挠挠头,然后把它关上。
  2. 你去钓鱼,你需要一个鱼竿。
  3. 你回家到储藏室去拿鱼竿。
  4. 去钓鱼,放上鱼竿,钓上一条鱼,你需要一个网。
  5. 回家后到贮藏室取网
  6. 去钓鱼,拿起你钓到的鱼,用网子浮在钩上,你需要一个容器来储存你钓到的鱼。
  7. 回家吧!.....我可以继续吗?

或者你可以直接从储藏室(OnInit)拿你需要的所有东西,不用跑来跑去就可以捕鱼,当你回到家时,把所有东西放在储藏室和冰箱(OnDeinit)。

你可能已经在论坛上知道了这个消息。你只需要听一听,有时候听听别人怎么说。

否则,你得到一个问题,得到一个答案,说 "废话",然后按照你的想法去做。

你必须首先思考问题,提出问题,然后开始编辑。

你是否知道,编程中最简单的事情就是打印代码?而发展的大头是对逻辑的思考。

 

我很抱歉第二次提出这个问题。

但有一个问题我还不能解决,即

在同一个蜡烛图上开出一系列的订单(一个接一个)。

我需要防止EA在同一个蜡烛图上开新单。

我想过用Sleep() 来解决这个问题,但Makar说最好不要停止进程。

问题。

现在的代码看起来像这样。

// Параметры советника
input string  sParametersEA = "";     // Параметры советника
input double  Lot           = 0.01;   // Количество лотов
input int     StopLoss      = 30;     // Уровень убытка
input int     TakeProfit    = 30;     // Уровень прибыли
input int     Slippage      = 3;      // Проскальзование (в пунктах)
input int     Magic         = 1;      // Индентификатор советника
input double  K_Martin1     = 2.0;    // Множитель мартин 1
input double  K_Martin2     = 2.0;    // Множитель мартин 2
input double  K_Martin3     = 2.0;    // Множитель мартин 3
input int     OrdersClose   = 5;      // Ограничение лотности мартин1
input int     OrdersClose2  = 5;      // Ограничение лотности мартин2
input int     DigitsLot     = 2;      // Точность лотности
// Параметры индикатора
input string  sParametersMA = "";     // Параметры индикатора
input int     PeriodMA      = 14;     // Период мувинга
input int     MovingShift   = 1;      // Сдвиг мувинга
// Глобальные переменные
string AC;
datetime Start;
double dMA;
double MaxMartinLot;
double MaxMartinLot2;
//+-----------------------------------------------------------------------------------------------+
int OnInit()
  {
Start          = TimeCurrent();
MaxMartinLot   = Lot*MathPow(1.4,OrdersClose);
MaxMartinLot2  = Lot*MathPow(K_Martin2,OrdersClose2);
AC             = StringConcatenate(" ", AccountCurrency());
return(INIT_SUCCEEDED);
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick()
  {
// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.

// Если нет открытых ордеров, то входим в условие
      if(CountOrders()==0)
     {
// Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

// Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
   }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
int CountOrders() 
  {
   int cnt=0;
   int i=OrdersTotal()-1;
   for(int pos=i;pos>=0;pos--)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol()==_Symbol)
           {
            if(OrderMagicNumber()==Magic) cnt++;
           }
        }
     }
   return(cnt);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if(dMA > Open[1] && dMA < Close[1])  //Open[1] и Close[1]- цены открытия и закрытия каждого бара текущего графика.
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   if(dMA < Open[1] && dMA > Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
// Тикет ордера
   int iOTi = 0;   

   iOTi = OrderSend(Symbol(), OP_BUY, LOT(), Ask, Slippage, 0, 0, "", Magic, 0, clrNONE);
   
// Проверим открылся ли ордер
   if(iOTi > 0)
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
// Тикет ордера  
   int iOTi = 0;   
//Print(bCheckOrders());
   iOTi = OrderSend(Symbol(), OP_SELL, LOT(), Bid, Slippage, 0, 0, "", Magic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify(int iOTi)
  {
   int    iOTy = -1;    // Тип ордера
   double dOOP = 0;     // Цена открытия ордера
   double dOSL = 0;     // Стоп Лосс
   int    iMag = 0;     // Идентификатор советника
   double dSL  = 0;     // Уровень убытка
   double dTP  = 0;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if(OrderSelect(iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMag)
     {
// Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
      if(dOSL == 0)
        {
         if(iOTy == OP_BUY)
           {
            dSL = NormalizeDouble(dOOP - StopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP + TakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }

         if(iOTy == OP_SELL)
           {
            dSL = NormalizeDouble(dOOP + StopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP - TakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError(int iErr)
  {
   switch(iErr)
     {
      case 129:   // Неправильная цена
      case 135:   // Цена изменилась
      case 136:   // Нет цен
      case 138:   // Новые цены
         Sleep(1000);
         RefreshRates();
         break;

      case 137:   // Брокер занят
      case 146:   // Подсистема торговли занята
         Sleep(3000);
         RefreshRates();
         break;
     }
  }
//+-----------------------------------------------------------------------------------------------+
double LOT()
{
   int n=0;
   int m=0;
   int v=0;
   double OL=Lot;
   for (int j = OrdersHistoryTotal()-1; j >= 0; j--)
   {
      if (OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {
            if (OrderProfit()>0) 
            {

               if (n==0) OL=NormalizeDouble(OrderLots()+K_Martin1,DigitsLot);
               n++;
               
               if ((OL>=MaxMartinLot)&& (m==0)) OL=NormalizeDouble(OrderLots()*K_Martin2,DigitsLot);
               m++;
               
               if ((OL>=MaxMartinLot2) && (v==0)) OL=NormalizeDouble(OrderLots()*K_Martin3,DigitsLot);
               v++;
            }
            else
            {
               if (n==0) {return(Lot);}
               else {return(OL);}
            }
         }
      }
   }
   
   return(OL);
}
 
законопослушный гражданин #:

我需要EA不能在同一个蜡烛上开立新的订单。

void OnTick()
  {
  datetime cTime;
  static datetime time = 0;

  cTime = iTime(NULL, PERIOD_CURRENT, 0);

  if (time != cTime)
    time = cTime;
  else
    return;

// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.

// Если нет открытых ордеров, то входим в условие
      if(CountOrders()==0)
     {
// Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

// Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
   }
原因: