プライスアクションインジ(MQL4

# 目的
プライスアクションのインジを作る

# プライスアクションとは？

[ここ](https://www.fxbroadnet.com/tech/priceaction/)が参考になると思います。

全てはインジケータで表現しきれないので，ある程度絞っていきたいと思います。

実装したものだけ引用して紹介します。

## 1.ピンバー

上記[リンク](https://www.fxbroadnet.com/tech/priceaction/pin_bar.jsp)には・・・

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/9ccc202f-1d9d-f8ed-9601-4c29350ce60e.png)
>ヒゲが長く伸びてローソクの実体部分が極端に短いローソク足のこと。
>長く伸びたヒゲは、取引時間中に値を伸ばしたものの、その後の値動きで大きく押し戻されたことを示しています。
>ピンバーが何度も発生する水準は、値動きの先に強い抵抗帯が存在するを教えいます。
>相場の転換や停滞への可能性を示唆するプライスアクションです。

## 2.スパイクハイ/スパイクロー

上記[リンク](https://www.fxbroadnet.com/tech/priceaction/spike.jsp)には・・・

>スパイクは、ピンバー同様にヒゲが長くローソクの実体部分が短いローソク足のこと。
>長いヒゲは、取引時間中の値動きが押し戻されて取引を終えた結果を示しています。

### 2.1.スパイクハイ

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/b4962974-0204-b4ce-a56f-3015f2c2f1ad.png)
>
>スパイクハイとは、上昇が続いた後の高値水準で上ヒゲの長いスパイクが発生することを言います。
>上昇したその先に強い抵抗ゾーンの存在を教えてくれ、相場転換の可能性を示唆します。

### 2.2.スパイクロー

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/9caf93e1-529c-62a1-0263-cac3a373a467.png)
>
>スパイクローとは、下落が続いた後の安値水準で下ヒゲの長いスパイクが発生することを言います。
>下落したその先に強い支持ゾーンの存在を教えてくれ、相場転換の可能性を示唆します。

## 3.スラストアップ/スラストダウン

上記[リンク](https://www.fxbroadnet.com/tech/priceaction/thrust.jsp)には・・・

### 3.1.スラストアップ
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/a43586e6-42dc-ae77-e62d-cca670300e48.png)
>スラストアップは、直前のローソク足の高値を上回って終値が確定されると完成します。
>
>上昇トレンドの途中では、自然とスラストアップが数多く発生します。
>連続してスラストアップが発生している上昇トレンドは値動きの勢いが強いことを示しています。
>スラストアップを探していくことで、トレンドの強さを確認できるプライスアクションです。

### 3.2.スラストダウン
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/679a4a3d-6ecb-c598-9d50-24dccc5675a9.png)
>スラストダウンは、直前のローソク足の安値を下回って終値が確定されると完成します。
>下降トレンドの途中では、自然とスラストダウンが数多く発生します。
>連続してスラストダウンが発生している下降トレンドは値を下げる勢いが強いことを示しています。
>スラストダウンを探していくことで、強い下落トレンドを確認できるプライスアクションです。


## 4.リバーサル

上記[リンク](https://www.fxbroadnet.com/tech/priceaction/reversal.jsp)には・・・

### 4.1.強気リバーサル
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/6ffede35-73b2-3299-4c42-41f6f7956992.png)
>強気リバーサルは、下落トレンドが反転上昇する可能性を示唆するプライスアクションです。
>取引時間中に安値を更新したものの、直前のローソク足の実体部分を上回る終値の確定で発生とみなします。
>
>ローソクの実体部分だけでなく、高値も更新する終値となった場合は、強力な強気リバーサルの出現です。
>強気リバーサルが発生した後は、下落基調が反転し価格の上昇に備えます。

### 4.2.弱気リバーサル
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/706efc25-86ca-092c-878d-1e1014288e23.png)
>弱気リバーサルは、上昇トレンドが反転下落する可能性を示唆するプライスアクションです。
>取引時間中に高値を更新したものの、直前のローソク足の実体部分を下回る終値の確定で発生を確認します。
>
>ローソクの実体部分だけでなく、安値も更新する終値となった場合は、強い弱気リバーサルの出現です。
>弱気リバーサルが発生した後は、上昇基調が反転し価格の下落に備えます。

## 5.ランウェイ

