错误、漏洞、问题 - 页 577

 
papaklass:

...

好的。你的立场很明确。
 

甚至很难想象这样一个专家顾问,它在现实生活中缺乏一个核心的力量。例如,如果在测试器中,专家顾问在一年的历史上每天传递一个符号(这太多了!也许我们应该重写代码!),那么在现实生活中,它将平均加载CPU 1/250的功率=0.4%。

对于10个符号的EA来说--你得到的平均负载为4%。加载其他核心的意义不大。

 

至于康斯坦丁(Lizar)的想法,我认为它很好。但对于这种解决方案,我们需要将直接来自图表的事件和自定义生成的事件分开。对于自定义事件,我们可以有两个事件队列和两个处理程序,比如OnUserEvents。

自定义事件的一个有趣的补充是能够明确指定它们的优先级(比如从0到9),这可以让用户控制某些事件的抢占和处理。例如,这样的功能将允许执行价值较低的事件,并从队列中删除价值较高的事件(如果队列中充满了更重要的事件,就不会有新的事件被排入队列)。

papaklass:

我从来没有做过任何软件开发,所以我不能说软件开发人员的技术语言。我将描述我想从我的4核电脑和MT5中得到什么。一般来说,它看起来像这样。


现在可以处理几个工具了,开发人员创造了一个完全可行的解决方案。

2.关于测试员的工作和一堆核心。这是一个特例,将这一机制与真实交易进行比较是不正确的。解决测试者问题的本质是,有几个专家顾问变体(或者说是一个专家顾问+很多独特的参数集),在所有可用的核心/代理之间分配计算是合理的。因此,我们得到了整个任务集的异步性,但从单个代理的角度来看,一切都在同步进行。

3.谈到多线程,我们不是在谈论同时处理多个工具,而是同时处理多个事件(而且是在一个特定的单一代理内)。这在任何版本的终端中都不存在。

开发者也是可以理解的:开销太大,用户组合太 "杂","多线程 "专家顾问将访问的数据的同步问题太多,等等。

另一方面,与事件有关的想法没有得到合理的结论。好吧,实现 "多线程 "很昂贵,也很有问题,但有可能在终端本身最大限度地并行化进程和信息流+创建一套足以解决最大数量任务的处理程序(并且有一套正常的参数)。

 
papaklass:

我在M5上的专家顾问,在2010年1月4日至2011年9月1日期间,在12种货币上,在1436秒(24分钟)内完成一次交易,同时进行了5687次交易。只有一个核心被加载,其他三个是空闲的。也就是说,在每个单次通过时,我损失了3/4的时间,因为该平台不使用计算机功率。在调试策略时,这是平台的一个显著缺点。只有在优化过程中,核心才会被充分使用。但优化比单次运行要稀少得多。而大量的时间被浪费在单次运行上。

"失去3/4的时间 "的做法表明,你认为:使用多线程只是错过了一个机会,是开发者的一个明显缺陷。

不幸的是,在顺序任务上的多线程(而单个测试员通过是一个顺序任务)并不是免费提供的。在现实中,多线程对进程同步有巨大的(有时是多个)损失。事实上,对共享资源的所有访问都必须与同步器捆绑在一起。

我们特意把测试器从终端移到一个单独的进程中,只是为了让它在99%的测试时间里在没有任何锁的情况下在一个单线程中工作。这导致了显著的速度提升。

"让我们把多任务塞给每个EA "的建议来自于对这种情况下多线程的成本(总减速)和后果(减速+把99%的非专业开发者的屋顶炸开)的完全误解。


我们有效地解决了在终端、测试器中应用多任务的问题,并在远程代理和MQL5云端网络模式中实现了几乎无限的功率扩展。


如果我打开12个图表,在每个图表上放一个指标,那么我可以看到终端在某些时候是如何滞后的。从论坛上的留言来看,这不仅仅发生在我身上。如果我需要增加工具和指标的数量,终端会崩溃。而一个核心将被使用,而其余的将被休息。那么,加载其他核心有意义吗? 如果我们将终端进程 分配到各核心中,即充分利用计算机的功率,我们将能够在另一个层面上解决任务。这就是我的意思。

如果有12个不同的宪章,有不同的字符,这意味着每个图表的每个字符显然是在自己的线程中运行,而不影响其他的。

如果图表开始放缓,原因很平庸--其中一个指标非常不经济。在这种情况下,再多的多任务处理也无济于事,因为根源在于程序员的工作,他在头脑中写下指标,而不关心效率。

 

