请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3364677 新帖:0

双十一我们到底买什么??物流?电商?新零售?

专门套利发表于:5 月 10 日 07:48回复(1)

看了不少关于双十一概念股的新闻,心血来潮做了点小研究,感兴趣的朋友可以克隆研究看一下,里面有些函数可能能有点用,话不多说,详细内容我写到研究里了~

#导入需要的包

import jqdata
from jqdata import *
from jqdata import jy
import pandas as pd
import matplotlib.pyplot as plt

双十一到底应该买什么??¶

最近又看到了铺天盖地的双十一宣传,今年是阿里的第十个双十一,不知道会不会有什么更大的举动。
2016年天猫双11全天交易额是1207亿元,今年估计在1500亿以上。
10月26日,苏宁易购总裁侯恩龙在双十一发布会现场承诺,11月1日至11日,苏宁自营产品将实现运费全免。
而在此之前,多家物流企业发布通知,称将上调部分地区的快件费用。
看到这么多新闻,跟中国股市到底有什么关系呢?我们还是来分析一下历年双十一期间,到底股市里出现过什么异动。

选取研究的股票¶

1、选了三个被股评新闻推荐的双十一概念电商类股票:苏宁易购、南极电商、焦点科技
2、选了目前上市的知名物流公司:顺丰控股、圆通速递、申通快递、韵达股份
3、选取新零售概念板块;

#选了三个被股评新闻推荐的双十一概念电商类股票:苏宁易购、南极电商、焦点科技
dianshang=['002024.XSHE','002127.XSHE','002315.XSHE']

#选了目前上市的知名物流公司:顺丰控股、圆通速递、申通快递、韵达股份
wuliu=['002352.XSHE','600233.XSHG','002468.XSHE','002120.XSHE']

#选取新零售概念板块   
lingshou = get_concept_stocks('GN227')

#合并所选股票
stocks=dianshang+wuliu+lingshou

#取消下面的注释可显示所选股票名称
#for stock in stocks:
#    print (get_security_info(stock).display_name)

下面几个函数功能如注释介绍,大家也可以拿去使用

1、获取某日前或者后第n个交易日的方法

2、获取任意股票列表在输入日期前或者后几天的涨跌幅(依赖1)

3、画柱状图

# 1、获取某日前或者后第n个交易日的方法  get_before_after_trade_days(date, count, is_before)
# 在此方法的基础上可以得到指定日期前或者后n个交易日列表(即中间变量_before_days,和_after_days)


# 获取某日前或者第n个交易日的方法
from jqdata import *
def get_before_after_trade_days(date, count, is_before):
    # print("输入的节假日日期为{0}".format(date))
    # 得到该节日前n天的交易日
    _before_days = get_trade_days(end_date=date, count=count)
    # print(_before_days)
    before_days = _before_days[0]
    # print("节假日前第{0}个交易日为{1}".format(count, before_days))
    # 得到该节日后n天的交易日
    _end_date = datetime.datetime.strptime(str(date),'%Y-%m-%d')
    # 获取该天count+30天后日期作为end_date
    last_date = _end_date + datetime.timedelta(days = (count + 30))
    _after_days = get_trade_days(start_date=_end_date, end_date=last_date).tolist()
    # print(_after_days)
    after_days = _after_days[(count - 1)]
    # print("节假日后第{0}个交易日为{1}".format(count, after_days))
    if is_before == True:
        trade_day = before_days
    else:
        trade_day = after_days
    return trade_day
# 2、获取任意股票列表在输入日期前或者后几天的涨跌幅 get_security_list_pct_sum(date, count, security_list, is_before)

# (1)获取前或者后几天的交易日;
# (2)获取指定交易日内的涨跌幅;
# (3)整理数据并排序;
# (4)返回结果。

def get_security_list_pct_sum(date, count, security_list, is_before):
    # 获取前或者后count天的交易日
    trade_day = get_before_after_trade_days(date=date, count=count, is_before=is_before)
    # print("输入的日期{0}前或后{1}天的日期为{2}".format(date, count, trade_day))
    # 根据前或者后获取指数数据
    if is_before == True:
        start_date = trade_day
        end_date = date
    else:
        start_date = date
        end_date = trade_day
    # 循环获取每个涨幅都比较大的count_num只股票在指定时间段中的涨跌幅
    # 此处可以一次取多个股票的,但是处理起来比较麻烦,所以就一个一个取,因为量不是很大,所以影响不大
    stocks_pct_sum = []
    stocks_name = []
    for stock in security_list:
        # 获取指定股票在节假日后几天的涨跌幅,并按照时间排序
        _stock_pct = get_money_flow([stock], start_date=start_date, end_date=end_date, fields=["date", "sec_code", "change_pct"]).sort_values(by='date')
        # print(_stock_pct)
        # 每天的涨幅list
        _stock_pct = _stock_pct['change_pct'].tolist()
        stock_pct = sum(_stock_pct)
        # print(stock_pct)
        stocks_pct_sum.append(stock_pct)
        stocks_name.append(get_security_info(stock).display_name)
        # print('@'*50)
        
    _stocks_pct_sum = {date:stocks_pct_sum}
    stocks_pct_sum = pd.DataFrame(_stocks_pct_sum, index=stocks_name).sort_values(by=str(date), ascending=False)
    
    # print(stocks_pct_sum)
    return stocks_pct_sum
