はじめに
MQL5ソースコードの紹介です。大した事はやってませんが、主に初心者の方の参考になれば幸いです。自分用に書いたものなのでコーディング規約はありません。変数名などに統一性が無く見づらい部分も多々ありますので、予めご了承ください。
機能
指定したタイムフレームで指定した期間(ローソク足)を対象に、最高値と最安値を算出して水平ラインを描画するインジケーター。
ソースコード
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
input ENUM_TIMEFRAMES Rate_TimeFrame = PERIOD_D1; //タイムフレーム
input int RatesCount =120; //計算対象となるローソク足の本数
input int CancelRateCount =5; //計算対象外とする直近のローソク足の本数
input int HighLineFlag =1; //最高値ラインの描画(0=描画する、1=描画しない)
input color HighLineColor =clrHotPink; //最高値ラインの色
input int LowLineFlag =1; //最安値ラインの描画(0=描画する、1=描画しない)
input color LowLineColor =clrHotPink; //最安値ラインの色
input int HighEntityLineFlag =0; //実体の最高値ラインの描画(0=描画する、1=描画しない)
input color HighEntityLineColor =clrYellow; //実体最高値ラインの色
input int LowEntityLineFlag =0; //実体の最安値ラインの描画(0=描画する、1=描画しない)
input color LowEntityLineColor =clrYellow; //実体最安値ラインの色
string HighLineName ="HgihLine"; //チャートに描画する最高値ラインの名称
string LowLineName ="LowLine"; //チャートに描画する最安値ラインの名称
string HighEntityLineName ="HgihEntityLine"; //チャートに描画する最高値(実体)ラインの名称
string LowEntityLineName ="LowEntityLine"; //チャートに描画する最安値(実体)ラインの名称
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//最高値ラインの生成
if(HighLineFlag==0)
{
ObjectCreate(0,HighLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,HighLineName,OBJPROP_COLOR,HighLineColor);
}
//最安値ラインの生成
if(LowLineFlag==0)
{
ObjectCreate(0,LowLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,LowLineName,OBJPROP_COLOR,LowLineColor);
}
//実体部分最高値ラインの生成
if(HighEntityLineFlag==0)
{
ObjectCreate(0,HighEntityLineName,OBJ_HLINE,0,0,0);
ObjectSetInteger(0,HighEntityLineName,OBJPROP_COLOR,HighEntityLineColor);
}
//実体部分最安値ラインの生成
if(LowEntityLineFlag==0)
{
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-CancelRateCount;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));
Comment("差額(ヒゲ含): "+(string)NormalizeDouble(Price_High-Price_Low,_Digits)+"\n"+
"差額(実体): "+(string)NormalizeDouble(Price_HighEntity-Price_LowEntity,_Digits));
return(rates_total);
}
ソースコードの説明
新たに追加した部分のみの説明です。
- 8行目
最高値/最安値の判定から除外する直近のローソク足の本数 - 9、11、13、15行目
各水平ラインの描画有無フラグ追加 - 28~51行目
水平ライン描画有無の判別式を追加 - 115~116行目
画面左上への表示内容追加(ヒゲ付き高値-安値の変動幅と、実体の高値-安値の変動幅)
結果
パラメータ設定画面の初期値は以下のようになります。
実行結果は以下のようになります。
日足のローソク足120本のうち、直近5本を除いた中で実体部分の最高値と最安値に黄色の水平ラインが引かれます。更に、画面左上に水平ラインの値幅が表示されます。
値幅部分の拡大
差額(ヒゲ含):3.964、差額(実体):3.795と表示されてます。
このインジケーターで何がわかるのか?
120日(土日を省いた約半年間)のレートの変動幅は106.383~110.178(3.795円)であったが、直近5日間で大きく上抜けてきた。という事実のみが分かります。ただそれだけです。ただそれだけですが、算出期間のパラメータを増やしてみたりすると、また違った事実が見えてくるかもしれません。ちなみにこのチャートで算出期間を240(土日を省いた約1年間)にしてみたところ、水平ラインがレジスタンスラインに見えなくもなかったので、怖かったけどちょっとだけ売りポジションを持ってみました。少し下がった所で得意のチキン利食いにて決済、微益を得ることができました。
EAへの組み込み(案)
このソースをちょっと改良し、安値の水平ラインを下回ったら買い、高値の水平ラインを上回ったら売るという逆張りのEAや、安値の水平ラインを下から上抜けたら買い、高値の水平ラインを上から下抜けたら売るという順張りのEAなんか作ったらおもしろいかもしれません。思い付きの案なので結果がどうなるかまったくわかりませんが、時間が出来たら作ってみようかと思います。