Pregunta extra: ¿Alguien sabe cómo reproducir/escuchar una serie temporal (financiera) grabada como serie pandas, dataframe, lista python, array numpy, archivo csv/txt,...? ?
Esto es bastante divertido y tiene aplicaciones prácticas a las finanzas cuantitativas. De hecho, mis socios y yo llevamos un tiempo experimentando con esto como base de un modelo y hemos obtenido resultados muy interesantes.
Al principio, me resultó muy sencillo asignar mis series temporales a las frecuencias de las teclas del piano. En concreto, hice un diccionario de frecuencias de teclas de piano a partir de una sola octava de un piano. La octava constaba de siete teclas blancas y cinco negras (agudas). Cada tecla estaba calibrada en relación con las demás, igual que se afina un piano. De este modo, la "afiné" en Do central:
$$note frequency = base frequency * 2^\frac N{12} $$
Donde el $base frequency$ es la de do central (261,63 Hz) y cada $N$ es una nota de Do a Si (Do, Do, Re, Re, Mi, Fa, Fa, Sol, Sol, La, La, Si). Esto se conoce como sistema de temperamento igual .
En Python, podemos crear un diccionario de frecuencias como este:
def piano_notes():
'''
Returns a dictionary containing the frequencies of piano notes
'''
base_freq = 261.63
octave = ['C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B']
note_freqs = {octave[i]: base_freq * 2**(i/12) for i in range(len(octave))}
note_freqs[''] = 0.0 # pause / silent note
return note_freqs
La salida de print(note_freqs)
:
{'C': 261.63, 'c': 277.18732937722245, 'D': 293.66974569918125, 'd': 311.1322574981619, 'E': 329.63314428399565, 'F': 349.2341510465061, 'f': 370.00069432367286, 'G': 392.0020805232462, 'g': 415.31173722644, 'A': 440.00745824565865, 'a': 466.1716632541139, 'B': 493.89167285382297, '': 0.0}
A partir de aquí, debe decidir cómo transformar cada precio o rendimiento de su serie temporal en un número entero de 0 a 11 y asignarlos a sus respectivos valores del diccionario. Ese paso requiere algo de creatividad, y te lo dejo a ti.
Ahora que tienes tus series temporales mapeadas a frecuencias de notas de piano, para poder escuchar tus series temporales, necesitas convertir tus frecuencias en algo que se pueda tocar, es decir, ¡necesitas convertirlas en ondas sonoras!
Una onda puede describirse matemáticamente como: $$g(f)=A * \sin(2\pi\ {ft})$$ donde: $A$ =amplitud, $f$ =frecuencia, y $t$ =Hora. Dicho esto, necesitamos una función que genere una matriz de ondas con respecto al tiempo, lo cual es mucho más fácil de lo que parece:
import numpy as np
sample_rate = 44100 # Standard sample rate in digital audio (in Hertz, Hz)
def waves(freq, duration=0.5):
'''
Takes frequency, and time_duration as inputs and returns
a numpy array of values at all points in time
'''
amplitude = 4096 # tuning fork frequency
t = np.linspace(0, duration, int(sample_rate * duration))
wave = amplitude * np.sin(2 * np.pi * freq * t)
return wave
Después de convertir tus notas en ondas reproducibles, las concatenas, las guardas localmente y las reproduces.
import numpy as np
from scipy.io.wavfile import write
def song_data(music_notes):
'''
concatenate all the waves
'''
note_freqs = piano_notes()
song = [waves(note_freqs[note]) for note in music_notes.split('-')]
song = np.concatenate(song)
return song
He aquí un ejemplo de uso de las funciones anteriores para reproducir "Mary Had A Little Lamb". El archivo se guardará en su directorio de trabajo y podrá reproducirlo con un reproductor .wav genérico en casi cualquier máquina.
music_notes = 'E-D-C-D-E-E-E--D-D-D--E-E-E--E-D-C-D-E-E-E--E-D-D-E-D-C-'
data = song_data(music_notes)
write('mary-had-a-little-lamb.wav', samplerate, data.astype(np.int16))
En la práctica, las similitudes entre las matemáticas que subyacen a la música y otros patrones de la naturaleza son sumamente interesantes. Nuestra idea original se ha transformado en un piano completo (88 teclas) con siete octavas y todos los acordes conocidos. Recientemente hemos empezado a incorporar también otros instrumentos.
Te dejo a ti la tarea de determinar si los mercados están tocando una canción que te gusta y de la que puedes sacar provecho.