# 3、将数据绘制到一张柱状图上

def plot_total_years_pct_sum(data, title):
    data.plot(kind='bar', figsize=(20, 12), title=title)
    # 绘制0轴
    plt.axhline(0, c='k', linestyle="--")

刚准备开始研究这些股票的往年数据,就发现了一些问题: 顺丰控股上市时间是2017年2月24日
圆通速递上市时间是2016年10月20日
申通快递上市时间是2016年12月30日
韵达股份上市时间是2017年1月18日
因此,对我们来说很遗憾,跟双十一关联最紧密的这几家A股上市公司,只有2017年的双十一数据是可以作为参考的; 那么,我们先来看一下2017年11月11日前后,这几只股票的表现到底如何吧

#参数设置为前五天,物流股票,日期是2017年11月11日
count = 5
security_list = wuliu
date = '2017-11-11'
is_before = True

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2017-11-11前5天的涨跌幅:
--------------------------------------------------
      2017-11-11
顺丰控股       -0.62
圆通速递       -1.37
申通快递       -4.03
韵达股份       -5.77
##参数设置为后五天,物流股票,日期是2017年11月11日
count = 5
security_list = wuliu
date = '2017-11-11'
is_before = False

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2017-11-11后5天的涨跌幅:
--------------------------------------------------
      2017-11-11
韵达股份       -4.37
申通快递       -6.72
顺丰控股      -13.22
圆通速递      -15.35

嗯。。。从2017年双十一的表现来看,似乎市场并没有太多的热情。。。

对了,除了双十一以外,每年6.18也是电商的一个促销节日,也许6.18活动会有其他不一样的表现?我们再来看看

#参数设置为前五天,物流股票,日期是2017年6月18日
count = 5
security_list = wuliu
date = '2017-6-18'
is_before = True

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2017-6-18前5天的涨跌幅:
--------------------------------------------------
      2017-6-18
韵达股份       5.50
申通快递       2.83
圆通速递       1.82
顺丰控股      -4.95
##参数设置为后五天,物流股票,日期是2017年6月18日
count = 5
security_list = wuliu
date = '2017-6-18'
is_before = False

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2017-6-18后5天的涨跌幅:
--------------------------------------------------
      2017-6-18
韵达股份       0.19
申通快递      -0.10
圆通速递      -0.54
顺丰控股      -1.49
#参数设置为前五天,物流股票,日期是2018年6月18日
count = 5
security_list = wuliu
date = '2018-6-18'
is_before = True

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2018-6-18前5天的涨跌幅:
--------------------------------------------------
      2018-6-18
申通快递      -1.30
顺丰控股      -3.57
韵达股份      -4.08
圆通速递      -8.97
##参数设置为后五天,物流股票,日期是2018年6月18日
count = 5
security_list = wuliu
date = '2018-6-18'
is_before = False

print("-"*50)
print("获取股票列表在%s%d天的涨跌幅:"%(date,count))
print('-'*50)
    
stocks_pct_sum_before = get_security_list_pct_sum(date, count, security_list, is_before)

print (stocks_pct_sum_before)

## 将上面历年数据绘制到一张图上  

title="股票列表在%s%d天的涨跌幅:"%(date,count)
plot_total_years_pct_sum(stocks_pct_sum_before[date], title)
--------------------------------------------------
获取股票列表在2018-6-18后5天的涨跌幅:
--------------------------------------------------
      2018-6-18
顺丰控股      -1.98
韵达股份      -4.39
圆通速递     -14.04
申通快递     -30.02

看完这些数据,我们应该可以得出一个结论:
无论是双十一还是6.18这些日子基本对快递公司的股价没有产生什么独特的影响!!!

同样的方式,我们再测试了电商股票、新零售板块,同时,也尝试了多个日期的参数,发现得到的结论基本相同,
就是确实都没有什么明显的影响。。。。

大家如果有兴趣的话,也可以自己调调参数试试

总之,我以后是再也不轻信财经新闻或者某些分析师的概念信息了,毛主席说了,只有实践才是检验真理的唯一标准

下面再放个大招,我们看下历年全市场在双十一这一天附近的表现

比较神奇的发现在双十一附近涨幅较大的股票,是跟我们理解完全不同的粤泰股份,应该是个巧合了

# 导入所需的python库

import jqdata
from jqdata import *
from jqdata import jy
import pandas as pd
import matplotlib.pyplot as plt

mpl.rcParams['axes.unicode_minus']=False # 处理绘图时的负号问题

