专栏首页奔跑的键盘侠Python——量化分析介绍(八)

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

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

依旧,先贴一下目录:

├── README
├── MyQuant_v1 #量化分析程序目录
   ├── __init__.py
   ├── data #数据处理目录
   │   ├── __init__.py
   │   ├── basic_crawler.py# 爬取股票基础信息存入MongoDB数据库.
   │   ├── data_crawler.py  #爬取指数、股票数据
   │   └── data_module.py  #从数据集中获取股票数据
   ├──util # 公用程序
   │   ├── __init__.py
   │   ├── stock_util.py#获取股票交易日期、前一交易日日期、股票代码
   │   └── database.py #链接数据库
   ├── backtest #回测
   │   ├── __init__.py
   │   └── _backtest_ #计划写一下回测走势图
   ├── factor #因子
   │   ├── __init__.py
   │   └── pe_factor.py#计算各股票的止盈率,用于后面的股票池策略
   ├── strategy #策略
   │   ├── __init__.py   │  
   └── _strategy_ #计划简单写个,主要用于回测
   ├── trading #交易
   │   ├── __init__.py
   │   └── _trading_ #不准备开发
   └── log #日志目录
          ├── __init__.py
          ├── backtest.log #不准备开发
           └── transactions.log#不准备开发

今天内容不多,也不复杂。首先,之前写的stock_util补充一个获取指定日期前某个交易日期的函数,毕竟后期写到买卖点指标的时候,难免要用到前后两个交易日指标值的计算。接着,data包中再新增一个从数据集中提取数据的模块。

1

更新后的stock_util.py

这个模块,修改完之后就是3个函数了:获取交易日、获取某日期的前一交易日、获取某日所有股票代码。

其中get_trading_date_before(date,days)是新加的,而get_all_codes(date)函数是进行了改进,更简洁明了。
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Time    : 2019-07-13 18:19
# @Author  : Ed Frey
# @File    : stock_util.py
# @Software: PyCharm
from pymongo import ASCENDING,DESCENDING
from util.database import DB_CONN
from datetime import datetime, timedelta

def get_trading_dates(begin_date=None, end_date=None):
    """
    to get the list of trading dates.
    if the begin_date is none, then get the date one year ago'
    :param begin_date: beginning date
    :param end_date: ending date
    :return: a trading dates' list
    """
    now = datetime.now()
    if begin_date is None:
        one_year_ago = now - timedelta(days=365)
        begin_date = one_year_ago.strftime('%Y-%m-%d')

    if end_date is None:
        end_date = now.strftime('%Y-%m-%d')

    daily_cursor = DB_CONN.daily.find(
        {'code': '000001', 'date': {'$gte': begin_date, '$lte': end_date}, 'index': True},
        sort=[('date', ASCENDING)],
        projection={'date': True, '_id': False})

    dates = [x['date'] for x in daily_cursor]

    return dates

def get_trading_date_before(date, days):
    '''
    to get the trading date before,if days==1,means getting the last trading date;if days == 2,means getting the last second trading date
    :param date:
    :param days:
    :return:
    '''
    count = days + 1
    daily_cursor = DB_CONN.daily.find(
        {'code': '000001', 'date': {'$lte': date}, 'index': True},
        sort=[('date', DESCENDING)],
        projection={'date': True, '_id': False},
        limit=count
    )

    dates = [daily['date'] for daily in daily_cursor]

    if len(dates) == count:
        return dates[days]

    return None
def get_all_codes(date=None):
    """
    to get the list of stocks.
    if there's no date, then get the last day's.
    if the last day is not a trading day(can't get any code), then get the next last day's, and then on.
    :param date: date
    :return: a list of stocks' codes
    """
    datetime_obj = datetime.now()
    if date is None:
        date = datetime_obj.strftime('%Y-%m-%d')
    if date not in get_trading_dates(date,date):
        date = get_trading_date_before(date, 1)

    codes = []
    code_cursor = DB_CONN.daily.find(
        {'date': date},
        projection={'code': True, '_id': False})

    codes = [x['code'] for x in code_cursor]

    return codes


if __name__ == "__main__":

    # dates = get_trading_dates(begin_date='2018-01-01', end_date='2019-07-28')
    # print(dates,flush=True)
    code = get_all_codes("2019-07-28")
    print(len(code),code,flush=True)

测试结果如下:

/Users/Ed_Frey/anaconda2/envs/python36/bin/python /Users/Ed_Frey/Desktop/MyQuant_v1/util/stock_util.py

3646 ['000001', '000300', '399001', '399005', '399006', '688016', '688022',………………'600781', '002481', '300788', '300108', '603778', '002660', '000918', '300431']

Process finished with exit code 0

中间省略了几千个股票代码。

