量化分析整体思路虽不难,但是要代码实现,其实挺繁杂的,需要很多铺垫工作,比如要先搭建自己的数据库。
1
MongoDB
上一节提到要搭建自己的数据库,除了免除耗时下载外,还有一个很重要的原因,就是数据更准确可靠,算法自己一清二楚。而第三方渠道获取的数据,万一某天突然升级改造一下,可能我们的代码就瘫痪了。
so,还是要搭建自己的数据库,于是我们要引入一个新的工具,MongoDB
,反正吧,编程一旦深入一点,琳琅满目的工具就找上门了,别怂,就是用!
安装指南可自行百度:
https://jingyan.baidu.com/article/425e69e601f281be14fc166d.html
不过,还是卡壳了我……这个外文的网站,缓冲了近一个多小时才切到版本选择界面
今天可能来不及安装了。
2
data_crawler.py
由于MongoDB今天没安装好,数据存储的代码就下次再讲,直接贴一下爬取指数和个股的代码吧,今天用到了类(之前学了好久,一直没怎么用过),有些内容,看着挺复杂的,但是接触多了,慢慢发现其实也不难而且用起来,还蛮顺手的。
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Time : 2019-07-01 22:11
# @Author : Ed Frey
# @File : data_crawler.py
# @Software: PyCharm
import tushare as ts
from pymongo import MongoClient
class DataCrawler():
def __init__(self):
# self.db = MongoClient('mongodb:127.0.0.1:27017'['my_quant'])
pass
def crawl_index(self,begin_date=None,end_date=None):
'''
to crawl the index's trading information and set up our own database
:param begin_date: YYYY-MM-DD
:param end_date: YYYY-MM-DD
:return:
'''
# codes = ['000001','000300','399001','399005','399006']
codes = ['000001']
for code in codes:
df_daily = ts.get_k_data(code,index=True,start=begin_date,end=end_date)
for index in df_daily.index:
doc = dict(df_daily.loc[index])
doc['index'] = True
doc['code'] = code
print(doc,flush=True)
pass
def crawl_stock(self,autype=None,begin_date=None,end_date=None):
'''
to crawl the stock's trading information and set up our own database
:param autype: 前复权qfq or 后复权hfq or 不复权none
:param begin_date: YYYY-MM-DD
:param end_date: YYYY-MM-DD
:return:
'''
df_stock = ts.get_stock_basics()
# codes = list(df_stock.index)
codes = ['600153','600000']
for code in codes:
df_daily = ts.get_k_data(code,autype=autype,start=begin_date,end=end_date)
for index in df_daily.index:
doc = dict(df_daily.loc[index])
doc['index'] = False
doc['code'] = code
print(doc,flush=True)
pass
if __name__ == '__main__':
dc = DataCrawler()
dc.crawl_index(begin_date='2019-07-01',end_date='2019-07-03')
dc.crawl_stock(begin_date='2019-07-01', end_date='2019-07-03')
就是把爬取指数信息的函数crawl_index、爬取个股信息的函数crawl_stock封装到了DataCrawler这个类中,正是所谓的面向对象编程,简单一点讲“物以类聚”。之前的代码分享基本都是函数式编程,抽象一个函数,然后多个场景可以直接调用;而面向对象编程呢,个人感觉比函数式编程更进了一步,功能也更强大了。
举个简单的例子:比如鱼类跟哺乳类,用腮呼吸是鱼类的特定方式(函数方法),而用肺呼吸是哺乳类的特定方式(函数方法);而二者共有的特征是循环系统都是由心脏和血管构成,这个特定方式是2个类完全相同的特定方式(函数方法)。
大概就是这么个样子,根据特性再进一步的提取,增强了某些共通特性的复用性,就酱紫,不废话了。
运行结果如下:
/Users/Ed_Frey/anaconda2/envs/python36/bin/python /Users/Ed_Frey/Desktop/MyQuant_v1/data/data_crawler.py
{'date': '2019-07-01', 'open': 3024.6199999999999, 'close': 3044.9000000000001, 'high': 3045.3699999999999, 'low': 3014.6900000000001, 'volume': 250840433.0, 'code': '000001', 'index': True}
{'date': '2019-07-02', 'open': 3042.5799999999999, 'close': 3043.9400000000001, 'high': 3048.48, 'low': 3033.7800000000002, 'volume': 214520624.0, 'code': '000001', 'index': True}
{'date': '2019-07-03', 'open': 3031.8299999999999, 'close': 3015.2600000000002, 'high': 3031.8299999999999, 'low': 3006.3200000000002, 'volume': 212296173.0, 'code': '000001', 'index': True}
{'date': '2019-07-01', 'open': 8.9800000000000004, 'close': 8.9399999999999995, 'high': 9.0800000000000001, 'low': 8.9100000000000001, 'volume': 134979.0, 'code': '600153', 'index': False}
{'date': '2019-07-02', 'open': 8.9000000000000004, 'close': 9.0500000000000007, 'high': 9.0500000000000007, 'low': 8.8699999999999992, 'volume': 185049.0, 'code': '600153', 'index': False}
{'date': '2019-07-03', 'open': 9.0299999999999994, 'close': 9.1500000000000004, 'high': 9.1799999999999997, 'low': 8.9399999999999995, 'volume': 183247.0, 'code': '600153', 'index': False}
{'date': '2019-07-01', 'open': 11.859999999999999, 'close': 11.710000000000001, 'high': 11.92, 'low': 11.69, 'volume': 548878.0, 'code': '600000', 'index': False}
{'date': '2019-07-02', 'open': 11.720000000000001, 'close': 11.609999999999999, 'high': 11.74, 'low': 11.57, 'volume': 511657.0, 'code': '600000', 'index': False}
{'date': '2019-07-03', 'open': 11.619999999999999, 'close': 11.56, 'high': 11.630000000000001, 'low': 11.51, 'volume': 365670.0, 'code': '600000', 'index': False}
Process finished with exit code 0
结果中数字小数点好多位,这个问题回头再说。上面的代码提取到了000001这个指数7.1-7.3的交易数据,还有600153和600150这2只个股在7.1-7.3的交易数据。另外,get_k_data函数获取到的信息,满足不了我们的需求,我们又增加了2个字段,一个是来区分某个代码到底是指数还是个股(index),还有一个用来记录股票代码(code)。
正常来讲,我们要把爬取到的数据给存储到数据库中,便于今后的使用。由于MongoDB没安装好,留待下次再讲,敬请期待。