# 将数据绘制到一张柱状图上
def plot_total_years_pct_sum(data, title):
    data.plot(kind='bar', figsize=(20, 12), title=title)
    # 绘制0轴
    plt.axhline(0, c='k', linestyle="--")
    
## 计算获取至今历年的日期
# (1)输入给定日期及年份;
# (2)返回2010年至给定年份的历年日期。

def get_years_date(date, year):
    date = date[4:]
    year = [year for year in range(2010, (int(year) + 1), 1)]
    dates = [str(year) + date for year in year]
    return dates

## 获取某日前或者后第n个交易日的方法
# 在此方法的基础上可以得到指定日期前或者后n个交易日列表(即中间变量_before_days,和_after_days)

# 获取某日前或者第n个交易日的方法
def get_before_after_trade_days(date, count, is_before):
    # print("输入的节假日日期为{0}".format(date))
    # 得到该节日前n天的交易日
    _before_days = get_trade_days(end_date=date, count=count)
    # print(_before_days)
    before_days = _before_days[0]
    # print("节假日前第{0}个交易日为{1}".format(count, before_days))
    # 得到该节日后n天的交易日
    _end_date = datetime.datetime.strptime(str(date),'%Y-%m-%d')
    # 获取该天count+30天后日期作为end_date
    last_date = _end_date + datetime.timedelta(days = (count + 30))
    _after_days = get_trade_days(start_date=_end_date, end_date=last_date).tolist()
    # print(_after_days)
    after_days = _after_days[(count - 1)]
    # print("节假日后第{0}个交易日为{1}".format(count, after_days))
    if is_before == True:
        trade_day = before_days
    else:
        trade_day = after_days
    return trade_day

# 获取指数在指定日期历年节假日前或后几天的涨跌幅
def get_years_pct_sum(festival, year, index_list, count, is_before, is_festival):
    """
    # is_festival和festival一起使用,是不是节假日,是的话festival输入节日;不是的话,输入日期,可以得到非节假日的数据
    """
    if is_festival == True:
        dates = get_festival_date(festival, year)
    else:
        dates = get_years_date(festival, year)
    # print("2010年至{0}年,历年的{1}的公历日期为:{2}".format(year, festival, dates))
    years_pct_sum0 = []
    for date in dates:
        # print(date)
        index_pct_sum = get_index_pct(index_list, count, date, is_before)
        years_pct_sum0.append(index_pct_sum)
    indexs_years_pct_sum = pd.concat(years_pct_sum0, axis=1)
    return indexs_years_pct_sum

## 获取指数前或者后n天的涨跌幅
# 获取多个指数在指定天前或者后几的涨跌幅
def get_index_pct(index_list, count, date, is_before):
    """
    index_list:指数列表
    count:取输入日期前或者后几天的指数数据
    date:日期
    is_before:取指定日期前还是后count天的数据
    """
    
    # 根据指数的代码,获得指数的名称
    index_list_name = [get_security_info(security).display_name for security in index_list]
    # print(index_list_name)
    
    # 获取前或者后count天的交易日
    trade_day = get_before_after_trade_days(date=date, count=count, is_before=is_before)
    # print("输入的日期{0}前或后{1}天的日期为{2}".format(date, count, trade_day))
    # 根据前或者后获取指数数据
    if is_before == True:
        start_date = trade_day
        end_date = date
    else:
        start_date = date
        end_date = trade_day
    # print("start和end日期分别为:{0}, {1}".format(start_date, end_date))
    
    # 获取数据
    index_data = get_price(index_list, start_date=start_date, end_date=end_date, frequency='daily', 
                         fields=['close'])['close']
    # print(index_data)
    # print('-'*50)
    
    # 计算pct并求和
    _index_pct_sum = index_data.pct_change().fillna(0).sum()*100
    _index_pct_sum = pd.DataFrame({date:list(_index_pct_sum)}, index=index_list_name)
    index_pct_sum = _index_pct_sum.fillna(0)
    
    return index_pct_sum


# 获取不同级申万行业名称及代码(一级:'sw_l1')
def get_sw_index_name(level):
    # 获取申万一级行业指数
    sw_index_list = get_industries(name='sw_l1') 
    sw_index = list(sw_index_list.index)
    sw_name = list(sw_index_list.name)
    return sw_index, sw_name

## 获取指定行业在指定时间段内涨跌幅的和
def get_sw_index(sw_index, start_date, end_date):
    # print("输入的行业代码为{0}".format(sw_index))
    index_list = ['ClosePrice']
    jydf = jy.run_query(query(jy.SecuMain).filter(jy.SecuMain.SecuCode==str(sw_index)))
    link=jydf[jydf.SecuCode==str(sw_index)]
    rows=jydf[jydf.SecuCode==str(sw_index)].index.tolist()
    result=link['InnerCode'][rows]
    close_price = jy.run_query(query(jy.QT_SYWGIndexQuote).filter(jy.QT_SYWGIndexQuote.InnerCode == str(result[0]),
                                                        jy.QT_SYWGIndexQuote.TradingDay >= start_date,
                                                        jy.QT_SYWGIndexQuote.TradingDay <= end_date
                                                        ))
    close_price.index = close_price['TradingDay']
    close_price = close_price[index_list]
    close_price['pct'] = close_price['ClosePrice'].pct_change()
    sw_index_pct_sum = close_price['pct'].fillna(0).sum()*100
    return sw_index_pct_sum

