見出し画像

フィボナッチライン自動描画インジケータ MT4用 無料部分組み立てれば完成します。。。

どうもひろぽんです。ツイッターでMT4とかMT5、pythonとか自動売買についてつぶやいています。良かったらフォローしてください。泣いて喜びます。

https://twitter.com/python_btc_bot

さて、最近は自動売買のほかに裁量でもトレードを行っているのですが、皆さんは押しや戻りを見る際に何を使われていますか?流行りはフィボナッチリトレースメントとか、フィボナッチエクスパンジョンとかみたいですが、MT4に標準搭載されているフィボナッチ系のインジって使いにくくないですか?


画像1

いちいち高値安値を結ばせる手間も鬱陶しいですし、横線に記載された文字も小さい。一番気にくわないのは、まるでトレンドラインのごとく残る斜めの点線ですよね。見間違ってしまいそうになることもしばしば。。。


ってことで、こんなのあったらいいなってことで、範囲さえ指定すれば範囲内の高値安値を自動で取得してフィボナッチを引いてくれる便利なインジを作りました。


GIFが動くなら見れるはずです。インジはこんな感じで動きます。詳細は以下に書いていきますね。

画像2

なお、コードのヒントは無料部分にほとんど記載しています。コードの知識がある人ならまとめるだけで作成可能です。そんな時間もったいないし、完成品買ってあげるよって方は、最後の有料部分に全コード記載しています。

もっとこうしたら良いのにとか、こんなもの作ってほしいとかあれば教えてください。


2020年8月11日 追記

フィボナッチライン到達で、メールにアラート配信できる機能を追加しました。


2020年11月2日 追記

有料部分からex4ファイルをダウンロードできるように変更しました。


注意事項

当サイトに含まれる情報の全ては、情報提供を唯一の目的としたものであり、収益の保証、或いは、直接的に投資助言業務、投資勧誘を行うものではありません。投資方針や時期選択等の最終決定は、リスク等を熟知した上、ご自身で判断されますようお願いいたします。
当サイトの利用、あるいは取引により利用者に生じたいかなる損害についても著者及び発行者はそれに対し、一切の責任を負いません。あらかじめご了承ください。
万が一、損失を被った場合でも、著者は一切の責任を負わないものとします。


自動でフィボナッチを引いてくれるインジの中身

画像3

インジケータをチャートに放り込むと、黄緑色の縦線がチャート左側に表示されます。これはただの縦線のオブジェクトなので、ダブルクリックすれば左右に動かすことができます。

初期設定では、現在足から縦線までの期間における高値安値を判定し、フィボナッチを自動で引いてくれます。

画像4

基本の61.8%と38.2%、利確目安の161.8%を表示できるようにしています。

画像5

%と価格を表示しています。

画像6

緑の縦線を左に動かせば、最安値が変わるので、フィボナッチのラインが引かれる価格も変わります。(基本的にクリックイベントで表記が変更するように作成しています。)


右の線も表示すれば、過去検証も可能

画像7

パラメータ一番上のRtLineをtrueに変更すれば、右側にも縦線が表示されます。

画像8

どちらの縦線も動かすことが可能です。両方の縦線に囲まれた範囲での高値と安値を取得し、フィボナッチを引いてくれます。


画像9

ここから右側の縦線を左に動かすと。。。

画像10


過去検証って何ができるの??

画像11

フィボナッチはリトレースメントで戻りや押しを確認し、エクスパンジョンで利確を見ます。

過去検証の場合は、安値と高値を含む範囲を左右の縦線で挟みます。これだけです。

上記は最近のEURJPYの4時間足です。114円で安値を付け116円で高値を付けた価格は38.2%のライン(115.39)まで押し、その後高値をブレイクしましたが、161.8%(118.349)で戻されました。ビタビタにフィボナッチが効いてるチャートですよね。

ではこの後どうなるでしょうか?

画像12

次の押しは50%に届かずに上昇再開。161.8%を目指す動きとなっていますが、ちょっと足踏み状態な印象です。


ショートカットキーも入れてみた

縦線をつかみながら過去へ過去へと戻るのは大変なので、表示したいチャートまで戻ってから縦線を呼び出すショートカットを作成しました。

画像13

2月3月のチャートです。ここでキーボードの『Q』を押すと。。。

画像14

2本の縦線が表示されます。あとは縦線を動かせば、フィボナッチラインが表示されます。

画像15


フィボナッチ自動描画インジのコード内容

以下に今回フィボナッチを自動描画させる際に、使ったテクニックなどを紹介していきます。


チャートイベント

チャートをクリックしたら、マウスをクリックしたらなど何かの動きに対してイベントを発生させることが出来ます。今回の自動描画インジの場合、縦線をクリックしたらイベントが発生するようにしています。(ドラッグ移動でイベントでは重かったので、クリックイベントにしました。)

