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);
}
今回のプログラムもコピペでコンパイル&実行できるので、是非実際に動作させてみて下さい。