//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2000-2024, MetaQuotes Ltd. |
//| 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("handle=%d로 %s/%s 지표를 차트에 연결하는데 실패하였습니다. 오류 코드 %d",
_Symbol,
EnumToString(_Period),
handle,
GetLastError());
//--- 프로그램 작업 종료
return;
}
//--- 지표를 표시하기 위해 차트를 새로고침
ChartRedraw();
//--- 마지막 두 지그재그 프랙쳐 찾기
double two_values[];
datetime two_times[];
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("마지막 두 지그재그 프랙쳐를 발견하는 데 실패하였습니다!");
//--- 프로그램 작업 종료
return;
}
//--- 이제 표준 편차 채널을 첨부
string channel="StdDeviation Channel";
if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0))
{
PrintFormat("%s 개체를 생성하는 데 실패하였습니다. 오류 코드 %d",
EnumToString(OBJ_STDDEVCHANNEL),GetLastError());
return;
}
else
{
//--- 두 번째 포인트를 정의하는 채널이 생성되었습니다.
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: 지그재그 지표의 핸들을 생성하는 데 실패하였습니다. 오류 코드 %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("%d 시도에 대한 지표를 계산에 실패하였습니다!");
//--- 프로그램 작업 종료
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: handle=%d를 사용하여 지표의 %d 값을 복사에 실패했습니다. 오류 코드 %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++;
//--- 두 프랙처가 발견되면, 루프 중단
if(k>2) break;
}
i++;
}
//--- 시계열에서와 같이 배열에 대한 액세스 순서 정의
ArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true);
if(CopyTime(_Symbol,_Period,0,size,times)<=0)
{
PrintFormat("%s: CopyTime()에서 %d 값을 복사에 실패했습니다. 오류 코드 %d",
__FUNCTION__,size,GetLastError());
return false;
}
//--- 막대가 열린 시간(마지막 2회 프랙처가 발생한 시간)을 열기
get_times[0]=times[positions[1]];// 마지막 값 하나만 첫 번째 프랙처로 기록됩니다
get_times[1]=times[positions[2]];// 끝에서 세 번째 값은 두 번째 프랙처입니다
PrintFormat("%s: first=%s, second=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0]));
//--- 성공
return true;
}
|