页面载入中,请稍后...

沪深指数听上去像什么?|

作者: zzy5111398 分类: I.T技术,数据科学 发布时间: 2019-02-06 21:18

最近我突发奇想,涨跌的百分数恰好有-10,-9,…,-1,0,1,2,…,8,9,10共21个,而三个音阶如果将沪深指数的收益率映射到音阶上听上去会是什么样?话不多说,直接开干。

1. 数据获取

首先第一步就是获取沪深指数自2015年至2019年末的所有收益率数据,一共有976个交易日收益率数据。
由于近期tushare转为商业应用了,这一次我推荐使用Python中Pandas以前自带的Yahoo数据接口进行数据获取。

1.1 Python工具环境部署

首先第一步,确保你的python版本和pandas版本。我推荐使用Miniconda对python进行安装和包的管理(过去推荐Anaconda,但由于Anaconda自带包太多,因此下载比较慢)
1. (安装过程中记得勾选设置环境变量Environment Variable)直接在官方网页下载与系统对应的最新版本,注意检查系统是否是64位,不要下错版本。
2. 在cmd、terminal或shell中运行conda检查是否设置环境变量,如果提示找不到该命令(Command Not found),请百度学习一下如何设置环境变量。
3. 用conda自带的pip工具进行python包的下载。

pip install pandas pandas_datareader

4. 进入python,调用pandas_datareader
笔者推荐使用Jupyter Notebook,下载方式如下。

pip install pandas pandas_datareader

如果不习惯Jupyter而习惯Matlab这类IDE可以使用Pycharm,下载方式百度即可。
进入jupyter后,新建python文档,输入以下命令并Ctrl+Enter运行即可调用Pandas_datareader并获取苹果公司股价数据。

import pandas_datareader as pdr
pdr.get_data_yahoo('AAPL') # 获取苹果公司股价

至此,我们已经具备调用谷歌财经API的工具,下面,我们设置好开始和结束日期,对沪深指数进行下载。

1.2 沪深指数下载

首先,找到yahoo财经中沪深指数的code。

例如,我们可以看到上证综指的code是000001.SS,然后我们通过

import pandas_datareader as pdr
from numpy import log

ssdata = pdr.get_data_yahoo('000001.SS',start="2015-01-02", end="2019-01-01") # 获取苹果公司股价
return_ss=log(hsdata['Close']).diff()

下好的数据,我们直接用Numpy的log()函数求对数收益率。要注意的是不是Math包里的log,因为那个函数只能求纯数字的,而不能用于Pandas.DataFrame的对象。
于是,我们得到了如图的数据。

2. MIDI实现

MIDI(Musical Instrument Digital Interface)乐器数字接口是编曲届最广泛的音乐格式。其本质是一种协议,使得通过电子产生的音乐能让乐器或扬声器理解其旋律和音符。

Mac系统中自带有Garageband库乐队软件,可以编辑或播放MIDI文件。那么问题是如何将获得的收益率数据转化为MIDI。这里我们需要用到一个python库。

2.1 MIDIUtil使用

首先,用pip可以下载这个包。

pip install MIDIUtil

根据官方DEMO,我们可以得到一个简单的C大调MIDI文件。

from midiutil import MIDIFile

degrees  = [60, 62, 64, 65, 67, 69, 71, 72]  # MIDI note number
track    = 0
channel  = 0
time     = 0    # In beats
duration = 1    # In beats
tempo    = 60   # In BPM
volume   = 100  # 0-127, as per the MIDI standard

MyMIDI = MIDIFile(1)  # One track, defaults to format 1 (tempo track is created
                      # automatically)
MyMIDI.addTempo(track, time, tempo)

for i, pitch in enumerate(degrees):
    MyMIDI.addNote(track, channel, pitch, time + i, duration, volume)

with open("major-scale.mid", "wb") as output_file:
    MyMIDI.writeFile(output_file)

demo中可以看出,每一个音符都是用数字表示的。我们找到Docs文档,看到该函数的声明如下:

MIDIFile.addNote(track, channel, pitch, time, duration, volume, annotation=None)
Parameters:	
track – The track to which the note is added.
channel – the MIDI channel to assign to the note. [Integer, 0-15]
pitch – the MIDI pitch number [Integer, 0-127].
time – the time at which the note sounds. The value can be either quarter notes [Float], or ticks [Integer]. Ticks may be specified by passing eventtime_is_ticks=True to the MIDIFile constructor. The default is quarter notes.
duration – the duration of the note. Like the time argument, the value can be either quarter notes [Float], or ticks [Integer].
volume – the volume (velocity) of the note. [Integer, 0-127].
annotation – Arbitrary data to attach to the note.

其中,pitch是音高,即音符。取整数从0直127。而65即为C大调的Fa,因此如我们将其与涨跌幅的0对应,以此类推,只需要将涨跌幅的整数部分对应到各自音符上即可。但是由于音符的代表数字并非连续的,因此我们先建立一个列表用于存储三个音阶各自的音符。

degrees  = [48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83] 

2.2 Stock乐谱

下面,我们着手将收益率数据转化为MIDI曲谱。
首先,我们需要将数据对应到-10到+10的21个整数。

%matplotlib inline
stock_track = trunc(return_ss * 100)
stock_track.plot()

其实稍加改变就能得到0到20的索引数据。从而将其转变为MIDI文件

from midiutil import MIDIFile


degree  = [60, 62, 64, 65, 67, 69, 71]
degrees = [i - 12 for i in degree]
degrees += degree
degrees += [i + 12 for i in degree]
print(degrees)
stock_midi = [degrees[i] for i in stock_track]

track    = 0
channel  = 0
time     = 0    # In beats
duration = 1    # In beats
tempo    = 60   # In BPM
volume   = 100  # 0-127, as per the MIDI standard

MyMIDI = MIDIFile(1)  # One track, defaults to format 1 (tempo track is created
                      # automatically)
MyMIDI.addTempo(track, time, tempo)

for i, pitch in enumerate(stock_midi):
    MyMIDI.addNote(track, channel, pitch, time + i, duration, volume)

with open("stock_midi.mid", "wb") as output_file:
    MyMIDI.writeFile(output_file)

保存的文件可以用GarageBrand打开,如下图

然后点击分享,保存成mp3文件。

3. 小结

总的来说声音还算祥和,由于股市的收益率都集中在较低的幅度范围,因此音律也集中于中音。
但是相对来说从2015年至2019年旋律略微低沉了些。
以后我会选取别的方式产生旋律,或者试试和弦等乐理技巧。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。