우리는 필요합니다 :
#property indicator_buffers 2 #property indicator_plots 1 input double retracement=23.6;//회귀 금액 input double minSizeInAtrUnits=0.0;//분 단위의 파도 크기(ATR 단위) input int rollingAtrPeriod=14;//롤링 ATR 기간 input color Color=clrDodgerBlue;//웨이브 색상 input int Width=3;//파도 폭 input ENUM_LINE_STYLE Style=STYLE_SOLID;//웨이브 스타일 //+------------------------------------------------------------------+ //| 사용자 지정 표시기 초기화 기능 | //+------------------------------------------------------------------+ //--- 상승 파동과 하강 파동 double upWaves[],dwWaves[];
upWaves 배열은 고점을 저장하고 dwWaves 배열은 저점을 저장합니다.
시스템 변수를 저장합니다:
마지막 파동 유형, 시작 위치, 끝 위치, 시작과 끝까지의 막대 거리를 알아야 합니다.
그런 다음 로컬 고점 및 로컬 저점 변수와 각 지점에서 막대까지의 거리가 필요합니다.
//--- 지그재그 추적 유지 //--- 웨이브 유형 [0] 없음 [1] 위 [2] 아래 int wave_type=0; //--- 웨이브의 가격(시작 가격) double wave_start_price=0.0; //--- 웨이브의 가격(종가) double wave_end_price=0.0; //--- 시작 가격에서 막대 단위로 표시된 거리입니다. int wave_start_distance=0; //--- 최종 가격에서 막대 단위로 표시된 거리 int wave_end_distance=0; //--- 높은 가격 추적 double high_mem=0.0; int distance_from_high=0; //--- 저렴한 가격 추적 double low_mem=0.0; int distance_from_low=0; //--- 롤링 ATR double rollingAtr=0.0; int rollingAtrs=0;
마지막으로 롤링 atr 단위와 계산된 수입니다.
그런 다음 시스템 재설정 기능을 만듭니다 :
void resetSystem(){
ArrayFill(upWaves,0,ArraySize(upWaves),0.0);
ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
} 표준 항목 , 배열을 0으로 채우고 시스템 변수를 재설정합니다.
처음에는 버퍼와 플롯을 설정하고 처음으로 재설정을 호출합니다:
SetIndexBuffer(0,upWaves,INDICATOR_DATA); SetIndexBuffer(1,dwWaves,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG); PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color); PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width); PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style); resetSystem();
이제 계산으로 바로 넘어가 보겠습니다.
가장 먼저 처리해야 할 것은 롤링 ATR입니다.
우리가 더 많은 막대를 수집 할 때까지 우리는 다른 일을하지 않을 것입니다.
롤링 atr을 관리하는 부분은 다음과 같습니다:
//--- ATR 관리 rollingAtrs++; if(rollingAtrs>rollingAtrPeriod){ double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod); //--- 이전 부분을 제거하고 새 부분을 추가합니다. rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion; } else if(rollingAtrs<=rollingAtrPeriod){ rollingAtr+=(high[i]-low[i])/_Point; if(rollingAtrs==rollingAtrPeriod){ rollingAtr/=((double)rollingAtrs); //--- 최고 및 최저 메모리와 시스템을 시작하십시오. high_mem=high[i]; low_mem=low[i]; distance_from_high=0; distance_from_low=0; } }
멋지네요, 이제 또 다른 문제가 있습니다.
이 지그재그의 기초는 되돌림입니다.
그러나 되돌림이 발생하려면 적어도 하나의 파동이 있어야 합니다.
하지만 첫 번째 파동은 무엇을 되돌림할까요?
따라서 우리는 다음을 수행할 것입니다:
이렇게 하면 초기 파동으로 되돌림이 없지만, 어떻게든 시퀀스를 시작해야 합니다.
여기서 첫 번째 파동에 대해서만 고전적인 프랙탈 접근법을 사용하고 이후에는 되돌림을 계속하는 방법을 선택할 수도 있습니다.
이것이 우리가 파동이없는 한 우리가하는 일입니다:
//--- 아직 웨이브 유형이 없는 경우 else{ //--- 우리가 고점을 깨고 저점을 깨지 않았다면 if(high[i]>high_mem&&low[i]>=low_mem){ double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr; 새 웨이브 크기가 유효한 경우 //--- if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- 새로운 업 웨이브 시작 wave_type=1; //--- 시작 가격은 낮은 메모리 wave_start_price=low_mem; wave_start_distance=distance_from_low; //--- 종가가 새로운 최고가입니다. wave_end_price=high[i]; wave_end_distance=0; //--- 물결 그리기 dwWaves[i-wave_start_distance]=low_mem; upWaves[i]=high[i]; //--- 높음 변경 high_mem=high[i]; distance_from_high=0; //--- 로우 변경 low_mem=low[i]; distance_from_low=0; } } //--- 저점이 아닌 고점을 돌파한 경우 else if(low[i]<low_mem&&high[i]<=high_mem){ double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr; 새 웨이브 크기가 유효한 경우 //--- if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- 새 다운 웨이브 시작 wave_type=-1; //--- 시작 가격은 높은 메모리 wave_start_price=high_mem; wave_start_distance=distance_from_high; //--- 종가가 새로운 최저가입니다. wave_end_price=low[i]; wave_end_distance=0; //--- 물결 그리기 upWaves[i-wave_start_distance]=high_mem; dwWaves[i]=low[i]; //--- 높음 변경 high_mem=high[i]; distance_from_high=0; //--- 로우 변경 low_mem=low[i]; distance_from_low=0; } } //--- 둘 다 깨진 경우 else if(low[i]<low_mem&&high[i]>high_mem){ //--- 변경 high_mem=high[i]; low_mem=low[i]; distance_from_high=0; distance_from_low=0; } }
좋습니다. 이제 마지막 부분입니다.
위의 관련 코드는 다음과 같습니다:
//--- 업 웨이브가 있는 경우 if(wave_type==1){ //--- 파도가 위로 확장되는 경우 if(high[i]>wave_end_price){ //--- 배열 위치에서 이전 종가를 제거합니다(0.0=비어 있음). upWaves[i-wave_end_distance]=0.0; //--- 새 위치에 놓습니다. upWaves[i]=high[i]; wave_end_price=high[i]; wave_end_distance=0; //--- 높음 변경 high_mem=high[i]; distance_from_high=0; //--- 로우 변경 low_mem=low[i]; distance_from_low=0; } //--- 되돌림 확인 if(low[i]<low_mem||distance_from_low==0){ low_mem=low[i]; distance_from_low=0; double size_of_wave=(wave_end_price-wave_start_price)/_Point; double size_of_retracement=(wave_end_price-low_mem)/_Point; if(size_of_wave>0.0){ double retraced=(size_of_retracement/size_of_wave)*100.0; double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr; 새 웨이브 크기가 유효한 경우 //--- if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- 되돌림이 큰 경우 , 하락파를 시작합니다. if(retraced>=retracement){ //--- 새 다운 웨이브 시작 wave_type=-1; //--- 시작 가격은 높은 메모리 wave_start_price=high[i-distance_from_high]; wave_start_distance=distance_from_high; //--- 종가가 새로운 최저가입니다. wave_end_price=low[i]; wave_end_distance=0; //--- 물결 그리기 upWaves[i-wave_start_distance]=high_mem; dwWaves[i]=low[i]; //--- 높음 변경 high_mem=high[i]; distance_from_high=0; //--- 로우 변경 low_mem=low[i]; distance_from_low=0; } } } } }
하락파가 있을 때는 반대로 합니다.
그리고 우리는 완료되었습니다 , 되돌림 지그재그가 준비되었습니다.
다음은 23.6 % 되돌림과 0.0 분 크기의 파동 (atr 단위) 이있는 지그재그입니다.
그리고 다음은 3분 단위의 파동 크기를 가진 동일한 지그재그입니다.
MetaQuotes Ltd에서 영어로 번역함.
원본 코드: https://www.mql5.com/en/code/56619
무역 보고서 내보내기
TradeReportExporter 스크립트는 거래(거래) 내역을 편리한 CSV 파일로 내보내도록 설계되었습니다. 스크립트가 설치된 상품의 지난 1년간 모든 거래에 대한 데이터를 자동으로 수집합니다. 파일에는 날짜 및 시간, 거래 유형(매수/매도), 가격, 거래량, 수수료, 수익/손실 등의 데이터가 포함됩니다. 결과는 Excel 또는 다른 스프레드시트 편집기에서 열 수 있는 파일로 저장됩니다.
A Really Random Robot
이 로봇은 난수 생성기를 사용하여 각 거래의 방향을 결정하기 위해 단순히 동전을 던지는 과정을 시뮬레이션합니다. 이는 객체 지향 방식으로 프로그래밍된 최소한의 전문가 자문 시스템(Expert Advisor)의 예시를 보여줍니다. 또한 다양한 진입 방식이 가져다주는 부가가치를 정량화하기 위한 기초를 제공합니다.