English Русский 中文 Español Deutsch Português
ラグを最小に抑えた有効な平均化アルゴリズム:インディケータでの使用

ラグを最小に抑えた有効な平均化アルゴリズム:インディケータでの使用

MetaTrader 4 | 17 2月 2016, 13:38
987 0
Nikolay Kositsin
Nikolay Kositsin

はじめに

私はテクニカル分析やトレーディングシステムにとって平滑化アルゴリズムがいかに重要であるか説明する必要はないと思います。実質的にすべてのインディケータコードは明示的なまたは暗黙的な平均化アルゴリズムを持つものです。オンラインのトレーディングプラットフォームやクライアントターミナルをよく見ると、それらのほとんど、そしてインディケータのほとんどはもっともシンプルな(もっとも効果的とはいいがたいですが)平均化アルゴリズムを使用しているのが判ります。

現在までにもっとずっと効果的な平均化アルゴリズムが開発されてきています。ただ、それらを通常インディケータに応用する試みは、アルゴリズムの複雑さゆえに、ただプログラマーの忍耐が続かない結果に終わり、つねに決して正確に動作しないインディケータを最大1つまたは2つ作成しました。その後、この方向で作業することにうんざりするのでした。単純平均の基本的メリットは、それらが常にいつでもどこにも適応可能なシンプルなカスタム関数であることです。


主題

本稿では、かなりシンプルなカスタム関数として提供される最小ラグを伴う MQL4 の効果的な平均化アルゴリズムの知識があるトレーダー向けに説明をしたいと思います。こういった関数の使用はテクニカルインディケータの使用に比べ、だんぜん複雑というわけではありません。関数はずいぶん以前に書かれ、その処理クオリティーも長期にわたり確認されてきました。それには不具合、問題、計算の誤りは発見されていません。よって、以下のアルゴリズムを考察していきます。
- JJMASeries () - 適用可能な JMA 平滑化アルゴリズム
- JLiteSeries() - 適用可能なアルゴリズムを持たない JMA 平滑化アルゴリズム
- JurXSeries () - JRSX インディケータから取られる超線形平滑化アルゴリズム
- ParMASeries() - 放物線近似を基にした平滑化アルゴリズム
- LRMASeries () - 線形回帰を基にした平滑化アルゴリズム
- T3Series () - ティルソンアルゴリズムを基にした平滑化アルゴリズム

平滑化関数の実現

関数は次のようなのファイルとして表されています。:JJMASeries.mqh、JLiteSeries. mqh, JurXSeries. mqh、ParMASeries.mqh、LRMASeries.mqh、T3Series.mqh。

それらを呼びだす関数は完全に同一で、唯一の異なる点は、外部変数を持たない関数があることです。そのような関数は通常、外部変数として動作するカスタム配列およびインディケータ配列を処理するのに使われます。私見ですが、それはかならずしも便利であるとは限りません。そのため、そういった関数は配列ではなく通常の変数を処理するのに使う方がずっと好ましいでしょう。この場合、1つの計算サイクル内でこれらアルゴリズムを用いて無限の平滑化を行うことが可能です。本稿では関数コードを提供する必要はないと考えます。コードは別のアルゴリズムを基にして似たような関数を作成しようとしている方にのみ興味深いものとなることでしょう。われわれが興味あるのはインディケータコード内の関数呼び出しアルゴリズムだけです。

JJMASeries ()
それらの学習を関数 JJMASeries() から始めます。
double JJMASeries(int number, int din, int MaxBar, int limit, 
                  int Phase, int Length, double series, int bar,
                  int& reset)

ファイル JJMASeries.mqh には4つの関数があります。JJMASeries()、JJMASeriesResize()、JJMASeriesAlert() 、JMA_ErrDescr() です。このファイルにはグローバル変数として宣言される変数も入っています。


関数 JJMASeries() はテクニカルインディケータや Expert Advisor を書く際、JMA アルゴリズムを使用し、従来の平均化計算をこのアルゴリズムに置き換えます。ます。この関数は「制限」パラメータが値ゼロを採る場合、動作しません。JJMASeries 向けに作成したインディケータはすべてこの制限を考慮するようにできています。ファイルはフォルダ MetaTrader\experts\include\ に保存します。「バー」変数が MaxBar 変数の値を越えると、JJMASeries() 関数はこのバーに対して値ゼロを返すことに注意が必要です。そしてそのため、この値はインディケータ計算によっては、分数という言い方では存在しない可能性があるのです。JJMASeries() は30バーの結果としてもゼロを返すのです!

JJMASeries() のこのバージョンは、Expert Advisor によって使用されるカスタムインディケータ内で処理される場合、Expert Advisor をサポートします。その上、JJMASeries() のこのバージョンは、DO 記述や変数を保存したままエキスパートのコードに入れられたインディケータコード全体で処理される場合Expert Advisor をサポートします。JJMASeries を使用してインディケータや Expert Advisor をコード化する際には、変数に nJMA... や dJMA... で始まる名前をつけることはお薦めできません。JJMASeries() 関数は、JJMASeries() を呼びだすときに毎回、そういったカスタム関数の呼び出し時に固有の番号を持つことを条件として、その他のカスタム関数の内部コードで使用されます。JJMASeries() のこのバージョンは現行チャートの時系列配列に関連する変数を処理します。この関数が他のチャートの時系列配列で計算される変数を処理するのに使われると、その計算は誤りとなります。

インプット:
- number - インディケータコード(0, 1, 2, 3, ...)における JJMASeries() 関数呼び出し回数
- din - パラメータ。これにより各バーのパラメータ「長さ」および「フェーズ」が変更可能となります。0 - パラメータは変わりません。その他の値でパラメータ変更が可能です。
- MaxBar - 計算されたバー数の最大値。通常、『周期』がバー数である場合のバー-1-周期で、そこでは初期シリーズ値は産出されません。
- limit - 未計算バープラス1の数量、または最終の未計算バー数。バー-IndicatorCounted()-1 に等しくなります。
- Length - 平均化の深さ
- Phase - -100 ~ +100 の範囲で変化するパラメータ。発信処理のクオリティーに影響を与えます。
- series - インプット。JJMASeries() の計算に入っています。
- bar - 計算されるバー数。このパラメータは DO 記述によって最大値からゼロまで変化します。最大値はつねに 'limit' の値と等しくなります。


出力パラメータ:
- JMASeries() - JMA 値。パラメータ 'bar' の値が MaxBar-30 を越えると、関数 JJMASeries() はつねにゼロを返します。
- reset - 関数計算にエラーが発生する場合、ゼロ以外の値を参照によって返すパラメータ。計算に問題なければゼロを返します。このパラメータは変数でなくてはなりませんが、値ではありません!


関数初期化
JJMASeries() 関数を呼びだす前、すでに計算済みのバー数がゼロであれば、関数の内部バッファ変数はサイズを変更されます(カスタムインディケータや Expert Advisor の初期化ブロックでそれを行うほうが良いでしょう)。このためには、ヘルパー関数 JJMASeriesResize() を使用して次のパラメータを用い、JJMASeries() の変数を呼びだす必要があります。: JJMASeriesResize(number+1);パラメータ 'number' (MaxJMA.number) を JJMASeriesを呼びだす回数に等しくする必要があります。すなわち、'number'の最大値よりも1大きくするのです。JJMASeries() のバッファサイズを変更するのと共に、初期化ブロック内で、JJMASeriesAlert() を用いて JJMASeries() のインプットであるインディケータのインプット値「長さ」と「フェーズ」が、変化範囲内にあるかどうか確認します。

