#property description "지표가 로컬 캔들스틱을 강조처리 합니다" #property description "고가 및 저가. 검색 간격 길이" #property description "입력 매개변수를 사용하여 극한값을 찾아야 합니다." //--- 지표 설정 #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 1 //---- 플롯 #property indicator_label1 "극값" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrLightSteelBlue,clrRed,clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- 사전정의된 상수 #define INDICATOR_EMPTY_VALUE 0.0 //--- 매개변수 입력 input int InpNum=4; // 간격 길이의 반 //--- 지표 버퍼 double ExtOpen[]; double ExtHigh[]; double ExtLow[]; double ExtClose[]; double ExtColor[]; //--- 글로벌 변수 int ExtStart=0; // 극값이 아닌 최초의 캔들스틱 인덱스 int ExtCount=0; // 간격 내 비극값 수 //+------------------------------------------------------------------+ //| 비극값 캔들 스틱 채움 | //+------------------------------------------------------------------+ void FillCandles(const double &open[],const double &high[], const double &low[],const double &close[]) { //--- 캔들스틱 채움 ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount); } //+------------------------------------------------------------------+ //| 사용자 지정 지표 초기화 함수 | //+------------------------------------------------------------------+ int OnInit() { //--- 지표 버퍼 맵핑 SetIndexBuffer(0,ExtOpen); SetIndexBuffer(1,ExtHigh); SetIndexBuffer(2,ExtLow); SetIndexBuffer(3,ExtClose); SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX); //--- 표시되지 않ㅇ는 값을 지정 PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE); //--- 데이터 창에 표시할 지표 버퍼 이름 지정 PlotIndexSetString(0,PLOT_LABEL,"시가;고가;저가;종가"); //--- 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[]) { //--- 시계열에서 정확한 인덱스 설정 ArraySetAsSeries(open,false); ArraySetAsSeries(high,false); ArraySetAsSeries(low,false); ArraySetAsSeries(close,false); //--- 막대 계산 시작의 변수 int start=prev_calculated; //--- 첫 번째 InpNum*2 막대에 대한 계산이 수행되지 않습니다 if(start==0) { start+=InpNum*2; ExtStart=0; ExtCount=0; } //--- 막대가 막 형성된 경우, 다음 극값을 확인 if(rates_total-start==1) start--; //--- 극값에 대해 확인할 막대 인덱스 int ext; //--- 지표 값 계산 루프 for(int i=start;i<rates_total-1;i++) { //--- 초기에 그려지지 않은 i 막대 ExtOpen[i]=0; ExtHigh[i]=0; ExtLow[i]=0; ExtClose[i]=0; //--- 확인할 극값 인덱스 ext=i-InpNum; //--- 로컬 최대값 확인 if(IsMax(high,ext)) { //--- 극값의 캔들스틱 강조 ExtOpen[ext]=open[ext]; ExtHigh[ext]=high[ext]; ExtLow[ext]=low[ext]; ExtClose[ext]=close[ext]; ExtColor[ext]=1; //--- 다른 캔들스틱을 극단까지 뉴트럴 색상으로 강조 FillCandles(open,high,low,close); //--- 변수 색상 변경 ExtStart=ext+1; ExtCount=0; //--- 다음 반복으로 넘어가기 continue; } //--- 로컬 최소값 확인 if(IsMin(low,ext)) { //--- 극값의 캔들스틱 강조 ExtOpen[ext]=open[ext]; ExtHigh[ext]=high[ext]; ExtLow[ext]=low[ext]; ExtClose[ext]=close[ext]; ExtColor[ext]=2; //--- 다른 캔들스틱을 극단까지 뉴트럴 색상으로 강조 FillCandles(open,high,low,close); //--- 변수 값 변경 ExtStart=ext+1; ExtCount=0; //--- 다음 반복으로 넘어가기 continue; } //--- 간격에 따라 비극값 수를 늘림 ExtCount++; } //--- 다음 호출을 위한 prev_calculated의 반환 값 return(rates_total); } //+------------------------------------------------------------------+ //| 현재 배열 요소가 로컬 고가인지 확인 | //+------------------------------------------------------------------+ bool IsMax(const double &price[],const int ind) { //--- 간격 시작 변수 int i=ind-InpNum; //--- 간격 종료 기간 int finish=ind+InpNum+1; //--- 간격의 전반부를 점검 for(;i<ind;i++) { if(price[ind]<=price[i]) return(false); } //--- 간격의 후반부를 점검 for(i=ind+1;i<finish;i++) { if(price[ind]<=price[i]) return(false); } //--- 이는 극값입니다 return(true); } //+------------------------------------------------------------------+ //| 현재 배열 요소가 로컬 저가인지 확인 | //+------------------------------------------------------------------+ bool IsMin(const double &price[],const int ind) { //--- 간격 시작 변수 int i=ind-InpNum; //--- 간격 끝 변수 int finish=ind+InpNum+1; //--- 간격의 전반부를 점검 for(;i<ind;i++) { if(price[ind]>=price[i]) return(false); } //--- 간격의 후반부를 점검 for(i=ind+1;i<finish;i++) { if(price[ind]>=price[i]) return(false); } //--- 이는 극값입니다 return(true); } |