目前我的选股条件是阳包阴,而且当天要涨停。
下面送上代码。执行代码的前提是,需要有python,需要安装本地mysql数据库,还需要导入mysql、tushare、pandas、lxml、bs4等需要支持的python库。
另外:完整项目也可以访问我的github,地址:https://github.com/cat-steel/stock_pick
整个架构就是这样子
write_allstock.py
- 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()
creat_everydatebase.py
- 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')
write_everyday.py- #每天下午三点之后进行股票数据添加到数据库,这个文件一般只需要每天执行一次,也可以用来补行情,如果数据库缺少那天的数据的话,只需修改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()
find_stock.py
- 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')
win_rates.py
- #这个文件可以联合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')
run_all.py
- #总的运行文件,实现将统计报告发送邮件到自己的邮箱,将这个文件放到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()
delete_stock.py
- 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')
add_sql_unique.py
- 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()
可以选股了,拿去赚钱吧,亏钱了可不要赖我哦。效果如图:
哦,最后还得说,需要将执行文件run_all.py放入Jenkins,每天收盘之后定时执行就行了,这样,每天收盘之后就可以收到,送过来的好股票了。 赚钱去咯,欢迎各位大神提意见,帮忙完善。
联系客服