上記[リンク](https://www.fxbroadnet.com/tech/priceaction/runway.jsp)には・・・

### 5.1.ランウェイアップ
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/cbb34a54-cc45-51cf-a716-6b2d13a97cf4.png)
>ランウェイアップは、価格水準を切り上げて上昇する値動きを確認できるプライスアクションです。
>以下の２つの条件を満たすローソク足の発生で確認します。
>①高値が過去n本のローソク足の高値よりも超えている
>②安値がn本先のローソク足まで下回ることがない
>
>n本とある様に、あらかじめカウントするローソク足の本数を決めておく必要があります。
>日足の場合は、1週間を基準に5本（5営業日分）とすることが一般的です。
>
>過去の水準からの切り上がりと、一定期間後も元の水準に戻らないことを確認する。
>継続的に値段が上昇する強いトレンドの途中で数多く見られるプライスアクションです。

### 5.2.ランウェイダウン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/25dd8b10-cf92-3dd4-018e-93049aaec4a3.png)
>ランウェイダウンは、価格水準を切り下げて下落する値動きを確認できるプライスアクションです。
>以下の２つの条件を満たすローソク足の発生で確認します。
>①安値が過去n本のローソク足の安値を下回っている
>②高値がn本先のローソク足まで破られない
>
>n本とある様に、あらかじめカウントするローソク足の本数を決めておく必要があります。
>日足の場合は、1週間を基準に5本（5営業日分）とすることが一般的です。
>
>過去の水準からの切り下げと、一定期間後も元の水準に戻らないことを確認する。
>継続的に値段が下落するトレンドの途中で数多く見られるプライスアクションです。

# 全コード
定義に従って，ひたすらコード書いていくだけです。
ただ，定義といっても主観が伴うので，必ず同じ動きにはならんのですよね！
ランウェイは途中までしか実装できませんでした！

