Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 7342
1
"""This file contains code used in "Think DSP",
2
by Allen B. Downey, available from greenteapress.com
3
4
Copyright 2014 Allen B. Downey
5
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
6
"""
7
8
from __future__ import print_function, division
9
10
import numpy as np
11
import pandas as pd
12
13
import thinkdsp
14
import thinkplot
15
16
PI2 = np.pi * 2
17
GRAY = '0.7'
18
19
20
def plot_wave_and_spectrum(wave, root):
21
"""Makes a plot showing a wave and its spectrum.
22
23
wave: Wave object
24
root: string used to generate filenames
25
"""
26
thinkplot.preplot(cols=2)
27
wave.plot()
28
thinkplot.config(xlabel='Time (days)',
29
ylabel='Price ($)')
30
31
thinkplot.subplot(2)
32
spectrum = wave.make_spectrum()
33
print(spectrum.estimate_slope())
34
spectrum.plot()
35
thinkplot.config(xlabel='Frequency (1/days)',
36
ylabel='Amplitude',
37
xlim=[0, spectrum.fs[-1]],
38
xscale='log',
39
yscale='log')
40
41
thinkplot.save(root=root)
42
43
44
def plot_sawtooth_and_spectrum(wave, root):
45
"""Makes a plot showing a sawtoothwave and its spectrum.
46
"""
47
thinkplot.preplot(cols=2)
48
wave.plot()
49
thinkplot.config(xlabel='Time (s)')
50
51
thinkplot.subplot(2)
52
spectrum = wave.make_spectrum()
53
spectrum.plot()
54
thinkplot.config(xlabel='Frequency (Hz)',
55
#ylabel='Amplitude',
56
xlim=[0, spectrum.fs[-1]])
57
58
thinkplot.save(root)
59
60
61
def make_filter(window, wave):
62
"""Computes the filter that corresponds to a window.
63
64
window: NumPy array
65
wave: wave used to choose the length and framerate
66
67
returns: new Spectrum
68
"""
69
padded = thinkdsp.zero_pad(window, len(wave))
70
window_wave = thinkdsp.Wave(padded, framerate=wave.framerate)
71
window_spectrum = window_wave.make_spectrum()
72
return window_spectrum
73
74
75
def plot_filters(close):
76
"""Plots the filter that corresponds to diff, deriv, and integral.
77
"""
78
thinkplot.preplot(3, cols=2)
79
80
diff_window = np.array([1.0, -1.0])
81
diff_filter = make_filter(diff_window, close)
82
diff_filter.plot(label='diff')
83
84
deriv_filter = close.make_spectrum()
85
deriv_filter.hs = PI2 * 1j * deriv_filter.fs
86
deriv_filter.plot(label='derivative')
87
88
thinkplot.config(xlabel='Frequency (1/day)',
89
ylabel='Amplitude ratio',
90
loc='upper left')
91
92
thinkplot.subplot(2)
93
integ_filter = deriv_filter.copy()
94
integ_filter.hs = 1 / (PI2 * 1j * integ_filter.fs)
95
96
integ_filter.plot(label='integral')
97
thinkplot.config(xlabel='Frequency (1/day)',
98
ylabel='Amplitude ratio',
99
yscale='log')
100
thinkplot.save('diff_int3')
101
102
103
def plot_diff_deriv(close):
104
change = thinkdsp.Wave(np.diff(close.ys), framerate=1)
105
106
deriv_spectrum = close.make_spectrum().differentiate()
107
deriv = deriv_spectrum.make_wave()
108
109
low, high = 0, 50
110
thinkplot.preplot(2)
111
thinkplot.plot(change.ys[low:high], label='diff')
112
thinkplot.plot(deriv.ys[low:high], label='derivative')
113
114
thinkplot.config(xlabel='Time (day)', ylabel='Price change ($)')
115
thinkplot.save('diff_int4')
116
117
118
def plot_integral(close):
119
120
deriv_spectrum = close.make_spectrum().differentiate()
121
122
integ_spectrum = deriv_spectrum.integrate()
123
print(integ_spectrum.hs[0])
124
integ_spectrum.hs[0] = 0
125
126
thinkplot.preplot(2)
127
integ_wave = integ_spectrum.make_wave()
128
close.plot(label='closing prices')
129
integ_wave.plot(label='integrated derivative')
130
thinkplot.config(xlabel='Time (day)', ylabel='Price ($)',
131
legend=True, loc='upper left')
132
133
thinkplot.save('diff_int5')
134
135
136
def plot_ratios(in_wave, out_wave):
137
138
# compare filters for cumsum and integration
139
diff_window = np.array([1.0, -1.0])
140
padded = thinkdsp.zero_pad(diff_window, len(in_wave))
141
diff_wave = thinkdsp.Wave(padded, framerate=in_wave.framerate)
142
diff_filter = diff_wave.make_spectrum()
143
144
cumsum_filter = diff_filter.copy()
145
cumsum_filter.hs = 1 / cumsum_filter.hs
146
cumsum_filter.plot(label='cumsum filter', color=GRAY, linewidth=7)
147
148
integ_filter = cumsum_filter.copy()
149
integ_filter.hs = integ_filter.framerate / (PI2 * 1j * integ_filter.fs)
150
integ_filter.plot(label='integral filter')
151
152
thinkplot.config(xlim=[0, integ_filter.max_freq],
153
yscale='log', legend=True)
154
thinkplot.save('diff_int8')
155
156
# compare cumsum filter to actual ratios
157
cumsum_filter.plot(label='cumsum filter', color=GRAY, linewidth=7)
158
159
in_spectrum = in_wave.make_spectrum()
160
out_spectrum = out_wave.make_spectrum()
161
ratio_spectrum = out_spectrum.ratio(in_spectrum, thresh=1)
162
ratio_spectrum.plot(label='ratio', style='.', markersize=4)
163
164
thinkplot.config(xlabel='Frequency (Hz)',
165
ylabel='Amplitude ratio',
166
xlim=[0, integ_filter.max_freq],
167
yscale='log', legend=True)
168
thinkplot.save('diff_int9')
169
170
171
172
def plot_diff_filters(wave):
173
174
window1 = np.array([1, -1])
175
window2 = np.array([-1, 4, -3]) / 2.0
176
window3 = np.array([2, -9, 18, -11]) / 6.0
177
window4 = np.array([-3, 16, -36, 48, -25]) / 12.0
178
window5 = np.array([12, -75, 200, -300, 300, -137]) / 60.0
179
180
thinkplot.preplot(5)
181
for i, window in enumerate([window1, window2, window3, window4, window5]):
182
padded = thinkdsp.zero_pad(window, len(wave))
183
fft_window = np.fft.rfft(padded)
184
n = len(fft_window)
185
thinkplot.plot(abs(fft_window)[:], label=i+1)
186
187
thinkplot.show()
188
189
190
def main():
191
names = ['date', 'open', 'high', 'low', 'close', 'volume']
192
df = pd.read_csv('fb_1.csv', header=0, names=names, parse_dates=[0])
193
ys = df.close.values[::-1]
194
close = thinkdsp.Wave(ys, framerate=1)
195
plot_wave_and_spectrum(close, root='diff_int1')
196
197
change = thinkdsp.Wave(np.diff(ys), framerate=1)
198
plot_wave_and_spectrum(change, root='diff_int2')
199
200
plot_filters(close)
201
202
plot_diff_deriv(close)
203
204
signal = thinkdsp.SawtoothSignal(freq=50)
205
in_wave = signal.make_wave(duration=0.1, framerate=44100)
206
plot_sawtooth_and_spectrum(in_wave, 'diff_int6')
207
208
out_wave = in_wave.cumsum()
209
out_wave.unbias()
210
plot_sawtooth_and_spectrum(out_wave, 'diff_int7')
211
212
plot_integral(close)
213
plot_ratios(in_wave, out_wave)
214
215
216
if __name__ == '__main__':
217
main()
218
219