## 获取行业在指定日期历年节假日前或后几天的涨跌幅
def get_sw_years_pct_sum(festival, year, level, count, is_before, is_festival):
    if is_festival == True:
        dates = get_festival_date(festival, year)
    else:
        dates = get_years_date(festival, year)
    # print("2010年至{0}年,历年的{1}的公历日期为:{2}".format(year, festival, dates))
    sw_years_pct_sum0 = []
    for date in dates:
        # print(date)
        index_pct_sum = get_sw_indexs(level, count, date, is_before)
        sw_years_pct_sum0.append(index_pct_sum)
    sw_years_pct_sum = pd.concat(sw_years_pct_sum0, axis=1)
    return sw_years_pct_sum


# 获取多个行业在指定时间段内涨跌幅的和
def get_sw_indexs(level, count, date, is_before):
    """
    index_list:指数列表
    count:取输入日期前或者后几天的指数数据
    date:日期
    is_before:取指定日期前还是后count天的数据
    """
    # 获取前或者后count天的交易日
    trade_day = get_before_after_trade_days(date=date, count=count, is_before=is_before)
    # print("输入的日期{0}前或后{1}天的日期为{2}".format(date, count, trade_day))
    # 根据前或者后获取指数数据
    if is_before == True:
        start_date = trade_day
        end_date = date
    else:
        start_date = date
        end_date = trade_day
    # print("start和end日期分别为:{0}, {1}".format(start_date, end_date))
    # 获取指定级别的行业代码及名称
    sw_indexs, sw_names = get_sw_index_name(level)
    indexs_pct_sum = []
    for sw_index in sw_indexs:
        index_pct_sum = get_sw_index(sw_index, start_date, end_date)
        indexs_pct_sum.append(index_pct_sum)
    # print(sw_indexs)
    # print(indexs_pct_sum)
    # 直接使用字典添加元素有可能生成乱序,数据对应不上,因此使用列表组合后的字典
    _sw_indexs = {'sw_indexs':sw_indexs, date:indexs_pct_sum}
    _sw_indexs = pd.DataFrame(_sw_indexs, index=sw_names, columns=['sw_indexs', date])
    # 查看名称和行业代码是否对应
    # print(_sw_indexs)
    # 删除行业代码
    sw_indexs_pct_sum = _sw_indexs.drop('sw_indexs', 1)
    # print(_sw_indexs)
    return sw_indexs_pct_sum

# 对历年的数据进行统计及绘图(指数)
# years_pct_sum来自get_years_pct_sum(指数)及get_sw_years_pct_sum(申万行业)
# years_pct_sum可以为indexs_years_pct_sum或者sw_years_pct_sum(申万行业)

def pct_sum_plot_statistics(sort_count, years_pct_sum, is_before):
    # 选取历年涨幅前几的行业
    industry_sort_count = []
    years = years_pct_sum.columns
    # 遍历每年的
    for year in years:
        year_pct_sum_sort = years_pct_sum[year].sort_values(ascending=False)
        _industry_sort = list(year_pct_sum_sort.index[:sort_count])
        # print(_industry_sort)
        industry_sort_count.append(_industry_sort)
        # print(industry_sort_count)
        # 为了将所有的图分开
#         plt.figure()
#         year_pct_sum_sort.plot(kind='bar', figsize=(12, 8), title=year)
#         # 绘制横轴
#         plt.axhline(0, c='k', linestyle="--")
    # 解包
    industry_sort_count = [s for b in industry_sort_count for s in b]
    industry_sort_count = pd.Series(industry_sort_count).value_counts()
    industry = list(industry_sort_count.index[:sort_count])
    industry_count = list(industry_sort_count.values[:sort_count])
    industry_ratio = [round(float(count*100.0/len(years)), 2) for count in industry_count]
    # 处理下打印结果
    before_after = " "
    if is_before == True:
        before_after = "前"
    else:
        before_after = "后"
    print("历年此日{0}几天涨幅较大的指数或行业为:{1},他们出现次数在总体年份的百分比例分别为:{2}".format(before_after,
                                                                industry, industry_ratio))
    
## 获取历年节假日前涨幅比较大的股票,看看有没有什么共性


