MQL4プログラミング 第10回 バックグラウンドの色を変える(2)

キーボート押下でバックグラウンドの色を変える

今回はまた小さな追加ですが、私個人的には重宝している機能なので紹介したいと思います。前回の続きとなるので未読のかたは「MQL4プログラミング 第9回 バックグラウンドの色を変える」を参照下さい。
この機能を使うシーンとしては裁量エントリーしていて、もうすぐエントリー条件に達する状況である通貨ペアのチャートに対して注目すべきチャートであるとの印をつけたい場合があります。この場合は私は何か1つキーボート上のキーを決めておいて、そのキーを押したら該当チャートのバックグラウンド色を変えるようにしています。
今回はキーボードの「A」キーを押下すると選択中のチャートのバックグラウンドカラーを変える機能とします。

今回はチャートに対してキーボード入力をおこなう機能を追加するのでMT4のMetaEditorで新規にファイルを作成する場合は次の手順で行います。

①「ファイル」メニューの「新規作成」を選ぶ

②「カスタムインディケータ」を選択する

③「名前」を適宜入力する

④「OnChartEvent」にチェックを入れる

⑤「完了」ボタンを押下

そうすると、自動作成されたソースコードの最後に「OnChartEvent」関数が追加されています。

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+

この「OnChartEvent」関数に今回のテーマとなるキー入力処理を追加します。
下記は追加した後のソースコードです。

//+------------------------------------------------------------------+
//| OnChartEvent function
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---

//キー押下
   if(id == CHARTEVENT_KEYDOWN) {
      if (lparam == 65) { // Aキー
         if (ChartBackColorGet() != normalColor) {
            ChartBackColorSet(normalColor);
         }
         else {
            ChartBackColorSet(lookColor);
         }
      }
   }
}

13行目:「lparam == 65」の65とはキーボードの「A」を示すWindows OSの仮想キーコードの値となります。Mac OSの場合は仮想キーコードの値が異なるので「Mac OS 仮想キーコード」等でグーグル先生に質問して調べて下さい。
Windows OSの仮想キーコード一覧はこちらとなります。(「Copyright © 2022 K.Tamura」さまのサイトより)

14行目:現在のバックグラウンドカラーが通常の色ではない場合は通常の色に戻します。
15行目:現在のバックグラウンドカラーが通常の色である場合は注目すべき色にします。
要するに「A」を押すと注目すべき色と通常の色と交互にバックグラウンドカラーが変わる仕様です。

今回の追加機能はこれだけです。以下に全ソースコードを公開します。

// prg-0010.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link      "https://www.smile-invest-blog.com/prg-0010/"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Yellow
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2

double Log1Up[];   // Highサイン用バッファ
double Log1Down[]; // Low サイン用バッファ
int    realBars = 0;

int shortMaPeriod = 10;  // 短期移動平均線の期間
int longMaPeriod  = 30;  // 長期移動平均線の期間
int adxPeriod     = 14;  // ADXの期間

color upColor     = C'2,90,98';
color downColor   = C'57,14,71';
color lookColor   = C'73,77,2';
color normalColor;

//+------------------------------------------------------------------+
//| initialization function
//+------------------------------------------------------------------+
int init() {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, Log1Up);
   SetIndexStyle(1, DRAW_ARROW, EMPTY);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, Log1Down);
   
   normalColor = getChartBackColor();

//----
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| deinitialization function
//+------------------------------------------------------------------+
int deinit() {
   getChartBackColor(normalColor);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| OnChartEvent function
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---

//キー押下
   if(id == CHARTEVENT_KEYDOWN) {
      if (lparam == 65) { // Aキー
         if (getChartBackColor() != normalColor) {
            setChartBackColor(normalColor);
         }
         else {
            setChartBackColor(lookColor);
         }
      }
   }
}

