はじめに
MQL5ソースコードの紹介です。大した事はやってませんが、主に初心者の方の参考になれば幸いです。自分用に書いたものなのでコーディング規約はありません。変数名などに統一性が無く見づらい部分も多々ありますので、予めご了承ください。
機能
過去120日分の日足における最高値(ローソク足の実体)と最安値(ローソク足の実体)に水平ラインを描画するインジケーターです。描画されたラインはタイムフレームを変更しても同じ値に描画されます。
ソースコード
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
input ENUM_TIMEFRAMES Rate_TimeFrame = PERIOD_D1; //タイムフレーム
input int RatesCount =120; //計算対象となるローソク足の本数
input color HighLineColor =clrHotPink; //最高値ラインの色
input color LowLineColor =clrHotPink; //最安値ラインの色
input color HighEntityLineColor =clrYellow; //実体最高値ラインの色
input color LowEntityLineColor =clrYellow; //実体最安値ラインの色
string HighLineName ="HgihLine"; //チャートに描画する最高値ラインの名称
string LowLineName ="LowLine"; //チャートに描画する最安値ラインの名称
string HighEntityLineName ="HgihEntityLine"; //チャートに描画する最高値(実体)ラインの名称
string LowEntityLineName ="LowEntityLine"; //チャートに描画する最安値(実体)ラインの名称
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//最高値ラインの生成
ObjectCreate(0,HighLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,HighLineName,OBJPROP_COLOR,HighLineColor);
//最安値ラインの生成
ObjectCreate(0,LowLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,LowLineName,OBJPROP_COLOR,LowLineColor);
//実体部分最高値ラインの生成
ObjectCreate(0,HighEntityLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,HighEntityLineName,OBJPROP_COLOR,HighEntityLineColor);
//実体部分最安値ラインの生成
ObjectCreate(0,LowEntityLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,LowEntityLineName,OBJPROP_COLOR,LowEntityLineColor);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//オブジェクトの削除
ObjectsDeleteAll(0,-1,-1);
}
//+------------------------------------------------------------------+
//| 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[])
{
MqlRates rt[];
if(CopyRates(_Symbol,Rate_TimeFrame,0,RatesCount,rt)!=RatesCount)
{
Print("チャート履歴の取得に失敗しました!");
return(rates_total);
}
double Price_High =0;
double Price_Low =0;
double Price_HighEntity =0;
double Price_LowEntity=0;
for(int i=0;i<RatesCount;i++)
{
//最高値
if(rt[i].high>Price_High || Price_High==0){Price_High=rt[i].high;}
//最安値
if(rt[i].low<Price_Low || Price_Low==0){Price_Low=rt[i].low;}
//陽線の実体部分の高値、安値
if(rt[i].close>=rt[i].open)
{
if(rt[i].open<Price_LowEntity || Price_LowEntity==0){Price_LowEntity=rt[i].open;}
if(rt[i].close>Price_HighEntity || Price_HighEntity==0){Price_HighEntity=rt[i].close;}
}
//陰線の実体部分の高値、安値
if(rt[i].close<rt[i].open)
{
if(rt[i].open>Price_HighEntity || Price_HighEntity==0){Price_HighEntity=rt[i].open;}
if(rt[i].close<Price_LowEntity || Price_LowEntity==0){Price_LowEntity=rt[i].close;}
}
}
ObjectMove(0,HighLineName,0,0,NormalizeDouble(Price_High,_Digits));
ObjectMove(0,LowLineName,0,0,NormalizeDouble(Price_Low,_Digits));
ObjectMove(0,HighEntityLineName,0,0,NormalizeDouble(Price_HighEntity,_Digits));
ObjectMove(0,LowEntityLineName,0,0,NormalizeDouble(Price_LowEntity,_Digits));
return(rates_total);
}
結果
ローソク足の実体の最高値と最安値に黄色の水平ラインが引かれます。異なるタイムフレームでも同じ価格にラインが引かれます。
ソースコードの説明
前回のソースコードに追加した部分のみの説明です。
- 10~11行目
追加したラインの色を指定 - 15~16行目
追加したラインの名称指定 - 29~34行目
ラインの生成 - 70~71行目
実体部分の最高値と最安値を格納する変数 - 79~90行目
実体部分の最高値/最安値を判別し、変数に格納
※後々メンテしやすいように陰線と陽線で処理を分けています - 95~96行目
算出した値に水平ラインを移動
補足
ちょっとごちゃごちゃした感じがします。個人的にはヒゲ or 実体のどちらかの値しか使わないので、次のカスタマイズでは表示有無を指定できるようにしたいと思います。パラメーターは2つ追加したので以下のように表示されます。