00001 % @file @model2/update.m 00002 % @author weaves 00003 % 00004 % @fn void model2::update(obj self, collector0 returner) 00005 % Given the returns, update the volatilities. 00006 % 00007 % Passed an object that gives us some returns. 00008 function update(obj, returner) 00009 00010 % Price change (volatility proxy) over last 30 second. 00011 % Because using logs: this means p(t)/p(t-30). 00012 function v_ = vol_phase0(idx) 00013 v_ = NaN; 00014 if ~(idx > obj.smoother.phase0) 00015 return; 00016 end 00017 v_ = abs(obj.returns(idx) - obj.returns(idx-obj.smoother.phase0)); 00018 end 00019 00020 % Price max over a period. 00021 % Again the log is the ratio. 00022 function v_ = vol_regime0(idx) 00023 v_ = NaN; 00024 if ~(idx > obj.smoother.RegimePeriod) 00025 return; 00026 end 00027 intvl = (idx-obj.smoother.RegimePeriod):idx; 00028 v_ = obj.smoother.fagg0(obj.returns(intvl)) - ... 00029 obj.smoother.fagg0(min(obj.returns(intvl))); 00030 v_ = abs(v_); 00031 end 00032 00033 % Maximum change over a short period. 00034 % 00035 % eg. sum of p(t)/p(t-n) n = 4 to 8 00036 % There is a question of whether to scale by 5 or sqrt(5). 00037 % Using 5. 00038 function v_ = vol_local0(idx) 00039 v_ = NaN; 00040 if ~(idx > obj.smoother.localVolIndex + 1) 00041 return; 00042 end 00043 f3 = @(x) abs(obj.returns(idx) - obj.returns(idx - x) ); 00044 range_ = [ obj.smoother.localVolIndex0 : obj.smoother.localVolIndex ]; 00045 lvols = arrayfun(f3, range_); 00046 00047 scle_ = obj.smoother.localVolIndex - ... 00048 obj.smoother.localVolIndex0 + 1; 00049 v_ = sum(lvols) ; 00050 v_ = v_ / scle_; 00051 end 00052 00053 % The direction of the price changes. 00054 % 00055 % Difference in average price change in current period and 00056 % previous period. 30 second periods. 00057 function r_ = return_mean(idx) 00058 r_ = NaN; 00059 if ~(idx > 2*(obj.smoother.overN+1) ) 00060 return; 00061 end 00062 fv0 = @(x)(obj.returns( (x - obj.smoother.overN + 1):x) ); 00063 LateMean = obj.smoother.fagg0(fv0(idx)); 00064 EarlyMean = obj.smoother.fagg0(fv0(idx - obj.smoother.overN)); 00065 00066 r_ = (LateMean - EarlyMean); 00067 end 00068 00069 % An exponential average. 00070 % 00071 function v_ = vol_hvol(idx) 00072 v_ = NaN; 00073 if ~(idx > obj.smoother.hvollag + 1) 00074 return; 00075 end 00076 last_ = obj.vols(end,5); 00077 if isnan(last_) 00078 last_ = 0; 00079 end 00080 intvl = (idx-obj.smoother.hvollag+1) : idx; 00081 v_ = obj.smoother.fagg0( abs(diff(obj.returns(intvl))) ); 00082 % Not used 00083 v_ = dot( [ v_, last_ ], ... 00084 [ obj.smoother.hvol, 1 - obj.smoother.hvol ]); 00085 end 00086 00087 % The time series might have been refreshed. We ask for all prices 00088 % after a mark. It returns 00089 % { [count of new prices] [timeseries object of all prices] } 00090 returns = returner.returns2(obj.cache(1).tmark); 00091 if isempty(returns) || ~iscell(returns) || returns{1} <= 0 00092 return; 00093 end 00094 % Record the new timestamp. 00095 obj.cache(1).tmark = datenum(returns{2}(end).getabstime()); 00096 00097 % Takes logs of the data. Note no price difference is made. We 00098 % just use the prices as logs. 00099 obj.returns = log(returns{2}.Data); 00100 00101 % Step through new entries and add them to our big table. 00102 for midx=(length(obj.returns) - returns{1} +1):length(obj.returns); 00103 v_ = zeros(1, size(obj.cache.vols,2)); 00104 v_(1) = vol_phase0(midx); 00105 v_(2) = vol_regime0(midx); 00106 v_(3) = vol_local0(midx); 00107 v_(4) = return_mean(midx); 00108 v_(5) = vol_hvol(midx); 00109 % Filter out dead zones. 00110 if ~all(isnan(v_)) 00111 obj.cache(1).vols(obj.atomic_idx(),:) = [ v_ ]; 00112 end 00113 end 00114 00115 % Update the indicators. 00116 obj.quantify(); 00117 end 00118