Python——量化分析介绍

本文介绍了Python量化分析项目的目录结构,包括数据处理、回测、因子和策略等模块。重点讨论了数据爬取的优化,通过在MongoDB数据库中创建索引来提升爬取速度。此外,还提到了代码重写过程中遇到的数据类型一致性问题,并分享了如何解决问题的经验。强调了数据准确性的重要性,建议手动整理和验证数据。最后提供了交流群号以便进一步讨论和资源获取。
摘要由CSDN通过智能技术生成

贴一下目录:

├── 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交流群,进入后下载资源工具安装包等。最后,感谢观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值