前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python——量化分析介绍(七)

Python——量化分析介绍(七)

作者头像
Ed_Frey
发布2019-08-05 14:37:20
8940
发布2019-08-05 14:37:20
举报
文章被收录于专栏:奔跑的键盘侠奔跑的键盘侠

这是奔跑的键盘侠的第112篇文章

依旧,先贴一下目录:

代码语言:javascript
复制
├── README
├── MyQuant_v1 #量化分析程序目录
   ├── __init__.py
   ├── data #数据处理目录
   │   ├── __init__.py
代码语言:javascript
复制
   │   ├── basic_crawler.py# 爬取股票基础信息存入MongoDB数据库.
代码语言:javascript
复制
   │   └── data_crawler.py  #爬取指数、股票数据
代码语言:javascript
复制
   ├──util # 公用程序
   │   ├── __init__.py
代码语言:javascript
复制
   │   ├── stock_util.py#获取股票交易日期,所有股票代码
代码语言:javascript
复制
   │   └── database.py #链接数据库
代码语言:javascript
复制
   ├── backtest #回测
   │   ├── __init__.py
代码语言:javascript
复制
   │   └── _backtest_ #计划写一下回测走势图
代码语言:javascript
复制
   ├── factor #因子
   │   ├── __init__.py
   │   └──_ factor_.py #不准备开发
   ├── strategy #策略
   │   ├── __init__.py
   │   └── _strategy_ #计划简单写个,主要用于回测
   ├── trading #交易
   │   ├── __init__.py
代码语言:javascript
复制
   │   └── _trading_ #不准备开发
代码语言:javascript
复制
   └── log #日志目录
          ├── __init__.py
          ├── backtest.log #不准备开发
代码语言:javascript
复制
           └── transactions.log#不准备开发

今天依旧没有什么硬干货,延伸一下前面讲过的2个代码的实操。

1

完整的爬取数据

data_crawler.py虽然早就写出来了,但总要完整的爬取一遍才敢投入应用中,果然,随便一爬就有问题,速度贼慢,龟速……

于是需要一个改进方法:使用db.daily.createIndex({code:1,date:1})建立数据集索引,还有前复权、后复权的数据集都建立索引,爬取数据的速度就会快非常多,至于为何,暂时还没得空去研究

先用起来再说

2

basic_crawler.py重写

《Python——量化分析常用命令介绍(五)》中贴的basic_crawler.py代码一跑起来发现很多问题,最关键的一点是数据类型不一致不断抛出异常的问题,至于为啥,先一掠而过……翻新完的代码如下:

代码语言:javascript
复制
#!/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')
代码语言:javascript
复制

然后再试着跑一下,大功告成 运行结果就不贴了

同样,也要使用建立索引命令,加速代码运行速度。后面可能雷同问题,都可以用这招解决,记住了。

爬取这几个数据集(时间段1年半),大小已经到0.57G了,总耗时粗略估计在1.5-2小时左右。如果要下载更多年份的数据,估计3G收不住,我这边资源有限就一切从简了。

数据的准确性尤其特别重要,如果基础数据错误了,那后面的一切都有可能白费,所以……不能只依靠第三方数据,必须要自己动手整理自己的数据,不断发现问题然后修正到无瑕,最后才可以拿来用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 奔跑的键盘侠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档