# Copyright (C) Wesley Phoa, February 2000 import copy import operator from math import * from types import * from Numeric import * from LinearAlgebra import * import pythoncom class TestServer: _public_methods_ = ['Statistics', 'ExtendedStatistics'] _reg_progid_ = "Python.TestServer" _reg_clsid_ = "{9BF82FE0-E7F4-11D3-B626-0000F6C7C6C4}" _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER # internal methods # note that results of computations are cached in attributes def analyze_multiple_time_series(self, data): """Argument should be a 2D Numeric array; cols are series.""" # compute means num_dates = len(data) self.means = sum(data) / num_dates # detrend time series data = data - array(num_dates * [self.means]) # compute vols vars = (num_dates * sum(data * data) - \ sum(data) * sum(data)) / (num_dates * num_dates) self.vols = sqrt(vars) # transpose so that each time series is a row data = transpose(data) num_series = len(data) # construct [sigma_i * sigma_j] matrix temp2 = zeros( (num_series, num_series), Float) for i in range(num_series): for j in range(num_series): temp2[i][j] = self.vols[i] * self.vols[j] # construct covariance matrix covs = zeros( (num_series, num_series), Float) for i in range(num_series): for j in range(num_series): covs[i][j] = sum(data[i] * data[j]) / num_dates # compute correlations self.correls = covs / temp2 def find_principal_components(self): """Uses cached results from analyze_multiple_time_series.""" self.PCweights, self.PCvectors = \ eigenvectors(self.correls) self.PCweights = self.PCweights / sum(self.PCweights) # public interface methods def Statistics(self, data): """Argument should be rectangular tuple-of-tuples.""" data = array(data) self.analyze_multiple_time_series(data) return map(lambda val1, val2, vect: [val1] + [val2] + vect, list(self.means), list(self.vols), map(list, list(self.correls))) def ExtendedStatistics(self, data): """Argument should be rectangular tuple-of-tuples.""" data = array(data) self.analyze_multiple_time_series(data) self.find_principal_components() return map(lambda val1, val2, vect1, val3, vect2: [val1] + [val2] + vect1 + [val3] + vect2, list(self.means), list(self.vols), map(list, list(self.correls)), list(self.PCweights), map(list, list(self.PCvectors))) if __name__=='__main__': print "Invoking registration utility..." import win32com.server.register win32com.server.register.UseCommandLine(TestServer)