#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);
}
|