我不能得到反向图表,有些东西是错误的,新的条形图 在这个变体上出现故障。

我一直在摆弄的原始指标见附件

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---- проверка количества баров на достаточность для расчета
   for(int numb=0; numb<8; numb++) if(BarsCalculated(RSI_Handle[numb])<rates_total) return(RESET);
   if(rates_total<min_rates_total) return(RESET);

//---- объявления локальных переменных 
   int to_copy;

//---- расчеты необходимого количества копируемых данных
   if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора
      to_copy=rates_total-1;                   // стартовый номер для расчета всех баров
   else to_copy=rates_total-prev_calculated+1; // стартовый номер для расчета новых баров
   
//---- копируем вновь появившиеся данные в массивы
   if(CopyBuffer(RSI_Handle[0],0,0,to_copy,Buffer1)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[1],0,0,to_copy,Buffer2)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[2],0,0,to_copy,Buffer3)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[3],0,0,to_copy,Buffer4)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[4],0,0,to_copy,Buffer5)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[5],0,0,to_copy,Buffer6)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[6],0,0,to_copy,Buffer7)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[7],0,0,to_copy,Buffer8)<=0) return(RESET);
   
   //мой кусок отсель   
   if (Reverse)
      {
         int start=prev_calculated;
         for(int i=start;i<rates_total;i++)
            {
               Buffer1[i]=100-Buffer1[i];
               Buffer2[i]=100-Buffer2[i];
               Buffer3[i]=100-Buffer3[i];
               Buffer4[i]=100-Buffer4[i];
               Buffer5[i]=100-Buffer5[i];
               Buffer6[i]=100-Buffer6[i];
            }
         Buffer1[0]=100-Buffer1[0];
         Buffer2[0]=100-Buffer2[0];
         Buffer3[0]=100-Buffer3[0];
         Buffer4[0]=100-Buffer4[0];
         Buffer5[0]=100-Buffer5[0];
         Buffer6[0]=100-Buffer6[0];
       }  
   //досель    

//----     
   return(rates_total);
  }
//+------------------------------------------------------------------+

附加的文件:
Multi_RSI.mq5  15 kb
 

请告知问题出在哪里。

我正在编写一个多币种的

我得到了MA指标手柄

maHandle_EURUSD=iMA("EURUSD",PERIOD_H1,MA_Period_EURUSD,MA_Shift_EURUSD,MODE_SMA,PRICE_CLOSE);

maHandle_GBPUSD=iMA("GBPUSD",PERIOD_H1,MA_Period_GBPUSD,MA_Shift_GBPUSD,MODE_SMA,PRICE_CLOSE); 

我对锦标赛中允许的其余10种货币也做了同样的工作,但我在测试过程中得到了错误4801,所有12种货币都在历史中(我认为)。

我在欧元兑美元图表上测试

专家顾问正在测试GBPUSD(我已经在设置中这样设置了,以优化它)。

 
Lazarev:

请告知问题出在哪里。

我正在编写一个多币种的

我得到了MA指标手柄

我对锦标赛中允许的其余10种货币也做了同样的工作,但我在测试过程中得到了错误4801,所有12种货币都在历史中(我认为)。

我在欧元兑美元图表上测试

专家顾问正在测试GBPUSD(我已经在设置中这样设置了,以优化它)。

我需要在SymbolSelect 市场观察中添加符号
 

papaklass:

现在回答我这样一个简单的问题 ....

我将更简单地回答,即使不礼貌。

不幸的是,你完全偏离了主题,发表的言论只显示了对这些过程的肤浅想法。

恐怕我们的大部分技术论点都不会被理解,甚至同步化的基本问题和对其提供的损失也不会被理解。

因此,没有必要提出 "你告诉我们你的论据,我们来猜测 "的要求,这种情况是完全可以理解的

 

对于一个新手来说,我找不到这些问题的答案。

1) 当向动态数组 添加另一个元素时,是否需要用ArrayResize来扩展它?

2) 在MQL5中是否有一个函数可以从动态数组i中删除一个元素(例如数组中间的一个)?如果没有,最好的方法是什么?

Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Fia:

作为一个新手,我找不到这些问题的答案。

1) 当你向动态数组 添加另一个元素时,你必须用ArrayResize来扩展它吗?

你用一些储备来制作数组的大小,当接近极限时,你就增加大小。没有自动调整大小和添加到最后。请看ArrayInitialize()函数的例子