JJMASeriesAlert(int Number, string name, int ExternVar)

- Number - 値を2つ取るパラメータ。:0 - インプット ExternVar がJJMASeries() のインプットである「長さ」の変化範囲内にあるか確認します。1 - インプット ExternVar が JJMASeries() のインプットである「フェーズ」の変化範囲内にあるか確認します。
- name - 警告を出すインプット ExternVar の文字列名。

- ExternVar - インディケータのインプット

エラー表示

デバッグ中、インディケータコードまたは Expert Advisor はエラーを出すことがあります。エラーの原因をみつけるには、ログファイルを閲覧する必要があります。関数 JJMASeries() は \MetaTrader\EXPERTS\LOGS\ という名前のフォルダー内のログファイルにエラーすべてを記録します。JJMASeries() 関数に先行するコード内で、この関数呼び出し以前に MQL4 のエラーが発生する場合、この関数はエラーコードおよび内容をログファイルに記録します。JJMASeries() 関数の実行中に JJMASeries() アルゴリズム内で MQL4 eのエラーが発生した場合も、この関数はエラーコードおよび内容をログファイルに記録します。誤った JJMASeries() 関数呼び出し「数」が指定されたり、バッファ変数サイズ nJJMAResize.Size の定義に誤りがあると、不正なパラメータに関するメッセージがログファイルに記録されます。 'limit' パラメータの不正な定義に関する情報もログファイルに記録されます。

init() 関数実行中に JJMASeries バッファのサイズ変更が正常に行われないと、関数 JJMASeriesResize() がサイズ変更の失敗に関する情報をログファイルに記録します。外部 DO 記述によって JJMASeries() 関数を呼び出すとき、'bar' パラメータ変更の正確なシーケンスに違反があれば、この情報もログファイルに記録されます。コード内のエラーはそれを実行する際さらなるエラーを出すとみなされます。このため、JJMASeries() 関数がログファイルに一度に複数エラーを記録する場合、これらエラーは発生した順番に削除されていきます。正しくコード化されたインディケータでは、JJMASeries() 関数はオペレーションシステム障害のみログファイルに記録します。関数呼び出しごとに起こる、再起動しているインディケータや Expert Advisor でのバッファ変数のサイズ変更の記録は例外です。MQL4 のエラーはすべて、ログファイル内で関数 GetLastError() を用いて取得されたコードに従って、コードおよびエラー内容をフラッシュする関数JMA_ErrDescr() によってログファイルに記録されます。

典型的な JJMASeries() 関数呼び出し(エントリー価格のダブル JMA 平滑化)