# 获取节假日前n天涨幅较大的m个股票统计数据
def get_high_pct_statistics(dates, count, stock_num, security_list, count_num, is_before):
    """
    dates:获取指定节日历年对应的日期
    count:指定节日前或者后几天
    stock_num:从涨幅较大的多少个股票中选
    security_list:参与统计的股票列表
    count_num:获取统计股票的前几个
    """
    stocks_list = []
    for date in dates:
        # 获取节假日前n天涨幅较大的m个股票
        high_pct_stocks, high_change_pct = get_high_pct_stocks(date, count, stock_num, security_list, is_before)
        stocks_list.append(high_pct_stocks)
    # 得到的数据格式为[[],[]],需要解包
    stocks_list = [s for b in stocks_list for s in b]
    # print(stocks_list)
    # 统计下股票个数,取前几个
    stocks_statistics = pd.Series(stocks_list).value_counts()[:count_num]
    # print(stocks_statistics)
    # 统计数量前几的股票
    statistics_stocks = list(stocks_statistics.index) # 股票代码
    statistics_stocks_name = [get_security_info(stock).display_name for stock in statistics_stocks] # 股票名称
    # print(statistics_stocks)
    # 统计数量前几股票的出现次数
    _statistics_values = list(stocks_statistics.values)
    # 将次数转换为百分比
    statistics_values = [round(float(num*100.0/len(dates)), 2) for num in _statistics_values]
    # print(statistics_values)
    # 处理下打印结果
    # print(is_before)
    before_after = " "
    if is_before == True:
        before_after = "前"
    else:
        before_after = "后"
    print("历年此日{0}{1}天涨幅较大的股票为:{2},他们出现次数在总体年份的百分比例分别为:{3}".format(before_after, count, 
                                                                 statistics_stocks_name, statistics_values))
    return statistics_stocks, statistics_values

## 考察前节假日涨幅都比较大股票在节假日后几天的表现

# (1)输入节假日,得到历年涨幅大的股票;
# (2)得到涨幅大的股票在后几天的涨幅;
# (3)对比当时市场(hs300)的涨跌幅(get_money_flow获取不到指数据的涨跌幅,先不做)

##  考察前节假日涨幅都比较大股票在节假日后几天的表现
def get_last_days_result(festival, count, stock_num, security_list, count_num, after_num, end_year, is_festival,is_before):
    """
    festival:节日
    count:指定节日前几天
    stock_num:涨幅较大的多少个股票
    security_list:参与统计的股票列表
    count_num:获取统计股票的前几个
    after_num:获取节假日后几天内的涨跌幅
    end_year:结束年份,例如2017
    """
    #获取节假日后几天的
    is_before = is_before
    # print('='*50)
    results = {} # 获取最后的结果
    # 获取指定节日历年对应的日期
    if is_festival == True:
        dates = get_festival_date(festival, end_year)
    else:
        dates = get_years_date(festival, end_year)
    # print(dates)
    # 得到涨幅比较高的前几只股票
    stocks, values = get_high_pct_statistics(dates, count, stock_num, security_list, count_num, is_before)
#     print("在历年该节假日涨幅都比较大且出现次数比较多的几只股票为:\n{0}".format(stocks))
#     print('-'*50)
#     print("历年中出现百分百比分别为:\n{0}".format(values))
#     print('-'*50)
    for date in dates:
        # 获取指定年的节假日作为开始时间
        _start_date = datetime.datetime.strptime(str(date),'%Y-%m-%d')
        # 获取该天count+30天后日期作为end_date
        _last_date = _start_date + datetime.timedelta(days = (count+30))
        # 获取该指定年节假日后after_num天的交易日
        _after_days = get_trade_days(start_date=_start_date, end_date=_last_date).tolist()[:after_num]
        # print(_after_days)
        _end_date = _after_days[-1]
        # print(_end_date)
        # print('*'*50)
        # 循环获取每个涨幅都比较大的count_num只股票在指定时间段中的涨跌幅
        # 此处可以一次取多个股票的,但是处理起来比较麻烦,所以就一个一个取,因为量不是很大,所以影响不大
        stock_pct_dict = {}
        for stock in stocks:
            # 获取指定股票在节假日后几天的涨跌幅,并按照时间排序
            _stock_pct = get_money_flow([stock], start_date=date, end_date=_end_date, fields=["date", "sec_code", "change_pct"]).sort_values(by='date')
            # print(_stock_pct)
            # 每天的涨幅list
            _stock_pct = _stock_pct['change_pct'].tolist()
            stock_pct = sum(_stock_pct)
            # print(stock_pct)
            stock_pct_dict[stock] = stock_pct
            # print('@'*50)
        results[date] = stock_pct_dict
    results = pd.DataFrame(results)
    # print(results)
    # print('-'*50)
    return stocks, values, results

