キーボードのボタン一つでインジケーター


//+------------------------------------------------------------------+
//|                                       320_MousePositionPrice.mq4 |
//|                                      (c) 2019 さいとさんにぃまる |
//|                                        https://site-320.com/mt4/ |
//+------------------------------------------------------------------+ #property  copyright   "(c) 2019 さいとさんにぃまる" #property  link        "https://site-320.com/mt4/" #property  version     "1.00" #property  strict #property  description "マウスの位置の価格を表示するインジケーター" #property  indicator_plots 0 #property  indicator_chart_window

/*-- 列挙型の宣言 --------------------------------------------------*/
enum EPos{      //表示位置
  LeftView=1,  //左側に表示
  CenterView,  //中央に表示
  RightView    //右側に表示
};

enum ESize{     //文字の大きさ
  NoView=0,    //0:表示しない
  VerySmall,   //1:極小
  Small,       //2:小
  Medium,      //3:中
  Large,       //4:大
  VeryLarge    //5:極大
};

enum ELineS{    //線の種類
  Solid  = 0,  //0:実線
  Dash,        //1:破線
  Dot,         //2:点線
  DashDot,     //3:破線と点線
  DashDotDot   //4:破線と2重点線
};

enum ELineW{    //線の太さ
  Width0 = 0,  //0:無し
  Width1,      //1:極細
  Width2,      //2:細い
  Width3,      //3:普通
  Width4,      //4:太い
  Width5       //5:極太
};

/*-- 定数の宣言 ----------------------------------------------------*/
const string cstPrefix = "320_MPP_"; //オブジェクト名の接頭辞兼インジケーター名

/*-- 変数の宣言 ----------------------------------------------------*/
bool HLineShow = false; //水平線を表示する(=true)
int  SaveX = 0;
int  SaveY = 0;

/*-- パラメーター --------------------------------------------------*/
input color  mppFontColor = clrNONE;    //文字の色(None=背景色と同じ色)
input color  mppBackColor = clrNONE;    //背景の色(None=前景色と同じ色)
input bool   mppBackFill  = true;       //背景塗りつぶし
input ESize  mppSize      = Small;      //文字の大きさ
input EPos   mppPos       = CenterView; //表示位置
input int    mppX         = 0;          //X座標調整
input int    mppY         = 0;          //Y座標調整
input color  mppLineColor = clrNONE;    //線の色(None=BIDorグリッドと同じ色)
input ELineS mppLineStyle = Dot;        //線の種類
input ELineW mppLineWidth = Width1;     //線の太さ

//+------------------------------------------------------------------+
//|カスタムインジケーターの初期処理                                  |
//+------------------------------------------------------------------+
int OnInit() {
  //二重挿入防止策(メインウィンドウ用)
  IndicatorSetString(INDICATOR_SHORTNAME,cstPrefix);
  int wCount = 0;
  for (int i = 0; i < ChartIndicatorsTotal(0,0); i++)
     if (cstPrefix == ChartIndicatorName(0,0,i)) wCount++;
  if (wCount >= 2) {
     Alert("Only one can be inserted.");
     return (INIT_FAILED);
  }

  //マウス操作イベントの通知を送信するように設定
  ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);

  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|カスタムインジケーターの終了処理                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  //正常に起動した場合
  if (reason != REASON_INITFAILED) {
     //マウス操作イベントの通知を送信しないように設定
     ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
     //全オブジェクトのうち、オブジェクト名の接頭辞が一致するものを削除
     ObjectsDeleteAll(0,cstPrefix);
  }
}

//+------------------------------------------------------------------+
//|カスタムインジケーターのイベント処理                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                 const long &lparam,
                 const double &dparam,
                 const string &sparam)
{
  //「L」キー押下時
  if ((id == CHARTEVENT_KEYDOWN) && (lparam == 65)) {
     //水平線表示モードを切り替える
     HLineShow = !HLineShow;
     //マウス位置の価格表示処理を呼び出す
     MPPD(SaveX,SaveY);
  //マウス操作またはチャート変更時lllkkjl;;;ooiiuuytrrwqertyhoop;jlllllll
  } else if ((id == CHARTEVENT_MOUSE_MOVE) || (id == CHARTEVENT_CHART_CHANGE)){
     //マウス位置の価格表示処理を呼び出す
     MPPD((int)lparam,(int)dparam);
  }
}

//+------------------------------------------------------------------+
//|カスタムインジケーターのメイン処理                                |
//+------------------------------------------------------------------+
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[])
{
  //何もしない
  return(rates_total);
}