/*
For the indicator to operate, files 
JJMASeries.mqh 
PriceSeries.mqh 
must be placed into the directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
into the directory: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+   
//|                                                        J2JMA.mq4 | 
//|                       JMA code: Copyright © 2005, Jurik Research | 
//|                                          http://www.jurikres.com/ | 
//|    MQL4 JJMASeries+J2JMA: Copyright © 2006,     Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+   
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing of the indicator in the main window
#property indicator_chart_window 
//---- amount of indicator buffers
#property indicator_buffers 1 
//---- color of the indicator
#property indicator_color1 Magenta 
//---- INDICATOR INPUTS 
extern int Length1 = 5; // depth of the first smoothing 
extern int Length2 = 5; // depth of the second smoothing 
// the first smoothing parameter changing within the range between -100 and +100, 
//it influences the transient quality; 
extern int Phase1  = 100;
// the second smoothing parameter changing in the range between -100 and +100, 
//it influences the transient quality; 
extern int Phase2  = 100;
// indicator shifting along the time axis 
extern int Shift   = 0;
/* Choosing of prices to be used for indicator calculations 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- indicator buffers
double J2JMA[];
//---- floating points variables  
double Temp_Series; 
//----+ Introducing of function JJMASeries 
//----+ Introducing of function JJMASeriesResize 
//----+ Introducing of function JJMASeriesAlert  
//----+ Introducing of function JMA_ErrDescr  
#include <JJMASeries.mqh>   
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+------------------------------------------------------------------+ 
//| J2JMA indicator initialization function                          | 
//+------------------------------------------------------------------+ 
int init() 
  {  
//---- defining of the chart drawing style
   SetIndexStyle (0, DRAW_LINE); 
//---- 1 indicator buffer is used for calculations
   SetIndexBuffer(0, J2JMA);
//---- horizontal shift of the indicator line 
   SetIndexShift (0, Shift);  
//---- placing of indicator values that will not be visible in the chart
   SetIndexEmptyValue(0, 0); 
//---- name for data windows and label for subwindows 
   IndicatorShortName ("J2JMA(Length1=" + Length1 + ", Phase1=" + Phase1 +
                       ", Length2=" + Length2 + ", Phase2=" + Phase2 + 
                       ", Shift=" + Shift + ")"); 
   SetIndexLabel (0, "J2JMA"); 
//---- Setting the indicator imaging precision format
   IndicatorDigits(Digits);
//----+ Resizing of buffer variables of function JJMASeries, 
//nJMAnumber=2(two calls for function JJMASeries)
   if(JJMASeriesResize(2) != 2)
       return(-1);
//---- setting alerts for nonaccepted values of external variables
   JJMASeriesAlert (0,"Length1", Length1);
   JJMASeriesAlert (0,"Length2", Length2);
   JJMASeriesAlert (1,"Phase1", Phase1 );
   JJMASeriesAlert (1,"Phase2", Phase2 );
   PriceSeriesAlert(Input_Price_Customs);
//---- complete initialization
   return(0); 
  } 
//+------------------------------------------------------------------+   
//| J2JMA iteration function                                         | 
//+------------------------------------------------------------------+ 
int start() 
  { 
//---- Bar quantity control over sufficiency for further calculations
   if(Bars - 1 < 61)
       return(0);
//----+ Introducing of integer variables and obtaining of bars already computed
   int reset, MaxBar1, MaxBar2, counted_bars = IndicatorCounted();
//---- checking for possible errors
   if(counted_bars < 0) 
       return(-1);
//---- the last counted bar should be recalculated 
//---- (without this recalculation for counted_bars, function JJMASeries will not 
//     operate correctly!!!)
   if(counted_bars > 0) 
       counted_bars--;
//---- determining of the oldest bar number, starting from which new bars
//     will be recalculated
   int limit = Bars - counted_bars - 1; 
   MaxBar1 = Bars - 1; 
   MaxBar2 = MaxBar1 - 30;
 
//----+ INDICATOR COMPUTING BASIC LOOP 
   for(int bar = limit; bar >= 0; bar--)
     {
       // Call for function PriceSeries to get the entry price Series
       Temp_Series = PriceSeries(Input_Price_Customs, bar);
       // Two calls fro function JJMASeries numbered as 0,1. Parameters 
       //nJMA.Phase and nJMA.Length 
       //do not change at each bar (nJMA.din=0)
       //(In the second call, parameter nJMA.MaxBar is decreased by 30 since it is 
       //the repeated JMA smoothing)
       Temp_Series = JJMASeries(0,0,MaxBar1,limit,Phase1,Length1,
                                Temp_Series,bar,reset);
       // checking for errors in the preceding operation
       if(reset != 0)
           return(-1);
       Temp_Series = JJMASeries(1,0,MaxBar2,limit,Phase2,Length2,
                                Temp_Series,bar,reset);
       // checking for errors in the preceding operation
       if(reset != 0)
           return(-1);
       J2JMA[bar] = Temp_Series;
     }
//---- complete calculation of indicator values
   return(0); 
  } 
//+--------------------------------------------------------+


よって、本関数適用においては、以下のポイントを強調します。
1. インディケータコードの冒頭に行 #include を持つファイルJJMASeries.mqh のパーツとしての関数宣言。宣言されるのは変数と4つの関数:JJMASeries()、 JJMASeriesResize()、JJMASeriesAlert()、JMA_ErrDescr() です。
2. 初期化ブロックにおいて関数 JJMASeriesResize() を用いて関数 JJMASeries() によるバッファエレメントのサイズ変更。
3. 初期化ブロックにおける、JJMASeriesAlert() 関数を使用しての、関数 JJMASeries() の外部変数であるインディケータ外部変数の値が正しいかどうかの確認。
4. 適切なエラー制御を行う DO 記述を用いて作成される関数 JJMASeries() 自体の呼び出し。>


その他の関数

その他関数を呼びだすアルゴリズムは上記で考察したアルゴリズムとほとんど同じですが、関数内で利用可能な外部変数の数量にいくらか違いがあります。
JJMASeries (int number, int din, int MaxBar, int limit, int Phase,
            int Length, double series, int bar, int&reset)
JLiteSeries(int number, int din, int MaxBar, int limit, int Phase,
            int Length, double series, int bar, int&reset)
JurXSeries (int number, int din, int MaxBar, int limit,
            int Length, double series, int bar, int&reset)
T3Series   (int number, int din, int MaxBar, int limit, int Phase,
            int Length, double series, int bar, int&reset )
ParMASeries(int number, int MaxBar, int limit, int period, 
            double series, int bar, int&reset)
LRMASeries (int number, int MaxBar, int limit, int period, 
            double series, int bar, int&reset )


当然のことながら、関数 JJMASeries() および JLiteSeries() は同一の Expert Advisor やインディケータ内で互換性はありません。実際、関数名JJMASeries() を持つ同一の JMA コードが適応なしでファイル JLiteSeries.mqh に入っています。Expert Advisor やインディケータで関数 JJMASeries() を関数 JLiteSeries() と置き換えるには、行 #include を #include と置き換えるだけで十分です。ファイル JLiteSeries.mqh の関数呼び出しはすべて、ファイル JJMASeries.mqh の関数に対するものと一致している関数の呼び出しであるとみなされます。

その他の関数は同一インディケータや Expert Advisor のコード内では完全に互換性があります。関数 ParMASeries() および LRMASeries() では、外部変数の値は 501 に制限されています。もっと大きな値が必要な場合は、それぞれファイルParMASeries.mqh または LRMASeries.mqh にある関数 ParMASeries() に対するバッファ dParMA.TempBuffer[][501] および dParMA.TEMPBUFFER[][501]、または関数 LRMASeries() に対するバッファ dLRMA.TempBuffer[][501] および dLRMA.TEMPBUFFER[][501] の最初の(ゼロではない!)パラメータを変更する必要があります。>


関数 JurXSeries()
以下は関数 JurXSeries() の典型的な呼び出しです(追加平滑化を伴うエントリー価格の超線形平滑化)。

/*
For the indicator to operate, it is necessary to place files 

JurXSeries.mqh, 
JJMASeries.mqh, 
PriceSeries.mqh,  
to directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
to directory: MetaTrader\indicators\
This indicator is based on the smoothing algorithm of indicator JRSX.
The final result of this indicator bear some resemblance to 
double JMA smoothing, but is less perfect since it is simpler.
 
*/
//+------------------------------------------------------------------+
//|                                                        JJurX.mq4 | 
//|                           Copyright © 2006,     Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in the main window
#property indicator_chart_window 
//---- amount of indicator buffers
#property indicator_buffers 1 
//---- color of the indicator
#property indicator_color1 Gold
//---- INDICATOR INPUTS 
extern int JurX_Length  = 5; // depth of JurX smoothing 
extern int JJMA_Length  = 4; // depth of JJMA smoothing 
// parameter of JJMA smoothing ranging between -100 and +100 
// influences the transient quality; 
extern int JJMA_Phase   = -100;
extern int Shift        = 0;      // indicator shift along the time axis 
/* Choosing of prices underlying the indicator calculations 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- indicator buffers
double Ind_Buffer[];
//---- floating point variables  
double Price,JurX,JJurX,Error;
//+------------------------------------------------------------------+
//----+ Introducing of function JJMASeries 
//----+ Introducing of function JJMASeriesResize 
//----+ Introducing of function JJMASeriesAlert  
//----+ Introducing of function JMA_ErrDescr  
#include <JJMASeries.mqh> 
//+------------------------------------------------------------------+
//----+ Introducing of function JurXSeries
//----+ Introducing of function JurXSeriesResize
//----+ Introducing of function JurXSeriesAlert 
//----+ Introducing of function JurX_ErrDescr  
#include <JurXSeries.mqh> 
//+------------------------------------------------------------------+ 
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+------------------------------------------------------------------+
//| JJurX indicator initialization function                          | 
//+------------------------------------------------------------------+ 
int init() 
{  
//---- defining of the charting style
SetIndexStyle (0,DRAW_LINE); 
//---- 1 indicator buffer is used to calculate
SetIndexBuffer(0,Ind_Buffer);
//---- horizontal shift of the indicator line 
SetIndexShift (0, Shift); 
//---- setting indicator values that will not be visible in the chart
SetIndexEmptyValue(0,0); 
//---- name for data windows and label for subwindows 
IndicatorShortName ("JJurX( JurX_Length="+JurX_Length+", Shift="+Shift+")"); 
SetIndexLabel (0, "JJurX"); 
//---- Setting the indicator imaging precision format
IndicatorDigits(Digits);
//----+ Resizing buffer variables of function JurXSeries, 
//      nJurXnumber=2
//(To calls for function JurXSeries)
if (JurXSeriesResize(2)!=2)return(-1);
//----+ Resizing buffer variables of function JJMASeries,
//      nJMAnumber=1
//(One call for function JJMASeries)
if (JJMASeriesResize(1)!=1)return(-1);
//---- setting alerts for nonaccepted values of external variables  
JurXSeriesAlert(0,"JurX_Length",JurX_Length); 
JJMASeriesAlert(0,"JJMA_Length",JJMA_Length); 
JJMASeriesAlert(1,"JJMA_Phase",JJMA_Phase); 
PriceSeriesAlert(Input_Price_Customs);
//---- complete initialization
return(0); 
} 
//+-----------------------------------------------------------------------------+
//| JJurX iteration function                                                    | 
//+-----------------------------------------------------------------------------+
int start() 
{ 
//---- Bar quantity control over sufficiency for further calculations
if (Bars-1<JurX_Length+32)return(0);
//----+ Introducing of integer variables and obtaining of bars already computed
int reset,MaxBar,counted_bars=IndicatorCounted();
//---- checking for possible errors
if (counted_bars<0)return(-1);
//---- the last counted bar should be recalculated 
//(without this recalculation for counted_bars, function JurXSeries will not 
// operate correctly!!!)
if (counted_bars>0) counted_bars--;
//---- determining of the oldest bar number, starting from which new bars
//     will be recalculated
int limit=Bars-counted_bars-1; 
determining of the oldest bar number, starting from which all bars
//     will be recalculated
MaxBar=Bars-1; 
 
//----+ INDICATOR COMPUTING BASIC LOOP 
for(int bar=limit;bar>=0;bar--)
 {
  //----+ Call for function PriceSeries to get the entry
  //      price Series
  Price=PriceSeries(Input_Price_Customs,bar);
  //----+ One call for function JurXSeries numbered as 0. 
  //Parameter nJJurX.Length does not change on each bar (nJurXdin=0)
  JurX=JurXSeries(0,0,MaxBar,limit,JurX_Length,Price,bar,reset); 
  //----+ checking for errors in the preceding operation
  if(reset!=0)return(-1); 
  //----+ detection of error in calculations of parameter JurX
  //----+ the second call for function JurXSeries numbered as 1. 
  //Parameter nJJurX.Length does not change on each bar (nJurXdin=0)
  Error=JurXSeries(1,0,MaxBar,limit,JurX_Length,100,bar,reset); 
  //----+ checking for errors in the preceding operation
  if(reset!=0)return(-1);
  if(Error==0)Error=100;
  JurX*=100/Error;
  //----+ Call for function JJMASeries numbered as 0. 
  //      Parameters nJMA.Phase and nJMA.Length do not change on each bar 
  //      (nJMA.din=0)
  JJurX=JJMASeries(0,0,MaxBar,limit,JJMA_Phase,JJMA_Length,JurX,bar,reset);
  //----+ checking for errors in the preceding operation
  if(reset!=0)return(-1);
  Ind_Buffer[bar]=JJurX;                 
 }
//---- complete calculation of indicator values
return(0); 
} 
//+-------------------------------------------------------------------------+


この例では、関数 JurXSeries() はエントリー価格と定数の両方を平均化することに留意が必要です。低数値で平均化結果を割っているので、平滑化エラーが出ます。価格系列平滑化のより精密な結果を取得するには、平滑化結果をこのエラー値で割る必要があります。われわれの場合、それが行われました。以下の2つのケースでは、分子と分母が個別に平滑化されているため、上記の手順は必要ありません。そのようなエラーは他の平滑化関数には発生しません。

以下は関数 JJMASeries() および JurXSeries() の典型的な呼び出しです(追加平滑化を伴う CCI 類似体)。

/*
For the indicator to operate, it is necessary to place files 
JJMASeries.mqh
JurSeries.mqh 
PriceSeries.mqh 
to directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
to directory: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+   
//|                                                        JCCIX.mq4 |
//|                               Copyright © 2006, Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+    
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in a separate window
#property indicator_separate_window
//---- amount of indicator buffers
#property indicator_buffers  1
//---- colors of indicator
#property indicator_color1  BlueViolet
//---- parameters of the indicator horizontal levels
#property indicator_level1  0.5
#property indicator_level2 -0.5
#property indicator_level3  0.0
#property indicator_levelcolor MediumBlue
#property indicator_levelstyle 4
//---- INDICATOR INPUTS 
extern int  JJMA.Length = 8;  // depth of JJMA smoothing of entry price
// depth of JurX smoothing of the obtained indicator 
extern int  JurX.Length = 8;
// parameter ranging between -100 and +100 influences 
// the smoothing transient quality
extern int  JJMA.Phase = 100;
 /* Choosing of prices underlying the indicator calculations  
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- indicator buffers
double Ind_Buffer1[];
//---- integer constans 
int    w;
//+------------------------------------------------------------------+
//----+ Introducing of function JJMASeries 
//----+ Introducing of function JJMASeriesResize 
//----+ Introducing of function JJMASeriesAlert  
//----+ Introducing of function JMA_ErrDescr  
#include <JJMASeries.mqh> 
//+------------------------------------------------------------------+ 
//----+ Introducing of function JurXSeries
//----+ Introducing of function JurXSeriesResize
//----+ Introducing of function JurXSeriesAlert 
//----+ Introducing of function JurX_ErrDescr  
#include <JurXSeries.mqh> 
//+------------------------------------------------------------------+  
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+------------------------------------------------------------------+ 
//| JCCIX initialization function                                    |
//+------------------------------------------------------------------+
int init()
 {
//---- indicator drawing styles
   SetIndexStyle(0,DRAW_LINE);
//---- 1 indicator buffer is used for calculations. 
   SetIndexBuffer(0,Ind_Buffer1);
//---- setting of the indicator values that will not be visible in the chart
   SetIndexEmptyValue(0,0); 
//---- names for data windows and labels for subwindows
   SetIndexLabel(0,"JCCIX");
   IndicatorShortName("JCCIX(JJMA.Length="+JJMA.Length+", JurX.Length"+
                      JurX.Length+")");
//---- Setting imaging precision format (count of characters after decimal point) 
//to visualize the indicator values  
   IndicatorDigits(2);
//----+ Resizing buffer variables of function JurXSeries, 
//      nJurXnumber=2
//(Two calls for function JurXSeries)
   if (JurXSeriesResize(2)!=2)return(-1);
//----+ Resizing buffer variables of function JJMASeries, 
//      nJMAnumber=1
//(One call for function JJMASeries)
   if (JJMASeriesResize(1)!=1)return(-1);
//---- setting alerts for nonaccepted values of external variables
   JurXSeriesAlert (0,"JurX.Length",JurX.Length);
   JJMASeriesAlert (0,"JJMA.Length",JJMA.Length);
   JJMASeriesAlert (1,"JJMA.Phase",JJMA.Phase);
   PriceSeriesAlert(Input_Price_Customs);
//---- setting the bar number, starting from which the indicator will be 
//     drawn  
   SetIndexDrawBegin(0,JurX.Length+31);
//---- coefficients initialization to compute the indicator 
   if (JurX.Length>5) w=JurX.Length-1; else w=5;
//---- initialization complete
   return(0);
  }
//+------------------------------------------------------------------------+
//|  JCommodity Channel IndexX                                             |
//+------------------------------------------------------------------------+
int start()
  {
//---- Introducing of floating point variables    
double price,Jprice,JCCIX,UPCCI,DNCCI,JUPCCIX,JDNCCIX; 
//----+ Introducing of integer variables and getting bars already computed
int reset,MaxBar,MaxBarJ,limit,counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0)return(-1);
//---- the last counted bar must be recalculated 
//---- (without this recalculation for counted_bars, functions JJMASeries 
//and JurXSeries will not work correctly!!!)
if (counted_bars>0) counted_bars--;
//---- determining of the oldest bar number, starting from which new bars
//     will be recalculated
limit=Bars-counted_bars-1; 
//---- determining of the oldest bar number, starting from which all bars
//     will be recalculated
MaxBar=Bars-1; MaxBarJ=MaxBar-30;
//---- correction of the start calculated bar in the loop
if(limit>=MaxBar)limit=MaxBar;
 
for(int bar=limit; bar>=0; bar--)
 { 
   //----+ Call for function PriceSeries to get entry 
   //      price Series
   price=PriceSeries(Input_Price_Customs, bar);
   //+----------------------------------------------------------------
   //----+ One call for function JJMASeries numbered as 0 
   //----+ Parameters nJMA.Phase and nJMA.Length do not change within  
   //      each bar (nJMA.din=0)
   //+---------------------------------------------------------------+   
   Jprice=JJMASeries(0,0,MaxBar,limit,JJMA.Phase,JJMA.Length,price,
                     bar,reset);
   //----+ check for errors in the preceding operation
   if(reset!=0)return(-1);
   //+---------------------------------------------------------------+    
   UPCCI=price-Jprice;         
   DNCCI=MathAbs(UPCCI);
   //----+ Two calls for function JurXSeries numbered as 0 and 1. 
           Parameter nJJurXLength does not 
   //change within each bar (nJurXdin=0)
   //----+ check for errors in the preceding operation
   JUPCCIX=JurXSeries(0,0,MaxBarJ,limit,JurX.Length,UPCCI,bar,reset); 
   if(reset!=0)return(-1); 
   JDNCCIX=JurXSeries(1,0,MaxBarJ,limit,JurX.Length,DNCCI,bar,reset); 
   if(reset!=0)return(-1); 
   //----+
   if (bar>MaxBarJ-w)JCCIX=0;
   else 
     if (JDNCCIX!=0)
       {
        JCCIX=JUPCCIX/JDNCCIX;
        if(JCCIX>1)JCCIX=1;
        if(JCCIX<-1)JCCIX=-1;
       }
     else JCCIX=0;
   Ind_Buffer1[bar]=JCCIX; 
   //----+
 }
//----
   return(0);
  }
//+-------------------------------------------------------------------+


次の事実を考慮する必要があります。:関数 JurXSeries() による平滑化2件の後、取得される値の1つは分母であるためゼロではないことが確認されます。

以下は関数 JJMASeries() および JurXSeries() の典型的な呼び出しです(追加平滑化を伴う RSI 類似体)。

/*
For the indicator to operate, it is necessary to place files  
JurXSeries.mqh
JJMASeries.mqh  
PriceSeries.mqh 
to directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
to directory: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+ 
//|                                                        JJRSX.mq4 |
//|    MQL4 JJRSX: Copyright © 2006,                Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing of the indicator in a separate window
#property indicator_separate_window
//---- amount of indicator buffers
#property indicator_buffers  1
//---- colors of the indicator
#property indicator_color1  BlueViolet
//---- parameters of the indicator horizontal levels
#property indicator_level1  0.5
#property indicator_level2 -0.5
#property indicator_level3  0.0
#property indicator_levelcolor MediumBlue
#property indicator_levelstyle 4
//---- INDICATOR INPUTS 
extern int  Length = 8;  // depth of JurX smoothing of the indicator
// depth of JJMA smoothing of the obtained indicator
extern int  Smooth = 3;
// parameter ranging between -100 and +100, influences 
//the smoothing transient quality
extern int  Phase = 100;
/* Choosing of prices, at which the indicator is computed 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- indicator buffers
double Ind_Buffer[];
//---- integer variables 
int    w;  
//+------------------------------------------------------------------+  
//----+ Introducing of function JJMASeries 
//----+ Introducing of function JJMASeriesResize 
//----+ Introducing of function JJMASeriesAlert  
//----+ Introducing of function JMA_ErrDescr  
#include <JJMASeries.mqh> 
//+------------------------------------------------------------------+ 
//----+ Introducing of function JurXSeries
//----+ Introducing of function JurXSeriesResize
//----+ Introducing of function JurXSeriesAlert 
//----+ Introducing of function JurX_ErrDescr  
#include <JurXSeries.mqh> 
//+------------------------------------------------------------------+ 
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+---------------------------------------------------------------------+ 
//| JJRSX initialization function                                       |
//+---------------------------------------------------------------------+ 
int init()
  {
//---- indicator drawing styles
   SetIndexStyle(0,DRAW_LINE);
//---- 1 indicator buffer is used for counting. 
   SetIndexBuffer(0,Ind_Buffer);
//---- setting the indicator values that will not be visible in the chart
   SetIndexEmptyValue(0,0); 
//---- names for data windows and labels for subwindows
   SetIndexLabel(0,"JRSX");
   IndicatorShortName("JRSX(Length="+Length+", Input_Price_Customs="+
                      Input_Price_Customs+")");
//---- Setting imaging precision format (count of characters after decimal point) 
//to visualize the indicator values  
   IndicatorDigits(2);
//----+ Resizing buffer variables of function JurXSeries,
        nJurXnumber=2
//(Two calls for function JurXSeries)
   if (JurXSeriesResize(2)!=2)return(-1);
//----+ Resizing buffer variables of function JJMASeries,
        nJMAnumber=1
//(One call for function JJMASeries)
   if (JJMASeriesResize(1)!=1)return(-1);
//---- setting alerts for nonaccepted values of external variables
   JurXSeriesAlert (0,"Length",Length);
   JJMASeriesAlert (0,"Smooth",Smooth);
   JJMASeriesAlert (1,"Phase",Phase);
   PriceSeriesAlert(Input_Price_Customs);
//---- setting the bar number, starting from which there will be drawn the
       indicator  
   SetIndexDrawBegin(0,Length+31);
//---- correction of nonaccepted value ща parameter Length
   if(Length<1)Length=1; 
//---- coefficients initialization to compute the indicator 
   if (Length>5) w=Length-1; else w=5;
//---- initialization complete
return(0);
  }
//+-----------------------------------------------------------------------------+ 
//| JJRSX iteration function                                                    |
//+-----------------------------------------------------------------------------+ 
int start()
{
//---- Introducing floating point variables 
double dPrice,dPriceA,UPJRSX,DNJRSX,JRSX,JJRSX; 
//----+ Introducing of integer variables and obtaining of bars already computed
int bar,limit,reset,MaxBar,MaxBarJ,counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0)return(-1);
//---- the last counted bar must be recalculated
if (counted_bars>0) counted_bars--;
//---- determining of the oldest bar number, starting from which all bars
//     will be recalculated
MaxBar=Bars-2; MaxBarJ=MaxBarJ-w-1; 
//---- determining of the oldest bar number, starting from which new bars
//     will be recalculated
limit=Bars-counted_bars-1; 
//----+ 
if (limit>MaxBar){limit=MaxBar;Ind_Buffer[MaxBar]=0.0;}
 
for(bar=limit;bar>=0;bar--)
  {
   //----+ two calls for function PriceSeries to get the difference
   //      between entry prices dPrice
   dPrice = PriceSeries(Input_Price_Customs, bar)-
                        PriceSeries(Input_Price_Customs, bar+1);
   //----+  
   dPriceA=MathAbs(dPrice);
   //----+ Two calls for function JurXSeries numbered as 0 and 1. 
   //      Parameter nJJurXLength 
   //does not change on each bar (nJurXdin=0) 
   //check for errors in the preceding operation
   UPJRSX=JurXSeries(0,0,MaxBar,limit,Length,dPrice, bar,reset); 
   if(reset!=0)return(-1);
   DNJRSX=JurXSeries(1,0,MaxBar,limit,Length,dPriceA,bar,reset);
   if(reset!=0)return(-1); 
   //----+
   if (bar>MaxBar-w)JRSX=0;
   else if (DNJRSX!=0){JRSX=UPJRSX/DNJRSX;
   if(JRSX>1)JRSX=1;
   if(JRSX<-1)JRSX=-1;}else JRSX=0;
   //+---------------------------------------------------------------+ 
   //----+ One call for function JJMASeries numbered as 0 
   //----+ Parameters nJMA.Phase and nJMA.Length do not change 
   //      on each bar (nJMA.din=0)
   //+---------------------------------------------------------------+   
   JJRSX=JJMASeries(0,0,MaxBarJ,limit,Phase,Smooth,JRSX,bar,reset);
   //----+ check for errors in the preceding operation
   if(reset!=0)return(-1);
   //+---------------------------------------------------------------+  
   Ind_Buffer[bar]=JJRSX;  
}
//---- complete calculation of the indicator values
return(0);
}
//+------------------------------------------------------------------+



関数 T3Series()
以下は関数 T3Series() の典型的な呼び出しです(追加 T3 平滑化を伴う3つのボリンジャーバンド)。
/*
To work with the indicator, files 
T3Series.mqh 
PriceSeries.mqh 
must be placed in directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
in directory: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+ 
//|                                          T3.6Bollinger Bands.mq4 | 
//|                        Copyright © 2006,        Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing of the indicator in the main window
#property indicator_chart_window 
//---- amount of indicator buffers
#property indicator_buffers 7
//---- indicator color
#property indicator_color1 Gray 
#property indicator_color2 Red
#property indicator_color3 Blue 
#property indicator_color4 Lime
#property indicator_color5 Blue
#property indicator_color6 Red
#property indicator_color7 Gray 
//---- indicator line style
#property indicator_style1 4
#property indicator_style2 2
#property indicator_style3 4
#property indicator_style4 4
#property indicator_style5 4
#property indicator_style6 2
#property indicator_style7 4
//---- INDICATOR INPUTS 
// averaging period of J2Bollinger Bands
extern int        Bands_Period = 100;
extern double Bands_Deviations = 2.0; // deviation 
extern int         MA_method = 0;   // averaging method
// smoothing depth of the obtained Moving Avereges
extern int         MA_Smooth = 20;
// smoothing depth of the obtained Bollinger Bands
extern int        Bands_Smooth = 20;
// smoothing parameter ranging between -100 and +100, 
// influences the transient quality; 
extern int    Smooth_Curvature = 100;
// indicator shift along the time axis 
extern int         Bands_Shift = 0;
//Choosing of prices, on which the indicator is calculated 
/*(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi High, 12-Heiken Ashi Low, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.)*/
extern int Input_Price_Customs = 0;
//---- indicator buffers
double UpperBuffer3  [];
double UpperBuffer2  [];
double UpperBuffer1  [];
double T3MovingBuffer[];
double LowerBuffer1  [];
double LowerBuffer2  [];
double LowerBuffer3  [];
double Series_buffer [];
//+------------------------------------------------------------------+ 
//----+ Introducing of function T3Series 
//----+ Introducing of function T3SeriesResize 
//----+ Introducing of function T3SeriesAlert 
//----+ Introducing of function T3_ErrDescr  
#include <T3Series.mqh> 
//+------------------------------------------------------------------+ 
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+------------------------------------------------------------------+  
//| T3.6Bollinger Bands initialization function        | 
//+------------------------------------------------------------------+  
int init()
  {
//---- defining the chart drawing style
   SetIndexStyle(0,DRAW_LINE); 
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexStyle(3,DRAW_LINE); 
   SetIndexStyle(4,DRAW_LINE);
   SetIndexStyle(5,DRAW_LINE); 
   SetIndexStyle(6,DRAW_LINE);
//---- 4 indicator buffers are used for calculations  
   IndicatorBuffers(8);
   SetIndexBuffer(0,UpperBuffer3 );
   SetIndexBuffer(1,UpperBuffer2 );
   SetIndexBuffer(2,UpperBuffer1 );
   SetIndexBuffer(3,T3MovingBuffer);
   SetIndexBuffer(4,LowerBuffer1 );
   SetIndexBuffer(5,LowerBuffer2 );
   SetIndexBuffer(6,LowerBuffer3 );
   SetIndexBuffer(7,Series_buffer);
//---- setting up indicator values that will not be visible in the chart
   SetIndexEmptyValue(0,0);
   SetIndexEmptyValue(1,0);
   SetIndexEmptyValue(2,0);
   SetIndexEmptyValue(3,0);
   SetIndexEmptyValue(4,0);
   SetIndexEmptyValue(5,0);
   SetIndexEmptyValue(6,0);
//---- setting up the bar number, starting from which the indicator
//     will be drawn  
   int drawbegin=100+Bands_Shift;
   SetIndexDrawBegin(0,drawbegin);
   SetIndexDrawBegin(1,drawbegin);
   SetIndexDrawBegin(2,drawbegin);
   SetIndexDrawBegin(3,drawbegin);
   SetIndexDrawBegin(4,drawbegin);
   SetIndexDrawBegin(5,drawbegin);
   SetIndexDrawBegin(6,drawbegin);
//---- horizontal shift of the indicator lines  
   SetIndexShift (0, Bands_Shift); 
   SetIndexShift (1, Bands_Shift); 
   SetIndexShift (2, Bands_Shift); 
   SetIndexShift (3, Bands_Shift); 
   SetIndexShift (4, Bands_Shift); 
   SetIndexShift (5, Bands_Shift); 
   SetIndexShift (6, Bands_Shift); 
//---- name for data windows and labels for subwindows
   IndicatorShortName ("T3.4Bollinger Bands( Period="+Bands_Period+
        ", Deviations="+Bands_Deviations+")"); 
   SetIndexLabel (0, "Upper3 Bands");
   SetIndexLabel (1, "Upper2 Bands");
   SetIndexLabel (2, "Upper1 Bands"); 
   SetIndexLabel (4, "Lower1 Bands"); 
   SetIndexLabel (5, "Lower2 Bands"); 
   SetIndexLabel (6, "Lower3 Bands"); 
   string Moving;
   switch(MA_method)
       {
        case  0: Moving= "T3SMA";break;
        case  1: Moving= "T3EMA";break;
        case  2: Moving="T3SSMA";break;
        case  3: Moving="T3LWMA";break;
        default: Moving="T3SMA";
       }
   SetIndexLabel (3, "Moving Avereges "+Moving+" ("+Bands_Period+")");
//---- Setting imaging precision format for the indicator 
   IndicatorDigits(Digits);
//----+ Resizing of buffer variables of function T3Series, 
//nT3.number=7(Seven calls for function T3Series)
   if (Bands_Smooth<=1){if (T3SeriesResize(1)!=1)return(-1);}
   else if (T3SeriesResize(7)!=7)return(-1);
//---- setting alerts for nonaccepted values of external variables
   T3SeriesAlert(0,"MA_Smooth",MA_Smooth);
   T3SeriesAlert(0,"Bands_Period",Bands_Period);
   PriceSeriesAlert(Input_Price_Customs);
   if((MA_method<0)||(MA_method>3))
        Alert("Parameter MA_method must range between 0 and 3" 
        + " You input a nonaccepted " 
       +MA_method+ "0 will be used");
//---- correction of the nonaccepted value of parameter Bands_Period
   if(Bands_Period<1)Bands_Period=1; 
//---- initialization complete
   return(0);
  }