## 获取输入的股票列表在指定日期的前或者后几天的涨跌幅和
def get_high_pct_stocks(date, count, stock_num, security_list, is_before):
    """
    date:节假日
    count:前或者后几天
    stock_num:涨幅较大的前多少个股票
    security_list:参与统计的股票列表
    is_before:获取节假日前还是后
    """
    # 获取前或者后count天的交易日
    trade_day = get_before_after_trade_days(date=date, count=count, is_before=is_before)
    # print("输入的日期{0}{1}{2}天的日期为{3}".format(date, is_before, count, trade_day))
    if is_before == True:
        start_date = trade_day
        end_date = date
    else:
        start_date = date
        end_date = trade_day
    # print("start和end日期分别为:{0}, {1}".format(start_date, end_date))
    
    # 得到日前或后n天对应每天涨幅高的股票,重新创建索引并排序
    pct_change = get_money_flow(security_list, start_date = start_date, end_date=end_date, 
                                 fields=['date', 'change_pct', 'sec_code'])
    # print(pct_change)
    stocks_pct_sum = {}
    for security in security_list:
        stocks_pct_sum[security] = pct_change[pct_change['sec_code'] == security].sum()
    _stocks_pct_sum = pd.DataFrame(stocks_pct_sum)
    _stocks_pct_sum = _stocks_pct_sum.T.fillna(0).sort_values(by='change_pct', ascending=False)
    # 如果输入股票列表长度小于所要获取的前几排序,会报错,处理下
    if stock_num > len(security_list):
        stock_num = len(security_list)
    stocks_pct_sum = _stocks_pct_sum[:stock_num]
    high_pct_stocks = list(stocks_pct_sum.index)
    high_change_pct = list(stocks_pct_sum['change_pct'])
    return high_pct_stocks, high_change_pct

## 以今天为界限,获取历史中今天的前后几天数据

def get_history_today_tomorrow(date, count, sort_count, index_list):
    """
    date:今天的日期
    count:前或者后几天
    sort_count:取指数的前几名(3)
    """
    # 公用参数
    year = date[:4]
    dates = get_years_date(date, year)
    is_festival = False
    level = 'sw_l1'
    stock_num = 100
    count_num = 10
    security_list = list(get_all_securities(date=date).index) 
    
    ## 指定日期前
    is_before = True
    
    ## 统计该日期前或后几天的指数、行业及个股
    # 根据指数的代码,获得指数的名称
    index_list_name = [get_security_info(security).display_name for security in index_list]
    # 统计该日期前或后几天的指数(前)
    indexs_years_pct_sum = get_years_pct_sum(date, year, index_list, count, 
                                             is_before, is_festival)
    # 历年指数数据展示在同一个图上(前)
    title_index1 = '该日期前几天各指数的涨跌幅,(%)'
    plot_total_years_pct_sum(indexs_years_pct_sum.T, title_index1)
    # 历年指数数据统计(前)
    pct_sum_plot_statistics(sort_count, indexs_years_pct_sum, is_before)

    # 统计该日期前或后几天的行业(前)
    sw_years_pct_sum = get_sw_years_pct_sum(date, year, level, count, is_before, is_festival)
    # 历年行业数据展示在同一个图上(前)
    title_sw1 = '该日期前几天各行业的涨跌幅(%)'
    plot_total_years_pct_sum(sw_years_pct_sum.T, title_sw1)
    # 历年行业数据统计(前)
    pct_sum_plot_statistics(sort_count, sw_years_pct_sum, is_before)

    # 历年节假日前涨幅比较大的股票
    stocks_before, statistics_values = get_high_pct_statistics(dates, count, stock_num, security_list, count_num, is_before) 
    print('-'*50)


    ## 指定日期前后
    is_before = False
    
    ## 统计该日期前或后几天的指数、行业及个股
    # 统计该日期前或后几天的指数(后)
    after_indexs_years_pct_sum = get_years_pct_sum(date, year, index_list, 
                                               count, is_before, is_festival)
    # 历年指数数据展示在同一个图上(后)
    title_index2 = '该日期后几天各指数的涨跌幅'
    plot_total_years_pct_sum(after_indexs_years_pct_sum.T, title_index2)
    # 历年指数数据统计(后)
    pct_sum_plot_statistics(sort_count, after_indexs_years_pct_sum, is_before)
    
    # 统计该日期前或后几天的行业(后)
    after_sw_years_pct_sum = get_sw_years_pct_sum(date, year, level, count, is_before, is_festival)
    # 历年行业数据展示在同一个图上(后)
    title_sw2 = '该日期后几天各行业的涨跌幅(%)'
    plot_total_years_pct_sum(after_sw_years_pct_sum.T, title_sw2)
    # 历年行业数据展示在同一个图上(后)
    pct_sum_plot_statistics(sort_count, after_sw_years_pct_sum, is_before)

     # 历年节假日前涨幅比较大的股票
    stocks, values, stock_results = get_last_days_result(date, count, stock_num, security_list, count_num, 
                                                   count, year, is_festival,True)
    # 将历年数据绘制到一张图上  
    title_stocks = '涨幅比较高且历年出现次数多的股票在该节假日前的涨幅(%)'
    plot_total_years_pct_sum(stock_results.T, title_stocks)
    
    # 历年节假日后涨幅比较大的股票
    stocks, values, stock_results = get_last_days_result(date, count, stock_num, security_list, count_num, 
                                                   count, year, is_festival,False)
    # 将历年数据绘制到一张图上  
    title_stocks = '涨幅比较高且历年出现次数多的股票在该节假日后的涨幅(%)'
    plot_total_years_pct_sum(stock_results.T, title_stocks)
    
    # 返回指定日期前或后涨幅大的股票
    stock_after = stock_results.T
    return stocks_before, stock_after