//+------------------------------------------------------------------+
//|マウス位置の価格表示処理(Mouse Position Price Display)            |
//+------------------------------------------------------------------+
void MPPD(const int X,const int Y) {
  static int   SaveWidth = 0;
  static color SaveBack  = -1;
  static color SaveFore  = -1;
  static color SaveLine  = -1;
  int      wWin;
  string   wObj;
  datetime wTime;
  double   wPrice;
  //マウス位置の価格を取得
  if (ChartXYToTimePrice(0,X,Y,wWin,wTime,wPrice)) {
     //メインウィンドウの場合
     if (wWin == 0) {
        //座標を保持する
        SaveX = X;
        SaveY = Y;
        //価格を表示する場合
        if (mppSize >= VerySmall) {
           //オブジェクトが無ければ生成
           wObj = cstPrefix+"PBK";
           if (ObjectFind(0,wObj) == -1) {
              //背景のオブジェクトを生成
              if (mppBackFill) {
                 ObjectCreate(0,wObj,OBJ_LABEL,0,0,0);
                 ObjectSetInteger(0,wObj,OBJPROP_SELECTABLE,false);
                 ObjectSetInteger(0,wObj,OBJPROP_FONTSIZE,(mppSize+1) * 6);
                 ObjectSetInteger(0,wObj,OBJPROP_ANCHOR,ANCHOR_UPPER);
                 ObjectSetInteger(0,wObj,OBJPROP_YDISTANCE,mppY);
                 ObjectSetString(0,wObj,OBJPROP_FONT,"Webdings");
                 ObjectSetString(0,wObj,OBJPROP_TEXT,"gggg");
              }
              //文字のオブジェクトを生成
              wObj = cstPrefix+"PRC";
              ObjectCreate(0,wObj,OBJ_LABEL,0,0,0);
              ObjectSetInteger(0,wObj,OBJPROP_SELECTABLE,false);
              ObjectSetInteger(0,wObj,OBJPROP_FONTSIZE,(mppSize+1) * 6);
              ObjectSetInteger(0,wObj,OBJPROP_ANCHOR,ANCHOR_UPPER);
              ObjectSetInteger(0,wObj,OBJPROP_YDISTANCE,mppY);
           }
           //チャートの幅を取得(ドット数)
           int wkWidth  = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
           //チャートの幅が変わった場合
           if (SaveWidth != wkWidth) {
              //変更後を退避
              SaveWidth = wkWidth;
              //X座標を設定
              int wkX = 0;
              if (mppPos == RightView) {
                 wkX = wkWidth - (mppSize+1) * 16;
              } else if (mppPos == CenterView) {
                 wkX = (int)MathFloor(wkWidth / 2);
              } else {
                 wkX = (mppSize+1) * 16;
              }
              if (mppBackFill) ObjectSetInteger(0,cstPrefix+"PBK",OBJPROP_XDISTANCE,wkX+mppX);
              ObjectSetInteger(0,cstPrefix+"PRC",OBJPROP_XDISTANCE,wkX+mppX);
           }
           //背景色、前景色を取得
           color wkBack = (color)ChartGetInteger(0,CHART_COLOR_FOREGROUND,0);
           color wkFore = (color)ChartGetInteger(0,CHART_COLOR_BACKGROUND,0);
           if (mppBackColor != clrNONE) wkBack = mppBackColor;
           if (mppFontColor != clrNONE) wkFore = mppFontColor;
           //色が変わった場合
           if ((SaveBack != wkBack) || (SaveFore != wkFore)) {
              //変更後を退避
              SaveBack = wkBack;
              SaveFore = wkFore;
              //背景色および文字色を設定
              if (mppBackFill) ObjectSetInteger(0,cstPrefix+"PBK",OBJPROP_COLOR,wkBack);
              ObjectSetInteger(0,cstPrefix+"PRC",OBJPROP_COLOR,wkFore);
           }
           //価格を表示
           ObjectSetString(0,cstPrefix+"PRC",OBJPROP_TEXT,DoubleToString(wPrice,_Digits));
        //価格を表示しない場合
        } else {
           //オブジェクトがあれば破棄
           wObj = cstPrefix+"PBK";
           if (ObjectFind(0,wObj) != -1) ObjectDelete(0,wObj);
           wObj = cstPrefix+"PRC";
           if (ObjectFind(0,wObj) != -1) ObjectDelete(0,wObj);
        }

        //水平線のオブジェクト名
        wObj = cstPrefix+"HL";
        //水平線を表示する場合
        if ((HLineShow) && (mppLineWidth >= Width1)) {
           //オブジェクトが無ければ生成
           if (ObjectFind(0,wObj) == -1) {
              ObjectCreate(0,wObj,OBJ_HLINE,0,0,0);
              ObjectSetInteger(0,wObj,OBJPROP_STYLE,mppLineStyle); //線の種類を設定
              ObjectSetInteger(0,wObj,OBJPROP_WIDTH,mppLineWidth); //線の太さを設定
              ObjectSetInteger(0,wObj,OBJPROP_SELECTABLE,false);   //線の選択
           }
           //背景色、前景色を取得 #ifdef  __MQL5__
           color wkLine = (color)ChartGetInteger(0,CHART_COLOR_BID,0); #else 
           color wkLine = (color)ChartGetInteger(0,CHART_COLOR_GRID,0); #endif 
           if (mppLineColor != clrNONE) wkLine = mppLineColor;
           //色が変わった場合
           if (SaveLine != wkLine) {
              //変更後を退避
              SaveLine = wkLine;
              //線の色を設定
              ObjectSetInteger(0,wObj,OBJPROP_COLOR,wkLine);
           }
           ObjectSetDouble(0,wObj,OBJPROP_PRICE,wPrice);           //水平線の価格変更
        //水平線を表示しない場合
        } else {
           //オブジェクトがあれば破棄
           if (ObjectFind(0,wObj) != -1) ObjectDelete(0,wObj);
           //初期化
           SaveLine  = -1;
        }

        //再描画
        ChartRedraw(0);
     }
  }
}