キャンバスがカッコいい! - ページ 20

 
Anatoli Kazharski:

限界があります。最大512個のインジケーターバッファを作成可能 >>https://www.mql5.com/ru/docs/indicators

ありがとうございます。
そうですね、コードの長さに加えて、何百ものインジケーターバッファはメモリの無駄遣いになってしまいますね。私のバリアントは、画面上のバーの数 + 最大期間という次元の1つの配列を使用します。
 
Nikolai Semko:

数百本の移動平均線をCanvasで実装した超高速インジケーターです。

100 MAライン(ピリオドステップ10)-計算と画面表示の時間-4-7ミリ秒


1000 MAライン(期間ステップ1)-計算と表示のための時間-20-30ミリ秒。


あまりコードのテストはしていないのですが。バグがあるかもしれません。1ピクセルの太さのバーに対してのみ実装される(このスケールに強制的に合わせられる)。また、画面のリフレッシュレートも最適化されていません。全ての行程を計算し、1目盛りごとに完全に出力します。

平均値もシンプルに?今なら指数関数的に 同じことができる。

 
Dmitry Fedoseev:

どうして平均が単純だとわかるのですか?では、指数関数にも同じことをするのでしょうか?

これはあくまでデモの例です。あらゆるタイプのMAを実装することが可能です。必要なのは、あなたの欲求と必要性だけです。Expotentialを使用すると、コードが少し複雑になります。試してみることをお勧めします。
 

スピードを説明するために...

マウスポインターで2つのパラメータを変更する

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:

スピードを説明するために...

マウスポインターで2つのパラメータを変更する

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:

私のはマウスを動かしたときだけ動くんです。

そう、ちょっとしたバグがあったんです。修正しました。

ありがとうございます。

理由: