1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > python tushare量化股票大数据分析整合版

python tushare量化股票大数据分析整合版

时间:2022-04-08 12:01:53

相关推荐

python tushare量化股票大数据分析整合版

前言:对前面的代码功能进行一次简要整合,简要添加了多线程功能:

1.tushare股票数据本地csv格式。

2.csv格式文件mysql化。

3.tushare股票数据分析word文档化。

代码如下:

import osimport docximport timeimport pymysqlimport datetimeimport warningsimport pandas as pdimport tushare as tsimport threadingimport dateutil.parserfrom docx.shared import Cm, Inchesfrom docx.shared import RGBColor,Ptfrom docx.enum.text import WD_ALIGN_PARAGRAPHwarnings.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('0101', '0106'),#那么你放数据文件夹内不能缺少任何一个这段时期内的交易数据文件,否则报错#tushare的流通市值跟总市值单位是‘万元’,成交额单位是‘千元’,代码都将他们转化成亿单位,方便阅读分析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['amount'] = df_all['amount']/100000 #千转亿df_all['circ_mv'] = df_all['circ_mv']/10000 #万转亿df_all['total_mv'] = df_all['total_mv']/10000 #万转亿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.dtypes)print('%s download complete.' % (str(date)))return df_all#将csv导入本地mysql数据库#连接 Mysql 数据库def output_mysql():try:conn = pymysql.connect(host='localhost', user='root', password='你的密码', db='你创建的数据库', charset='utf8')cur = conn.cursor()print('数据库连接成功!')print(' ')except:print('数据库连接失败!')#读取任意文件夹下的csv文件#获取程序所在路径及该路径下所有文件名称os.chdir('D:/stock_data/')path = os.getcwd()files = os.listdir(path)#遍历所有文件i = 0for file in files:#判断文件是不是csv文件,file.split('.')[-1]获取‘.’后的csv字符串if file.split('.')[-1] in ['csv']:i += 1#构建一个表名称,供后期SQL语句调用,file.split('.')[0]获取的是.csv前面的名字filename = file.split('.')[0]filename = 'tab_' + filename#使用pandas库读取csv文件的所有内容,结果f是一个数据框,保留了表格的数据存储方式,是pandas的数据存储结构。f = pd.read_csv(file, encoding='gbk')#获取数据框的标题行(即字段名称),将来作为sql语句中的字段名称。columns = f.columns.tolist()#print(columns)#将csv文件中的字段类型转换成mysql中的字段类型,只有跟mysql的数据格式一致才能导入#获取f数据类型types = f.dtypes#print(types)field = [] #用来接收字段名称的列表table = [] #用来接收字段名称和字段类型的列表char = []for item in range(len(columns)):#print(types[item])#print(columns[item])if 'object' == str(types[item]):char = '`' + columns[item] + '`' + ' VARCHAR(255)' #必须加上`这个点,否则在写入mysql是会报错elif 'int64' == str(types[item]):char = '`' + columns[item] + '`' + ' INT'elif 'float64' == str(types[item]):char = '`' + columns[item] + '`' + ' FLOAT'elif 'datetime64[ns]' == str(types[item]):char = '`' + columns[item] + '`' + ' DATETIME'else:char = '`' + columns[item] + '`' + ' VARCHAR(255)'table.append(char)field.append('`' + columns[item] + '`') #必须加上`这个点,否则在写入mysql是会报错#print(char)#print(field)#构建SQL语句片段#将table列表中的元素用逗号连接起来,组成table_sql语句中的字段名称和字段类型片段,用来创建表。tables = ','.join(table)#print(tables)#将field列表中的元素用逗号连接起来,组成insert_sql语句中的字段名称片段,用来插入数据。fields = ','.join(field) #字段名#print(fields)#创建数据库表#如果数据库表已经存在,首先删除它cur.execute('drop table if exists {};'.format(filename))#print(filename)mit()#构建创建表的SQL语句table_sql = 'CREATE TABLE IF NOT EXISTS ' + filename + '(' + 'id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,' + tables + ');'#print('table_sql is: ' + table_sql)#开始创建数据库表print('表:' + filename + ',开始创建…………')cur.execute(table_sql)mit()print('表:' + filename + ',创建成功!')#向数据库表中插入数据print('表:' + filename + ',开始插入数据…………')#将数据框的数据读入列表。每行数据是一个列表,所有数据组成一个大列表。也就是列表中的列表,将来可以批量插入数据库表中。f_sql = f.astype(object).where(pd.notnull(f), None)values = f_sql.values.tolist() #所有的数据#print(values)#计算数据框中总共有多少个字段,每个字段用一个 %s 替代。s = ','.join(['%s' for _ in range(len(f.columns))])#print(s)#构建插入数据的SQL语句insert_sql = 'insert into {}({}) values({})'.format(filename,fields,s)#print('insert_sql is:' + insert_sql)#开始插入数据cur.executemany(insert_sql, values) #使用 executemany批量插入数据mit()print('表:' + filename + ',数据插入完成!')print(' ')cur.close()conn.close()print('任务完成!共导入 {} 个CSV文件。'.format(i))#分析csv数据并生成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_nowdf = 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['ts_code'] = df['ts_code'].astype(str)df['list_date'] = pd.to_datetime(df['list_date'])# 添加交易所列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'#此change表示的是价格变化的多少,不是指上涨下跌的百分比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]#print(limit_up['list_date'])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)]#print(pd.to_datetime(date_now))# 涨停股数中次新股,上市日期小于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]获取上涨的行数,df.shape[1]获取列数,df.values获取值# 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.CENTERhead1 = 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 = Truetext1.add_run('{}'.format(str(df_down.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)text1.add_run('A股走平个数:').bold = Truetext1.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 = Truetext2.add_run('{}'.format(str(round(df['amount'].sum(),2)))).font.color.rgb = RGBColor(128, 0, 128)text2.add_run('亿')text2.add_run('总成交量:').bold = Truetext2.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 = Truetext3.add_run('{} '.format(str(round(df['pe'].mean())))).font.color.rgb = RGBColor(128, 0, 128)text3.add_run('平均流通市值:').bold = Truetext3.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 = Truetext3.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 = Truetext4.add_run('{}'.format(str(limit_up.shape[0]))).font.color.rgb = RGBColor(255, 0, 0)text4.add_run('个')text4.add_run('涨停中上市日期小于15天的:').bold = Truetext4.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 = Truetext4.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 = Truetext5.add_run('{}'.format(str(limit_down.shape[0]))).font.color.rgb = RGBColor(0, 255, 0)text5.add_run('个')text5.add_run('跌停中上市日期小于15天的:').bold = Truetext5.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 = Truetext5.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 outputfor 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 = Truetabletext.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这个统计需要长时间计算,如果需要速度快你可以试着把output_total去掉,当然你也可以在上面的列表内加上,变成for j in [output_limit_up, output_limit_down, 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__":t1 = threading.Thread(target=get_all_stockdata, args=(2001, 2025))time.sleep(1)t1.start()t1.join()t2 = threading.Thread(target=output_mysql)time.sleep(1)t2.start()t3 = threading.Thread(target=get_analysis_stockdata, args=(2001, 2025))t3.start()

tushare注册链接:link

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。