//+------------------------------------------------------------------+ //| Demo_iBands.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 description "이 지표는 다음 데이터를 얻는 방법을 보여줍니다:" #property description "iBands 기술 지표용 지표 버퍼." #property description "지표 계산에 사용되는 심볼 및 타임프레임은" #property description "심볼 및 주기 매개변수로 설정됩니다." #property description "핸들을 만드는 방법은 'type' 매개변수(함수 유형)를 통해 설정됩니다." #property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 3 //--- 상단 플롯 #property indicator_label1 "Upper" #property indicator_type1 DRAW_LINE #property indicator_color1 clrMediumSeaGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- 하단 플롯 #property indicator_label2 "Lower" #property indicator_type2 DRAW_LINE #property indicator_color2 clrMediumSeaGreen #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- 중단 플롯 #property indicator_label3 "Middle" #property indicator_type3 DRAW_LINE #property indicator_color3 clrMediumSeaGreen #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //+------------------------------------------------------------------+ //| 핸들 생성 방법 열거 | //+------------------------------------------------------------------+ enum Creation { Call_iBands, // iBands 사용 Call_IndicatorCreate // IndicatorCreate 사용 }; //--- 입력 매개변수 input Creation type=Call_iBands; // 함수의 종류 input int bands_period=20; // 이동 평균 주기 input int bands_shift=0; // 이동 input double deviation=2.0; // 표준편차 수 input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // 가격 유형 input string symbol=" "; // 심볼 input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // 타임프레임 //--- 지표 버퍼 double UpperBuffer[]; double LowerBuffer[]; double MiddleBuffer[]; //--- iBands 지표의 핸들을 저장하기 위한 변수 int handle; //--- 저장 변수 string name=symbol; //--- 차트의 지표명 string short_name; //--- 볼린저 밴드 지표의 값 수를 유지할 것입니다 int bars_calculated=0; //+------------------------------------------------------------------+ //| 커스텀 지표 초기화 함수 | //+------------------------------------------------------------------+ int OnInit() { //--- 지표 버퍼에 배열 할당 SetIndexBuffer(0,UpperBuffer,INDICATOR_DATA); SetIndexBuffer(1,LowerBuffer,INDICATOR_DATA); SetIndexBuffer(2,MiddleBuffer,INDICATOR_DATA); //--- 각 선의 이동 설정 PlotIndexSetInteger(0,PLOT_SHIFT,bands_shift); PlotIndexSetInteger(1,PLOT_SHIFT,bands_shift); PlotIndexSetInteger(2,PLOT_SHIFT,bands_shift); //--- 지표가 그려지는 심볼 결정 name=symbol; //--- 오른쪽과 왼쪽의 공백을 삭제 StringTrimRight(name); StringTrimLeft(name); //--- 'name' 문자열의 길이가 0이 되는 경우 if(StringLen(name)==0) { //--- 지표가 부착된 차트의 심볼을 취합니다 name=_Symbol; } //--- 지표 핸들 생성 if(type==Call_iBands) handle=iBands(name,period,bands_period,bands_shift,deviation,applied_price); else { //--- 구조물을 지표의 매개변수로 채움 MqlParam pars[4]; //--- ma 주기 pars[0].type=TYPE_INT; pars[0].integer_value=bands_period; //--- 이동 pars[1].type=TYPE_INT; pars[1].integer_value=bands_shift; //--- 표준편차의 수 pars[2].type=TYPE_DOUBLE; pars[2].double_value=deviation; //--- 가격 유형 pars[3].type=TYPE_INT; pars[3].integer_value=applied_price; handle=IndicatorCreate(name,period,IND_BANDS,4,pars); } //--- 핸들이 생성되지 않은 경우 if(handle==INVALID_HANDLE) { //--- 실패에 대해 구분하고 오류 코드를 출력 PrintFormat("%s/%s 심볼에 대한 iBands 지표 핸들 생성 실패, 오류 코드 %d", name, EnumToString(period), GetLastError()); //--- 지표가 일찍 중단됨 return(INIT_FAILED); } //--- 볼린저 밴드 지표의 심볼/타임프레임 표시 short_name=StringFormat("iBands(%s/%s, %d,%d,%G,%s)",name,EnumToString(period), bands_period,bands_shift,deviation,EnumToString(applied_price)); IndicatorSetString(INDICATOR_SHORTNAME,short_name); //--- 지표의 정상 초기화 return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 커스텀 지표 반복 함수 | //+------------------------------------------------------------------+ 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[]) { //--- iBands 지표에서 복사된 값 수 int values_to_copy; //--- 지표에서 계산된 값 수를 결정 int calculated=BarsCalculated(handle); if(calculated<=0) { PrintFormat("BarsCalculated() 가 %d 을(를) 반환, 오류 코드 %d",calculated,GetLastError()); return(0); } //--- 지표의 첫 번째 계산 시작이거나 iBands 지표의 값 수가 변경된 경우 //---또는 두 개 이상의 막대에 대한 지표 계산이 필요한지 여부(가격 이력에서 무언가가 변경되었음을 의미함) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- 지표 버퍼의 크기가 심볼/주기 iBands 지표 값 수보다 크면 모든 항목을 복사하지 않습니다 //--- 모든 항목을 복사하지 않고 지표ㅍ 버퍼 크기보다 작게 복사합니다. if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- 이는 지표 계산의 첫 번째가 아니며 계산을 위한 OnCalculate()의 마지막 호출이 //--- 두 개 이하의 막대가 추가되었음을 의미합니다 values_to_copy=(rates_total-prev_calculated)+1; } //--- 배열을 볼린저 밴드 지표 값으로 채웁니다 //--- FillArraysFromBuffer가 false를 반환하면 정보가 아직 준비되지 않았음을 의미하므로 작업을 종료합니다 if(!FillArraysFromBuffers(MiddleBuffer,UpperBuffer,LowerBuffer,bands_shift,handle,values_to_copy)) return(0); //--- 메시지 형성 string comm=StringFormat("%s ==> 지표 %s 값 업데이트: %d", TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS), short_name, values_to_copy); //--- 차트에 서비스 메시지 표시 Comment(comm); //--- 볼린저 밴드 지표의 값 수를 기억 bars_calculated=calculated; //--- 다음 호출에 대해 prev_calculated 값을 반환합니다 return(rates_total); } //+------------------------------------------------------------------+ //| iBands 지표 지표 버퍼 채우기 | //+------------------------------------------------------------------+ bool FillArraysFromBuffers(double &base_values[], // 볼린저 밴드의 중간선 표시 버퍼 double &upper_values[], // 위쪽 테두리의 지표 버퍼 double &lower_values[], // 아래쪽 테두리의 지표 버퍼 int shift, // 이동 int ind_handle, // iBands 지표 핸들 int amount // 복제 값 수 ) { //--- 오류 코드 재설정 ResetLastError(); //--- 인덱스가 0인 지표 버퍼의 값으로 MiddleBuffer 배열의 일부를 채웁니다 if(CopyBuffer(ind_handle,0,-shift,amount,base_values)<0) { //--- 복사가 실패하면 오류 코드를 알려줍니다 PrintFormat("iBands 지표로부터 데이터 복제 실패, 오류 코드 %d",GetLastError()); //--- 결과가 0인 종료 - 지표가 계산되지 않은 것으로 간주됨을 의미합니다 return(false); } //--- UpperBuffer 배열의 일부를 인덱스 1이 있는 지표 버퍼의 값으로 채웁니다 if(CopyBuffer(ind_handle,1,-shift,amount,upper_values)<0) { //--- 복사가 실패하면 오류 코드를 알려줍니다 PrintFormat("iBands 지표로부터 데이터 복제 실패, 오류 코드 %d",GetLastError()); //--- 결과가 0인 종료 - 지표가 계산되지 않은 것으로 간주됨을 의미합니다 return(false); } //--- LowerBuffer 배열의 일부를 인덱스 2가 있는 지표시기 버퍼의 값으로 채웁니다 if(CopyBuffer(ind_handle,2,-shift,amount,lower_values)<0) { //--- 복사가 실패하면 오류 코드를 알려줍니다 PrintFormat("iBands 지표로부터 데이터 복제 실패, 오류 코드 %d",GetLastError()); //--- 결과가 0인 종료 - 지표가 계산되지 않은 것으로 간주됨을 의미합니다 return(false); } //--- 모든 게 좋습니다 return(true); } //+------------------------------------------------------------------+ //| 지표 초기화 해제 함수 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(handle!=INVALID_HANDLE) IndicatorRelease(handle); //--- 지표 삭제 후 차트 지우기 Comment(""); } |