最近炒股是买什么就跌,一直是亏损哎,哭,做为学过python的人来说怎么能容忍,以前也炒过股票以为用阳包阴这样的k线来选出来的股票还不错。因而说作就作,我能够用python来写一个选股的程序。javascript
好!有了idea是第一步,要怎么实现呢,网上找了资料,大部分都是用tushare库来获取股票数据的。因而动起来 写了一个直接经过接口获取数据的程序,从3504只股票里面选取出来我须要的股票,执行时间竟然须要二十多分钟, 太慢!差评!一样不能容忍。所以,我想到了数据库。我就想能不能将全部的A股数据添加进数据库里面,我每次执行的时候直接从数据库里面去取数据, 这样会大大加快了个人执行速度 因而说干就干,先理清楚思路。1.须要获取到全部股票的代码跟名称等。因而有了writeallstock这个文件 2.须要从全部的股票里面找出阳包阴的股票,以及计算出它们的收益率的话,我须要全部股票的一段时间的行情 因而有了createverydatebase 3.有了这一段时间的数据,可是这些数据时死了,不会天天给我自动更新,所以我须要天天定时的将当天的数据加 进去。因此写了writeeveryday 4.好了,全部的股票数据一段时间的行情并且会天天定时更新都存在个人数据库里面了,就须要去统计今天有哪些股票知足 阳包阴的状况因而产生了findstock 5.虽然找到了当天知足阳包阴的股票了,可是我内心仍是没有谱,我想对比一下这个股票以前出现这种状况的时候若是 次日买入的话到底有多少收益,因此有了winrates 6.好了总体框架和思路都出来了,那么有两个文件须要每一个交易日都执行的,因此将它们绑在一块儿,并且天天的报告出来 以后也不必定都有时间打开电脑去看,因此加入了经过邮件自动发送当天报告到邮箱的功能。就有了runall 至于其它的几个文件,打开看看下面都有解释和注释 目前个人选股条件是阳包阴,并且当天要涨停。java
下面送上代码。执行代码的前提是,须要有python,须要安装本地mysql数据库,还须要导入mysql、tushare、pandas、lxml、bs4等须要支持的python库。python
另外:完整项目也能够访问个人github,地址:https://github.com/cat-steel/stock_pick
import mysql.connector import tushare as ts #将全部的股票名称和股票代码、行业、地区写入到名为allstock的表中,这个文件只须要执行一次 #经过tushare库获取全部的A股列表 stock_info = ts.get_stock_basics() #链接数据库 conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() codes = stock_info.index names = stock_info.name industrys = stock_info.industry areas = stock_info.area #经过for循环遍历全部股票,而后拆分获取到须要的列,将数据写入到数据库中 a=0 for i in range(0,len(stock_info)): cursor.execute('insert into allstock (code,name,industry,area) values (%s,%s,%s,%s)',(codes[i],names[i],industrys[i],areas[i])) a += 1 #统计全部A股数量 print('共获取到%d支股票'%a) conn.commit() cursor.close() conn.close()
import tushare as ts import mysql.connector import re,time #建立全部股票的表格以及插入每支股票的近段时间的行情,这个文件只须要执行一次!!! #想要写入哪一段时间的数据只须要修改starttime,endtime的时间就能够了 def everdate(starttime,endtime): #获取全部有股票 stock_info = ts.get_stock_basics() #链接数据库 conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() codes = stock_info.index a = 0 #经过for循环以及获取A股只数来遍历每一只股票 for x in range(0,len(stock_info)): #匹配深圳股票(由于整个A股太多,因此我选择深圳股票作个筛选) if re.match('000',codes[x]) or re.match('002',codes[x]): #以stock_加股票代码为表名称建立表格 cursor.execute('create table stock_' + codes[x] + ' (date varchar(32),open varchar(32),close varchar(32),high varchar(32),low varchar(32),volume varchar(32),p_change varchar(32),unique(date))') #利用tushare包获取单只股票的阶段性行情 df = ts.get_hist_data(codes[x],starttime,endtime) print('%s的表格建立完成'%codes[x]) a += 1 #这里使用try,except的目的是为了防止一些停牌的股票,获取数据为空,插入数据库的时候失败而报错 #再使用for循环遍历单只股票每一天的行情 try: for i in range(0,len(df)): #获取股票日期,并转格式(这里为何要转格式,是由于以前我2018-03-15这样的格式写入数据库的时候,经过通配符%以后他竟然给我把-符号当作减号给算出来了查看数据库日期就是2000百思不得其解想了好久最后决定转换格式) times = time.strptime(df.index[i],'%Y-%m-%d') time_new = time.strftime('%Y%m%d',times) #插入每一天的行情 cursor.execute('insert into stock_'+codes[x]+ ' (date,open,close,high,low,volume,p_change) values (%s,%s,%s,%s,%s,%s,%s)' % (time_new,df.open[i],df.close[i],df.high[i],df.low[i],df.volume[i],df.p_change[i])) except: print('%s这股票目前停牌'%codes[x]) conn.close() cursor.close() #统计总共插入了多少张表的数据 print('全部股票总共插入数据库%d张表格'%a) everdate('2018-01-01','2018-03-14')
#天天下午三点以后进行股票数据添加到数据库,这个文件通常只须要天天执行一次,也能够用来补行情,若是数据库缺乏那天的数据的话,只需修改new_time就行,以下示例 import tushare as ts import mysql.connector import re,time #天天行情出来了以后,插入当天的行情到每支股票的每一个表格中 def everystock(): #获取全部股票列表 stock_info = ts.get_stock_basics() #获取股票代码列 codes = stock_info.index #链接数据库 conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() #获取当前时间 new_time = time.strftime('%Y-%m-%d') #new_time = '2018-03-13' a = 0 ##使用for循环遍历全部的股票 for x in range(0,len(stock_info)): try: if re.match('000',codes[x]) or re.match('002',codes[x]): #获取单只股票当天的行情 df = ts.get_hist_data(codes[x],new_time,new_time) #将时间转换格式 times = time.strptime(new_time,'%Y-%m-%d') time_new = time.strftime('%Y%m%d',times) # #将当天的行情插入数据库 cursor.execute('insert into stock_'+codes[x]+ ' (date,open,close,high,low,volume,p_change) values (%s,%s,%s,%s,%s,%s,%s)' % (time_new,df.open[0],df.close[0],df.high[0],df.low[0],df.volume[0],df.p_change[0])) print('%s的数据插入完成'%codes[x]) a += 1 except: print('%s无行情或者数据库已经存在当天的数据'%codes[x]) #统计当天插入数据库的股票数量 dir_log = 'D:\\python\\work\\stock\\WD\\run\log\\' filename = dir_log + new_time +'.log' flog = open(filename,'w') flog.write('今天的行情插入完成%s条'%a) # print('今天的行情插入完成%s条'%a) flog.close() conn.commit() conn.close() cursor.close() #everystock()
import mysql.connector import re,time import datetime,os #从数据库获取股票数据,统计想要查找日期的知足阳包阴而且当天涨停的股票 def valid_stock(dates): #载入日志,好查错(由于以前统计出来的股票我去实时查了一下彻底不知足条件,因此想到了加入日志好定位是哪一个地方出错了) dir_log = 'D:\\python\\work\\stock\\WD\\run\log\\' filename = dir_log + dates +'.log' flog = open(filename,'w') # 先将字符串格式的时间转换为时间格式才能计算昨天的日期 now = datetime.date(*map(int,dates.split('-'))) oneday = datetime.timedelta(days=1) yestody = str(now - oneday) #将昨天日期转换为规定的字符串格式 times = time.strptime(yestody,'%Y-%m-%d') str_yestoday = time.strftime('%Y%m%d',times) flog.write('执行的时间前一天是%s\n'%str_yestoday) #将想要查找的日期转换为规定的字符串格式 str_today = time.strptime(dates,'%Y-%m-%d') today = time.strftime('%Y%m%d',str_today) flog.write('执行的时间是%s\n'%today) #链接数据库 conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() #查找allstock表获取全部股票代码 cursor.execute('select code from allstock') value_code = cursor.fetchall() a = 0 count = [] #遍历全部股票 for i in range(0,len(value_code)): if re.match('000',value_code[i][0]) or re.match('002',value_code[i][0]): #查询全部匹配到的股票,将今天与昨天的数据对比 try: cursor.execute('select * from stock_'+ value_code[i][0]+ ' where date=%s or date =%s order by date desc'%(today,str_yestoday)) #当天 #cursor.execute('select * from stock_'+ value_code[i][0]+ ' where date=%s or date =%s'%('20180315','20180314')) value = cursor.fetchall() #1是昨天,2是今天 #今天的开盘价 opens1 = float(value[0][1]) #今天的收盘价 close1 = float(value[0][2]) #今天的涨幅 p_change1 = float(value[0][6]) #昨天的。。。。。 opens2 = float(value[1][1]) close2 = float(value[1][2]) p_change2 = float(value[1][6]) #加入这两天的数据知足昨天下跌超过2%,并且今天的开盘价低于昨天的收盘价,且今天的收盘价高于昨天的收盘价,就知足阳包阴的条件 if opens2<close1 and close2>opens1 and p_change2<-2 and p_change1>9.8: flog.write('%s票%s的开盘价是%s\n'%(value_code[i][0],today,opens1)) flog.write('%s票%s的收盘价是%s\n'%(value_code[i][0],today,close1)) flog.write('%s票%s的涨幅是%s\n'%(value_code[i][0],today,p_change1)) flog.write('%s票%s的开盘价是%s\n'%(value_code[i][0],str_yestoday,opens2)) flog.write('%s票%s的收盘价价是%s\n'%(value_code[i][0],str_yestoday,close2)) flog.write('%s票%s的涨幅是%s\n'%(value_code[i][0],str_yestoday,p_change2)) #将知足条件的股票代码放进列表中,统计当天知足条件的股票 count.append(value_code[i][0]) a += 1 except: #以前有次sql语句出错了,order by后面没加date,每次寻找都是0支,找了半个多小时才找出来是sql语句的问题 flog.write('%s停牌无数据,或者请查看sql语句是否正确\n'%value_code[i][0])#通常不用管,除非执行好多天的数据都为0时那可能输sql语句有问题了 print('总共找到%d支知足条件的股票'%a) flog.close() conn.close() cursor.close() return count,a #valid_stock('2018-3-1')
#这个文件能够联合find_stock单独运行,输入todays的日期能够直接查找当天出现过的股票 import mysql.connector import re,time import datetime import find_stock #统计当天知足阳包阴全部股票,在设置的这段时间里面有没有出现过相似的行情,而且计算若是出现过,那么那天以后的5天收益率是多少 def rate(todays): print(todays) #将知足阳包阴的这些股票,以及它们以前知足的时候收益率都写到报告里面方便查看总体状况 count,a = find_stock.valid_stock(todays) dir_repor = 'D:\\python\\work\\stock\\WD\\run\\report\\' filename = dir_repor + todays +'.txt' fp = open(filename,'w') fp.write('总共找到%d支知足条件的股票分别是\n%s\n'%(a,count)) #链接数据库 conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() #遍历知足条件的这些股票 for x in count: #从数据库里挑出它们的行情 cursor.execute('select * from stock_'+x+' order by date desc') value = cursor.fetchall() # print(value) for i in range(0,len(value)): #遍历这支股票的全部天数 try: dates = value[i][0] opens2 = float(value[i][1]) #第i行的第一列 opens1 = float(value[i+1][1]) close2 = float(value[i][2]) #第i行的第二列 close1 = float(value[i+1][2]) p_change1 = float(value[i+1][6]) #第i行的第六列 p_change2 = float(value[i][6]) if opens2<close1 and close2>opens1 and p_change1<-2 and p_change2>9.8: #这一句很重要,就是在出现阳包阴以后得有5天的数据区统计,不然就会变成-5就会从开始统计的那天去取数据,结果就致使当天的这些股票统计收益的时候也有不过都是错的 if i-6>0: #收益率 wins = (float(value[i-6][2])-float(value[i-1][1]))/float(value[i-1][1])*100 print('%s的%s以后5天收率为百分之%d'%(x,dates,wins)) fp.write('%s在%s以后5天收率为百分之%d\n'%(x,dates,wins)) else: fp.write('%s在%s以前没有知足条件的行情\n'%(x,dates)) except: pass # print('%s前3个月无知足条件的状况'%x) fp.close() conn.close() cursor.close() #rate('2018-03-16')
#总的运行文件,实现将统计报告发送邮件到本身的邮箱,将这个文件放到Jenkin上每一个交易日下午3点以后运行就能够收到当天知足行情的股票了 import win_rates import write_everyday import time import os import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header #获取最新的文件 def new_file(test_report_dir): lists = os.listdir(test_report_dir) lists.sort(key = lambda fn:os.path.getmtime(test_report_dir + fn)) file_path = os.path.join(test_report_dir,lists[-1]) return file_path #发送邮件 def send_email(): f = open(new_file(test_report_dir),'rb') mail_body = f.read() # print(mail_body) f.close() #设置邮件服务器和帐号密码 smtpserver = 'smtp.163.com' user = '17665324876@163.com' password = '*****' #设置接收邮箱和主题 sender = user receiver = '497051142@qq.com' subject = '今天的股票行情来啦' msg = MIMEMultipart('mixed') att = MIMEText(mail_body,'txt','utf-8') att['Content-Type'] = 'application/octet-stream' att['Content-Disposition'] = 'attachment; filename = "%s.txt"'%todays msg.attach(att) msg['From'] = user msg['To'] = receiver msg['Subject'] =Header(subject,'utf-8') smtp = smtplib.SMTP() smtp.connect(smtpserver,25) smtp.login(user,password) smtp.sendmail(sender,receiver,msg.as_string()) smtp.quit() if __name__ == '__main__': test_report_dir = 'D:\\python\\work\\stock\\WD\\run\\report\\' #若是执行的不是当天的日期的话请将第一个todays注释掉,最好也将write_everyday.everystock()注释掉,用第二个todays todays = time.strftime('%Y-%m-%d') # todays = '2018-03-14' #若是不是交易日执行的话write_everyday会报错,会报tushare获取不到行情,因此请手动输入日期并将下面一行注释掉 write_everyday.everystock() time.sleep(3) win_rates.rate(todays) send_email()
import mysql.connector import re,time import datetime,os def delete(dates): conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() cursor.execute('select code from allstock') value_code = cursor.fetchall() a = 0 for i in range(0,len(value_code)): if re.match('000',value_code[i][0]) or re.match('002',value_code[i][0]): cursor.execute('delete from stock_'+ value_code[i][0]+ ' where date=%s'%(dates)) #删除重复的数据 a +=1 print('%s已删除'%value_code[i][0]) print('共删除%d支股票的数据'%a) conn.commit() conn.close() cursor.close() delete('20180313')
import mysql.connector import re,time import datetime,os #由于以前建立表格的时候没加惟一性约束,容易插入重复的数据,致使最后计算记过不许确,因此穿件一个函数给以前没加约束的加上去 def addunique(): conn = mysql.connector.connect(user='root',password='password',database='test') cursor = conn.cursor() cursor.execute('select code from allstock') value_code = cursor.fetchall() a = 0 for i in range(0,len(value_code)): if re.match('000',value_code[i][0]) or re.match('002',value_code[i][0]): cursor.execute('alter table stock_'+ value_code[i][0]+ ' add unique (date)') #删除重复的数据 print('%s已添加惟一性约束完成'%value_code[i][0]) conn.close() cursor.close() addunique()
能够选股了,拿去赚钱吧,亏钱了可不要赖我哦。mysql
哦,最后还得说,须要将执行文件run_all.py放入Jenkins,天天收盘以后定时执行就好了,这样,天天收盘以后就能够收到,送过来的好股票了。赚钱去咯,欢迎各位大神提意见,帮忙完善。git