void OnChartEvent(
                const int id,          // イベントID
                const long& lparam,    // long型イベント
                const double& dparam,  // double型イベント
                const string& sparam)  // string型イベント
{ 
  // ここにイベント条件とイベント処理を書く

2本の縦線に関しては、初期化関数内にて作成しておきます。

int OnInit()
{
  Lt = WindowFirstVisibleBar()-MathRound(WindowBarsPerChart()*0.25);
  ObjectCreate(OBJNAME_VLINE_L,OBJ_VLINE,0,Time[Lt],0);
  ObjectSet(OBJNAME_VLINE_L, OBJPROP_COLOR, clrGreenYellow);
  ObjectSet(OBJNAME_VLINE_L, OBJPROP_WIDTH, 2);
  if(RtLine==true)
  {
     Rt = WindowFirstVisibleBar()-MathRound(WindowBarsPerChart()*0.75);
     ObjectCreate(OBJNAME_VLINE_R,OBJ_VLINE,0,Time[Rt],0);
     ObjectSet(OBJNAME_VLINE_R, OBJPROP_COLOR, clrGold);
  }
  return(INIT_SUCCEEDED);
}

縦線がチャートの左25%の部分と右側25%の部分に表示されるようにLt、Rtの変数を作成しています。WindowFirstVisibleBarは現在表示されているチャートの左端のBarが現在Barから何本目かを表しています。WindowBarPerChartは現在表示されているチャートに何本Barが表示できるかを表しています。

なお、オブジェクトの名前は、”HL_VL_L”みたいにせず、OBJNAME_VLINE_Lのように””(ダブルコーテーション)なしでOKです。

その代わり、#defineとして先に記載しておく必要があります。

#define OBJNAME_VLINE_L "HL_VL_L"
#define OBJNAME_VLINE_R "HL_VL_R"

これは、OnChartEventで一致を調べるsparamの値が、ダブルコーテーションで囲まれた名前ではエラーになってしまうからです。これを使ってOnChartEventを書き加えます。

void OnChartEvent(
                const int id,          // イベントID
                const long& lparam,    // long型イベント
                const double& dparam,  // double型イベント
                const string& sparam)  // string型イベント
{ 
  if ( id == CHARTEVENT_OBJECT_CLICK) {
     if ( sparam == OBJNAME_VLINE_L || sparam == OBJNAME_VLINE_R) {
      // ここにイベント条件とイベント処理を書く
     }
  }
}

id == CHARTEVENT_OBJECT_CLICK はクリックイベントを表し、そこでクリックされたものをsparamsで一致確認を行います。

ここまでできれば、あとは上記のイベント部分で、高値安値足の計算を行い、オブジェクトを作成するだけでOKです。


ある期間の高値、安値を求める

LtTime = ObjectGetInteger(0,"HL_VL_L",OBJPROP_TIME);
RtTime = RtLine==true ? ObjectGetInteger(0,"HL_VL_R",OBJPROP_TIME) : TimeCurrent();

ObjectGetIntegerをつかって縦線の位置の時間を取得します。右側の縦線も同じように取得します。外部変数で使うかどうするかを判定し、使わなければTime[0]を右側縦線の位置としています。


LtInd = Bars(Symbol(),0,LtTime,TimeCurrent())-1;
RtInd = RtLine==true ? Bars(Symbol(),0,RtTime,TimeCurrent())-1 : 0;

LtTime、RtTimeはunixtimeなのでInt型です。これを現在表示しているチャートの時間足における足の本数に変更するため、Barsを使います。


HighInd = iHighest(Symbol(),0,MODE_HIGH,LtInd-RtInd,RtInd);
LowInd = iLowest(Symbol(),0,MODE_LOW,LtInd-RtInd,RtInd);
HighPrice = High[HighInd];
LowPrice = Low[LowInd];

iHighestとiLowestを使って、LtIndとRtIndに挟まれた期間の最大値、最小値を取るBar番号と取得します。

High[HighInd]とすることで、そのBar番号の高値を取得します。


高値安値からフィボナッチ価格を求める

UpPrice = NormalizeDouble(LowPrice + (HighPrice-LowPrice)*UpperHigh, Digits());
MuPrice = NormalizeDouble(LowPrice + (HighPrice-LowPrice)*MiddleHigh, Digits());
MmPrice = NormalizeDouble(LowPrice + (HighPrice-LowPrice)*0.5, Digits());
MlPrice = NormalizeDouble(LowPrice + (HighPrice-LowPrice)*MiddleLow, Digits());
LoPrice = NormalizeDouble(HighPrice - (HighPrice-LowPrice)*LowerLow, Digits());

高値安値からフィボナッチに使う価格を求めます。NormalizeDoubleを用いて小数点をそろえています。

なお、初期値はフィボナッチの値、61.8%などにしていますが、外部変数で変更できるようにしています。

画像16

0.618を0.732とかに変更可能です。


オブジェクトを作っていく

ObjectsDeleteAll(0,"HL_HL_");

クリックイベントの度に書き変えるため、チャートに残っているオブジェクトを削除します。接頭の文字で特定しています。


// 100%
ObjectCreate("HL_HL_H",OBJ_TREND,0,Time[LtInd],HighPrice,Time[RtT],HighPrice);
ObjectSet("HL_HL_H", OBJPROP_COLOR, clrWhite);
ObjectSet("HL_HL_H", OBJPROP_RAY_RIGHT, false);
ObjectSet("HL_HL_H", OBJPROP_BACK, true);
ChartTimePriceToXY(0,0,Time[0],HighPrice,pixel_x,pixel_y);
ObjectCreate("HL_HL_Label_1",OBJ_LABEL,0,0,0);
ObjectSet("HL_HL_Label_1", OBJPROP_XDISTANCE, pixel_x);
ObjectSet("HL_HL_Label_1", OBJPROP_YDISTANCE, pixel_y);
ObjectSetString(0,"HL_HL_Label_1",OBJPROP_TEXT,"100.0% (" + string(HighPrice) +")");

ObjectCreateでトレンドラインを作成します。左側と右側の縦線の間かつ、計算した価格を設定します。

OBJPROP_RAY_RIGHTで、現在足より右側に延長しないように設定しています。

2021年4月24日 追記

現在足より右側の延長を選択できるように変更しました。
パラメータの『ExtendLine』をtrueにすると延長、『false』で現在足で切れるようにしています。


OBJPROP_BACKをtrueで、ローソク足より後ろに表示されるようにしています。

現在足の右側に、それぞれの価格の高さで価格表示するように設定しています。これにはラベルを使っていますが、ラベルは価格と時間で位置を指定できません。代わりにX座標とY座標を指定します。

ChartTimePriceToXYを使って、時間と価格からX,Yの位置座標を取得します。

最後にObjectSetStringで文字列を作成して終了です。

この作業を、すべてのフィボナッチラインで行っただけです。


2020年8月11日 追記

フィボナッチラインに到達した際に、MT4にて設定したメールアドレスにアラートを配信できるように変更しました。

画像17

・MailSendON : trueにすることでメール配信ができます。
・HighLow : trueなら高値安値がラインをブレイクしたら配信、falseなら終値がラインをブレイクしたら配信されます。

画像18

・MailTitle : メールの題名
・UpperHighBreakMes : 161.8%に到達した時のメッセージ
・HighBreakMes : 100%に到達した時のメッセージ
・MiddleHighUPBreakMes : 上方向に61.8%を超えた時のメッセージ
・MiddleHighDOWNBreakMes : 下方向に61.8%を割った時のメッセージ
・MiddleUPBreakMes : 上方向に50%を超えた時のメッセージ
・MiddleDOWNBreakMes : 下方向に50%を割った時のメッセージ
・MiddleLowUPBreakMes : 上方向に38.2%を超えた時のメッセージ
・MiddleLowDOWNBreakMes : 下方向に38.2%を割った時のメッセージ
・LowBreakMes : 下方向に0%を割った時のメッセージ
・LowerLowBreakMes : 下方向に-161.8%を割った時のメッセージ

これらのメッセージ内容は、インジケータのパラメータで変えられます。

なお、61.8%とかはMiddleHighなどのパラメータで決めたものを書いただけなので、70%とか65%とか好きに変えてください。

画像19

こんな感じで届きます。


void AlertMail(const string mes)
{
  SendMail(MailTitle, mes);
}

アラートメールを送るだけの関数を作りました。


なお、MT4のアラートメールを配信する設定に関しては、こちらのブログが分かりやすかったので、添付しておきます。

メールアドレスはYAHOOがオススメです。

最初Gメールで設定したのですが、セキュリティなどがややこしくうまくいかなかったので、YAHOOにしたところ、うまくいきました。

YAHOOなら捨てアドも簡単に作れますからね。


2021年4月24日 追記

アラートボックスでの通知もできるように変更しました。
パラメータ内、『AlertBox』をtrueにすると、クロス時点でアラートがメッセージボックスで表示されます。


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[])
{
  static int BarsBefore = 0;
  int BarsNow = Bars;
  int BarsCheck = BarsNow-BarsBefore;

  if(BarsCheck==1)
  {
     if(MailSendON==true)
     {
        if(HighLow==true)
        {
           if(High[2]<UpPrice && UpPrice<High[1]) AlertMail(UpperHighBreakMes);
           if(High[2]<HighPrice && HighPrice<High[1]) AlertMail(HighBreakMes);
           if(High[2]<MuPrice && MuPrice<High[1]) AlertMail(MiddleHighUPBreakMes);
           if(Low[2]>MuPrice && MuPrice>Low[1]) AlertMail(MiddleHighDOWNBreakMes);
           if(High[2]<MmPrice && MmPrice<High[1]) AlertMail(MiddleUPBreakMes);
           if(Low[2]>MmPrice && MmPrice>Low[1]) AlertMail(MiddleDOWNBreakMes);
           if(High[2]<MlPrice && MlPrice<High[1]) AlertMail(MiddleLowUPBreakMes);
           if(Low[2]>MlPrice && MlPrice>Low[1]) AlertMail(MiddleLowDOWNBreakMes);
           if(Low[2]>LowPrice && LowPrice>Low[1]) AlertMail(LowBreakMes);
           if(Low[2]>LoPrice && LoPrice>Low[1]) AlertMail(LowerLowBreakMes);
        }else{
           if(Close[2]<UpPrice && UpPrice<Close[1]) AlertMail(UpperHighBreakMes);
           if(Close[2]<HighPrice && HighPrice<Close[1]) AlertMail(HighBreakMes);
           if(Close[2]<MuPrice && MuPrice<Close[1]) AlertMail(MiddleHighUPBreakMes);
           if(Close[2]>MuPrice && MuPrice>Close[1]) AlertMail(MiddleHighDOWNBreakMes);
           if(Close[2]<MmPrice && MmPrice<Close[1]) AlertMail(MiddleUPBreakMes);
           if(Close[2]>MmPrice && MmPrice>Close[1]) AlertMail(MiddleDOWNBreakMes);
           if(Close[2]<MlPrice && MlPrice<Close[1]) AlertMail(MiddleLowUPBreakMes);
           if(Close[2]>MlPrice && MlPrice>Close[1]) AlertMail(MiddleLowDOWNBreakMes);
           if(Close[2]>LowPrice && LowPrice>Close[1]) AlertMail(LowBreakMes);
           if(Close[2]>LoPrice && LoPrice>Close[1]) AlertMail(LowerLowBreakMes);
        }
     }
  }

  BarsBefore = BarsNow;

  return(rates_total);
}

