Volatility Measured from Daily High / Low

On the volatility page, we showed the graph below depicting the relationship to stable gamma and the VIX.  The calculation of the stable gamma from one-minute intra-day prices, requires access to a lot of data that generally isn't available in historical data bases for long time frames.  We have found that the same information may be obtained from the daily high and low prices which are available for many years in the past.

Needs["GEV`"];
AutoCorrelationF[data_,lag_]:=Module[{dataf,dataf1},dataf=Fourier[Join[data-Mean[data] ,Table[0.`,{lag}]]];
dataf1=Take[Chop[Fourier[Abs[dataf]^2]],lag+1] ;
(dataf1/(dataf1[[1]]))];
LogReturn[data_]:=Differences[Log[N[data]]];
data=<<"C:\\Mathematica 7\\Portfolio\\OneMinuteData\\SPY";
lr=LogReturn[data[[All,2]]];
absecf0=Compile[{t,{s,_Real,1}},Abs[Mean[Exp[I t s]]]-1/E];
ABSECF0[t_?NumericQ,s_]:=absecf0[t,s];
SScale[s_]:=Module[{cc,c0,c1},
c1=MeanDeviation[s];
(*generally this loop should not be entered*)
While[absecf0[1/c1,s]<0,c1=2c1;Print["Upper Bound Loop"]];
c0=c1;
While[absecf0[1/c0,s]>0,c1=c0;c0=0.8 c0];(*bracket solution from above*)
cc/.FindRoot[ABSECF0[1/cc,s],{cc,  c0,c1},Method->"Brent"]
];
(*partition data by days*)
dtt=Rest[data[[All,1]]];
dtlr=Transpose[{dtt,lr}];
dtlr1=Split[dtlr,Take[#1[[1]],3]===Take[#2[[1]],3]&];
lrp=#[[All,2]]&/@dtlr1;
(*end day partition routine*)
scl=SScale/@lrp;
dtpr=Last/@Split[Rest[data][[All,{1,2}]],Take[#1[[1]],3]===Take[#2[[1]],3]&];
dt=Last[#][[1]]&/@dtlr1;
vix=FinancialData["^VIX",{2007,7,5}];
vq=Mean[vix[[All,2]]]/Mean[scl];
Clear[rticks];
rticks[min_,max_]:=Table[{i,Round[i /vq 10000]/10000.},{i,Ceiling[min],Floor[max],30}];
DateListPlot[{Transpose[{dt,vq scl}],vix},PlotRange->All,Joined-> True,PlotStyle->{Darker[Red],Darker[Blue]}, FrameTicks->{Automatic,Automatic,None,rticks},FrameLabel-> {None,"VIX",None,"SPY Stable γ"},PlotLabel-> "VIX - Blue\nSPY Stable γ - Red"]

The plot below shows the logarithm of the ratio of the intra-day high price to the intra-day low price.  This information is readily available from historical databases going back for many years.  Also on the plot in red is the same Stable γ plot, rescaled to be consistent with the Log[High/Low].  The Stable γ plot is below the Log[High/Low], so it is somewhat obscured by the slightly higher variability of the Log[High/Low] data, but the information is clearly the same.

symbol="SPY";
date={First[dt],Last[dt]};
hi=FinancialData[symbol,"High",date];
lo=FinancialData[symbol,"Low",date];
lndf=Log[hi[[All,2]]/lo[[All,2]]];

gq=Mean[lndf]/Mean[scl];
Clear[rticks];
rticks[min_,max_]:=Table[{i,Round[i /gq 10000]/10000.},{i,Round[min 100]/100.,Round[max 100]/100.,0.02}];
DateListPlot[{Transpose[{dt,gq scl}],Transpose[{dt,lndf}]},PlotRange->All,Joined-> True,PlotStyle->{Darker[Red],Darker[Blue]}, FrameTicks->{Automatic,Automatic,None,rticks},FrameLabel-> {None,"Log[High/Low]",None,"SPY Stable γ"},PlotLabel-> "Log[High/Low] - Blue\nSPY Stable γ - Red"]

Below is an autocorrelation plot for the two measures and indeed they both show the same high degree of serial dependence.

ListPlot[{AutoCorrelationF[lndf,200],AutoCorrelationF[scl,200]},PlotRange->All,Joined->True,PlotLabel->"Log[High/Low]  -- Blue\nStable γ  -- Red",Frame->True,Axes->{True,False},FrameLabel->{"Lag in Days","Autocorrelation"}]

Despite the significant serial dependence in the structure, we looked at the histogram of the data and a generalized extreme value (GEV) fit. The log[high price/low price] represents a maximum of the Log[price] - Log[low price] for each price of a day, what is lost is the order of prices, so this represents a maximum price range of many prices during the day; consequently extreme value analysis seems appropriate.

gfit=GEVMLFit[lndf];
h1=Histogram[lndf,Automatic,"ProbabilityDensity"];
g1=Plot[PDF[GEVDistribution[Sequence@@gfit],x],{x,0,Max[lndf]},PlotRange->All,PlotStyle->{Darker[Red],Thickness[0.008]}];
Print[Show[h1,g1,Frame->True,Axes->False,PlotLabel->symbol<>" Log[High/Low] GEV Fit"]]
CellPrint[TextCell["GEV parameters {μ , σ, ξ} \n"<>ToString[ToString[#]&/@(gfit )],"Text"]];

GEV parameters {μ , σ, ξ} 
{0.013831, 0.00756971, 0.355292}

Below is a GEV fit to the Stable γ, which on other pages we have modeled with a lognormal distribution, without much rationale.  It may well be that the GEV is a better model.  Note that the shape parameters, ξ, for the two plots are quite close and that they differ only by location and scale parameters, μ and σ.  The ξ parameter of less than 0.5 indicates that these are light tailed distributions.  Thus we think the Log[High/Low] should be an excellent measure of volatility, which is easily accessible.

sfit=GEVMLFit[scl];
h1=Histogram[scl,Automatic,"ProbabilityDensity"];
g1=Plot[PDF[GEVDistribution[Sequence@@sfit],x],{x,0,Max[scl]},PlotRange->All,PlotStyle->{Darker[Red],Thickness[0.008]}];
Print[Show[h1,g1,Frame->True,Axes->False,PlotLabel->symbol<>" Stable γ GEV Fit"]]
CellPrint[TextCell["GEV parameters {μ , σ, ξ} \n"<>ToString[ToString[#]&/@(sfit )],"Text"]];

GEV parameters {μ , σ, ξ} 
{0.000275401, 0.000133989, 0.329263}

The measure can also be sampled different intervals below it is shown at weekly intervals.

whi=FinancialData[symbol,"High",Flatten[{date,"Week"},1]];
wlo=FinancialData[symbol,"Low",Flatten[{date,"Week"},1]];
wlndf=Log[whi[[All,2]]/wlo[[All,2]]];

DateListPlot[Transpose[{whi[[All,1]],wlndf}],Joined->True,PlotRange->All,PlotLabel-> "Weekly Log[High/Low]"]

The fit below shows the weekly results (a much smaller sample) for the same time interval.  The ξ parameter is a little lower.  In general, we expect that these should be self-similar distributions and that they should scale according to the sampling interval.  Since these distributions seem to be consistently in the Frechet maximum domain of attraction, we expect that the GEV parameters should scale according to (Subscript[μ, scaled ])= μ (n^ξ) and  (Subscript[σ, scaled ])= σ (n^ξ) where n is the  sampling interval.

wfit=GEVMLFit[wlndf];
h1=Histogram[wlndf,Automatic,"ProbabilityDensity"];
g1=Plot[PDF[GEVDistribution[Sequence@@wfit],x],{x,0,Max[wlndf]},PlotRange->All,PlotStyle->{Darker[Red],Thickness[0.008]}];
Print[Show[h1,g1,Frame->True,Axes->False,PlotLabel->symbol<>" Weekly Log[High/Low] GEV Fit"]]
CellPrint[TextCell["GEV parameters {μ , σ, ξ} \n"<>ToString[ToString[#]&/@(wfit )],"Text"]];

GEV parameters {μ , σ, ξ} 
{0.0355549, 0.0173166, 0.294231}

Below is a look at a long term plot of weekly volatility.

whi1=FinancialData[symbol,"High",{{1993,1,1},DateList[],"Week"}];
wlo1=FinancialData[symbol,"Low",{{1993,1,1},DateList[],"Week"}];
wlndf1=Log[whi1[[All,2]]/wlo1[[All,2]]];
DateListPlot[Transpose[{whi1[[All,1]],wlndf1}],Joined->True,PlotRange->All,PlotLabel-> symbol<>" Weekly Log[High/Low]"]

We have been working on an experimental site to do calculations on volatility on individual securities.  It may not always be operational, but when it is you may try it: click here.

txcolor=RGBColor[181/255,18/255,27/255];
t1 = Graphics[Text[Hyperlink[Framed[Style["Financial Home", {txcolor, Bold, Larger}]], "../map/Overview.html"], {-5, 0}]];
t2 = Graphics[Text[Hyperlink[Framed[Style["TrackVolatility", {txcolor, Bold, Larger}]],  "../v00/TrackVolatility.html"], {5,0}]];
t3 = Graphics[Text[Hyperlink[Framed[Style["Download Notebook", {txcolor, Bold, Larger}]], "../v01/HighLowVolatility.nb"], {5, -1}]];
t4 = Graphics[Text[Hyperlink[Framed[Style["Volatility", {txcolor, Bold, Larger}]],  "../r07/Volatility.html"], {0, 0}]];

Show[ t1, t2, t3,t4, ImageSize -> 500]
CellPrint[TextCell["\n\n© Copyright " <>ToString[DateList[][[1]]]<>" mathestate    "<>DateString[DateList[],"DateShort"], "Text"]]

© Copyright 2011 mathestate    Tue 8 Feb 2011