帆布很酷! - 页 20

 
Anatoli Kazharski:

有一个限制。最多可以做512个指标缓冲区 >>https://www.mql5.com/ru/docs/indicators

谢谢你。
是的,除了代码长度之外,数百个指示器缓冲区将是一种可怕的内存浪费。我的变体使用一个数组,其尺寸为:屏幕上的条数+最大周期。
 
Nikolai Semko:

一个由数百条移动平均线组成的超快速指标,在Canvas上实现。

100条MA线(周期步骤10)-计算和在屏幕上显示的时间-4-7毫秒


1000行MA(周期步骤1)-计算和显示的时间-20-30毫秒。


我还没有对代码进行过多的测试。可能会有虫子。只对一个像素厚的条形图实施(它被强制到这个比例)。此外,屏幕刷新率也没有得到优化。所有的线条都被计算出来,并在每一个刻度上完全输出。

据了解,平均数很简单?现在将对指数 进行同样的处理。

 
Dmitry Fedoseev:

你怎么知道平均数是简单的?现在你会对指数做同样的事吗?

这只是一个演示例子。所有类型的MA都可以实施。你所需要的只是你的愿望和必要性。随着指数的增加,代码将变得更加复杂。我建议你试一试。
 

为了说明速度...

通过鼠标指针改变两个参数

X--最大的MA周期变化

Y - MA周期变化的步骤


#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#property indicator_chart_window

double  Close[];
long Total;
int Ma=0;
int stepMa=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_SCALE,0,0);
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Total=SeriesInfoInteger(_Symbol,_Period,SERIES_BARS_COUNT);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   static int MaOld=-1,stepMaOld=-1;
   Ma=W.MouseX+100;
   stepMa=W.MouseY;
   if(stepMa<=0) stepMa=1;
   stepMa=1+stepMa/10;
   if(stepMa>Ma) stepMa=Ma-1;
   if(id==CHARTEVENT_CHART_CHANGE || MaOld!=Ma || stepMaOld!=stepMa)
     {
      ChartSetInteger(0,CHART_SCALE,0,0);
      CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
      nMA();
      MaOld=Ma; stepMaOld=stepMa;
     }
  }
//+------------------------------------------------------------------+

void nMA()
  {
   int preY=0;
   Canvas.Erase();
   double S=0;
   for(int i=0;i<Ma; i++) S+=Close[i];

   for(int Per=Ma;Per>0;)
     {
      double s=S;
      uint Clr=Grad((double)Per/Ma);
      for(int x=0; x<W.BarsInWind;x++)
        {
         int Y=(int)(Canvas.Y(s/Per)-0.5);
         if(x>0) if(fabs(Y-preY)>1) Canvas.Line(x-1,preY,x,Y,Clr);
         else Canvas.PixelSet(x,Y,Clr);
         if((Ma+x)<ArraySize(Close)) s=s-Close[x+Ma-Per]+Close[Ma+x]; else break;
         preY=Y;
        }
      for(int j=0; j<stepMa; j++) if(Per>0) {S=S-Close[Ma-Per]; Per--;} else break;
     }
   Canvas.Update();
  }
//+------------------------------------------------------------------+
uint Grad(double p)
  {
   static uint Col[6]={0xFF0000FF,0xFFFF00FF,0xFFFF0000,0xFFFFFF00,0xFF00FF00,0xFF00FFFF};
   if(p>0.9999) return Col[5];
   if(p<0.0001) return Col[0];
   p=p*5;
   int n=(int)p;
   double k=p-n;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+1];
   return ARGB(255,c1.c[2]+uchar(k*(c2.c[2]-c1.c[2])+0.5),
                   c1.c[1]+uchar(k*(c2.c[1]-c1.c[1])+0.5),
                   c1.c[0]+uchar(k*(c2.c[0]-c1.c[0])+0.5));
  }
//+------------------------------------------------------------------+
附加的文件:
MultiMA.mq5  8 kb
 
Nikolai Semko:

为了说明速度...

通过鼠标指针改变两个参数

X--最大的MA周期变化

Y - MA周期的步骤


很漂亮,但编译器会炸掉

can't open "..\MQL5\Include\Canvas\iCanvas.mqh" include file    MultiMA.mq5     9       11
 
Aleksey Vyazmikin:

它很美,但编译器在打架

当然,该库需要安装。在代码中,有一个指向这个库的链接。
 
Nikolai Semko:
当然,该库需要安装。在代码中,有一个指向这个库的链接。

谢谢你!这一切都在起作用!

如何使指标 在图表重绘/移位时重绘/移位?

 
Aleksey Vyazmikin:

谢谢你!这一切都在起作用!

如何让指标 在图表重绘/移位时重新绘制/移位?

这是它的工作方式。
 
Nikolai Semko:
这就是重绘的工作方式。

我的只有在鼠标移动时才工作。

 
Aleksey Vyazmikin:

我的只有在我移动鼠标时才会工作。

是的,有一个小错误。修正了它。

谢谢你的提醒。