
エリック・ナイマンの『チャネル』インディケータ
目次
- 概論
- 第1部『チャネル』インディケータの計算と構築原理について(サンプルコードつき)
- 第2部『チャネル』インディケータ実用とこのインディケータに基づくエキスパートアドバイザの作成
- 第3部『チャネル』インディケータに基づくエキスパートアドバイザの外部パラメータの最適化
- まとめ
概論
この記事およびインディケータは、エリック・L・ナイマン氏の著書に基づき作成されています。(『トレーダーの小百科事典』1999年、236p、K . VIRA-R Alfa Capital)本書の中では金融市場のテクニカル/ファンダメンタル分析の基礎に触れられており、その中から著者が『「チャネル」インディケータ』と名付けたメソッドを採用しました。ごく簡単にインディケータについて説明すると、これは選択した期間における価格の変化数の価格変化速度の比に基づいています。
本書の中で著者は自分の分析を表やチャートを用いて紹介していますが、本記事はそれに基づき執筆されました。著者はベアとブルの相互作用をベースに市場分析を行い、分析オブジェクトとして価格変化速度、取引数、変化量を使用しています。速度は取引数で測定され、量は隣合う二つの相場の差で定義されます(現在と前回)。本書の中では相場は最後の判明している価格とされています(第1部でこの件について計算例を用いてより詳細に説明します)。
著者の市場分析の目的は、ベアとブルの力が同時に市場に影響を与えているトレンド方向の判別と強さの計算にあります。この強さを計算することで、現時点で何がより強いかを判断することができます。著者は相反する二つの力の間の線を引っ張る力としていて、これを本書の中ではブルとベアの力を総計した『チャネル』値を通じて描いています。
著者は市場分析と統計・動的メソッドに基づく計算に対して、二つのアプローチを記述しています。『チャネル』値の計算は、本書の中では次のように行われています。
1. ブルとベアの『強さ』の計算と評価。方向性を見出す。
ブルの強さの算出式(本書から):
BuF = SPCi、ここでは
- BuFはブルの強さ。
- SPCiは、分析期間におけるの正の変化の和。
ベアの強さの算出式(本書から):
BeF = SNCi、ここでは
- BeFはベアの強さ。
- SNCiは、分析期間における負の変化の和。
次にBuFとBeFの値を比べ、値が大きい方が市場で優位であるということです。
強さの値を取得し、チャートの検証期間の二つの隣り合うバーで比較をすれば、動的評価を得ることができます。元の情報は次のように分析されます。
BuF > BeF and (BuF1 - BuFО) > (BeF1 - BeFО) ーこれはブルの総成長力です(ここでの1は現在の力の値で、0は前回値)。
BuF > BeF and (BuF1 - BuFО) < (BeF1 - BeFО) ーこれはブルの総衰退力です。
BuF < BeF and (BuF1 - BuFО) > (BeF1 - BeFО) ーこれはベアの総衰退力です。
BuF < BeF and (BuF1 - BuFО) < (BeF1 - BeFО) ーこれはベアの総成長力です。
ご覧のように、静的な強さの値に加えて、隣接する計算点でのこの数値の変化のダイナミクスも検証します。
2. ブルとベアの『活力』(変化数)の評価・計算・比較元の情報のブルとベアの活力の計算は以下のようになります。
BuV = NPCi、ここでは
- BuVはブルの活力。
- NPCiは分析期間における正の変化数。
BeV = NNCi、ここでは
- BeVはベアの活力。
- NNCiは分析期間における負の変化数。
算出した活力値を隣接する前のものと比較し、動的評価を取得します。前の分析ステップの比較例のように、動的評価は静的値と動的値の比較によって行われます。
3. ブルとベアの『スキル』の評価・計算・比較元の情報のブルとベアのスキルの計算は以下のようになります。
マーケットでの自分のポリシーの実行におけるブルとベアのスキルは次の式で求められます。
BuS = SPC1/NPC1
BeS = SNC1 / NNC1
こうして静的値が計算され、動的値は第一ステップからの例で計算されます。
4. ブルとベアの最終評価前の3つのステップの全ての値を計算しデータを比較することで、トレンドの方向と性質について結論を導き出すことができます。最終評価は全ての3つの指標を比較して行われます。本書では最終評価は以下のように示されています。
BuF > BeF、BuV > BeV、そしてBuS > BeSである場合(前述した動的関係に従う)、ブルはベアより遥かに望ましい動きをし、買い注文だけを検討した方が良いです。 静的データに対する市場の動的評価をする為には、二つの『チャネルラインの隣接する計算点』の動的値を加算する必要があります。
分析ステップのデータをベースにして、インディケータを構成する3つの主要計算値を選定することができます。
- 強さー分析期間の変化の合計。
- 活力ー分析機関の変更数。
- スキル=強さ/活力
動的部分は著者によって最も敏感で活力があるものとして分析されました。この記事、またコードでは計算の静的メソッドのみ選択されています。このように、3つの計算部分(『強さ』、『活力』、『スキル』)を比較することで、著者はトレンドの強さと方向について結論を出し、静的/動的データを計算し、それらの使用に様々な方法を紹介しています。次に、エリック・L・ナイマンの方法による『チャネル』インディケータ自体の構築について詳しく見ていきましょう。
第1部『チャネル』インディケータの計算と構築原理について(サンプルコードつき)
インディケータの構築には、線形とヒストグラムのメソッドが採用されています。線はブルとベアの計算値の合計になります。ヒストグラムはブルとベアの為の別々の計算を表示します。
ここで、各ステップのコメントがついたインディケータのコードを見ていきましょう。#propertyを介したインディケータの表示設定と変数の宣言から始めましょう。以下のコードにはデータ分析を簡単にする為に、インディケータの特性が書かれています。
//+------------------------------------------------------------------+ //| RopebyEricNaiman.mq5 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property description "RopebyEricNaiman by Im_hungry (https://login.mql5.com/en/users/Im_hungry)" #property description "RopebyEricNaiman - shows the direction of the desire of the market action and the power of this desire." #property version "1.00" #property strict //--- MovingAverages.mqhファイルからのMAの計算関数の接続 #include <MovingAverages.mqh> //--- #property indicator_separate_window // 別ウィンドウへの描画の設定 #property indicator_buffers 12 // インディケータの12の指標バッファの設定 #property indicator_plots 5 // インディケータによって描かれる5つの指標バッファの設定 //--- ブルのヒストグラム #property indicator_label1 "BULL" #property indicator_type1 DRAW_COLOR_HISTOGRAM // 0 - clrDarkGreen - カラーインデックス『買いのみ』、高確証カテゴリの買い // 1 - clrMediumSeaGreen - カラーインデックス『買いが可能』、中確証カテゴリの買い // 2 - clrLightGreen - カラーインデックス『買いが可能』、低確証カテゴリの買い // 3 - clrGray - カラーインデックス『買いは禁止』 #property indicator_color1 clrDarkGreen,clrMediumSeaGreen,clrLightGreen,clrGray #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- ベアのヒストグラム #property indicator_label2 "BEAR" #property indicator_type2 DRAW_COLOR_HISTOGRAM // 0 - clrDarkRed - カラーインデックス『売りのみ』、高確証カテゴリの売り // 1 - clrIndianRed - カラーインデックス『売りが可能』、中確証カテゴリの売り // 2 - clrLightPink - カラーインデックス『売りが可能』、低確証カテゴリの売り // 3 - clrGray - カラーインデックス『売りは禁止』 #property indicator_color2 clrDarkRed,clrIndianRed,clrLightPink,clrGray #property indicator_style2 STYLE_SOLID #property indicator_width2 2 //--- インディケータの主要ライン #property indicator_label3 "main line" #property indicator_type3 DRAW_COLOR_LINE // 0 - clrDarkGreen - カラーインデックス『買いのみ』、高確証カテゴリの買い // 1 - clrDarkRed - カラーインデックス『売りのみ』、高確証カテゴリの売り // 2 - clrGray - カラーインデックス『厳密な確証はなし』 #property indicator_color3 clrDarkGreen,clrDarkRed,clrGray #property indicator_style3 STYLE_SOLID #property indicator_width3 2 //--- インディケータの主要ラインに基づく短期MAのインディケータの描画 #property indicator_label4 "ma fast" #property indicator_type4 DRAW_LINE #property indicator_color4 clrAqua #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- インディケータの主要ラインに基づく長期MAのインディケータの描画 #property indicator_label5 "ma slow" #property indicator_type5 DRAW_LINE #property indicator_color5 clrYellow #property indicator_style5 STYLE_SOLID #property indicator_width5 1
著者自身はカラーインデックスの記載はせず、3つの指標の完全または一部の一致でトレンドの分析を行っています。
- ブルの強さ>ベアの強さの場合、強気トレンドで、反対の符号は弱気市場の優位性を語っています。
- ブルの活力>ベアの活力の場合、強気トレンドです。
- ブルのスキル>ベアのスキルの場合、強気トレンドです。
これらの指標を比較することで、トレンドの強さについて述べることができます。より多くの指標がトレンドを指すほど、そのトレンドは強いものとなります。上記の変数の初期化時に、3つの計算された指標に基づくヒストグラムのカラー表示について説明しています。3つの計算値の比較は任意の組み合わせで行われます。
0 — clrDarkGreenーカラーインデックス『買いのみ』、高確証カテゴリの買い
1 — clrMediumSeaGreenーカラーインデックス『買いが可能』、中確証カテゴリの買い
2 — clrLightGreenーカラーインデックス『買いが可能』、低確証カテゴリの買い
3 — clrGrayーカラーインデックス『買いは禁止』。
インディケータの主要ラインの為に、本書のオリジナルの説明に従った全ての3つの計算値が一致した時のみカラー描画をしています。
『BuF > BeF、BuV > BeV、そしてBuS > BeSである場合(前述した動的関係に従う)、ブルはベアより遥かに望ましい動きをし、買い注文だけを検討した方が良いです。 BuF < BeF、BuV < BeV、そしてBuS < BeSである場合(動的関係に従う)、ベアはブルよりも遥かに望ましいものです。売りのみを行った方が良いでしょう。』 |
インディケータの外部変数を宣言します。ここでは、インディケータの使用を便利にする為に、draw_lineやdraw_histogramの入力変数を使用したヒストグラムまたはラインの表示機能が入れられています。計算の汎用性の為に、_priceパラメータによるインディケータの計算用価格の選択の機能が追加されています。MAインディケータの設定も無効のオプションで行われています。
//--- input parameters input string section_1="___ main settings"; //--- ブルとベアのヒストグラムの描画を有効にする input bool draw_histogram=true; //--- インディケータの主要ラインの描画を有効にする input bool draw_line=true; //--- インディケータの期間 input int _period=76; //--- 計算に使う価格 input ENUM_APPLIED_PRICE _price=PRICE_CLOSE; //--- 計算における現在のバーからのバーの履歴の深さの制限 input int max_bars=0; //--- インディケータをより見やすくする為のヒストグラムからのMAとラインの簡単な偏差。全ての主要ラインとMAの数値は、line_deviationに乗算する input double line_deviation=3.0; //--- input string section_2="___ MA fast"; //--- 短期MAの描画を有効にする input bool draw_MA_fast=false; //--- インディケータでの短期MAの計算期間 input int period_MA_fast=25; //--- 短期MA計算メソッド input ENUM_MA_METHOD method_MA_fast=MODE_SMA; //--- input string section_3="___ MA slow"; //--- 長期MAの描画を有効にします input bool draw_MA_slow=false; //--- インディケータでの長期MA計算期間 input int period_MA_slow=143; //--- 長期MA計算メソッド input ENUM_MA_METHOD method_MA_slow=MODE_SMA; //---- buffers ...
本書では『チャネル』値を使った多くのバージョンを紹介しています。その中から次のものを引用しました。
- ゼロラインとインディケータの交差点。
- 全ての3つの計算値(強さ、活力、スキル)が一致した場合にのみ取引。主要ラインの色で実装されている。
- MAとインディケータの交差点。
- 二つのMAの交差点。
MAインディケータ(MovingAverages.mqhライブラリを介してダウンロードしたもの)は、Buffer_calcLINEのバッファ配列にあるインディケータの主要ラインの値に基づいて構築されます。この配列はMA計算による関数ライブラリへの引き渡し前の、データへのアクセスを簡単にする為に追加されました。
OnInit関数では、インディケータの構築と計算の為に主要データを初期化します。prev_rates_totalと_tm_prev変数のリセットは、インディケータ再起動の他の原因やチャート期間を変更した場合の計算にとても重要なものとなります。_tm_prev値は、次のバーが発生した時にそこから計算を始める、最後の計算バーの時間を担当しています。prev_rates_totalパラメータは、前のrates_total値(前のティックのもの)を保存します。これを現在のrates_totalと比較し(バーの数またはprice[]配列のサイズ)、データの再計算はあったか、全てのバーがロードされたか、履歴のギャップまでロードした結果誤ったデータがチャートに表示されるのを防ぐ為の計算はされているかといったことを判断することができます。
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- インディケータの初回起動についてのログへのメッセージ Print(__FUNCTION__+"\\ Initialization | _period: ",_period); //--- 現在のシンボルの小数点以下の桁数 _digits=(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS); //--- インディケータの数値表示の正確さ IndicatorSetInteger(INDICATOR_DIGITS,_digits); //--- インディケータウィンドウで表示される、インディケータの名前設定 IndicatorSetString(INDICATOR_SHORTNAME,"RopebyEricNaiman"); //--- INDICATOR_DATA - 描画の為のデータを保存 //--- INDICATOR_COLOR_INDEX - カラーインデックスを保存 //--- INDICATOR_CALCULATIONS - 描画のためではない中間計算のデータを保存 SetIndexBuffer(0,Buffer_main_bull,INDICATOR_DATA); // ブルのヒストグラムデータのバッファ SetIndexBuffer(1,Buffer_color_bull,INDICATOR_COLOR_INDEX); // ブルのカラーデータのバッファ SetIndexBuffer(2,Buffer_main_bear,INDICATOR_DATA); // ベアのヒストグラムのバッファ SetIndexBuffer(3,Buffer_color_bear,INDICATOR_COLOR_INDEX); // ベアのカラーデータのバッファ SetIndexBuffer(4,Buffer_mainline,INDICATOR_DATA); // インディケータの主要ラインのデータバッファ SetIndexBuffer(5,Buffer_mainline_color,INDICATOR_COLOR_INDEX); // インディケータの主要ラインのカラーデータバッファ SetIndexBuffer(6,Buffer_MAfast,INDICATOR_DATA); // 短期MAのデータバッファ SetIndexBuffer(7,Buffer_MAslow,INDICATOR_DATA); // 長期MAのデータバッファ SetIndexBuffer(8,Buffer_calc,INDICATOR_CALCULATIONS); // 価格計算のデータバッファ SetIndexBuffer(9,Buffer_calc_bull,INDICATOR_CALCULATIONS); // ブルの計算データバッファ SetIndexBuffer(10,Buffer_calc_bear,INDICATOR_CALCULATIONS); // ベアの計算データバッファ SetIndexBuffer(11,Buffer_calcLINE,INDICATOR_CALCULATIONS); // MAの為の計算データバッファ //--- 最後に計算されたバーの時間とprev_rates_total のリセット(前の呼び出しでのrates_total// rates_total = price[]配列サイズ) _tm_prev=0; prev_rates_total=0; //--- return(INIT_SUCCEEDED); }
次にチャート上でデータを表示する為にOnCalculate関数で全ての計算が行われます。本書147ページからの表の計算部分を考慮して二つの価格の正の結果が正の変化とし、バーの終値を価格としています(_price=PRICE_CLOSE価格の使用時)。このような差は市場の強気具合(正の変化)または弱気具合(負の変化)を表しています。次に、このような差は関数で定義された計算バー(i)の終値や、計算されたバーから前のバーの終値と同じ価格、始値からなる『バー』として見なされます。
for(int i=1; i<bars_calc && !IsStopped(); i++) { ...
3つの主要指標の計算の為には、_priceの設定に応じた価格配列を取得し、forオペレーターを使って_period変数の値を計算する必要があります。この期間におけるブルの正の価格変化とベアの負の価格変化を計算し、このような変化数を計算して、合計を数で割りそれらの関係性を見つけます。
- if(total_bull>0) Buffer_calc_bull[i]=sum_bull/total_bull; — ブル
- if(total_bear>0) Buffer_calc_bear[i]=sum_bear/total_bear; — ベア
下記に_period=5期間の主要ライン、ベア、ブルのヒストグラムの例における計算(実際のチャート)があります。
このように、各バーでのブルとベアの指標の合計結果は、将来的に計算に使用する『チャネル』値となります。インディケータでこれは考慮され、Buffer_mainline_color[]のインディケータカラーバッファを介して表示される3つの色を持つラインで表示されます。以下はOnCalculate()での計算となります。
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, // price[]配列のサイズ 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[]) { ArraySetAsSeries(time,true); //--- タイムセッションでの配列のインデックス設定、最小インデックス0は履歴の中の既知の最後の計算値を持っています ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); ArraySetAsSeries(Buffer_main_bull,true); ArraySetAsSeries(Buffer_color_bull,true); ArraySetAsSeries(Buffer_main_bear,true); ArraySetAsSeries(Buffer_color_bear,true); ArraySetAsSeries(Buffer_mainline,true); ArraySetAsSeries(Buffer_mainline_color,true); ArraySetAsSeries(Buffer_MAfast,true); ArraySetAsSeries(Buffer_MAslow,true); ArraySetAsSeries(Buffer_calc,true); ArraySetAsSeries(Buffer_calc_bull,true); ArraySetAsSeries(Buffer_calc_bear,true); ArraySetAsSeries(Buffer_calcLINE,true); //--- int copy=0; bars_calc=0; //--- インディケータデータの計算 //--- prev_calculated = 0の時には、再度全バーでの全てのデータを計算する、=0はインターネットの長時間の切断時などの履歴の中の切断の時に起こりえます if(prev_calculated==0) _tm_prev=0; //--- もし前回のサイズが現在のものより大きい場合、これはバグであるので、全てのデータを再計算する必要があります if(prev_rates_total>rates_total) _tm_prev=0; if(_tm_prev<time[0]) // 新しいバーの出現時の計算 { if(_tm_prev>0) // もしインディケータが既に以前に計算したデータを持っている場合 { copy=TakeShift_byTime(Symbol(),PERIOD_CURRENT,_tm_prev); // 最後に計算したバーの時間による現在のシンボルのバーのオフセットを取得 if(copy<=0) // オフセットが見つからない場合、計算が偏り、次のティックで繰り返される { return 0; } bars_calc=copy+1; // インディケータのまだ閉じていない現在のバーからの計算開始の為のバーのオフセットの設定 //--- 現在の閉じていないバーのリセット、つまりそのデータは計算しない Buffer_main_bull[0]=0.0; Buffer_color_bull[0]=5; // 無色に該当する5番にカラーインデックスを設定、したがって色は表示されない Buffer_main_bear[0]=0.0; Buffer_color_bear[0]=5; // 無色に該当する5番にカラーインデックスを設定、したがって色は表示されない Buffer_mainline[0]=0.0; Buffer_mainline_color[0]=5; // 無色に該当する5番にカラーインデックスを設定、したがって色は表示されない Buffer_MAfast[0]=0.0; Buffer_MAslow[0]=0.0; Buffer_calc[0]=0.0; Buffer_calc_bull[0]=0.0; Buffer_calc_bear[0]=0.0; Buffer_calcLINE[0]=0.0; } else // インディケータが初めて設定され数値が計算されていない場合 { bars_calc=Bars(Symbol(),PERIOD_CURRENT)-1; // 計算開始の為のバーのオフセットはバーの総数として-1が設定される //--- 描画エラーを防ぐ為に全てのバーの全データをリセットする for(int i=0; i<Bars(Symbol(),PERIOD_CURRENT) && !IsStopped(); i++) { Buffer_main_bull[i]=0.0; Buffer_main_bear[i]=0.0; Buffer_mainline[i]=0.0; Buffer_MAfast[i]=0.0; Buffer_MAslow[i]=0.0; Buffer_calc[i]=0.0; Buffer_calc_bull[i]=0.0; Buffer_calc_bear[i]=0.0; Buffer_calcLINE[i]=0.0; } } //--- インディケータの計算の為のバーの数がゼロ以下である場合、計算を停止 if(bars_calc<0) return 0; //--- max_bars値の計算の為のバーの数の制限 if(bars_calc>max_bars && max_bars!=0) bars_calc=max_bars; for(int i=1; i<bars_calc && !IsStopped(); i++) { //--- _priceの設定に応じた2つのバーの相場の差を計算 switch(_price) { case PRICE_CLOSE: Buffer_calc[i]=close[i]-close[i+1]; break; case PRICE_OPEN: Buffer_calc[i]=open[i]-open[i+1]; break; case PRICE_HIGH: Buffer_calc[i]=high[i]-high[i+1]; break; case PRICE_LOW: Buffer_calc[i]=low[i]-low[i+1]; break; case PRICE_MEDIAN: Buffer_calc[i]=((high[i]+low[i])/2)-((high[i+1]+low[i+1])/2); break; case PRICE_TYPICAL: Buffer_calc[i]=((high[i]+low[i]+close[i])/3)-((high[i+1]+low[i+1]+close[i+1])/3); break; case PRICE_WEIGHTED: Buffer_calc[i]=((high[i]+low[i]+close[i]+close[i])/4)-((high[i+1]+low[i+1]+close[i+1]+close[i+1])/4); break; default: return 0; } } //--- サイクルが終了するまたはプログラム終了のIsStopped=trueコマンドが表示される(チャートからインディケータが削除された場合など)までの未計算バーの収集を実行 for(int i=1; i<=bars_calc && !IsStopped(); i++) { //--- データリセット sum_bull=0.0; // 分析期間中の正の変化(ブル)の合計の変数 total_bull=0; // 分析期間中の正の変化の数の変数 sum_bear=0.0; // 分析期間中の負の変化(ベア)の合計の変数 total_bear=0; // 分析期間の負の変化の数の変数 Buffer_main_bull[i]=0.0; Buffer_color_bull[i]=5; Buffer_main_bear[i]=0.0; Buffer_color_bear[i]=5; Buffer_mainline[i]=0.0; Buffer_mainline_color[0]=5; Buffer_calc_bull[i]=0.0; Buffer_calc_bear[i]=0.0; Buffer_calcLINE[i]=0.0; //--- 分析期間に応じたデータの範囲を超える場合、バーの計算を停止 if(i>=(rates_total-_period)) continue; //--- 履歴の現在バーからの分析期間(_period)のデータの取捨 for(int i2=i; i2<i+_period; i2++) { //--- ブルの計算 if(Buffer_calc[i2]>0) { sum_bull+=Buffer_calc[i2]; // 正のバー価格の合計(『分析期間の正の変化の合計』) total_bull++; // 正のバーの数の計算(『分析期間の正の変化数』) } //--- ベアの計算 if(Buffer_calc[i2]<0) { sum_bear+=Buffer_calc[i2]; // 負のバー価格の合計(『分析期間の負の変化の合計』) total_bear++; // 負のバーの数の計算(『分析期間の負の変化数』) } } //--- 『ブルスキル』の計算、ポイントでのバーの値をバーの数で割る if(total_bull>0) Buffer_calc_bull[i]=sum_bull/total_bull; //--- 『ベアスキル』の計算 if(total_bear>0) Buffer_calc_bear[i]=sum_bear/total_bear; //--- シグナルの確証ごとの色付きヒストグラムの描画 if(draw_histogram) { //--- ブルのヒストグラムの描画、ポイントでのバーの値をバーの数で割る if(total_bull>0) Buffer_main_bull[i]=sum_bull/total_bull; //--- ベアのヒストグラムの描画、ポイントでのバーの値をバーの数で割る if(total_bear>0) Buffer_main_bear[i]=sum_bear/total_bear; //--- ヒストグラムの色(0)clrDarkGreen - カラーインデックス『買いのみ』、高確証カテゴリの買い //--- 確証カテゴリ ー 全ての3つの指標が強気トレンドを示している //--- ブルの活力>ベアの活力+ブルの強さ>ベアの強さ+ブルのスキル>ベアのスキル //--- 活力 ー バーの数 //--- 強さ ー ポイントでのバーの値の合計 //--- スキル ー 強さ/活力の指定した期間の全バーの合計値の平均 if(total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) Buffer_color_bull[i]=0; else { //--- ヒストグラムの色(1)clrMediumSeaGreen - カラーインデックス『買いが可能』、中確証カテゴリの買い //--- 確証カテゴリ ー 2つのブル指標と1つのベア指標、任意の組み合わせ if((total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i]))) Buffer_color_bull[i]=1; else { //--- ヒストグラムの色(2)clrLightGreen - カラーインデックス『買いが可能』、低確証カテゴリの買い //--- 確証カテゴリ ー 1つのブル指標と2つのベア指標、任意の組み合わせ if((total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || (total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i]))) Buffer_color_bull[i]=2; else { //--- ヒストグラムの色(3)clrGray ー カラーインデックス『買いは禁止』 //--- 確証カテゴリ ー ブル指標がない場合 Buffer_color_bull[i]=3; } } } //--- ヒストグラムの色(0)clrDarkRed - カラーインデックス『売りのみ』、高確証カテゴリの買い //--- 確証カテゴリ ー 全ての3つの指標が弱気トレンドを示している if(total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) Buffer_color_bear[i]=0; else { // ヒストグラムの色(1)clrIndianRed - カラーインデックス『売りが可能』、中確証カテゴリの売り //--- 確証カテゴリ ー 2つのベア指標と1つのブル指標、任意の組み合わせ if((total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i]))) Buffer_color_bear[i]=1; else { // ヒストグラムの色(2)clrLightPink - カラーインデックス『売りが可能』、低確証カテゴリの売り //--- 確証カテゴリ ー 1つのベア指標と2つのブル指標、任意の組み合わせ if((total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || (total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i]))) Buffer_color_bear[i]=2; else { //--- ヒストグラムの色(3)clrGray ー カラーインデックス『売りは禁止』 //--- 確証カテゴリ ー ベア指標がない場合 Buffer_color_bear[i]=3; } } } } //--- 主要ラインの計算値、ベアとブルのスキルの合計 Buffer_calcLINE[i]=(Buffer_calc_bull[i]+Buffer_calc_bear[i])*line_deviation; //--- シグナルの確証カテゴリごとの色付きヒストグラムの描画 // 0 - clrDarkGreen - カラーインデックス『買いのみ』、高確証カテゴリの買い // 1 - clrDarkRed - カラーインデックス『売りのみ』、高確証カテゴリの売り // 2 - clrGray - カラーインデックス『厳密な確証はなし』 if(draw_line) { //--- 主要ラインの値の描画、ベアとブルのスキルの合計 Buffer_mainline[i]=(Buffer_calc_bull[i]+Buffer_calc_bear[i])*line_deviation; //--- 未確定のラインの色の設定(2 - clrGray) Buffer_mainline_color[i]=2; //--- 全てのブル指標が一致した場合(bull>bear)のラインのブルの色の設定(0 - clrDarkGreen) if(total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_calc_bull[i])>MathAbs(Buffer_calc_bear[i])) Buffer_mainline_color[i]=0; //--- 全ての3つのベア指標のが一致した場合(bear>bull)のラインのベアの色の設定(1 - clrDarkRed) if(total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_calc_bull[i])<MathAbs(Buffer_calc_bear[i])) Buffer_mainline_color[i]=1; } } //--- 計算とMAの描画 if(draw_MA_fast || draw_MA_slow) { //--- MovingAverages.mqhライブラリへ引き渡す為の時系列でのインデックスの無効(配列の最後が履歴の現在のバーになるようにインデックスを変更する) ArraySetAsSeries(Buffer_calcLINE,false); ArraySetAsSeries(Buffer_MAfast,false); ArraySetAsSeries(Buffer_MAslow,false); //--- 全ての未計算バーの収集収集 = 全バー(rates_total) - 最後の既知の計算時間(_tm_prev (bars_calc))からのバーの偏差 for(int i=rates_total-bars_calc; i<rates_total && !IsStopped(); i++) { //--- max_barsパラメータで指定する計算の制限、指定したmax_barsのみの為の計算は、全バー(rates_total)から設定した数(max_bars)を差し引いた差 if(max_bars>0?(i<(rates_total-max_bars)):false) { //--- 現在のインデックスiが許容値外を超える場合、許容インデックスへ移行する i=rates_total-max_bars; continue; } //--- MAのデータが取得できなかった場合に配列のリセット Buffer_MAfast[i]=0.0; Buffer_MAslow[i]=0.0; //--- method_MA_fastパラメータによる短期MAの計算メソッドの選択 if(draw_MA_fast) { switch(method_MA_fast) { case MODE_SMA: // 単純平均 Buffer_MAfast[i]=SimpleMA(i,period_MA_fast,Buffer_calcLINE); // period_MA_fast期間でBuffer_calcLINEデータバッファのInclude\\MovingAverages.mqhライブラリからのインデックスiの計算したSimpleMAのデータの取得 break; case MODE_EMA: // 指数平均 Buffer_MAfast[i]=ExponentialMA(i,period_MA_fast,Buffer_MAfast[i-1],Buffer_calcLINE); break; case MODE_SMMA: // 平滑化平均 Buffer_MAfast[i]=SmoothedMA(i+period_MA_fast,period_MA_fast,Buffer_MAfast[i-1],Buffer_calcLINE); break; case MODE_LWMA: // 線加重平均 Buffer_MAfast[i]=LinearWeightedMA(i+period_MA_fast,period_MA_fast,Buffer_calcLINE); break; default: return 0; } } //--- method_MA_slowパラメータによる長期MAの計算メソッドの選択 if(draw_MA_slow) { switch(method_MA_slow) { case MODE_SMA: // 単純平均 Buffer_MAslow[i]=SimpleMA(i,period_MA_slow,Buffer_calcLINE); break; case MODE_EMA: // 指数平均 Buffer_MAslow[i]=ExponentialMA(i,period_MA_slow,Buffer_MAslow[i-1],Buffer_calcLINE); break; case MODE_SMMA: // 平滑化平均 Buffer_MAslow[i]=SmoothedMA(i,period_MA_slow,Buffer_MAslow[i-1],Buffer_calcLINE); break; case MODE_LWMA: // 線加重平均 Buffer_MAslow[i]=LinearWeightedMA(i,period_MA_slow,Buffer_calcLINE); break; default: return 0; } } } //--- 描画の為の時系列インデックスを有効にする ArraySetAsSeries(Buffer_calcLINE,true); ArraySetAsSeries(Buffer_MAfast,true); ArraySetAsSeries(Buffer_MAslow,true); //--- 計算されない為、現在のバーのMAのデータをリセット Buffer_MAfast[0]=EMPTY_VALUE; Buffer_MAslow[0]=EMPTY_VALUE; Buffer_calcLINE[0]=EMPTY_VALUE; } //--- 最後に計算されたバーの時間を記録 _tm_prev=time[0]; } //--- return value of prev_calculated for next call prev_rates_total=rates_total; return(rates_total); }
ラインとヒストグラム表示が有効な時に見やすくする目的で、ヒストグラムを超えていくように主要ラインの値 (主要ライン値* line_deviation)を増加させています。M1など小さい期間計算での計算を速くする為、バーの数の制限(max_bars)が追加されました。コードの最後のブロックTakeShift_byTimeは、bars_calcでの計算に必要となるバーの数を決定する目的で時間でのバーの偏差を取得する為に使用されます。
第2部『チャネル』インディケータの実用とエキスパートアドバイザの作成
この部では『チャネル』インディケータを元にしたEARopebyEricNaimanエキスパートアドバイザの作成について説明していきます(インディケータのソースコード名はRopebyEricNaiman)。インディケータはEARopebyEricNaimanエキスパートアドバイザの例における別個のストラテジーとして、またトレンド方向の判別の為のフィルターとして使用することができます。本書で著者はインディケータが算出したデータの使用法をいくつか検証しています。その中からエキスパートアドバイザに次のものを採用しました。
- 主要ラインと0の交差 (main line cross zero)。上への交差は買い、下への交差は売り。
- 主要ライン(main line color)の色が灰色から緑色に変わった(買い)、または灰色から赤色へ変わった(売り)時に発注。
- 主要ラインと短期MAの交差時に発注(main line cross MAfast)。主要ラインが下から上にMAを交差する場合は買い、上から下に交差する場合は売り。
2つのMAの交差時で発注(two MA cross)。短期MAが長期MAを下から上に交差する場合は買い、上から下に交差する場合は売り。
主要設定の他に、エキスパートアドバイザには別途シグナルに従って、または反対方向では保有ポジションタイプと比較して発注する4つの決済タイプを設定できます。
//--- ポジション決済設定 input string section_5="___ Close settings"; //--- 主要ラインとゼロラインの交差による決済 / 上から下への交差時の買い決済 input bool close1=true; // Close main line cross zero //--- 保有ポジションの反対方向へ色が変化した時に決済 / 赤色に変化した時に買い決済 input bool close2=false; // Close main line color //--- 主要ラインとMAとの交差時に決済 / 主要ラインが上から下にMAを交差した時の買い決済 input bool close3=false; // Close main line cross MAfast //--- 2つのMAの交差時に決済 / 短期MAが上から下に長期MAを交差した時の買い決済 input bool close4=true; // Close two MA cross
このように、発注はtrade_mode変数で選択したメソッドのうちの一つで起こり、決済はストップロス/テイクプロフィット/『上記のもののうちの1つ』で起こります。エキスパートアドバイザとインディケータの全ソースコードは、下に添付するファイルでダウンロードおよび参照することができます。この記事ではポジション保有と決済のシグナルの主な計算部分のみ見ていきます。
- OnInit()ブロックでは主な変数とRopebyEricNaimanインディケータの初期化が行われます。
- OnTick()ブロックには、ポジション保有/決済を制御するブロックが含まれています。
- 買いシグナル計算ブロックCheck_Indi_Open()では、インディケータとシグナル探索データがダウンロードされます。
//+------------------------------------------------------------------+ //| Check_Indi_Open | //+------------------------------------------------------------------+ int Check_Indi_Open() { //--- インディケータデータの取得の為の配列の宣言 int copy=0; double _arr_ind_1[]; double mafast[]; double mainline[]; double maslow[]; //--- switch関数を使用してtrade_mode外部変数パラメータによる発注メソッドが選択される switch((int)trade_mode) { case 0: //--- 現在のものを含めない、2つの最後のバーでのインディケータの主要ラインの比較 copy=Copy_indi_Buffer(RbEN_handle,4,1,2,_arr_ind_1,"RbEN"); if(copy!=2) return 4; if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]>0 && _arr_ind_1[1]<=0) { return 0; } if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]<0 && _arr_ind_1[1]>=0) { return 1; } break; case 1: //--- 現在のものを含めない、2つの最後のバーでのインディケータバッファ5番からのインディケータのカラーインデックスを取得 copy=Copy_indi_Buffer(RbEN_handle,5,1,2,_arr_ind_1,"RbEN"); if(copy!=2) return 5; if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]==0 && _arr_ind_1[1]!=0) { return 0; } if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]==1 && _arr_ind_1[1]!=1) { return 1; } break; case 2: //--- 現在のものを含めない、2つの最後のバーでのmafast(インディケータの主要ラインのMA)とmainline(インディケータの主要ライン)の比較と取得 copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN"); if(copy!=2) return 6; copy=Copy_indi_Buffer(RbEN_handle,4,1,2,mainline,"RbEN"); if(copy!=2) return 7; if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && mainline[0]>mafast[0] && mainline[1]<=mafast[1]) { return 0; } if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && mainline[0]<mafast[0] && mainline[1]>=mafast[1]) { return 1; } break; case 3: //--- 現在のものを含めない、2つの最後のバーでのmafast(インディケータの主要ラインの短期MA)とmaslow(インディケータの主要ラインの長期MA)の値の比較と取得 copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN"); if(copy!=2) return 8; copy=Copy_indi_Buffer(RbEN_handle,7,1,2,maslow,"RbEN"); if(copy!=2) return 9; if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE && maslow[0]<mafast[0] && maslow[1]>=mafast[1]) { return 0; } if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE && maslow[0]>mafast[0] && maslow[1]<=mafast[1]) { return 1; } break; default: return 3; } //--- return 2; }
Check_Indi_Close()ブロックでは、保有ポジション決済の全4種のメソッドの入力設定に応じた取捨が行われます。
//+------------------------------------------------------------------+ //| Check_Indi_Close | //+------------------------------------------------------------------+ int Check_Indi_Close() { //--- インディケータデータの取得の為の配列の宣言 int copy=0; double _arr_ind_1[]; double mafast[]; double mainline[]; double maslow[]; _str_close=""; //--- 現在のものを含めない、2つの最後のバーでの主要ラインのゼロラインとの比較と取得 if(close1) { copy=Copy_indi_Buffer(RbEN_handle,4,1,2,_arr_ind_1,"RbEN"); if(copy!=2) return 4; _str_close="Close main line cross zero"; if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]>0 && _arr_ind_1[1]<=0) { return 0; } if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]<0 && _arr_ind_1[1]>=0) { return 1; } } //--- 現在のものを含めない、2つの最後のバーでのインディケータバッファ5番からのインディケータのカラーインデックスを取得 if(close2) { copy=Copy_indi_Buffer(RbEN_handle,5,1,2,_arr_ind_1,"RbEN"); if(copy!=2) return 5; _str_close="Close main line color"; if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]==0 && _arr_ind_1[1]!=0) { return 0; } if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && _arr_ind_1[0]==1 && _arr_ind_1[1]!=1) { return 1; } } //--- 現在のものを含めない、2つの最後のバーでのmafast(インディケータの主要ラインのMA)とmainline(インディケータの主要ライン)の比較と取得 if(close3) { copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN"); if(copy!=2) return 6; copy=Copy_indi_Buffer(RbEN_handle,4,1,2,mainline,"RbEN"); if(copy!=2) return 7; _str_close="Close main line cross MAfast"; if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && mainline[0]>mafast[0] && mainline[1]<=mafast[1]) { return 0; } if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && mainline[0]<mafast[0] && mainline[1]>=mafast[1]) { return 1; } } //--- 現在のものを含めない、2つの最後のバーでのmafast(インディケータの主要ラインの短期MA)とmaslow(インディケータの主要ラインの長期MA)の値の比較と取得 if(close4) { copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN"); if(copy!=2) return 8; copy=Copy_indi_Buffer(RbEN_handle,7,1,2,maslow,"RbEN"); if(copy!=2) return 9; _str_close="Close two MA cross"; if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE && maslow[0]<mafast[0] && maslow[1]>=mafast[1]) { return 0; } if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE && maslow[0]>mafast[0] && maslow[1]<=mafast[1]) { return 1; } } //--- return 2; }
- Copy_indi_Buffer()ブロックは、CopyBuffer()関数を介してインディケータのデータを取得するためにあります。
- TakeLastOpenTime()ブロックは、一つのバーで複数のポジションが発生しないようにする為に、バーの始まり時間と比較するOnTick為の保有ポジションの最後の時間を取得する為にあります。
- OpenPosition() — ポジション保有関数。
- Copy_Time()は指定したバーの時間をコピーします。
- CloseAllPosition()は全てのポジションを決済します。
エキスパートアドバイザを作成したら、入力パラメータの最適化に移りましょう。
第3部『チャネル』インディケータに基づくエキスパートアドバイザの外部パラメータの最適化
エキスパートアドバイザを起動させるまえに、主要な入力パラメータを最適化する必要があります。例として、EURUSD H1 2005-2015を採用しました(最適化の遺伝的アルゴリズム)。4つの発注タイプのそれぞれに個別に最適化が行われました。
1. trade_mode = Close main line cross zero (主要ラインと0の交差: 上への交差は買い、下への交差は売り)。
最適化パラメータ:
意味 スタート ステップ ストップ ステップ StopLoss 0 50 10000 201 TakeProfit 0 50 10000 201 _period 1 1 200 200 close1 false true 2 総パス 16160400
最適化とより良いテストの結果は、"EURUSD H1 2005-2015\test1 - main line cross zero\"フォルダのoptimization.zipファイルでご覧いただけます。
2. trade_mode = Close main line color (主要ラインが灰色から緑色に変わった(買い)、または灰色から赤色に変わった(売り)場合に発注)。
最適化パラメータ:
意味 スタート ステップ ストップ ステップ StopLoss 0 50 10000 201 TakeProfit 0 50 10000 201 _period 1 1 200 200 close2 false true 2 総パス 16160400
最適化とより良いテストの結果は、"EURUSD H1 2005-2015\test2 - main line color\"フォルダのoptimization.zipファイルでご覧いただけます。
3. trade_mode = main line cross MAfast (主要ラインと短期MAの交差時に発注:主要ラインがMAを下から上に交差したら買い、上から下に交差したら売り)。
最適化パラメータ:
意味 スタート ステップ ストップ ステップ StopLoss 0 50 10000 201 TakeProfit 0 50 10000 201 _period 1 1 200 200 period_MA_fast 1 1 300 300 close3 false true 2 総パス 4848120000 最適化とより良いテストの結果は、"EURUSD H1 2005-2015\test3 - main line cross MAfast\"フォルダのoptimization.zipファイルでご覧いただけます。
4. trade_mode = two MA cross (2つのMAの交差時に発注:短期MAが長期MAを下から上に交差したら買い、上から下に交差したら売り)。
最適化パラメータ:
意味 スタート ステップ ストップ ステップ StopLoss 0 50 10000 201 TakeProfit 0 50 10000 201 _period 1 1 200 200 period_MA_fast 1 1 300 300 period_MA_slow 1 1 400 400 close4 false true 2 総パス 1939248000000 最適化とより良いテストの結果は、"EURUSD H1 2005-2015\test4 - two MA cross\"フォルダのoptimization.zipファイルでご覧いただけます。
まとめ
最適化結果は、エキスパートアドバイザが資産管理の追加関数を使用しない、純粋なインディケータの動作原理に基づいて作成されているにも関わらず、このストラテジーが能力を持っていることを示しています。純粋な論理とは、著者によって指摘されたトレンドを判別するストラテジーで、指定した時間内でのブルとベアの動きの静的評価をベースにしたものです。このインディケータを使用することで、市場エントリーのポイントを判別することができ、インディケータを自分のストラテジーのフィルターとして、また取引開始の基本的なシグナルとして使用できます。
以下に添付するファイルで、プログラミングとトレーディングにおいて独自の開発をすることができる、インディケータとエキスパートアドバイザのソースコードを見つけることができます。このストラテジーは小さな使用領域(基本的なエントリー/イグジットのシグナル)で実装及び表示され、初期段階で既にその能力を示しました。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/2027





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索