diff --git a/Code_Python/test.py b/Code_Python/test.py index 36456db..0215ca2 100644 --- a/Code_Python/test.py +++ b/Code_Python/test.py @@ -32,16 +32,10 @@ data = np.loadtxt(data_file, delimiter=',') n_samples = data.shape[0] data = data.reshape(n_samples, -1) +np.random.seed(1294404794) + spx = flt.Filter(data) -# args = (spx.X, spx.SMA(N=5), spx.EMA(alpha=0.7)) -# utl.plot_signals(args) - -# alpha = 0.8 -# bb = np.array([alpha]) -# aa = np.array([1.0, alpha - 1.0]) - - # res, bb, aa = spx.SincFunction(2, 50) # print(bb) # print(aa) @@ -50,11 +44,32 @@ spx = flt.Filter(data) # sigma_x = 0.1 # sigma_v = 0.1 * np.ones(n_samples) # res = spx.Kalman(sigma_x=sigma_x, sigma_v=sigma_v, dt=1.0, abg_type="abg") -alpha = 0.5 -beta = 0.005 -gamma = 0.0 -Yc, Yp = spx.ABG(alpha=alpha, beta=beta, gamma=gamma, dt=1.0) -signals = (spx.data[:, 0], Yc[:, 0], Yp[:, 0]) -utl.plot_signals(signals, 0, 50) +# alpha = 0.5 +# beta = 0.005 +# gamma = 0.0 +# Yc, Yp = spx.ABG(alpha=alpha, beta=beta, gamma=gamma, dt=1.0) +# signals = (spx.data[:, 0], Yc[:, 0], Yp[:, 0]) +# utl.plot_signals(signals, 0, 50) +# t, f = utl.synthetic_wave([1., 2., 3.], A=None, PH=None, num=30) +# plt.plot(t,f) +# plt.show() +aa = np.array([ + [0.8252, 0.2820], + [1.3790, 0.0335], + [-1.0582, -1.3337], + [-0.4686, 1.1275], + [-0.2725, 0.3502], + [1.0984, -0.2991], + [-0.2779, 0.0229], + [0.7015, -0.2620], + [-2.0518, -1.7502], + [-0.3538, -0.2857], + [-0.8236, -0.8314], + [-1.5771, -0.9792], + [0.5080, -1.1564]]) +synt_aa = utl.synthetic_series(data, False) +plt.plot(synt_aa) +plt.plot(data) +plt.show() diff --git a/Code_Python/utils.py b/Code_Python/utils.py index 1abad4a..23a6fa7 100644 --- a/Code_Python/utils.py +++ b/Code_Python/utils.py @@ -117,176 +117,76 @@ def plot_lag_response(b, a=1.0): plt.show() -def synthetic_wave(per, amp=None, pha=None, tim=None): +def synthetic_wave(P, A=None, PH=None, num=1000): """ Generates a multi-sinewave. P = [ P1 P2 ... Pn ] Periods - varargin = A, T, PH Amplitudes, time, phases A = [ A1 A2 ... An ] Amplitudes - T = [ ts tf dt] Time info: from ts to tf in dt steps PH = [PH1 PH2 ... PHn] Phases (rad) - Av = SUM(1 to n) of [ A*sin(2*pi*f*t + PH) ] - Tv Time (ts to tf with step dt) - Default amplitudes are ones - Default time is from 0 to largest period (1000 steps) Default phases are zeros + Time is from 0 to largest period (default 1000 steps) """ - n_waves = len(per) - per = np.asarray(per) + n_waves = len(P) + P = np.asarray(P) - # Check for amplitudes, times, and phases - if (amp is None): - amp = np.ones(n_waves) + # Define amplitudes and phases + if (A is None): + A = np.ones(n_waves) else: - amp = np.asarray(amp) - if (tim is None): - t_start = 0.0 - t_end = np.amax(per) - n_steps = 500 + A = np.asarray(A) + if (PH is None): + PH = np.zeros(n_waves) else: - t_start = tim[0] - t_end = tim[1] - n_steps = int(tim[2]) - if (pha is None): - pha = np.zeros(n_waves) - else: - pha = np.asarray(pha) + PH = np.asarray(PH) # Add all the waves - t = np.linspace(t_start, t_end, num=n_steps) + t = np.linspace(0.0, np.amax(P), num=num) f = np.zeros(len(t)) for i in range(n_waves): - f = f + amp[i] * np.sin(2.0 * np.pi * t / per[i] + pha[i]) + f = f + A[i] * np.sin(2.0 * np.pi * t / P[i] + PH[i]) return t, f -# function sP = SyntQT(P,type) -# % Function: generate a random (synthetic) price curve -# % -# % Inputs -# % ------ -# % P prices (for type equal to 'P' and 'R') -# % normal distribution data (for type equal to 'N') -# % P(1) = mean -# % P(2) = std -# % P(3) = length -# % type type of generation -# % P use returns from price -# % R use returns normal distribution -# % N use specified normal distribution -# % -# % Output -# % ------ -# % sP generated synthetic prices +def synthetic_series(data, multivariate=False): + """ + """ + n_samples, n_series = data.shape -# % Check for number of arguments -# if (nargin ~= 2) -# fprintf(1,'\n'); -# error('Wrong number of arguments'); -# end + # The number of samples must be odd (if the number is even drop the last value) + if ((n_samples % 2) == 0): + print("Warning: data reduced by one (even number of samples)") + n_samples = n_samples - 1 + data = data[0:n_samples, :] -# switch(type) - -# % Use actual returns from P to generate values -# case 'P' -# R = Price2ret(P,'S'); % "simple" method -# sR = phaseran(R,1); - -# % Use normal distribution to generate values -# % (mean and std are from the actual returns of P) -# case 'R' -# R = Price2ret(P,'S'); % "simple" method -# sR = normrnd(mean(R),std(R),length(R),1); - -# % Use defined normal distribution to generate values -# % P(1)=mean, P(2)=std, P(3)=length -# case 'N' -# sR = normrnd(P(1),P(2),P(3),1); + # FFT of the original data + data_fft = np.fft.fft(data, axis=0) -# otherwise -# fprintf(1,'\n'); -# error('Type not recognized'); - -# end - -# % Use 'simple' method and P0 = 1 to determine price -# sP = Ret2price(sR,'S'); - -# end % End of function + # Parameters + half_len = (n_samples - 1) // 2 + idx1 = np.arange(1, half_len+1, dtype=int) + idx2 = np.arange(half_len+1, n_samples, dtype=int) + # If multivariate the random phases is the same + if (multivariate): + phases = np.random.rand(half_len, 1) + phases1 = np.tile(np.exp(2.0 * np.pi * 1j * phases), (1, n_series)) + phases2 = np.conj(np.flipud(phases1)) -# % Input data -# % ---------- -# % recblk: is a 2D array. Row: time sample. Column: recording. -# % An odd number of time samples (height) is expected. If that is not -# % the case, recblock is reduced by 1 sample before the surrogate -# % data is created. -# % The class must be double and it must be nonsparse. - -# % nsurr: is the number of image block surrogates that you want to -# % generate. - -# % Output data -# % --------------------- -# % surrblk: 3D multidimensional array image block with the surrogate -# % datasets along the third dimension - -# % Example 1 -# % --------- -# % x = randn(31,4); -# % x(:,4) = sum(x,2); % Create correlation in the data -# % r1 = corrcoef(x) -# % surr = phaseran(x,10); -# % r2 = corrcoef(surr(:,:,1)) % Check that the correlation is preserved - -# % Carlos Gias -# % Date: 21/08/2011 - -# % Reference: -# % Prichard, D., Theiler, J. Generating Surrogate Data for Time Series -# % with Several Simultaneously Measured Variables (1994) -# % Physical Review Letters, Vol 73, Number 7 - -# function surrblk = phaseran(recblk,nsurr) - -# % Get parameters -# [nfrms,nts] = size(recblk); -# if ( rem(nfrms,2) == 0 ) -# nfrms = nfrms-1; -# recblk = recblk(1:nfrms,:); -# end - -# % Get parameters -# len_ser = (nfrms-1)/2; -# interv1 = 2:len_ser+1; -# interv2 = len_ser+2:nfrms; - -# % Fourier transform of the original dataset -# fft_recblk = fft(recblk); - -# % Create the surrogate recording blocks one by one -# surrblk = zeros(nfrms,nts,nsurr); -# for k = 1:nsurr -# ph_rnd = rand([len_ser 1]); - -# % Create the random phases for all the time series -# ph_interv1 = repmat(exp(2*pi*1i*ph_rnd),1,nts); -# ph_interv2 = conj(flipud( ph_interv1)); - -# % Randomize all the time series simultaneously -# fft_recblk_surr = fft_recblk; -# fft_recblk_surr(interv1,:) = fft_recblk(interv1,:).*ph_interv1; -# fft_recblk_surr(interv2,:) = fft_recblk(interv2,:).*ph_interv2; - -# % Inverse transform -# surrblk(:,:,k)= real(ifft(fft_recblk_surr)); -# end - -# end % End of function - + # If univariate the random phases is different + else: + phases = np.random.rand(half_len, n_series) + phases1 = np.exp(2.0 * np.pi * 1j * phases) + phases2 = np.conj(np.flipud(phases1)) + # FFT of the synthetic data + synt_fft = data_fft.copy() + synt_fft[idx1, :] = data_fft[idx1, :] * phases1 + synt_fft[idx2, :] = data_fft[idx2, :] * phases2 + # Inverse FFT of the synthetic data + synt_data = np.real(np.fft.ifft(synt_fft, axis=0)) + return synt_data diff --git a/README.md b/README.md index cc4cfce..5435712 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ ## Reference -- John F. Ehlers, "[Cycle Analytics for Traders: Advanced Technical Trading Concepts](http://www.mesasoftware.com/ehlers_books.htm)". +- John F. Ehlers, "[Cycle Analytics for Traders: Advanced Technical Trading Concepts](http://www.mesasoftware.com/ehlers_books.htm)." -- Wikipedia, "[Alpha beta filter](https://en.wikipedia.org/wiki/Alpha_beta_filter)". +- Wikipedia, "[Alpha beta filter](https://en.wikipedia.org/wiki/Alpha_beta_filter)." + +- D. Prichard, and J. Theiler, "[Generating surrogate data for time series with several simultaneously measured variables](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.73.951)." ## Characteristics