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