//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.MQL5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- 入力パラメータ
input string symbol="GBPUSD"; // 新しいチャートのシンボル
input ENUM_TIMEFRAMES period=PERIOD_H3; // 新しいチャートの時間軸
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 最初のチャートに指標を取り付ける
int handle;
//--- 指標を使用に向けて準備する
if(!PrepareZigzag(NULL,0,handle)) return; // 失敗に続く終了
//--- チャートに指標を別ウィンドウで取り付ける
if(!ChartIndicatorAdd(0,1,handle))
{
PrintFormat("Failed to attach to chart %s/%s an indicator with the handle=%d. Error code %d",
_Symbol,
EnumToString(_Period),
handle,
GetLastError());
//--- プログラム動作を終了する
return;
}
//--- チャートを更新して指標を表示する
ChartRedraw();
//--- ジグザグの最後の 2 つの切れ目を探す
double two_values[];
datetime two_times[];
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("Failed to find two last fractures in the Zigzag!");
//--- プログラム動作を終了する
return;
}
//--- 標準偏差チャンネルを取り付ける
string channel="StdDeviation Channel";
if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0))
{
PrintFormat("Failed to create object %s. Error code %d",
EnumToString(OBJ_STDDEVCHANNEL),GetLastError());
return;
}
else
{
//--- チャンネルが作成されたので2 番目の点を定義する
ObjectSetInteger(0,channel,OBJPROP_TIME,1,two_times[0]);
//--- チャンネルのツールヒントテキストを設定する
ObjectSetString(0,channel,OBJPROP_TOOLTIP,"Demo from MQL5 Help");
//--- チャートを更新する
ChartRedraw();
}
//--- テンプレートに結果を保存する
ChartSaveTemplate(0,"StdDevChannelOnZigzag");
//--- 新しいチャートを開いて、保存されたテンプレートを適用する
long new_chart=ChartOpen(symbol,period);
//--- グラフィックオブジェクトのツールヒントを有効にする
ChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR,true);
if(new_chart!=0)
{
//--- 保存されたテンプレートをチャートに適用する
ChartApplyTemplate(new_chart,"StdDevChannelOnZigzag");
}
Sleep(10000);
}
//+------------------------------------------------------------------+
//| ジグザグのハンドルを作成し、データの準備を整える |
//+------------------------------------------------------------------+
bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h)
{
ResetLastError();
//--- ジグザグ指標は terminal_data_folder\MQL5\Examples に位置する必要がある
h=iCustom(sym,tf,"Examples\\Zigzag");
if(h==INVALID_HANDLE)
{
PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",
__FUNCTION__,GetLastError());
return false;
}
//--- 指標ハンドルを作成時には、値を計算するための時間が必要となる
int k=0; // 指標計算を待機する試みの回数
//--- 各ループで50ミリ秒停止して計算を待機する
while(BarsCalculated(h)<=0)
{
k++;
//--- 試みの回数を表示する
PrintFormat("%s: k=%d",__FUNCTION__,k);
//--- 指標が計算されるまで 50 ミリ秒待機する
Sleep(50);
//--- 100 回以上試みた場合は、何かがおかしい
if(k>100)
{
//--- 問題を報告する
PrintFormat("Failed to calculate the indicator for %d attempts!");
//--- プログラム動作を終了する
return false;
}
}
//--- 指標が作成され、値が計算されて、準備が整う
return true;
}
//+------------------------------------------------------------------+
//| ジグザグの最後の 2 つの切れ目を探して配列に書き込む |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle)
{
double values[]; // ジグザグの値の配列
datetime times[]; // 時間取得の配列
int size=100; // 配列サイズ
ResetLastError();
//--- 指標の最後の100 個の値を複製する
int copied=CopyBuffer(handle,0,0,size,values);
//--- 複製された値の数をチェックする
if(copied<100)
{
PrintFormat("%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d",
__FUNCTION__,size,handle,GetLastError());
return false;
}
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(values,true);
//--- 切れ目が見つかったバーの数を書く
int positions[];
//--- 配列サイズを設定する
ArrayResize(get_values,3); ArrayResize(get_times,3); ArrayResize(positions,3);
//---カウンタ
int i=0,k=0;
//--- 切れ目を探し始める
while(i<100)
{
double v=values[i];
//--- 空の値には興味がない
if(v!=0.0)
{
//--- バー番号を覚える
positions[k]=i;
//--- 切れ目でのジグザグの値を覚える
get_values[k]=values[i];
PrintFormat("%s: Zigzag[%d]=%G",__FUNCTION__,i,values[i]);
//--- カウンタを増加する
k++;
//--- 切れ目が 2 つ見つかったら、ループから出る
if(k>2) break;
}
i++;
}
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true);
if(CopyTime(_Symbol,_Period,0,size,times)<=0)
{
PrintFormat("%s: Failed to copy %d values from CopyTime(). Error code %d",
__FUNCTION__,size,GetLastError());
return false;
}
//--- 最後の 2 つの折れ目が発生したバーのオープン時間を開く
get_times[0]=times[positions[1]];// 最後から2 番目の値が初めの折れ目として書かれる
get_times[1]=times[positions[2]];// 最後から3 番目の値が2 番目の折れ目になる
PrintFormat("%s: first=%s, second=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0]));
//--- 成功
return true;
}
|