//+------------------------------------------------------------------------+  
//| T3.6Bollinger Bands iteration function                                 | 
//+------------------------------------------------------------------------+  
int start()
  {
//---- check for whether the amount of bars is sufficient for calculations
if(Bars-1<=Bands_Period) return(0);
//---- Introducing of floating point variables  
double deviation1,deviation2,deviation3,Temp_Series,sum,midline,
       priceswing,Resalt;
//----+ Introducing of integer variables and getting the bars already calculated
int reset,MaxBar,MaxBarBB,MaxBarBB1,bar,kk,counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0)return(-1);
//---- the last counted bar must be recalculated 
// (without this recalculation for counted_bars, function T3Series will not work
// correctly!!!)
if (counted_bars>0) counted_bars--;
//---- determining of the oldest bar number, starting from which new bars
//     will be recalculated
int limit=Bars-counted_bars-1;
//---- determining of the oldest bar number, starting from which all bars
//     will be recalculated
MaxBar=Bars-1-Bands_Period; MaxBarBB=MaxBar-30-Bands_Period; 
MaxBarBB1=MaxBarBB-1;
//----+ loading of entry prices into the buffer for calculations       
for(bar=limit;bar>=0;bar--)
    Series_buffer[bar]=PriceSeries(Input_Price_Customs,bar);
