
ファジー理論を使用しインディケータを作成する簡単な例
はじめに
ファイナンシャルマーケット分析への多様なメソッドの利用は近年トレーダーの間でますます人気を集めています。私も一役買い、数十のコードラインを書くことでよいインディケータを作成する方法をお目にかけたいと思います。また、わずかではありますが、ファジー理論の基礎もお話します。
この問題に興味があってそれをもっと掘り下げたいと思う方は以下の試料をご一読ください。
- Leonenkov А. "Fuzzy Simulation in MATLAB and fuzzyTECH" (ロシア語).
- Bocharnikov V."Fuzzy Technology: Mathematical Background. Simulation Practice in Economics" (ロシア語).
- S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB.
- C. Kahraman. Fuzzy Engineering Economics with Applications (Studies in Fuzziness and Soft Computing).
1. ファジー理論の基礎
われわれの計算機に「もうすこし」、「速すぎ」、「ほとんどなし」などのシンプルな意味をどのように伝えることができるでしょうか?実際、ファジーな設定の理論エレメントまたはむしろいわゆる『メンバ関数』を使えば可能です。А. Leonenkovの著作に例があります。
「ホットコーヒー」というフレーズについてのメンバ関数を考察します。:コーヒーの温度は0℃ ~100℃の範囲とみなし、これは単純な理由によります。0℃以下では氷になり、一方100℃以上の温度では蒸発する、というものです。明らかに温度20℃の一杯のコーヒーをホットとは呼べません。すなわち「ホット」のカテゴリに属すメンバ関数は値0、一方70℃のコーヒーは完全に「ホット」のカテゴリーに属しています。そのためこの場合関数値は1ということになります。
温度の値については、この極端な2つの値の間ですが、状況はそれほど明確ではありません。55℃の温度のコーヒーを「ホット」だと思う人もいれば、一方でそれは「ホットでなはい」と思う人もいるかもしれません。これが『あいまいさ』です。
なんとなくメンバ関数の様子がわかってきたのではないでしょうか。それは「単調増加」です。
上図は「ピース方向のリニア」メンバ関数を示しています。
関数は次の分析的表現によって定義することができます。
そういう関数をわれわれのインディケータに使うのです。
2. メンバ関数
いずれにせよ、どんな技術的インディケータのタスクも現在のマーケット状況(横ばい、上昇傾向、下降傾向)を判断しています。マーケットの入り/出の作成もしかりです。メンバ関数の助けを借りてどのようにこれを行うことができるのでしょうか?簡単です。
まず、境界条件を確定する必要があります。次の境界条件を設けます。「100% 上昇傾向」では、期間2でEMAのクロッシングです。一般的な価格 (H+L+C)/3 に基づき上縁のエンベロープを伴い、パラメータ 8、 0.08、 SMA、 クローズを持ち、一方「100% 下降傾向」には同じEMAを横切りますが、低い境界のエンベロープを伴います。これら条件の間にあるすべては横ばいとみなされます。パラメータ32、0.15、SMA、クローズを持つエンベロープをもう一つ追加します。
結果は2つのそっくりなメンバ関数を取得します。それぞれ、関数が両方1なら、買いシグナルがアクティブになります。一方、関数が両方-1なら売りシグナルがアクティブになります。-1~1の範囲でチャートを作成するのは便利なので、結果チャートは2つの関数の算術平均 F(x)= (f1(x)+f2(x))/2を取得します。
チャートは以下のような体裁をしています。
この場合、メンバ関数は以下のグラフィカルな表現となります。
分析的には次のように書かれます。
,
ここで、それぞれa と b がエンベロープの上下ラインです。一方、 х は EMA(2)の値です。
関数を定義し、われわれは先に進んでインディケータコードを書きます。
3. プログラムコードの作成
まず、何をどのように描くのか決める必要があります。
メンバ関数計算の結果は線 - それぞれ赤と青で表示されます。
算術平均はゼロラインからのヒストグラムとして表示され、結果の関数値に応じて5色のどれかの色で塗られます。
DRAW_COLOR_HISTOGRAM 描画すタイプがそれに使用されます。
青と赤の長方形を買い/出シグナルとしてヒストグラムバーの上に書きます。値は 1 または -1です。
MetaEditorを実行して起動します。新規->カスタムインディケータ->次へ... 『パラメータ』フィールドを書きます。
バッファを作成します。
「終了」ボタンをクリックしたら、ソースコードを受け取り、それを改良していきます。
まず、バッファ数を決めます。うちの7個はすでにウィザードで作成されています。(5をデータ、2を色)もう5個必要です。
#property indicator_minimum -1.4 // Setting fractional values #property indicator_maximum 1.4 // Expert Advisors wizard ignores fractional parts for some reason #property indicator_buffers 12 // Changing the value from 7 to 12 (5 more buffers have been added)入力パラメータを編集します。
input string txt1="----------"; input int Period_Fast=8; input ENUM_MA_METHOD Method_Fast = MODE_SMA; /*Smoothing method*/ //moving average smoothing method input ENUM_APPLIED_PRICE Price_Fast = PRICE_CLOSE; input double Dev_Fast=0.08; input string txt2="----------"; input int Period_Slow=32; input ENUM_MA_METHOD Method_Slow = MODE_SMA; input ENUM_APPLIED_PRICE Price_Slow = PRICE_CLOSE; input double Dev_Slow=0.15; /*Deviation parameter*/ input string txt3="----------"; input int Period_Signal=2; input ENUM_MA_METHOD Method_Signal = MODE_EMA; input ENUM_APPLIED_PRICE Price_Signal = PRICE_TYPICAL; input string txt4="----------";
宣言された変数にコメントを入れるとたいへん便利です。コメントテキストはインディケータパラメータウィンドウに挿入します。
リスト作成機能もたいへん有用です。
インディケータハンドルとバッファ用変数の予約。
int Envelopes_Fast; // Fast envelope int Envelopes_Slow; // Slow envelope int MA_Signal; // Signal line double Env_Fast_Up[]; // Fast envelope upper border double Env_Fast_Dn[]; // Fast envelope lower border double Env_Slow_Up[]; // Slow envelope upper border double Env_Slow_Dn[]; // Slow envelope lower border double Mov_Sign[]; // Signal line
ではOnInit()関数に移ります。
少し見栄えをよくします。インディケータ名を指定し、不要なゼロを消去します。
IndicatorSetInteger(INDICATOR_DIGITS,1); // setting display accuracy, we do not need some outstanding accuracy values string name; // indicator name StringConcatenate(name, "FLE ( ", Period_Fast, " , ", Dev_Fast, " | ", Period_Slow, " , ", Dev_Slow, " | ", Period_Signal, " )"); IndicatorSetString(INDICATOR_SHORTNAME,name);
そして不足しているバッファを足します。
SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS);
INDICATOR_CALCULATIONSパラメータはバッファデータは中間計算にのみ必要であることを意味します。それはチャートには表示されません。
カラーバッファを伴うインディケータがどのように宣言されるか知っておきます。
SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA); // All indicator buffers at first SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA); // as this is Color Histogram2, then it has 2 data buffers SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX);// the color buffer comes next.
ハンドルを書きます。
Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast); Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow); MA_Signal = iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal);
OnInit() 関数に関する作業はすべて終わりです。
メンバ関数値を計算する関数を作成します。
double Fuzzy(double x,double a, double c) { double F; if (a<x) F=1; // 100% uptrend else if (x<=a && x>=c) F=(1-2*(a-x)/(a-c));// Flat else if (x<c) F=-1; // 100% downtrend return (F); }
分離は終わりました。変数とバッファは宣言され、ハンドルは割り当てられました。
OnCalculate()基本関数を使って先に進みます。
まず、中間バッファに必要なインディケータの値を書きます。 CopyBuffer()関数を使います。
CopyBuffer(Envelopes_Fast, // Indicator handle UPPER_LINE, // Indicator buffer 0, // The point to start 0 - from the very beginning rates_total, // How many to be copied - All Env_Fast_Up); // The buffer the values are written in // - the rest are done in a similar way CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn); CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up); CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn); CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign);
ここで、計算最適化(最後のバーのみ再計算が行われます)のコードを追加します。
// declaring start variable for storing the index of the bar, recalculation of the indicator buffers will be // carried out from. int start; if (prev_calculated==0) // in case no bars have been calculated { start = Period_Slow; // not all indicators have been calculated up to this value, therefore, there is no point in executing the code } else start=prev_calculated-1; for (int i=start;i<rates_total;i++) { // All remaining code will be written here }
残っていルコードはあとわずかです。
パラメータ x, a, b を設定、メンバ関数値計算、適切なバッファへの書き込みdouble x = Mov_Sign[i]; // Signal // Setting the first membership function parameters: double a1 = Env_Fast_Up[i]; // Upper border double b1 = Env_Fast_Dn[i]; // setting the first membership function value and writing it to the buffer Rule1Buffer[i] = Fuzzy(x,a1,b1); // Setting the second membership function parameters: double a2 = Env_Slow_Up[i]; // Upper border double b2 = Env_Slow_Dn[i]; // setting the second membership function value and writing it to the buffer Rule2Buffer[i] = Fuzzy(x,a2,b2);
インディケータラインが2行できました。
結果の値を計算します。
ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;
ヒストグラムバーを適当な色に塗ります。4色ありResultColors[i] 0 ~ 4のいずれかの値を取ることができます。
一般に、可能な色の数は64です。創造力を発揮するよい機会です。
for (int ColorIndex=0;ColorIndex<=4;ColorIndex++) { if (MathAbs(ResultBuffer[i])>0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1)) { ResultColors[i] = ColorIndex; break; } }
シグナル長方形を描きます。 DRAW_COLOR_HISTOGRAM2 描画スタイルを使います。
それはヒストグラムバーを伴うバッファデータを2つとその間にビルドされる1個のカラーバッファを持っています。
データバッファ値は常に同じです。:それぞれ買いシグナルには1.1と 1.3 、売りシグナルには -1.1 と -1.3 です。
EMPTY_VALUE はシグナル不在を意味します。
if (ResultBuffer[i]==1) { SignalBuffer1[i]=1.1; SignalBuffer2[i]=1.3; SignalColors[i]=1; } else if (ResultBuffer[i]==-1) { SignalBuffer1[i]=-1.1; SignalBuffer2[i]=-1.3; SignalColors[i]=0; } else { SignalBuffer1[i]=EMPTY_VALUE; SignalBuffer2[i]=EMPTY_VALUE; SignalColors[i]=EMPTY_VALUE; }
『コンパイル』をクリックすると、ご覧のとおり!
おわりに
他に追加できるものは?本稿では、ファジー理論の基礎アプローチに触れました。
さまざまな実験をするには十分なスペースがあります。たとえば、以下の関数を使うこともできます。
それの分析的式を書き、適切な条件を見つけるのは難しいことではないと思います。
がんばってください!
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/178





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