2

data_module.py

这个模块是为后面做铺垫的,接下来在数据处理分析时,会时不时的从数据集中提取所需股票信息,而且不止一次两次的重复提取。要知道,从数据库中读取数据,也就是所谓的IO,定会严重影响到代码执行速度,毕竟要从3000多只股票中提取数据,就像爬取数据时,爬一圈要个把小时,加个索引可能二十分钟就能搞定。

于是,我们把数据提取做成一个专用模块,提取一次,存入变量放到内存中,后续重复使用,直接从内存读变量值即可。

#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Time    : 2019-08-04 09:51
# @Author  : Ed Frey
# @File    : data_module.py
# @Software: PyCharm
from util.database import DB_CONN
from datetime import datetime
from pandas import DataFrame

class DataModule:

    def __init__(self):
        pass
    def get_all_stock_k_data_at_date(self, autype=None, date=None):

        if date is None:
            date = datetime.now().strftime('%Y-%m-%d')

        if autype is None:
            collection = "daily"
        elif autype == 'qfq':
            collection = "qfq_daily"
        elif autype == 'hfq':
            collection = "hfq_daily"
        else:
            return []

        daily_cursor = DB_CONN[collection].find(
            {'date': date, 'index': False},
            projection={'_id': False, 'index': False})

        df_daily = DataFrame([daily for daily in daily_cursor])

        if df_daily.index.size > 0:
            df_daily.set_index(['code'], 1, inplace=True)

        return df_daily


    def get_stocks_at_date(self, codes=None, autype=None, date=None):

        if codes is None:
            return self.get_all_stock_k_data_at_date(
                autype=autype, date=date)

        if date is None:
            date = datetime.now().strftime('%Y-%m-%d')

        collection = 'daily' if autype is None or autype == '' else 'daily_' + autype

        daily_cursor = DB_CONN[collection].find(
            {'code': {'$in': codes}, 'date': date, 'index': False},
            projection={'_id': False, 'index': False})

        df_daily = DataFrame([daily for daily in daily_cursor])

        if df_daily.index.size > 0:
            df_daily.set_index(['code'], 1, inplace=True)

        return df_daily
if __name__ == '__main__':
    dm = DataModule()
    df_daily = dm.get_all_stock_k_data_at_date(date='2019-07-25')
    print(df_daily, flush=True)
运行结果这个样子:

本想这个周末给草草了事得了,结果发现没那么简单

为了回测,赶紧写好买卖点指标就差不多了。后来觉得指标太简单了会比较low,于是计划写个爬虫爬取财报、计算个市盈率啥的,等这些数据好不容易做好,发现买卖指标又来不及写了,更别提回测了。总之,磨死个人……

本文分享自微信公众号 - 奔跑的键盘侠(runningkeyboardhero),作者:我是奔跑的键盘侠

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python——量化分析常用命令介绍(五)

    Last login: Sun Jul 14 08:52:32 on ttys000

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

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

    Ed_Frey
  • Python——量化分析介绍(九)

    从第三方获取到的数据,其实有挺多内容要自己填充完善的,比如股票停牌日的信息,要知道停牌日的个股信息是空的,如刚好持仓股遇到停牌,是无法交易的,计算持仓市值时,停...

    Ed_Frey
  • Python——量化分析常用命令介绍(五)

    Last login: Sun Jul 14 08:52:32 on ttys000

    Ed_Frey
  • php获取本年、本月、本周时间戳和日期格式的实例代码

    cal_days_in_month(par1,par2,par3);par1 :用来计算的某种历法,PHP Calendar 常量 par2 :参数par1选中...

    砸漏
  • 毫秒级时间戳转换封装

    const dateFormat = (time) => { var date = new Date() date.setTime(time) var t...

    余生
  • 快速生成日期维度数据

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1148526
  • 批处理之实战一--找到指定文件的指定关键词,并将结果保存到指定位置的TXT中!

    昨天看到有个小伙伴在微信后台留言,说想要做一个批处理文件,搜索软件运行产生的log日志,搜索其中的关键词,并将结果打印出来,这个真的是很有实用意义啊,一方面减小...

    浩Coding
  • shell语言关于date的一些用法

    今天没干什么正事儿,都开了会了,写点儿关于shell脚本语言的知识吧,这个也是前两天完成一个业务方的需求的时候使用到的方法,分享出来,希望对大家有点用吧...

    AsiaYe
  • 【爬虫军火库】生成指定日期间的日期列表

    今天没能空下来时间写太多,所以只简单记录一个很具体的需求: 指定了起止日期,如何生成一个日期列表。 这个需求是我之前在抓取一个环保的历史数据时遇到的: ? 如...

    不二小段

扫码关注云+社区

领取腾讯云代金券