最近炒股是買什麼就跌,一直是虧損哎,哭,做爲學過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