## 测试下双十一
if __name__ == '__main__':
    print('='*50)
    date = '2017-11-11'
    count = 5
    sort_count = 3
    index_list = ['000001.XSHG', '399001.XSHE', '399005.XSHE', '399006.XSHE', '399985.XSHE', '000016.XSHG', 
                  '000300.XSHG', '000905.XSHG', '000852.XSHG'] 
    print("以{0}为界限,获取历史中今天的前后几天数据:".format(date))
    stocks_before, stock_after = get_history_today_tomorrow(date, count, sort_count, index_list)
==================================================
以2017-11-11为界限,获取历史中今天的前后几天数据:
历年此日前几天涨幅较大的指数或行业为:['创业板指', '中证1000指数', '中证全指指数'],他们出现次数在总体年份的百分比例分别为:[50.0, 50.0, 37.5]
历年此日前几天涨幅较大的指数或行业为:['食品饮料I', '有色金属I', '银行I'],他们出现次数在总体年份的百分比例分别为:[37.5, 25.0, 25.0]
历年此日前5天涨幅较大的股票为:['联络互动', '南京化纤', '天通股份', '亿帆医药', '银之杰', '中光防雷', '广聚能源', '信维通信', '中富通', '方正证券'],他们出现次数在总体年份的百分比例分别为:[37.5, 37.5, 37.5, 37.5, 37.5, 25.0, 25.0, 25.0, 25.0, 25.0]
--------------------------------------------------
历年此日后几天涨幅较大的指数或行业为:['创业板指', '中证500', '中证1000指数'],他们出现次数在总体年份的百分比例分别为:[75.0, 62.5, 62.5]
历年此日后几天涨幅较大的指数或行业为:['银行I', '食品饮料I', '交通运输I'],他们出现次数在总体年份的百分比例分别为:[25.0, 25.0, 25.0]
历年此日前5天涨幅较大的股票为:['联络互动', '南京化纤', '天通股份', '亿帆医药', '银之杰', '中光防雷', '广聚能源', '信维通信', '中富通', '方正证券'],他们出现次数在总体年份的百分比例分别为:[37.5, 37.5, 37.5, 37.5, 37.5, 25.0, 25.0, 25.0, 25.0, 25.0]
历年此日后5天涨幅较大的股票为:['粤泰股份', '福建金森', '瑞丰高材', '隆华科技', '红宇新材', '汉商集团', '农发种业', '宇顺电子', '百川股份', '京运通'],他们出现次数在总体年份的百分比例分别为:[50.0, 37.5, 37.5, 37.5, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0]

我们又分析了物流电商行业或者概念股票¶

观察到了一个现象,物流及消费行业或概念在双十一前可能会涨,过了双十一大概率会下跌,所以,要是轻信了评论的朋友们,可以考虑卖了~¶

# 获取行业成分股及概念股
"""
概念数据
# 801178	物流II
# 851781	物流III
# 801170 交通运输I
# HY434	航空货运与物流
# HY005	日常消费
# HY446	消费电子产品
# HY450	家用器具与特殊消费品
# HY464	消费品经销商
行业数据
# GN720	物流电商平台
# GN941	电商物流
# GN132	智能物流
# GN703	物流
# GN909	消费金融
"""

# get_industry_stocks
industry_codes = ['801170', '801178', '851781', 'HY434', 'HY005', 'HY446', 'HY450', 'HY464']
# get_concept_stocks
concept_stocks = ['GN720', 'GN941', 'GN132', 'GN703', 'GN909'] 
## 获取任意股票列表在输入日期前或者后几天的涨跌幅
# (1)获取前或者后几天的交易日;
# (2)获取指定交易日内的涨跌幅;
# (3)整理数据并排序;
# (4)返回结果。

def get_security_list_pct_sum(date, count, security_list, is_before):
    # 获取前或者后count天的交易日
    trade_day = get_before_after_trade_days(date=date, count=count, is_before=is_before)
    # print("输入的日期{0}前或后{1}天的日期为{2}".format(date, count, trade_day))
    # 根据前或者后获取指数数据
    if is_before == True:
        start_date = trade_day
        end_date = date
    else:
        start_date = date
        end_date = trade_day
    # 循环获取每个涨幅都比较大的count_num只股票在指定时间段中的涨跌幅
    # 此处可以一次取多个股票的,但是处理起来比较麻烦,所以就一个一个取,因为量不是很大,所以影响不大
    stocks_pct_sum = []
    # stocks_name = []
    for stock in security_list:
        # 获取指定股票在节假日后几天的涨跌幅,并按照时间排序
        _stock_pct = get_money_flow([stock], start_date=start_date, end_date=end_date, fields=["date", "sec_code", "change_pct"]).sort_values(by='date')
        # print(_stock_pct)
        # 每天的涨幅list
        _stock_pct = _stock_pct['change_pct'].tolist()
        stock_pct = sum(_stock_pct)
        # print(stock_pct)
        stocks_pct_sum.append(stock_pct)
        # stocks_name.append(get_security_info(stock).display_name)
        # print('@'*50)
    _stocks_pct_sum = {date:stocks_pct_sum}
    stocks_pct_sum = pd.DataFrame(_stocks_pct_sum, index=security_list).sort_values(by=str(date), ascending=False)
    # print(stocks_pct_sum)
    return stocks_pct_sum