//+------------------------------------------------------------------+
//| start function
//+------------------------------------------------------------------+
int start() {
   bool ret_hantei;  // hantei関数の結果格納用
   int counted_bars=IndicatorCounted(); 
   int limit = Bars - counted_bars;

   for(int i = limit - 1; i >= 0; i--) {
      if(i == 0) {
         Log1Down[i] = EMPTY_VALUE;
         Log1Up[i]   = EMPTY_VALUE;

         ret_hantei = hantei(i);    // 上下サイン表示の判定を関数化した
         if (ret_hantei == true) {  // hantei関数の結果がtrueの時
            if (realBars < Bars) {  // 1本のローソク足で1回だけ実行するための条件
               realBars = Bars;     // realBarsをBarsにする事で同じローソク足では1回だけ実行する
               if (Log1Up[i] != EMPTY_VALUE) {           // hantei関数内で上サイン表示と判定された
                  Alert(Symbol(), " *** High ***");
                  setChartBackColor(upColor);
               }
               else if (Log1Down[i] != EMPTY_VALUE) {    // hantei関数内で下サイン表示と判定された
                  Alert(Symbol(), " *** Low ***");
                  setChartBackColor(downColor);
               }
            }
         }
         if (TaskPeriod()) {
            if (Log1Down[i] == EMPTY_VALUE && Log1Up[i] == EMPTY_VALUE) {
               setChartBackColor(normalColor);
            }
         }
      }
   }

   return(0);
}

//+------------------------------------------------------------------+
//| エントリーの条件判定関数
//| int i メイン関数からのiの値
//+------------------------------------------------------------------+
bool hantei(int i) {
   double shortMaPrevious, longMaPrevious;
   double shortMaCurrent, longMaCurrent;

   // 前回の移動平均値を取得
   shortMaPrevious = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);
   longMaPrevious  = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);

   // 現在の移動平均値を取得
   shortMaCurrent = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
   longMaCurrent  = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);

   if (shortMaPrevious < longMaPrevious && shortMaCurrent > longMaCurrent) {
      // 移動平均線のクロスを確認 → ゴールデンクロス
      Log1Up[i] = Low[i] - 10 * Point;
      return true;
   }
   else if (shortMaPrevious > longMaPrevious && shortMaCurrent < longMaCurrent) {
      // 移動平均線のクロスを確認 → デッドクロス
      Log1Down[i] = High[i] + 10 * Point;
      return true;
   }

   return false;

}

//+------------------------------------------------------------------+
//| ローソク足確定時の処理
//+------------------------------------------------------------------+
bool TaskPeriod() {
   static    datetime s_lasttime;                     // 最後に記録した時間軸時間
                                                      // staticはこの関数が終了してもデータは保持される

   datetime temptime = iTime(Symbol(), Period() ,0);  // 現在の時間軸の時間取得

   if (temptime == s_lasttime) {                      // 時間に変化が無い場合
      return false;                                   // 処理終了
   }
   s_lasttime = temptime;                             // 最後に記録した時間軸時間を保存
   // ----- 処理はこれ以降に追加 -----------
   return true;                                       // 移動平均線のクロス判定
}

//+------------------------------------------------------------------+
//| チャートの背景色を取得する
//| 引数1 チャートID(指定なしの場合は0つまり現在のチャート)
//+------------------------------------------------------------------+
color getChartBackColor(const long chart_ID=0) {
//--- 色を受け取る変数を準備する
   long result = clrNONE;
//--- エラー値をリセットする
   ResetLastError();
//--- チャートの背景色を受け取る
   if(!ChartGetInteger(chart_ID, CHART_COLOR_BACKGROUND, 0, result)) {
      //--- エキスパートジャーナルにエラーメッセージを表示する
      Print(__FUNCTION__+", Error Code = ", GetLastError());
   }
//--- チャートのプロパティの値を返します
   return((color)result);
}

//+------------------------------------------------------------------+
//| チャートの背景色を設定する
//| 引数1 背景色のcolor値
//| 引数2 チャートID(指定なしの場合は0つまり現在のチャート)
//+------------------------------------------------------------------+
bool setChartBackColor(const color clr, const long chart_ID=0) {
//--- エラー値をリセットする
   ResetLastError();
//--- チャートの背景色を設定する
   if(!ChartSetInteger(chart_ID, CHART_COLOR_BACKGROUND, clr)) {
      //--- エキスパート操作ログでエラーメッセージを表示する
      Print(__FUNCTION__+", Error Code = ", GetLastError());
      return(false);
   }
//--- 実行成功
   return(true);
}

今回のプログラムもコピペでコンパイル&実行できるので、是非実際に動作させてみて下さい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA