贴一下目录:
├── README ├── MyQuant_v1 #量化分析程序目录 ├── init.py ├── data #数据处理目录 │ ├── init.py │ ├── basic_crawler.py# 爬取股票基础信息存入MongoDB数据库. │ └── data_crawler.py #爬取指数、股票数据 ├──util # 公用程序 │ ├── init.py │ ├── stock_util.py#获取股票交易日期,所有股票代码 │ └── database.py #链接数据库 ├── backtest #回测 │ ├── init.py │ └── backtest #计划写一下回测走势图 ├── factor #因子 │ ├── init.py │ └──_ factor_.py #不准备开发 ├── strategy #策略 │ ├── init.py │ └── strategy #计划简单写个,主要用于回测 ├── trading #交易 │ ├── init.py │ └── trading #不准备开发 └── log #日志目录 ├── init.py ├── backtest.log #不准备开发 └── transactions.log#不准备开发 今天依旧没有什么硬干货,延伸一下前面讲过的2个代码的实操。
1
完整的爬取数据
data_crawler.py虽然早就写出来了,但总要完整的爬取一遍才敢投入应用中,果然,随便一爬就有问题,速度贼慢,龟速……
于是需要一个改进方法:使用db.daily.createIndex({code:1,date:1})建立数据集索引,还有前复权、后复权的数据集都建立索引,爬取数据的速度就会快非常多,至于为何,暂时还没得空去研究
先用起来再说
2
basic_crawler.py重写
《Python——量化分析常用命令介绍(五)》中贴的basic_crawler.py代码一跑起来发现很多问题,最关键的一点是数据类型不一致不断抛出异常的问题,至于为啥,先一掠而过……翻新完的代码如下:
在这里插入代码片#!/usr/bin/env python3.6 # -*- coding: utf-8 -*- # @Time : 2019-07-31 21:12 # @Author : Ed Frey # @File : basic_crawler.py.py # @Software: PyCharm from pymongo import UpdateOne, DESCENDING from util.database import DB_CONN from util.stock_util import get_trading_dates import tushare as ts from datetime import datetime, timedelta import numpy """ to get basic data from tushare and save it to MongoDB. """ class BasicCrawler: def __init__(self): self.basic = DB_CONN['basic'] self.daily = DB_CONN['daily'] def crawl_basic(self, begin_date=None, end_date=None): ''' to get the basic infomation of stocks on "date" :param begin_date: :param end_date: :return: ''' if begin_date is None: current_date = datetime.now().strftime('%Y-%m-%d') begin_date = self.daily.find_one( {'code': '000001', 'index': True, 'date': {'$lt': current_date}}, sort=[('date', DESCENDING)], projection={'date': True})['date'] dates = get_trading_dates(begin_date=begin_date, end_date=end_date) for date in dates: try: df_basic = ts.get_stock_basics(date) update_requests = [] for index in df_basic.index: doc = dict(df_basic.loc[index]) doc['code'] = index doc['date'] = date outstanding = doc['outstanding'] if outstanding == 0: continue # 解决流通股本和总股本单位不一致的情况,有些单位是股,目前a股股本规模的最大的工商银行,是3564亿股,最小的德方纳米4274万股 if outstanding > 4000: outstanding *= 1e4 else: outstanding *= 1e8 doc['outstanding'] = outstanding totals = doc['totals'] if totals > 4000: totals *= 1e4 else: totals *= 1e8 doc['totals'] = totals for key in doc: field_type = type(doc[key]) if type(doc[key]) == numpy.float64: doc[key] = float(doc[key]) elif field_type == numpy.int64: doc[key] = int(doc[key]) # format"20180101'turned to format"2018-01-01' timeToMarket = doc['timeToMarket'] doc['timeToMarket'] = datetime.strptime( str(timeToMarket), '%Y%m%d').strftime('%Y-%m-%d') update_requests.append( UpdateOne( {'code': doc['code'], 'date': doc['date']}, {'$set': doc}, upsert=True )) if len(update_requests) > 0: update_result = self.basic.bulk_write(update_requests, ordered=False) print('更新基本数据, 日期:%s, 插入:%4d,更新:%4d' % (date, update_result.upserted_count, update_result.modified_count), flush=True) except: print('获取基本信息出错,日期 %s' % date, flush=True) if __name__ == '__main__': bc = BasicCrawler() bc.crawl_basic('2018-01-01', '2019-07-28')然后再试着跑一下,大功告成 运行结果就不贴了
同样,也要使用建立索引命令,加速代码运行速度。后面可能雷同问题,都可以用这招解决,记住了。
爬取这几个数据集(时间段1年半),大小已经到0.57G了,总耗时粗略估计在1.5-2小时左右。如果要下载更多年份的数据,估计3G收不住,我这边资源有限就一切从简了。
数据的准确性尤其特别重要,如果基础数据错误了,那后面的一切都有可能白费,所以……不能只依靠第三方数据,必须要自己动手整理自己的数据,不断发现问题然后修正到无瑕,最后才可以拿来用。
如果还有问题未能得到解决,搜索887934385交流群,进入后下载资源工具安装包等。最后,感谢观看!