OnCaluculate内で、価格ラインを超えたらAlertMailが走るようにしています。

1つ前の足が確定したタイミングで、メールが配信されるように設定しています。現在値のタッチで送信する設定だと、ラインをタッチするたびにメールが配信され、エラーになってしまうので、確定で配信されるようにしています。

① 2個前のローソク足高値がラインの下
② 1個前のローソク足高値がラインを超えて確定
③ 新しいローソク足への切り替わりでメール配信

リアルタイム性が失われますが、これだとスマホが通知でいっぱいにはなりません。(高値タッチ判定だと1秒で100件とか配信してしまう。。。)


  static int BarsBefore = 0;
  int BarsNow = Bars;
  int BarsCheck = BarsNow-BarsBefore;

  if(BarsCheck==1)
  {
      // ローソク足の切り替わり後、1度だけ実行される
  }

  BarsBefore = BarsNow;

Tickの切り替わりでローソク足の本数が変わった時だけ実行される仕組み。


// 高値がラインを超えたら実行
if(High[2]<UpPrice && UpPrice<High[1]) AlertMail(UpperHighBreakMes);

// 終値がラインを超えたら実行
if(Close[2]<UpPrice && UpPrice<Close[1]) AlertMail(UpperHighBreakMes);

メッセージ内容はそれぞれパラメータで設定した内容です。


まとめ

以上が、今回紹介したフィボナッチ自動描画インジの中身になります。上に示したコードを順番に繋いでいけば、完成させることはできます。

たぶん。。。


これを作成しながら、ポン円で使っていたのですが良い感じですね。61.8%で反転してきれいに下げてきました。さらに下げて、前回安値131.62を抜くか注目しています。


さて有料パートに関してですが、裁量トレード片手間にモンスター飲みながら行ってました。3本飲んだので、500円でどうでしょう?

そんなコードを自分で組み立てるなんて面倒だぜ。
ジュース代?500円?
安いわ!払ってあげるよ!

なんて心の温かい人がいたら、買ってもらえるとうれしいです。


なお、有料パート部分はコードしか記載していません。
ここまで読んでいただき、ありがとうございました。


このインジケータの質問だけに限らず、こんなEAのアイデアとか形に出来そう?みたいなのがあれば、ツイッターでDMください。

https://twitter.com/python_btc_bot



ここから先は

31,961字 / 2ファイル

¥ 700

この記事が気に入ったらサポートをしてみませんか?