あとarrowについては，[ここ](https://www.mql5.com/ja/blogs/post/661991)から選べます。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/d29ea6ec-6573-170d-46c2-82aa6275360a.png)

それでは全コードいきます！

``` C

#property strict
#property indicator_chart_window

#property indicator_buffers 16 //インジケータのバッファを2つ用意
#property indicator_color1 Blue //1つ目のインジケータを赤色に設定
#property indicator_color2 Red //2つ目のインジケータを青色に設定
#property indicator_color3 clrDarkTurquoise //3つ目のインジケータを赤色に設定
#property indicator_color4 Red //4つ目のインジケータを青色に設定
#property indicator_color5 clrDeepSkyBlue //5つ目のインジケータを赤色に設定
#property indicator_color6 Red //6つ目のインジケータを青色に設定
#property indicator_color7 Blue //7つ目のインジケータを赤色に設定
#property indicator_color8 Red //8つ目のインジケータを青色に設定
#property indicator_color9 Blue //9つ目のインジケータを赤色に設定
#property indicator_color10 Red //10つ目のインジケータを青色に設定
#property indicator_color11 Blue //11つ目のインジケータを赤色に設定
#property indicator_color12 Red //12つ目のインジケータを青色に設定
#property indicator_width1 1 //1つ目のインジケータの太さを3に設定
#property indicator_width2 1 //2つ目のインジケータの太さを3に設定
#property indicator_width3 2 //3つ目のインジケータの太さを3に設定
#property indicator_width4 2 //4つ目のインジケータの太さを3に設定
#property indicator_width5 2 //5つ目のインジケータの太さを3に設定
#property indicator_width6 2 //6つ目のインジケータの太さを3に設定
#property indicator_width7 2 //7つ目のインジケータの太さを3に設定
#property indicator_width8 2 //8つ目のインジケータの太さを3に設定
#property indicator_width9 2 //9つ目のインジケータの太さを3に設定
#property indicator_width10 2 //10つ目のインジケータの太さを3に設定
#property indicator_width11 2 //9つ目のインジケータの太さを3に設定
#property indicator_width12 2 //10つ目のインジケータの太さを3に設定

//--- input parameters
input color backGroundColor=clrWhite;//チャート背景色
input color foreGroundColor=C'127,127,127';//チャート前景色
input color upColor=C'0,112,192';//上昇バーの色
input color downColor=C'192,0,0';//下降バーの色
input color bullColor=C'0,112,192';//上昇ローソク足の色
input color bearColor=C'192,0,0';//下降ローソク足の色
input int mySpread=6;//スプレッド
input bool thrustEnable=false;//スラストの有効化
input bool runWayEnable=false;//ランウェイの有効化
input bool pinBarEnable=false;//ピンバーの有効化
input bool spikeEnable=false;//スパイクの有効化
input bool reversalEnable=true;//リバーサルの有効化
input bool falseBreakEnable=false;//フォルスブレイクの有効化
input bool fakeSetEnable=false;//フェイクセットの有効化
input bool insideEnable=false;//インサイドの有効化
input bool outsideEnable=false;//アウトサイドの有効化
//--- buffers
double thrustUp[];//スラストアップ
double thrustDown[];//スラストダウン
double runWayUp[];//ランウェイアップ
double runWayDown[];//ランウェイダウン
double pinBarUp[];//ピンバーアップ
double pinBarDown[];//ピンバーダウン

double spikeHigh[];//スパイクハイ
double spikeLow[];//スパイクロー
double reversalHigh[];//リバーサルハイ
double reversalLow[];//リバーサルロー
double falseBreakOutUp[];//フォルスブレイクアウトアップ
double falseBreakOutDown[];//フォルスブレイクアウトダウン
double fakeSetUp[];//フェイクセットアップ
double fakeSetDown[];//フェイクセットダウン
double inside[];//インサイド
double outside[];//アウトサイド
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

   ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   ChartSetInteger(0,CHART_SHOW_GRID,false);
   ChartSetInteger(0,CHART_COLOR_BACKGROUND,backGroundColor);
   ChartSetInteger(0,CHART_COLOR_FOREGROUND,foreGroundColor);
   ChartSetInteger(0,CHART_COLOR_CHART_UP,upColor);
   ChartSetInteger(0,CHART_COLOR_CHART_DOWN,downColor);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,bullColor);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,bearColor);


//--- indicator buffers mapping

//--- 2 additional buffers are used for counting.
//--- indicator line
//スラストアップ
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,228); //右斜め上矢印（細目）
   SetIndexBuffer(0,thrustUp);
   SetIndexLabel(0,"スラストアップ");//ラベル

//スラストダウン
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,230); //右斜め下矢印（細目）
   SetIndexBuffer(1,thrustDown);
   SetIndexLabel(1,"スラストダウン");//ラベル

//ランウェイアップ　前後ローソク5本分
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,176); //右斜め上矢印
   SetIndexBuffer(2,runWayUp);
   SetIndexLabel(2,"ランウェイアップ");//ラベル
   SetIndexDrawBegin(2,10);

//ランウェイダウン　前後ローソク5本分
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,176); //右斜め下矢印
   SetIndexBuffer(3,runWayDown);
   SetIndexLabel(3,"ランウェイダウン");//ラベル
   SetIndexDrawBegin(3,10);


//ピンバーアップ
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(4,233); //上矢印
   SetIndexBuffer(4,pinBarUp);
   SetIndexLabel(4,"ピンバーアップ");//ラベル

//ピンバーダウン
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexArrow(5,234); //下矢印
   SetIndexBuffer(5,pinBarDown);
   SetIndexLabel(5,"ピンバーダウン");//ラベル

//スパイクロー
   SetIndexStyle(6,DRAW_ARROW);
   SetIndexArrow(6,200); //
   SetIndexBuffer(6,spikeLow);
   SetIndexLabel(6,"スパイクロー");//ラベル

//スパイクハイ
   SetIndexStyle(7,DRAW_ARROW);
   SetIndexArrow(7,202); //）
   SetIndexBuffer(7,spikeHigh);
   SetIndexLabel(7,"スパイクハイ");//ラベル

//リバーサルロー
   SetIndexStyle(8,DRAW_ARROW);
   SetIndexArrow(8,246); //右斜め下矢印
   SetIndexBuffer(8,reversalLow);
   SetIndexLabel(8,"リバーサルロー");//ラベル

//リバーサルハイ
   SetIndexStyle(9,DRAW_ARROW);
   SetIndexArrow(9,248); //右斜め上矢印
   SetIndexBuffer(9,reversalHigh);
   SetIndexLabel(9,"リバーサルハイ");//ラベル



//フォルスブレイクアウトアップ
   SetIndexStyle(10,DRAW_ARROW);
   SetIndexArrow(10,233); //上矢印
   SetIndexBuffer(10,falseBreakOutUp);

//フォルスブレイクアウトダウン
   SetIndexStyle(11,DRAW_ARROW);
   SetIndexArrow(11,234);//下矢印
   SetIndexBuffer(11,falseBreakOutDown);

//フェイクセットアップ
   SetIndexStyle(12,DRAW_ARROW);
   SetIndexArrow(12,236); //右斜め上矢印
   SetIndexBuffer(12,fakeSetUp);

//フェイクセットダウン
   SetIndexStyle(13,DRAW_ARROW);
   SetIndexArrow(13,238); //右斜め下矢印
   SetIndexBuffer(13,fakeSetDown);

//インサイド
   SetIndexStyle(14,DRAW_ARROW);
   SetIndexArrow(14,216); //上矢印
   SetIndexBuffer(14,inside);

//アウトサイド
   SetIndexStyle(15,DRAW_ARROW);
   SetIndexArrow(15,215);//下矢印
   SetIndexBuffer(15,outside);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   int i;
   int end_index = Bars - prev_calculated;  // バー数取得(未計算分)
   if(end_index <= IND_MIN_INDEX)          // 直近数本は常時更新
     {
      end_index = IND_MIN_INDEX ;
     }

   if(Bars <= IND_MIN_INDEX)              // ヒストリカルデータ不足時
     {
      return 0;                            // 全て再計算が必要なので、計算済みバー数を0にして終了する
     }

//--- the main loop of calculations
   int limit = rates_total - MathMax(prev_calculated,10);

   for(i =limit -1 ; i >=0; i--)
     {
      double thisClose=iClose(NULL,PERIOD_CURRENT,i);
      double thisOpen=iOpen(NULL,PERIOD_CURRENT,i);
      double thisLow=iLow(NULL,PERIOD_CURRENT,i);
      double thisHigh=iHigh(NULL,PERIOD_CURRENT,i);
      double oneBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+1);
      double oneBeforeLow = iLow(NULL,PERIOD_CURRENT,i+1);
      double oneBeforeClose = iClose(NULL,PERIOD_CURRENT,i+1);
      double oneBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+1);
      double twoBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+2);
      double twoBeforeLow = iLow(NULL,PERIOD_CURRENT,i+2);
      double twoBeforeClose = iClose(NULL,PERIOD_CURRENT,i+2);
      double twoBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+2);
      double threeBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+3);
      double threeBeforeLow = iLow(NULL,PERIOD_CURRENT,i+3);
      double threeBeforeClose = iClose(NULL,PERIOD_CURRENT,i+3);
      double threeBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+3);
      double fourBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+4);
      double fourBeforeLow = iLow(NULL,PERIOD_CURRENT,i+4);
      double fourBeforeClose = iClose(NULL,PERIOD_CURRENT,i+4);
      double fourBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+4);
      double fiveBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+5);
      double fiveBeforeLow = iLow(NULL,PERIOD_CURRENT,i+5);
      double fiveBeforeClose = iClose(NULL,PERIOD_CURRENT,i+5);
      double fiveBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+5);

      double sixBeforeHigh=0.0;
      double sixBeforeLow=0.0;
      double sixBeforeClose=0.0;
      double sixBeforeOpen=0.0;
      double sevenBeforeHigh=0.0;
      double sevenBeforeLow=0.0;
      double sevenBeforeClose=0.0;
      double sevenBeforeOpen=0.0;
      double eightBeforeHigh=0.0;
      double eightBeforeLow=0.0;
      double eightBeforeClose=0.0;
      double eightBeforeOpen=0.0;
      double nineBeforeHigh=0.0;
      double nineBeforeLow=0.0;
      double nineBeforeClose=0.0;
      double nineBeforeOpen=0.0;
      double tenBeforeHigh=0.0;
      double tenBeforeLow=0.0;
      double tenBeforeClose=0.0;
      double tenBeforeOpen=0.0;
      if(runWayEnable || insideEnable)
        {

         sixBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+6);
         sixBeforeLow = iLow(NULL,PERIOD_CURRENT,i+6);
         sixBeforeClose = iClose(NULL,PERIOD_CURRENT,i+6);
         sixBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+6);
         sevenBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+7);
         sevenBeforeLow = iLow(NULL,PERIOD_CURRENT,i+7);
         sevenBeforeClose = iClose(NULL,PERIOD_CURRENT,i+7);
         sevenBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+7);
         eightBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+8);
         eightBeforeLow = iLow(NULL,PERIOD_CURRENT,i+8);
         eightBeforeClose = iClose(NULL,PERIOD_CURRENT,i+8);
         eightBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+8);
         nineBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+9);
         nineBeforeLow = iLow(NULL,PERIOD_CURRENT,i+9);
         nineBeforeClose = iClose(NULL,PERIOD_CURRENT,i+9);
         nineBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+9);
         tenBeforeHigh = iHigh(NULL,PERIOD_CURRENT,i+10);
         tenBeforeLow = iLow(NULL,PERIOD_CURRENT,i+10);
         tenBeforeClose = iClose(NULL,PERIOD_CURRENT,i+10);
         tenBeforeOpen = iOpen(NULL,PERIOD_CURRENT,i+10);


        }


      double highLow = thisHigh-thisLow;
      double closeSumOpen = thisClose+thisOpen;

      if(thrustEnable)
        {
         //スラストアップ
         if(oneBeforeHigh<thisClose)
           {
            thrustUp[i]=thisLow - mySpread * 8.0  *Point();
           }
         else
           {
            thrustUp[i]=0.0;
           }

         //スラストダウン
         if(oneBeforeLow>thisClose)
           {
            thrustDown[i]=thisHigh + mySpread * 8.0  *Point();
           }
         else
           {
            thrustDown[i]=0.0;
           }
        }

      if(spikeEnable)
        {
         //スパイクロー
         if(MathMin(oneBeforeLow,MathMin(twoBeforeLow,MathMin(threeBeforeLow,MathMin(fourBeforeLow,fiveBeforeLow)))) > thisLow
            && MathMin(oneBeforeClose,MathMin(twoBeforeClose,MathMin(threeBeforeClose,MathMin(fourBeforeClose,fiveBeforeClose)))) > thisClose)
           {
            if(thisHigh - highLow*0.2 < closeSumOpen/2)
              {
               spikeLow[i]=thisLow - mySpread * 4.0  *Point();
              }
            else
              {
               spikeLow[i]=0.0;
              }
           }
         else
           {
            spikeLow[i]=0.0;
           }

         //スパイクハイ
         if(MathMax(oneBeforeHigh,MathMax(twoBeforeHigh,MathMax(threeBeforeHigh,MathMax(fourBeforeHigh,fiveBeforeHigh)))) < thisHigh
            && MathMax(oneBeforeClose,MathMax(twoBeforeClose,MathMax(threeBeforeClose,MathMax(fourBeforeClose,fiveBeforeClose)))) < thisClose)
           {
            if(thisLow + highLow*0.2 > closeSumOpen/2)
              {
               spikeHigh[i]=thisHigh + mySpread * 4.0  *Point();
              }
            else
              {
               spikeHigh[i]=0.0;
              }
           }
         else
           {
            spikeHigh[i]=0.0;
           }

        }

      if(reversalEnable)
        {
         //リバーサルハイ
         if(oneBeforeLow>thisClose && oneBeforeHigh < thisHigh)
           {
            reversalHigh[i]=thisHigh + mySpread * 6.0 *Point();
           }
         else
           {
            reversalHigh[i]=0.0;
           }

         //リバーサルロー
         if(oneBeforeHigh<thisClose && oneBeforeLow > thisLow)
           {
            reversalLow[i]=thisLow - mySpread * 6.0  *Point();
           }
         else
           {
            reversalLow[i]=0.0;
           }
        }

      if(runWayEnable)
        {
         //this 今日
         //one 1日前
         //two 2日前
         //three 3日前
         //four 4日前
         //five 5日前 *ruWay中心
         //six 6日前
         //seven 7日前
         //eight 8日前
         //nine 9日前
         //ten 10日前

         //ランウェイアップ
         if(MathMax(sixBeforeHigh,MathMax(sevenBeforeHigh,MathMax(eightBeforeHigh,MathMax(nineBeforeHigh,tenBeforeHigh)))) < fiveBeforeHigh
            && MathMin(oneBeforeLow,MathMin(twoBeforeLow,MathMin(threeBeforeLow,MathMin(fourBeforeLow,thisLow)))) > fiveBeforeLow)
           {

            runWayUp[i+5] = fiveBeforeLow - mySpread * 5.0 *Point();
           }
         else
           {
            runWayUp[i+5] = 0.0;
           }



        }


     }


//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

```


# REFERENCEs

https://www.fxbroadnet.com/tech/priceaction/

# さいごに

投資は自己責任！

カレンダー参加者募集してます！

https://qiita.com/advent-calendar/2022/mql

Have a good MQL Life!!!