//---- checking whether the bars are sufficient for calculation of Bollinger Bands 
//---- zero initialization        
if (limit>MaxBar)
     {
      for(bar=limit;bar>=MaxBar;bar--)T3MovingBuffer[bar]=0;
      limit=MaxBar;
     }
//----+ Moving Averages calculation loop
for(bar=limit;bar>=0;bar--)
     {
      //----+ Moving Averages calculation formula
      Temp_Series=iMAOnArray(Series_buffer,0,Bands_Period,0,
                             MA_method, bar);
      //----+ smoothing of the obtained Moving Averages
      //----+ call for function T3Series numbered as 0. 
      // Parameters nT3.Curvature and nT3.Length do not change on 
      // each bar (nT3.din=0)
      Resalt=T3Series(0,0,MaxBar,limit,Smooth_Curvature,MA_Smooth,
                      Temp_Series,bar,reset);
      //----+ check for error in the preceding operation
      if(reset!=0)return(-1); 
      T3MovingBuffer[bar]=Resalt; 
     }     
//---- CALCULATION of Bollinger Bands 
//---- zero initialization      
if (limit>MaxBarBB)
     {
      for(bar=limit;bar>=MaxBarBB;bar--)
       {
        UpperBuffer2[bar]=0;
        UpperBuffer1[bar]=0;
        LowerBuffer1[bar]=0;
        LowerBuffer2[bar]=0;
       }
      limit=MaxBarBB;
     }
