//+------------------------------------------------------------------+ //| Victor Umnyashkin.mq4 | //| Copyright © 2008, MetaQuotes Software Corp. | //| ver 6.0 Final http://www.metaquotes.net | //+------------------------------------------------------------------+ //---в сравнении с 4 вер убрано деление на N и изменен период для совместимости с Паркинсоновской ( вер. 5 тестовая) #property copyright "Copyright © 2008, Victor Umnyashkin" #property link "v354@hotbox.ru" //--------- #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 LightSeaGreen #property indicator_width1 1 //------parameters extern int HI_Vol_Period=21; extern int Trading_Day_In_Year=365; extern bool Volatility_In_Percent=true; extern int No_Use_Log_Scale = 0; extern int Number_Of_Bars=1000; extern double Coeff_Impl_Vol=1; //--------------common arrays-------------------------- double HiVol[]; double Price[]; //----------common variables int Nbar,Per,YearBase,IsLog; double Percent,Coeff; //-------------------------- int init() { //------если не задано количество баров берем всю историю if( Number_Of_Bars == 0 ) Number_Of_Bars=Bars; //------reassign parameters IsLog=No_Use_Log_Scale; Per=HI_Vol_Period-1; //------Изменено !!! чтобы количество баров для раскета совпадало с Паркинсоновской волатильностью Coeff=Coeff_Impl_Vol; //------период должен быть >=2 if( Per <= 1 ) Per=2; //-----нельзя посчитать за пределами доступной истории if( Number_Of_Bars > Bars) Number_Of_Bars=Bars; //------ Nbar=Number_Of_Bars-Per-1; //---------------check enough history if( Nbar <= 1 ) Alert("Недостаточно истории для расчета индикатора. Доступно баров ", Bars," Надо ",Per+1); //------type of measurement unit Percent=1; if( Volatility_In_Percent ) Percent=100; //--------вычисляем годовую базу текущего таймфрейма //-------т.е. количество баров текущего таймфрейма в количестве торговых дней года( кол-во баров в году) YearBase=Trading_Day_In_Year; YearBase=YearBase*PERIOD_D1/Period(); //--------если число торговых дней в году не указано то вычисляем просто волатильность за N bar if( YearBase == 0 ) YearBase=Per+1; //---- indicators int dig = MathMax(Digits,4); if( Volatility_In_Percent ) dig=4; IndicatorDigits(dig); IndicatorBuffers(1); SetIndexBuffer(0,HiVol); //----тип линии SetIndexStyle(0, DRAW_LINE); //------------------не рисовать нули SetIndexEmptyValue(0,0); //-----------формируем имя индикаторной линии string shortname,fullname; shortname ="HV("+HI_Vol_Period+")"; if (Volatility_In_Percent) shortname=shortname+" % "; SetIndexLabel(0,shortname); //формируем название индикатора fullname="Hist.Volatility "; if(IsLog == 1 ) fullname="HV of increment"; if(IsLog == 2 ) fullname="HV of difference"; //--------добавляем значение годовой базы в барах если надо if( YearBase != Per+1 ) fullname=fullname+" taken on "+YearBase+ " bars year base"; fullname=fullname+" "+shortname; //Print(fullname); IndicatorShortName(fullname); //-----------формируем массив цен печатам количество баров ArraySetAsSeries(Price,true); int TMP=ArrayResize(Price,Per+1); //int TMP2=ArraySize(HiVol); Print(shortname+" Bars used for calculation ", TMP," All History Bars ", Bars, " Used history bars ",Number_Of_Bars," Result array lenght Bars ",Nbar); return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int limit; int counted_bars=IndicatorCounted(); //----initial zero if( counted_bars < 1 )for(int i2=Bars-1; i2Bars-Nbar) limit=Bars-counted_bars+1; // Print("KT1 Limit = ",limit); //----calculate indicator //limit=3; for( int i = 0 ; i< limit ; i++) { //------form price array from Per+1 elemrnts for( int j=0;j<=Per;j++) { Price[j]=Close[i+j]; } //---------call function of calculate N-Bar volatility double Volatility= WVHiVol(Per,Price,IsLog); //------take volatility to year base //------& multiply on approx coeff of implyed voatility HiVol[i]=Volatility*MathSqrt(1.0*YearBase/HI_Vol_Period)*Percent*Coeff; } return(0); } //+------------------------------------------------------------------+ //===========calculate N-Bars Historical Volatility on array Price //=========== IsLog =0 use the Log scale ; IsLog = 1 use increment Scale Islog=2 difference scale //=========return N-bar volatility or -1 if error double WVHiVol(int N,double Price[],int IsLog) { int i,Log;double Mid,MidLog,MidIncr; //-------use the Log scale ? Log=IsLog; //if( IsLog != 1 ) Log=0; //---check parameters //-------N must be >=2 if( N<=1 ) { Print("WVHiVol Volatility period = ",N, " It must be >= 2 ", "Calculation impossible "); return(-1); } //------check array lenght int M=ArraySize(Price); if( M < N+1 ) { Print("WVHiVol Price array lenght = ",M," Volatility period = ",N, "Calculation impossible "); return(-1); } //---------check price values != 0 bool zerovalue = false; for( i = 0; i<= N ; i++) { if( Price[i] == 0) zerovalue =true; break; } if( zerovalue ) { Print("WVHiVol Price array contain zero value in ",i," element"+ "Calculation impossible. Switch off the Log scale "); return(-1); } //---------Calc middle value Mid MidIncr & MidLog Mid=0;MidIncr=0;MidLog=0;double delta=0; for( i=1; i <= N ; i++) { delta=Price[i-1]-Price[i]; Mid = Mid + delta; delta=delta/Price[i]; MidIncr= MidIncr + delta; delta=Price[i-1]/Price[i]; MidLog = MidLog + MathLog(delta); } //-------divide them on inerval Mid = Mid;//N; MidIncr=MidIncr;//N; MidLog = MidLog;//N; //----------calc disperce double Vol=0,VolLog=0,VolIncr=0;delta=0; for( i=1; i<=N; i++) { delta=Price[i-1]-Price[i]; Vol = Vol + (delta-Mid)*(delta-Mid); delta=delta/Price[i]; VolIncr= VolIncr + (delta-MidIncr)*(delta-MidIncr); delta = MathLog(Price[i-1]/Price[i]); VolLog = VolLog + (delta-MidLog)*(delta-MidLog); } //Print(" Vol ", DoubleToStr(Vol,15), " VolLog ", DoubleToStr(VolLog,15)); //--------calc volatility Vol = MathSqrt(Vol/(N-1.0)); VolLog = MathSqrt(VolLog/(N-1.0)); VolIncr = MathSqrt(VolIncr/(N-1.0)); //Print(" Vol ", DoubleToStr(Vol,10), " VolLog ", DoubleToStr(VolLog,10)); //-------return no log scale value if( Log == 2 ) return(Vol); if( Log == 1 )return(VolIncr); //-------return Log scale value return(VolLog); }