捡烟蒂投资股票烟蒂:利用python进行股票大数据的分析跟word报告本地生成

2022-04-29 11:36:00 首页 > 股票 Funny Power Panda

  前言:

  本人也是股票投资爱好着,这段时间行情不是很好,就想着做些其他事情转移下注意力,突然想起之前写过的小项目代码,运行后会对你想要的时间日期进行数据的分析生成,然后保存到本地,数据库之前我用的是tushare的,不过太久没用现在不知道数据的接口有没有改变,要想运行成功还是得要去他们那里搞个账号,具体我就不细节展开了。下面我放出代码,供各位大佬们参考,有能力的应该可以改成精美的图形html展示形式。

利用python进行股票大数据的分析跟word报告本地生成

  import os

  import docx

  import time

  import warnings

  import pandas as pd

  import tushare as ts

  from docx.shared import Cm, Inches

  from docx.enum.text import WD_ALIGN_PARAGRAPH

  from docx.shared import RGBColor,Pt

  warnings.filterwarnings('ignore')

  #pd.set_option()就是pycharm输出控制显示的设置

  pd.set_option('expand_frame_repr', False)#True就是可以换行显示。设置成False的时候不允许换行

  pd.set_option('display.max_columns', None)# 显示所有列

  #pd.set_option('display.max_rows', None)# 显示所有行

  pd.set_option('colheader_justify', 'centre')# 显示居中

  #os.chdir()用于改变当前工作目录到指定的路径

  #此路径必须改为放数据的路径且中间的不能缺失任何一天数据,例如get_analysis_stockdata('20200101', '20200106'),

  #那么你放数据文件夹内不能缺少任何一个这段时期内的交易数据文件,否则报错

  os.chdir('D:/stock_data/') #保存的绝对路径,需要自己修改跟创建,就是切换默认的工作目录到你设置的路径

  pro = ts.pro_api('要到tushare官网注册个账户然后将token复制到这里')

  #df_basic = pro.stock_basic() 获取基础信息数据,包括股票代码、名称、上市日期、退市日期等

  #df_daily = pro.daily() 获取所有股票日行情信息,或通过通用行情接口获取数据,包含了前后复权数据,停牌期间不提供数据

  #df_daily_basic = pro.daily_basic()获取全部股票每日重要的基本面指标,可用于选股分析、报表展示等。

  def get_all_stockdata(st_date, ed_date):

  trade_d = pro.trade_cal(exchange='SSE', is_open='1',start_date=st_date,end_date=ed_date,fields='cal_date')

  for date in trade_d['cal_date'].values:

  df_basic = pro.stock_basic(exchange='', list_status='L') #再获取所有股票的基本信息

  df_daily = pro.daily(trade_date=date) # 先获得所有股票的行情数据,成交额单位是千元,成交量是手

  df_daily_basic = pro.daily_basic(ts_code='', trade_date=date,fields='ts_code, turnover_rate, turnover_rate_f,'

  ' volume_ratio, pe, pe_ttm, pb, ps, ps_ttm,'

  ' dv_ratio, dv_ttm, total_share, float_share,'

  ' free_share, total_mv, circ_mv ') #获取每日指标,单位是万股,万元

  #基本数据跟行情数据合并,再跟每日指标数据合并生成一个csv数据文件

  df_first = pd.merge(left=df_basic, right=df_daily, on='ts_code', how='outer') #on='ts_code'以ts_code为索引,合并数据,how='outer',取并集

  df_all = pd.merge(left=df_first, right=df_daily_basic, on='ts_code', how='outer')

  #数据清洗,删除symbol列数据,跟ts_code数据重复

  df_all = df_all.drop('symbol', axis=1)

  for w in ['name', 'area', 'industry', 'market']: #在'name', 'area', 'industry', 'market'列内循环填充NaN值

  df_all[w].fillna('问题股', inplace=True)

  df_all['ts_code'] = df_all['ts_code'].astype(str) #强制转换成str字符串格式

  df_all['list_date'] = pd.to_datetime(df_all['list_date'])

  df_all['trade_date'] = pd.to_datetime(df_all['trade_date'])

  df_all.to_csv(str(date) + '_ts.csv', index=False, encoding='gbk') #保存数据,不保存索引,如果index=True,则保存索引会多出一列

  print(df_all)

  print('%s is downloaded.' % (str(date)))

  return df_all

  #分析数据并生成docx文档,存储至本地D盘D:/stock_analysis/

  def get_analysis_stockdata(st_date, ed_date):

  trade_d = pro.trade_cal(exchange='SSE', is_open='1',start_date=st_date,end_date=ed_date,fields='cal_date') #获取st_date,ed_date时间段内的交易日期

  for date_now in trade_d['cal_date'].values: #将以上获取时间段的交易日期赋值给date_now

  df = pd.read_csv('{}_ts.csv'.format(str(date_now)), encoding='gbk') #读取时间段内每日的股票数据

  df.fillna(0, inplace=True) #fillna填充缺失数据,传入inplace=True直接修改原对象

  #astype强制将涨幅,PE,总市值,流通市值转换成float格式,ts_code转化成str后,NAN也变成nan str格式

  df[['change', 'pe', 'total_mv', 'circ_mv']] = df[['change', 'pe', 'total_mv', 'circ_mv']].astype(float)

  df['list_date'] = pd.to_datetime(df['list_date'])

  df['ts_code'] = df['ts_code'].astype(str)

  # 添加交易所列

  df.loc[df['ts_code'].str.startswith('3'), 'exchange'] = 'CY'

  df.loc[df['ts_code'].str.startswith('6'), 'exchange'] = 'SH'

  df.loc[df['ts_code'].str.startswith('0'), 'exchange'] = 'SZ'

  df_up = df[df['change'] > 0.00] #找出上涨的股票

  df_even = df[df['change'] == 0.00] #找出走平的股票

  df_down = df[df['change'] < 0.00] #找出下跌的股票

  # 找出涨停的股票

  limit_up = df[df['change']/df['pre_close'] >= 0.097]

  limit_down = df[df['change']/df['pre_close'] <= -0.0970]

  # 涨停股数中的未封板股,上市日期小于15天

  limit_up_new = limit_up[pd.to_datetime(date_now) - limit_up['list_date'] <= pd.Timedelta(days=15)]

  # 涨停股数中次新股,上市日期小于1年

  limit_up_fresh = limit_up[pd.to_datetime(date_now) - limit_up['list_date'] <= pd.Timedelta(days=365)]

  # 涨停股数中的未封板股,上市日期小于15天

  limit_down_new = limit_down[pd.to_datetime(date_now) - limit_down['list_date'] <= pd.Timedelta(days=15)]

  # 涨停股数中次新股,上市日期小于1年

  limit_down_fresh = limit_down[pd.to_datetime(date_now) - limit_down['list_date'] <= pd.Timedelta(days=365)]

  #df_up.shape[0]获取上涨的行数

  print('A股上涨个数: %d, A股下跌个数: %d, A股走平个数: %d。' % (df_up.shape[0], df_down.shape[0], df_even.shape[0]))

  print('A股总成交额:%d, 总成交量:%d' % (df['amount'].sum(), df['vol'].sum()))

  print('A股平均市盈率:%.2f, 平均流通市值 %.2f 亿, 平均总市值 %.2f 亿' % (df['pe'].mean(), df['circ_mv'].mean(), df['total_mv'].mean()))

  print('涨停数量:%d 个, 涨停中上市日期小于15天的:%d, 涨停中上市日期小于1年的:%d' % (limit_up.shape[0], limit_up_new.shape[0], limit_up_fresh.shape[0]))

  print('跌停数量:%d 个, 跌停中上市日期小于15天的:%d, 跌停中上市日期小于1年的:%d' % (limit_down.shape[0], limit_down_new.shape[0], limit_down_fresh.shape[0]))

  file = docx.Document()

  #设置总标题,居中

  headb = file.add_heading('%s中国股市今日收盘分析报告' % (date_now), level=0).alignment = WD_ALIGN_PARAGRAPH.CENTER

  head1 = file.add_heading('股市基本概况:',level=1) #设置一级标题

  #添加段落内容

  text1 = file.add_paragraph() #首先创建一个空的段落,然后再往里面加文字,这样方便设置文字格式字体等设置,另外一种写法,缺点不能单独设置字体属性

  # text1 = file.add_paragraph('A股上涨个数: %d, A股下跌个数: %d, A股走平个数: %d。' % (df_up.shape[0], df_down.shape[0], df_even.shape[0]))

  text1.add_run('A股上涨个数:').bold = True #添加文字并设置粗体

  text1.add_run('{} '.format(str(df_up.shape[0]))).font.color.rgb = RGBColor(255, 0, 0) #添加变量

  text1.add_run('A股下跌个数:').bold = True

  text1.add_run('{} '.format(str(df_down.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)

  text1.add_run('A股走平个数:').bold = True

  text1.add_run('{} '.format(str(df_even.shape[0]))).font.color.rgb = RGBColor(0, 0, 255)

  text1.line_spacing = Pt(25) #设置段落行距

  text1.style = 'List Bullet' # 设置项目符号列表

  text2 = file.add_paragraph()

  text2.add_run('A股总成交额:').bold = True

  text2.add_run('{}'.format(str(round(df['amount'].sum(),2)))).font.color.rgb = RGBColor(128, 0, 128)

  text2.add_run('千元 ')

  text2.add_run('总成交量:').bold = True

  text2.add_run('{}'.format(str(round(df['vol'].sum(),2)))).font.color.rgb = RGBColor(128, 0, 128)

  text2.add_run('手 ')

  text2.line_spacing = Pt(25)

  text2.style = 'List Bullet'

  text3 = file.add_paragraph()

  text3.add_run('A股平均市盈率:').bold = True

  text3.add_run('{} '.format(str(round(df['pe'].mean())))).font.color.rgb = RGBColor(128, 0, 128)

  text3.add_run('平均流通市值:').bold = True

  text3.add_run('{}'.format(str(round(df['circ_mv'].mean(),2)))).font.color.rgb = RGBColor(128, 0, 128)

  text3.add_run('万元')

  text3.add_run('n')

  text3.add_run('平均总市值:').bold = True

  text3.add_run('{}'.format(str(round(df['total_mv'].mean(),2)))).font.color.rgb = RGBColor(128, 0, 128)

  text3.add_run('万元 ')

  text3.line_spacing = Pt(25)

  text3.style = 'List Bullet'

  text3.add_run('n')

  text4 = file.add_paragraph()

  text4.add_run('涨停数量:').bold = True

  text4.add_run('{}'.format(str(limit_up.shape[0]))).font.color.rgb = RGBColor(255, 0, 0)

  text4.add_run('个 ')

  text4.add_run('涨停中上市日期小于15天的:').bold = True

  text4.add_run('{}'.format(str(limit_up_new.shape[0]))).font.color.rgb = RGBColor(255, 0, 0)

  text4.add_run('个 ')

  text4.add_run('n')

  text4.add_run('涨停中上市日期小于1年的:').bold = True

  text4.add_run('{}'.format(str(limit_up_fresh.shape[0]))).font.color.rgb = RGBColor(255, 0, 0)

  text4.add_run('个 ')

  text4.line_spacing = Pt(25)

  text4.style = 'List Bullet'

  text5 = file.add_paragraph()

  text5.add_run('跌停数量:').bold = True

  text5.add_run('{}'.format(str(limit_down.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)

  text5.add_run('个 ')

  text5.add_run('跌停中上市日期小于15天的:').bold = True

  text5.add_run('{}'.format(str(limit_down_new.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)

  text5.add_run('个 ')

  text5.add_run('n')

  text5.add_run('跌停中上市日期小于1年的:').bold = True

  text5.add_run('{}'.format(str(limit_down_fresh.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)

  text5.add_run('个 ')

  text5.line_spacing = Pt(25)

  text5.style = 'List Bullet'

  file.add_page_break() #添加分页符

  def get_output(df, columns='_industry', name='_limit_up'):

  # df.copy(deep= False)和df.copy()都是浅拷贝,是复制了旧对象的内容,然后重新生成一个新对象,改变旧对象不会影响新对象。

  df = df.copy()

  output = pd.DataFrame()

  #df.groupby(columns)根据列值分组数据,并根据股票代码统计数据

  output = pd.DataFrame(df.groupby(columns)['ts_code'].count())

  output['平均市盈率'] = round(df.groupby(columns)['pe'].mean(),2)

  output['平均流通市值(万)'] = round(df.groupby(columns)['circ_mv'].mean(),2)

  output['平均总市值(万)'] = round(df.groupby(columns)['total_mv'].mean(),2)

  output['平均成交量(手)'] = round(df.groupby(columns)['vol'].mean(),2)

  output['平均成交额(千)'] = round(df.groupby(columns)['amount'].mean(),2)

  #依据ts_code进行降序,排序后的数据集替换原来的数据

  output.sort_values('ts_code', ascending=False, inplace=True)

  #改列值名字,将ts_code改成name+‘_count’的形式

  output.rename(columns={'ts_code': name + '合计'}, inplace=True)

  return output

  for i in ['industry', 'exchange', 'area']:

  # 对涨停的股票分析

  output_limit_up = get_output(limit_up, columns=i, name='涨停').reset_index()

  # 对跌停的股票分析

  output_limit_down = get_output(limit_down, columns=i, name='跌停').reset_index()

  # 对全量的股票分析

  output_total = get_output(df, columns=i, name='全部').reset_index()

  #添加表格开头类别说明

  tabletext = file.add_paragraph()

  tabletext.add_run('类别:').bold = True

  tabletext.add_run('{} '.format(str(i))).font.color.rgb = RGBColor(222, 125, 44)

  print(output_limit_up)

  print(output_limit_down)

  print(output_total)

  for j in [output_limit_up, output_limit_down, output_total]: #, output_total

  tb = file.add_table(rows=len(j.index)+1, cols=len(j.columns),style='Medium Grid 3 Accent 1')

  tb.autofit = True #关闭表格行宽自适应

  for x in range(len(j.columns)):

  tb.cell(0, x).text = j.columns[x] #添加表列头

  #tb.cell(0, x).width = Inches(1.2) #设置行宽

  tb.cell(0, x).paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER #文字居中

  for row in range(len(j.index)):

  for col in range(len(j.columns)):

  tb.cell(row+1, col).text = str(j.iloc[row, col]) #设置行宽

  tb.cell(row+1, col).paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER #文字居中

  file.add_paragraph('n') #表格换行

  file.add_page_break() #每制成一个类别表格分一次页面

  #之所以生成文件慢是因为output_total这个统计需要长时间计算,如果需要速度快你可以试着把output_total去掉

  #生成一个docx文件我的电脑需要3到4分钟左右

  file.save('D:stock_analysis{}_分析报告.docx'.format(str(date_now)))

  print('{}_分析报告分析完成'.format(str(date_now)))

  if __name__=="__main__":

  get_all_stockdata('20200611', '20200611')

  get_analysis_stockdata('20200611', '20200611')

利用python进行股票大数据的分析跟word报告本地生成

利用python进行股票大数据的分析跟word报告本地生成

股票

MORE>
最近发表
标签列表
最新留言