for(bar=limit;bar>=0;bar--)
   {       
     sum=0.0;
     midline=T3MovingBuffer[bar];
     kk=bar+Bands_Period-1;
     while(kk>=bar)
      {
       priceswing=PriceSeries(Input_Price_Customs,kk)-midline;
       sum+=priceswing*priceswing;
       kk--;
      }
     deviation2=Bands_Deviations*MathSqrt(sum/Bands_Period);     
     deviation1=0.5*deviation2;
     deviation3=1.5*deviation2;
     if (Bands_Smooth>1)
      {
       //----+ calculation and T3 smoothing of Bollinger Bands      
       //----+ ------------------------------------------------------+        
       //----+ six parallel calls for function T3Series numbered 
       //      as 1, 2, 3, 4, 5, 6. 
       //----+ Parameters nT3.Length do not change on each bar 
       //      (nT3.din=0)
       //----+ ------------------------------------------------------+ 
       Resalt=T3Series(1,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline+deviation3,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       UpperBuffer3[bar]=Resalt; 
       //----+ ------------------------------------------------------+ 
       Resalt=T3Series(2,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline+deviation2,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       UpperBuffer2[bar]=Resalt; 
       //----+ ------------------------------------------------------+       
       Resalt=T3Series(3,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline+deviation1,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       UpperBuffer1[bar]=Resalt; 
       //----+ ------------------------------------------------------+ 
       Resalt=T3Series(4,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline-deviation1,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       LowerBuffer1[bar]=Resalt; 
       //----+ ------------------------------------------------------+ 
       Resalt=T3Series(5,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline-deviation2,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       LowerBuffer2[bar]=Resalt; 
       //----+ ------------------------------------------------------+ 
       Resalt=T3Series(6,0,MaxBarBB1,limit,Smooth_Curvature,Bands_Smooth,
                       midline-deviation3,bar,reset);
       //----+ check for errors in the preceding operation
       if(reset!=0)return(-1); 
       LowerBuffer3[bar]=Resalt;        
       //----+ ------------------------------------------------------+ 
      }
     else 
      {
       //----+ calculation of Bollinger Bands without T3 smoothing 
       UpperBuffer3[bar]=midline+deviation3; 
       UpperBuffer2[bar]=midline+deviation2;
       UpperBuffer1[bar]=midline+deviation1;
       LowerBuffer1[bar]=midline-deviation1;
       LowerBuffer2[bar]=midline-deviation2;
       LowerBuffer3[bar]=midline-deviation3;
      }
      
   }
//---- complete indicator calculations
   return(0);
  }
//+-------------------------------------------------------------------+



関数 ParMASeries()
以下は関数 ParMASeries() の典型的な呼び出しです(追加 JMA 平滑化を伴うParMA 移動)。
/*
Moving average ParMA calculated on parabolic 
regression with bands 
 
for the indicator to work, one should place files 
JJMASeries.mqh 
ParMASeries.mqh 
PriceSeries.mqh 
to directory: MetaTrader\experts\include\
Heiken Ashi#.mq4
to directory: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+ 
//|                                                       JParMA.mq4 |
//|                       ParMA MQL4 CODE: Copyright © 2006, alexjou |
//|             JParMA Indicator: Copyright © 2006, Nikolay Kositsin |
//+------------------------------------------------------------------+ 
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in the main window
#property indicator_chart_window
//---- amount of indicator buffers
#property indicator_buffers 1
//---- color of the indicator 
#property indicator_color1 Red
//---- INDICATOR INPUTS 
extern int MA_Period  = 8; // ParMA period
extern int Length = 3;   // smoothing depth 
// parameter ranging between -100 and +100, 
//it influences the transient quality; 
extern int Phase  = 100;
extern int Shift  = 0;   // indicator shift along the time axis 
//Choosing of prices, at which the indicator is calculated 
/*(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi High, 12-Heiken Ashi Low, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- indicator buffers
double IndBuffer[];
//---- float point variables 
double JResalt, Price, Resalt;
//+------------------------------------------------------------------+  
//----+ Introducing of function JJMASeries 
//----+ Introducing of function JJMASeriesResize 
//----+ Introducing of function JJMASeriesAlert  
//----+ Introducing of function JMA_ErrDescr  
#include <JJMASeries.mqh>
//+------------------------------------------------------------------+ 
//----+ Introducing of function ParMAMASeries 
//----+ Introducing of function ParMASeriesResize 
//----+ Introducing of function ParMASeriesAlert 
//----+ Introducing of function ParMA_ErrDescr 
#include <ParMASeries.mqh>
//+------------------------------------------------------------------+  
//----+ Introducing of function PriceSeries
//----+ Introducing of function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+------------------------------------------------------------------+   
//| JParMA initialization function                                   |
//+------------------------------------------------------------------+ 
int init()
 {
  //---- Setting imaging precision format for the indicator
  IndicatorDigits(Digits);
  //---- defining the chart drawing style
  SetIndexStyle(0, DRAW_LINE);
  //---- 1 indicator buffer is used for calculations
  SetIndexBuffer(0, IndBuffer);
  //---- horizontal shift of the indicator line 
  SetIndexShift (0, Shift); 
  //---- setting the indicator values that will not be visible in
  //     the chart
  SetIndexEmptyValue(0, 0.0); 
  //---- name for data windows and label for subwindows 
  IndicatorShortName ("JParMA( Length="+Length+", Phase="+Phase+", 
                      Shift="+Shift+")");   
  SetIndexLabel(0, "JParMA Line");
  //---- setting the bar number, starting from which there will be drawn
         indicator 
  SetIndexDrawBegin(0, MA_Period);
  //----+ Resizing buffer variables of function JJMASeries, 
  //nJMAnumber=1(One call for function JJMASeries)
  if (JJMASeriesResize(1)!=1)return(-1);
  //----+ Resizing buffer variables of function ParMASeries, 
  //nParMAnumber=1(One call for function ParMASeries)
  if (ParMASeriesResize(1)!=1)return(-1);
  //---- setting alerts for nonaccepted values of external variables
  JJMASeriesAlert (0,"Length",Length);
  JJMASeriesAlert (1,"Phase", Phase );
  ParMASeriesAlert(0,"MA_Period",MA_Period);
  PriceSeriesAlert(Input_Price_Customs);
  return(0);
 }
//+-----------------------------------------------------------------------+ 
//| JParMA iteration function                                             |
//+-----------------------------------------------------------------------+ 
int start()
 {
 //---- check whether the amount of bars is sufficient for calculations
if (Bars-1<MA_Period)return(0);
//----+ Introducing of integer variables and getting bars already counted
int reset,MaxBar,MaxBarP,bar,Limit,counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0)return(-1);
//---- the last counted bar must be recalculated 
if (counted_bars>0) counted_bars--;
//---- defining the oldest bar number, starting from which all bars 
//will be recalculated
MaxBar=Bars-1; MaxBarP=MaxBar-MA_Period;

//---- defining the oldest bar number, starting from which new bars 
//will be recalculated 
Limit=Bars-counted_bars-1; 
 
//---- Indicator calculation
for (bar=Limit; bar>=0; bar--)
   { 
    //----+ 
     Price=PriceSeries(Input_Price_Customs,bar);
     //----+ getting the initial indicator
     //----+ Call for function ParMASeries numbered as 0
     Resalt=ParMASeries(0,MaxBar,Limit,MA_Period,Price,bar,reset); 
     //----+ check for errors in the preceding operation
     if(reset!=0)return(-1);
     //----+ JMA smoothing of the obtained indicator, 
     //parameter nJMA.MaxBar is decreased by MA_Period 
     //----+ Call for function JJMASeries numbered as 0, 
     // parameters nJMA.Phase and nJMA.Length do not change on each bar
     // (nJMA.din=0)
     JResalt=JJMASeries(0,0,MaxBarP,Limit,Phase,Length,Resalt,bar,reset);
     //----+ check for errors in the preceding operation
     if(reset!=0)return(-1);
     IndBuffer[bar]=JResalt;
   }
 //----
  return(0);
 }
 
//+-------------------------------------------------------------------+

すべてのインディケータで、通常適用される時系列配列 Close[] は関数 PriceSeries() を伴って配置されます。それを使用することで問題は発生しません。

double  PriceSeries(int Input_Price_Customs, int bar)

パラメータ Input_Price_Customs は 0 ~ 14 の範囲をとります。このパラメータ値によって、この関数は原稿チャートに対して第2パラメータとして使用されるバーの数分の価格値を返します。:0-CLOSE、1-OPEN、2-HIGH、3-LOW、4-MEDIAN、5-TYPICAL、6-WEIGHTED、7-Heiken Ashi Close、8-SIMPL、9-TRENDFOLLOW、10-0。5*TRENDFOLLOW、11-Heiken Ashi High、12-Heiken Ashi Low、 13-Heiken Ashi Open、14-Heiken Ashi Close。必要に応じて、時系列配列に基づくエントリー価格を決めるために関数ケースにおいて他にいくつかの代数式が書かれる場合もあります。関数 PriceSeries() を使うインディケータは Expert Advisor の最適化および検証にはひじょうに役立ちます。

おわりに

NK_library.zip には、こういったアルゴリズムを用いて書かれるインディケータが100以上存在します。そういった例は他のインディケータを書くために本稿で説明した関数の使い方を学習するのに十分すぎるほどです。zip ファイル内にある、平滑化関数のこれらバージョンを持つインディケータは Expert Advisor をサポートし、問題なく Expert Advisor と動作します。例外は最後に HTF のある名前を持つインディケータです。こういったインディケータは、計算の特異性により、Expert Advisor とは使用できません。zip ファイルフォルダにあるインディケータは MetaTrader 4 クライアントターミナルのプログラムフォルダ: \MetaTrader\EXPERTS\indicators に入れる必要があります。関数じたいはフォルダ INCLUDE の zip ファイルにあります。そのフォルダの全コンテンツは MetaTrader 4 クライアントターミナルのプログラムフォルダ:\MetaTrader\EXPERTS\INCLUDE に入れる必要があります。


翻訳:MetaQuotes Software Corp. (ロシア語より)
記事原文:http://articles.mql4.com/ru/articles/1450

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1450

添付されたファイル |
NK_library.zip (1939.17 KB)
トリコロールインディケータとインディケータを書くことを最大限シンプル化するいくつかの機会 トリコロールインディケータとインディケータを書くことを最大限シンプル化するいくつかの機会
本稿では、ビジュアルトレーディングのためにインディケータの情報値を増やすことの意味についていくらか説明します。私はインディケータを構築するために別のタイムフレームからのデータを使用するトリコロールインディケータの実行を分析してし、記事"Effective Averaging Algorithms with Minimal Lag: Use in Indicators"で述べられているインディケータのライブラリについても詳しく説明します。
アンチウイルスソフトとファイアウォール下でのMetaTrader 4 アンチウイルスソフトとファイアウォール下でのMetaTrader 4
トレーダーの大半は、PCの保護のために特別なプログラムを使用する。不幸にもこれらのプログラムはウイルスやトロイの木馬からコンピューターを保護するだけではなく、かなりのリソースを消費します。これは、ネットワークトラフィックにも関連し、様々な知的アンチウイルスソフトやファイアウォールによってコントロールされます。この記事を執筆した理由は、ファイアウォールを稼働させたため、動作の重いMetaTrader 4クライアントターミナルにトレーダーがクレームをつけたためです。Kaspersky Antivirus 6.0とOutpost Firewall Pro 4.0を用いて独自のリサーチを行うことにしました。
Forex トレーディングのイロハ Forex トレーディングのイロハ
金融市場を扱うということはまずトレード処理を意味します。ごく幼いころから、われわれは皆、何を売り、買うべきかということについて直観的考えを持っています。ですが Forex トレーディングは何か特別なものです。本稿ではいくつか用語の説明が必要な考えを取り上げます。またそういう語に対応する MQL 4 fの関数についても考察します。
インディケータのサウンドアラート インディケータのサウンドアラート
日常使いの『音声』インディケータの作成方法