반응형
시계열 데이터에서 파동 또는 패턴을 분석하기 위한 알고리즘중에 아래와 같은 코드가 있어서 분석해 보았다.
이런 자료들은 메타트레이더 관련 사이트에서 얻을 수 있는 것 같으니 참고 바란다.
https://www.mql5.com/en/articles/4502
이 코드의 목적은 효율적으로 시계열 데이터의 저점과 고점을 이루는 파동을 계산하기 위함이다.
아래 알고리즘에서 주요 고려 사항으로 생각 되는 포인트는 2가지 이다.
1. ZIGZAG 턴을 하기 위한 조건으로고점이 발생했을 때 캔들의 저점이 고점대비해서 얼마나 떨어졌을 때를 기준으로 판단할 것이냐 / 저점은 반대로 저점이 발생한 후 캔들의 고점이 저점 대비해서 얼마나 떨어질 때를 기준으로 잡냐가 될 것이다.
즉 dH = H * Point
2. 시계열 데이터의 경우 최신 가격 데이터가 업데이트 되었을 때 먼저 처리가 될 수 있게 하자
extern int H = 33;
extern int MinBars = 0;
extern bool SaveData = false;
double dH;
bool UpZ;
double CurMax,CurMin;
int CurMaxBar,CurMinBar;
double Top,Bot;
double SumR,SumT,SumTD;
int ZCnt;
int h = -1;
string FileName;
int PreBars;
datetime BarTime;
int StartPos;
int pos;
double HZZ[]; // 결과가 들어가는 곳
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() {
if (SaveData) FileName = "HZZ.txt";
SetIndexBuffer(0,HZZ);
SetIndexStyle(0,DRAW_SECTION,EMPTY,2);
SetIndexEmptyValue(0,0.0);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit() {
//Comment("");
if (SaveData) FileClose(h);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator reset function |
//+------------------------------------------------------------------+
int Reset() {
if (SaveData) {
FileClose(h);
h = FileOpen(FileName,FILE_CSV|FILE_WRITE,';');
}
// 제일 적은 Bars 가 0이면 시작 위치는 현재 바개수 -1 해서 시작
if (MinBars==0)
StartPos = Bars-1; // 마지막 데이터 부터 시작
else
StartPos = MinBars; // 중간 데이터 부터 시작
PreBars = 0;
BarTime = 0;
dH = H*Point; // 33 * Point
UpZ = true;
CurMaxBar = 1;
CurMinBar = 1;
CurMax = High[StartPos];
CurMin = Low[StartPos];
Top = CurMin+dH;
Bot = CurMax-dH;
ZCnt = 0;
SumR = 0.0;
SumT = 0.0;
SumTD = 0.0;
StartPos++;
return(StartPos);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
// 캔들의 개수가 이전과 동일하다면 처리하지 않는다.
// [TODO] 최신 캔들의 데이터가 변경이 되었다면 처리를 해야 될 수 있다.
if (Bars == PreBars)
return(0);
if (Bars < MinBars) {
Console.WriteLine("차크 바 개수가 부족한 조건입니다.")
return(0);
}
// 현재 바 갯수 - 이전 바 갯수가 1이면 새로운 바가 생긴 것이고, 시간이 BarTime 과 같다면
if (Bars-PreBars == 1 && BarTime==Time[1])
StartPos = 1; // 시작 위치는 1
else
StartPos = Reset(); // 아니면 리셋
PreBars = Bars;
BarTime=Time[0];
for (pos=StartPos; pos>0 ;pos--) {
HZZ[pos] = 0;
if (UpZ) {
if (High[pos]>CurMax) {
CurMax = High[pos]; // 최고가격 업데이트
CurMaxBar = Bars-pos; //
Bot = CurMax - dH;
} else {
// 고점이 낮아 질 때 저가가 최고값 대비 dH 만큼보다 작아진다면
if (Low[pos]<Bot) {
ZCnt++;
if (ZCnt > 3) { // ZigZag 가 3개 이상 되엇다면
SumR += CurMax-CurMin; // 상승선의 최대 최소 값의 차이 누적
SumT += CurMaxBar-CurMinBar; // 중간 바의 갯수 누적
SumTD += Bars-pos-CurMaxBar; //
//if (SaveData) FileWrite(h,Time[Bars-CurMaxBar],NormalizeDouble(CurMax,Digits));
}
UpZ = false; // 방향 전환
HZZ[Bars-CurMaxBar]=CurMax; // ZIGZAG 위치에 최고 가격 기록
CurMinBar = Bars-pos; // 판단된 위치 가 저가일 수 도 있기 때문에 최저가 바 업데이트
CurMin = Low[pos]; // 최저가 없데이트
Top = CurMin+dH; // 다시 상승 반전하기 위한 Threshold 값 설정
}
}
} else {
if (Low[pos]<CurMin) { // 최저가 갱신시에 위치
CurMinBar = Bars-pos;
CurMin = Low[pos];
Top = CurMin+dH;
} else {
if (High[pos]>Top) {
ZCnt++;
if (ZCnt > 3) { // ZigZag 가 3개 이상 되엇다면
SumR += CurMax-CurMin;
SumT += CurMinBar-CurMaxBar;
SumTD += Bars-pos-CurMinBar;
//if (SaveData) FileWrite(h,Time[Bars-CurMinBar],NormalizeDouble(CurMin,Digits));
}
UpZ = true;
HZZ[Bars-CurMinBar]=CurMin;
CurMaxBar = Bars-pos;
CurMax = High[pos];
Bot = CurMax-dH;
}
}
}
} // pos=StartPos;pos>0;pos--)
if (ZCnt > 3) {
int NZ = ZCnt-3;
// 발견된 선분의 평균 변동폭,
// 발견된 선분의 평균 바카운트
//
//Comment("Средни?размах: ",SumR/NZ,", Сред?? длительность: ",SumT/NZ,", Сред?? задержка: ",SumTD/NZ);
}
return(0);
}
위 코드를 C# 으로 적용하여 아래와 같은 결과를 얻을 수 있었다.
반응형
'Investment > System Trading' 카테고리의 다른 글
[OPENAPI] 실시간 시세 (선물) 처리 기초 (0) | 2022.09.27 |
---|---|
[OPENAPI] 선물 실시간 시세 조회 (1) | 2022.09.20 |
[OPENAPI] 계좌비밀번호 입력창을 통해 조회에 사용한 계좌번호의 비밀번호를 입력하십시오.(44) 오류 (2) | 2022.09.19 |
[OPENAPI] 선옵 코드 구성 및 코드 생성 (0) | 2022.09.15 |
Python : 아나콘다 환경 설정 (for OpenAPI) (0) | 2020.11.02 |
댓글