import pandas
as pd
import tushare
as ts
import pymysql
import os
import docx
import time
import datetime
import warnings
from urllib
import parse
from sqlalchemy
import create_engine
from docx
.shared
import Cm
, Inches
from docx
.shared
import RGBColor
,Pt
from docx
.enum
.text
import WD_ALIGN_PARAGRAPH
warnings
.filterwarnings
('ignore')
pd
.set_option
('expand_frame_repr', False)
pd
.set_option
('display.max_columns', None)
pd
.set_option
('colheader_justify', 'centre')
pro
= ts
.pro_api
('77675d1dcec7fa0f2e893dca61d3acd7910cdd4672318f62b0354487')
def tushare_to_mysql(st_date
, ed_date
):
engine
= create_engine
('mysql://root:%s@127.0.0.1:3306/tushare?charset=utf8' % parse
.unquote_plus
('123456.'))
print('数据库连接成功')
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 ')
df_first
= pd
.merge
(left
=df_basic
, right
=df_daily
, on
='ts_code', how
='outer')
df_all
= pd
.merge
(left
=df_first
, right
=df_daily_basic
, on
='ts_code', how
='outer')
df_all
= df_all
.drop
('symbol', axis
=1)
for w
in ['name', 'area', 'industry', 'market']:
df_all
[w
].fillna
('问题股', inplace
=True)
df_all
['ts_code'] = df_all
['ts_code'].astype
(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
= df_all
.rename
(columns
={'ts_code': '股票代码', 'name': '股票名称', 'area': '所在地域', 'industry': '行业'
, 'market': '市场类型', 'list_date': '上市日期', 'trade_date': '交易日期', 'change': '涨跌额'
, 'pct_chg': '涨跌幅', 'vol': '成交量(手)', 'amount': '成交额(千元)', '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': '流通市值(万元)'})
engine
.execute
('drop table if exists {}_ts;'.format(date
))
print('%s is downloading....' % (str(date
)))
df_all
.to_sql
('{}_ts'.format(date
),engine
,index
=False)
print('{}成功导入数据库'.format(date
))
def get_mysql_data_analysis(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')
conn
= pymysql
.connect
(host
='localhost', user
='root', password
='123456.', db
='tushare', charset
='utf8')
for date_now
in trade_d
['cal_date'].values
:
cursor
= conn
.cursor
()
sql
= 'select * from {}_ts;'.format(date_now
)
cursor
.execute
(sql
)
col_result
= cursor
.description
result
= cursor
.fetchall
()
columns
= []
for i
in range(len(col_result
)):
columns
.append
(col_result
[i
][0])
df
= pd
.DataFrame
(list(result
),columns
=columns
)
df
= df
.set_index
('股票代码', drop
=False)
df
['成交额(千元)'] = df
['成交额(千元)']/100000
df
['流通市值(万元)'] = df
['流通市值(万元)']/10000
df
['总市值(万元)'] = df
['总市值(万元)']/10000
df
.loc
[df
['股票代码'].str.startswith
('3'), 'exchange'] = 'CY'
df
.loc
[df
['股票代码'].str.startswith
('6'), 'exchange'] = 'SH'
df
.loc
[df
['股票代码'].str.startswith
('0'), 'exchange'] = 'SZ'
df_up
= df
[df
['涨跌额'] > 0.00]
df_even
= df
[df
['涨跌额'] == 0.00]
df_down
= df
[df
['涨跌额'] < 0.00]
limit_up
= df
[df
['涨跌额']/df
['pre_close'] >= 0.097]
limit_down
= df
[df
['涨跌额']/df
['pre_close'] <= -0.0970]
limit_up_new
= limit_up
[pd
.to_datetime
(date_now
) - limit_up
['上市日期'] <= pd
.Timedelta
(days
=15)]
limit_up_fresh
= limit_up
[pd
.to_datetime
(date_now
) - limit_up
['上市日期'] <= pd
.Timedelta
(days
=365)]
limit_down_new
= limit_down
[pd
.to_datetime
(date_now
) - limit_down
['上市日期'] <= pd
.Timedelta
(days
=15)]
limit_down_fresh
= limit_down
[pd
.to_datetime
(date_now
) - limit_down
['上市日期'] <= pd
.Timedelta
(days
=365)]
print('A股上涨个数: %d, A股下跌个数: %d, A股走平个数: %d。' % (df_up
.shape
[0], df_down
.shape
[0], df_even
.shape
[0]))
print('A股总成交额:%d 亿, 总成交量:%d 手' % (df
['成交额(千元)'].sum(), df
['成交量(手)'].sum()))
print('A股平均市盈率:%.2f, 平均流通市值 %.2f 亿, 平均总市值 %.2f 亿' % (df
['市盈率'].mean
(), df
['流通市值(万元)'].mean
(), df
['总市值(万元)'].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
.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
['成交额(千元)'].sum(),2)))).font
.color
.rgb
= RGBColor
(128, 0, 128)
text2
.add_run
('亿 ')
text2
.add_run
('总成交量:').bold
= True
text2
.add_run
('{}'.format(str(round(df
['成交量(手)'].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
['市盈率'].mean
())))).font
.color
.rgb
= RGBColor
(128, 0, 128)
text3
.add_run
('平均流通市值:').bold
= True
text3
.add_run
('{}'.format(str(round(df
['流通市值(万元)'].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
['总市值(万元)'].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
= df
.copy
()
output
= pd
.DataFrame
()
output
= pd
.DataFrame
(df
.groupby
(columns
)['股票代码'].count
())
output
['平均市盈率'] = round(df
.groupby
(columns
)['市盈率'].mean
(),2)
output
['平均流通市值(亿)'] = round(df
.groupby
(columns
)['流通市值(万元)'].mean
(),2)
output
['平均总市值(亿)'] = round(df
.groupby
(columns
)['总市值(万元)'].mean
(),2)
output
['平均成交量(手)'] = round(df
.groupby
(columns
)['成交量(手)'].mean
(),2)
output
['平均成交额(亿)'] = round(df
.groupby
(columns
)['成交额(千元)'].mean
(),2)
output
.sort_values
('股票代码', ascending
=False, inplace
=True)
output
.rename
(columns
={'股票代码': name
+ '合计'}, inplace
=True)
return output
for i
in ['行业', '市场类型', '所在地域']:
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)
for j
in [output_limit_up
, output_limit_down
]:
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
).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
()
file.save
('E:\\James\\code\\quantitative_finance\\{}_分析报告.docx'.format(str(date_now
)))
print('{}_分析报告分析完成'.format(str(date_now
)))
if __name__
=="__main__":
tushare_to_mysql
('20200801', '20200902')
get_mysql_data_analysis
('20200801', '20200902')
转载请注明原文地址:https://tech.qufami.com/read-24516.html