## 获取任意股票列表历年在输入日期前或者后几天的涨跌幅
# (1)获取历年该日期;
# (2)遍历历年数据;
# (3)整理结果。

def get_years_security_list_pct_sum(date, year, count, security_list, is_before):
    dates = get_years_date(date, year)
    years_pct_sum0 = []
    for date in dates:
        _security_list_pct_sum = get_security_list_pct_sum(date, count, security_list, is_before)
        years_pct_sum0.append(_security_list_pct_sum)
    years_security_list_pct_sum = pd.concat(years_pct_sum0, axis=1)
    return years_security_list_pct_sum

## 返回输入行业或者概念历年涨跌幅的平均值
def get_industry_concept_avg(date, year, count, industry_or_concept, is_before, is_concept):
        # 每个行业或者概念历年均值
    industry_concept_avg = {}
    # 计算每个行业所有股票的涨跌幅每年的平均值
    for industry_concept_stock in industry_or_concept:
        if is_concept == True:
            security_list = get_concept_stocks(industry_concept_stock)
        elif is_concept == False:
            security_list = get_industry_stocks(industry_concept_stock)
        years_security_list_pct_sum_after = get_years_security_list_pct_sum(date, year, count, security_list, is_before).T
        years_security_list_pct_sum_after['avg'] = years_security_list_pct_sum_after.mean(axis=1)
        industry_concept_avg[industry_concept_stock] = list(years_security_list_pct_sum_after['avg'])
        ## 绘制历年股票列表在指定日期前或者后几天的涨跌幅
        # title='绘制历年股票列表在指定日期后几天的涨跌幅(%)'
        # plot_total_years_pct_sum(years_security_list_pct_sum_after, title)
    dates = get_years_date(date, year)
    industry_concept_avg = pd.DataFrame(industry_concept_avg, index=dates)
    return industry_concept_avg
## 双十一前表现

if __name__ == '__main__':
    print("="*50)
    print("获取股票列表历年在输入日期前几天的涨跌幅:\n")
    print('-'*50)
    date = '2017-11-11'
    year = '2017'
    count = 5
    is_before = True
    
    # 获取概念的数据
    concept_codes = ['GN720', 'GN941', 'GN132', 'GN703', 'GN909']
    is_concept = True # 是否概念
    concept_avg = get_industry_concept_avg(date, year, count, concept_codes, is_before, is_concept)
    
    # 获取行业的数据
    industry_codes = ['801170', '801178', '851781', 'HY434', 'HY005', 'HY446', 'HY450', 'HY464']
    is_concept = False # 是否概念
    industry_avg = get_industry_concept_avg(date, year, count, industry_codes, is_before, is_concept)
    
    # 将行业和概念合并起来
    industry_concept_results = pd.concat([concept_avg, industry_avg], axis=1)
    
    title = "概念或行业历年节日前涨幅"
    plot_total_years_pct_sum(industry_concept_results, title)
==================================================
获取股票列表历年在输入日期前几天的涨跌幅:

--------------------------------------------------
## 双十一后表现

if __name__ == '__main__':
    print("="*50)
    print("获取股票列表历年在输入日期后几天的涨跌幅:\n")
    print('-'*50)
    date = '2017-11-11'
    year = '2017'
    count = 5
    is_before = False
    
    # 获取概念的数据
    concept_codes = ['GN720', 'GN941', 'GN132', 'GN703', 'GN909']
    is_concept = True # 是否概念
    concept_avg = get_industry_concept_avg(date, year, count, concept_codes, is_before, is_concept)
    
    # 获取行业的数据
    industry_codes = ['801170', '801178', '851781', 'HY434', 'HY005', 'HY446', 'HY450', 'HY464']
    is_concept = False # 是否概念
    industry_avg = get_industry_concept_avg(date, year, count, industry_codes, is_before, is_concept)
    
    # 将行业和概念合并起来
    results = pd.concat([concept_avg, industry_avg], axis=1)
    
    title = "概念或行业历年节日后涨幅"
    plot_total_years_pct_sum(results, title)
==================================================
获取股票列表历年在输入日期后几天的涨跌幅:

--------------------------------------------------

全部回复

0/140

量化课程

    移动端课程