2017年5月24日水曜日

[MT4インジケータ]最小二乗法移動平均(LSMA)

#LWMAとLSMA間違えてましたので記事修正

Trading Viewみてたら最小二乗法移動平均(LSMA)ってあるんですね・・・。なんかよさそう。
あれ?MT4になくね?(いえ、探せばフリーインジであるので、わざわざ作る必要ないのですが・・・。)

ということで作ってみました。
指定価格の近似直線を計算して、近似直線の起点から傾き*Lengthを足した値に点を描画するインジケータです。傾きでトレンドの方向、実際の価格位置でトレンドとマッチしているかがわかる感じのようです。


//------------------------------------------------------------------
// 最小二乗法移動平均
#property copyright "Copyright 2017,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_chart_window

//バッファーを指定する。
#property indicator_buffers 1

//プロット数を指定する。
#property indicator_plots   1

#property indicator_type1   DRAW_LINE
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input ENUM_APPLIED_PRICE MaPrice = PRICE_CLOSE; // 対象価格

input int Length = 25;  // 長さ
input int Offset = 0;   // オフセット

double lsma[];

//------------------------------------------------------------------
//初期化
int OnInit()
{
   //インジケーターバッファを初期化する。
   int count = 0 ;
   SetIndexBuffer(count++, lsma);

   string short_name = "LSMA";
   IndicatorShortName(short_name);

   return INIT_SUCCEEDED;
}

//------------------------------------------------------------------
//計算イベント
int OnCalculate(const int rates_total,          //各レート要素数
                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[])            //スプレット
{
   //LSMA計算式 LSMA = 平均値 + 傾き * (Length - 1 - Offset)
   //左側を0起点とするように計算しないとおかしなことになるので注意
   for( int i = rates_total - prev_calculated - 1; i >= 0 && !IsStopped(); i-- )
   {
      if( i > rates_total - Length - 1 ) continue;
      
      //指定価格の最小二乗平均値を求める
      double sumX = 0;
      double sumY = 0;
      double sigXY = 0;
      double sigX2 = 0;

      for( int j = 0; j < Length; j++ )
      {
         double value = GetPrice(open[i + j], close[i + j], high[i + j], low[i + j], MaPrice);
         
         sumX += (Length - j - 1);
         sumY += value;
         sigXY += (Length - j - 1) * value;
         sigX2 += MathPow((Length - j - 1), 2);
      }
      
      sumX /= Length;
      sumY /= Length;
      double base = (sigX2 - Length * MathPow(sumX, 2));
      
      double a = 0 ;
      double b = 0 ;
      if( base != 0 )
      {
         a = ( sigXY - Length * sumX * sumY) / base;
         b = sumY - a * sumX;
      }
      
      lsma[i] = b + a * (Length - 1 - Offset);
   }
   
   return rates_total - 1;
}

//------------------------------------------------------------------
// 価格を計算する。
// return 対象価格
double GetPrice(
   double open,   // オープン値
   double close,  // クローズ値
   double high,   // 高値
   double low,    // 安値
   ENUM_APPLIED_PRICE maPrice    //取得価格
   )
{
   double price = 0;

   switch( maPrice )
   {
      case PRICE_CLOSE:
         price = close;
         break;
      case PRICE_OPEN:
         price = open;
         break;
      case PRICE_HIGH:
         price = high;
         break;
      case PRICE_LOW:
         price = low;
         break;
      case PRICE_MEDIAN:
         price = (high + low) / 2;
         break;
      case PRICE_TYPICAL:
         price = (high + low + close) / 3;
         break;
      case PRICE_WEIGHTED:
         price = (high + low + close + close) / 4;
         break;
   }
   return price;
}




「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program
Trading View プロフィール

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ FX テクニカルトレード派へ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。