English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
ファジー理論を使用しインディケータを作成する簡単な例

ファジー理論を使用しインディケータを作成する簡単な例

MetaTrader 5トレーディング | 6 10月 2015, 17:27
748 0
Максим Востров
Максим Востров

はじめに

ファイナンシャルマーケット分析への多様なメソッドの利用は近年トレーダーの間でますます人気を集めています。私も一役買い、数十のコードラインを書くことでよいインディケータを作成する方法をお目にかけたいと思います。また、わずかではありますが、ファジー理論の基礎もお話します。

この問題に興味があってそれをもっと掘り下げたいと思う方は以下の試料をご一読ください。

  1. Leonenkov А. "Fuzzy Simulation in MATLAB and fuzzyTECH" (ロシア語).
  2. Bocharnikov V."Fuzzy Technology: Mathematical Background. Simulation Practice in Economics" (ロシア語).
  3. S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB.
  4. 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

添付されたファイル |
標準ライブラリクラスを使ってオリジナルのMarket Watchを作成します。 標準ライブラリクラスを使ってオリジナルのMarket Watchを作成します。
新しいMetaTrader 5クライアント端末とMQL5言語はトレーダーにビジュアル情報を提供する機会をもたらします。 本稿では、汎用的拡張可能なクラスセットを提案します。それはチャート上の任意のテキストの表示作成作業をすべて行うものです。 Market Watch インディケータの例を提供します。
MQL5ウィザード:プログラミングしないExpert Advisorsの作成 MQL5ウィザード:プログラミングしないExpert Advisorsの作成
プログラミングで時間を無駄にせずトレーディング戦略を試してみたいと思いませんか?MQL5ウィザードではただトレーディングシグナルを選び、トレーリングポジションと資金管理のモジュールに追加するだけです。 - それで仕事は終わりです!独自のモジュール実装または、Jobsサービスから注文します。 - そうして新しいモジュールを既存のモジュールと融合させるのです。
新しいMQL4のオフラインチャート 新しいMQL4のオフラインチャート
新しいバージョンのMQL4では、履歴データの保存方法が変更され、MqlRates構造体が新たに追加されました。MqlRates構造体は、Time、Open、Low、High、Close、Volumeなどの値を保存するのに役立ちます。長年にわたってトレーダーは、オフラインチャートを作成する為にHSTファイルに自分のデータを集めて書き込む、自分のプログラムをMQL4で作成していました。各トレーダーは、以前にコンパイルされた全てのEX4ファイルが、新しいMetaTrader4ターミナルで、以前と同様に動作すると確信していることでしょう。
Growing Neural Gas: MQL5への実装 Growing Neural Gas: MQL5への実装
本稿では、Growing neural gas (GNG)と呼ばれるクラスタの適用アルゴリズを実装するムMQL5プログラム開発方法をお見せしていきます。本稿は言語ドキュメンテーションを学習し、一定のプログラミングスキルがあり、神経情報科学分野の基礎知識がある方を対象としています。