自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用 Python 做了一個(gè)“盯盤機(jī)器人”,還能郵件通知你!

開(kāi)發(fā) 后端
即將走上量化投資交易的你,工欲善其事,必先利其器,將Python作為量化投資交易的首選語(yǔ)言,無(wú)疑是最為明智的,余生很短,請(qǐng)跟我一起用python!

[[415785]]

前言

Python憑借其開(kāi)發(fā)效率高和功能強(qiáng)大的特性,在眾多編程語(yǔ)言中脫穎而出,成為大數(shù)據(jù)時(shí)代的分析利器。

據(jù)我多年的領(lǐng)悟,編程語(yǔ)言只是一種按照人的意圖去實(shí)現(xiàn)特定功能的高效工具而已,程序化所實(shí)現(xiàn)的核心決策功能依然需要人工智慧來(lái)支撐,在量化投資交易領(lǐng)域,投資者所思考的交易邏輯是非常重要,正所謂重劍無(wú)鋒,大巧不工(真正的劍技不是要依靠劍鋒,而是個(gè)人的修行,投資也是如此,投資者的素養(yǎng)最為重要),因此應(yīng)當(dāng)把80%的時(shí)間與精力放到投資模型構(gòu)建的思考上,20%的時(shí)間與精力放到編程實(shí)現(xiàn)上。

即將走上量化投資交易的你,工欲善其事,必先利其器,將Python作為量化投資交易的首選語(yǔ)言,無(wú)疑是最為明智的,余生很短,請(qǐng)跟我一起用python!

思路

在量化交易方面,通過(guò)計(jì)算機(jī)程序自動(dòng)實(shí)現(xiàn)股票盯盤與找到買賣信號(hào),應(yīng)該是很多人都比較向往的吧。但九層之臺(tái),起于累土,千里之行,始于足下,只有打下堅(jiān)實(shí)的基礎(chǔ),將各個(gè)知識(shí)點(diǎn)逐一突破后加以綜合運(yùn)用,才能構(gòu)建自己完整的量化交易體系。

今天就從量化交易最基礎(chǔ)的入門知識(shí)點(diǎn)講起,通過(guò)Python程序,編寫股票價(jià)格實(shí)時(shí)盯盤的機(jī)器人,當(dāng)股價(jià)觸發(fā)一定的漲幅條件時(shí),自動(dòng)發(fā)送電子郵件或短信通知到投資者,這一場(chǎng)景可運(yùn)用于平時(shí)喜歡炒股,但是沒(méi)有時(shí)間盯盤的股民朋友。

通過(guò)該文章的學(xué)習(xí),讀者可以掌握對(duì)證券(包括股票和基金)實(shí)時(shí)價(jià)格的獲取、電子郵件發(fā)送、程序定時(shí)運(yùn)行和程序打包成exe文件等知識(shí)點(diǎn)。

盯盤機(jī)器人的工作流程圖及效果圖

為便于讓各位讀者從全局觀了解整個(gè)程序運(yùn)行的邏輯,特將流程圖繪制如下。

1. 程序工作流程圖

2. 股價(jià)監(jiān)控的效果

例如: 2021年7月19日,所監(jiān)控的目標(biāo)股票三峽能源(證券交易代碼:600905)因某時(shí)點(diǎn)的漲跌幅達(dá)到監(jiān)控水平線,自動(dòng)觸發(fā)郵件提醒,通過(guò)郵件方式告知投資者當(dāng)前價(jià)格,漲跌幅和盈虧情況等數(shù)據(jù),效果如下圖所示。

代碼實(shí)現(xiàn)

1. 需要安裝的第三方庫(kù)及簡(jiǎn)要介紹

這里首先為大家介紹一下,本文需要用到的若干Python庫(kù)。

  •  Tushare:一個(gè)免費(fèi)、開(kāi)源的python財(cái)經(jīng)數(shù)據(jù)接口包,通過(guò)該庫(kù)的get_realtime_quotes(code)的方法(code為目標(biāo)證券的交易代碼,包括股票和ETF基金的交易代碼都可以),可以返回股票的當(dāng)前報(bào)價(jià)和成交信息,返回值的數(shù)據(jù)類型為DataFrame,該DataFram包括name(證券名稱),open(今日開(kāi)盤價(jià)),pre_close(昨日收盤價(jià)),price(當(dāng)前價(jià)格)...time(時(shí)間)等,根據(jù)本次需求,僅需要部分維度即可,其他的維度,讀者可以自行通過(guò)print()打印方式查看所有的維度信息。
  •  pandas:數(shù)據(jù)分析的核心庫(kù),因?yàn)檎{(diào)用Tushare庫(kù)的get_realtime_quotes(code)方法返回DataFrame數(shù)據(jù)類型,所以需要該庫(kù)對(duì)返回?cái)?shù)據(jù)進(jìn)行操作。
  •  schedule:在證券交易中的制度中,有交易和休市時(shí)間,要實(shí)現(xiàn)程序的定時(shí)運(yùn)行,該庫(kù)必不可少,詳見(jiàn)程序部分對(duì)該庫(kù)用法的介紹。
  •  smtplib:該庫(kù)主要實(shí)現(xiàn)電子郵件的發(fā)送。
  •  sys:在交易日的15:00以后已經(jīng)閉市,為避免資源的浪費(fèi),此時(shí)可以調(diào)用sys.exit()方法實(shí)現(xiàn)程序的自動(dòng)退出。
  •  pyinstaller:用該庫(kù)可以將程序打包成可執(zhí)行的exe格式文件,便于程序的運(yùn)行。

以上所需的第三方庫(kù),可以使用pip指令完成安裝即可。

2. 程序代碼實(shí)現(xiàn)

① 編寫獲取當(dāng)前證券價(jià)格信息的方法 

  1. def get_now_jiage(code):  
  2.    df = ts.get_realtime_quotes(code)[['name','price','pre_close','date','time']]  
  3.    return df 

其中參數(shù)code為目標(biāo)股票的交易代碼,例如股票名稱為“三峽能源”的證券交易代碼為“600905”。調(diào)用Tushare的get_realtime_quotes(‘600905’)方法,即可返回一個(gè)DataFrame類型的數(shù)據(jù),根據(jù)功能需要,我們只需要獲取name(股票名稱)、price(當(dāng)前價(jià)格)、pre_close(昨日收盤價(jià))、date(價(jià)格對(duì)應(yīng)的日期)和time(價(jià)格對(duì)應(yīng)的時(shí)間)即可。

編寫好該方法后,主需要傳遞目標(biāo)股票的交易代碼至get_now_jiage方法,即可獲取需要的數(shù)據(jù)。

② 編寫判斷是否在交易時(shí)間段內(nèi)的方法

在每個(gè)交易日,股票交易的時(shí)間為09:30-11:30,13:00-15:00,早上9:30程序開(kāi)始監(jiān)控,可以通過(guò)schedule來(lái)實(shí)現(xiàn)(后面講解),在11:30-13:00之間的午間休市時(shí)間內(nèi),為避免造成資源浪費(fèi),就不必調(diào)用Tushare接口的數(shù)據(jù),該時(shí)間段我們可以稱為暫停交易時(shí)間。判斷是否在暫停交易時(shí)間段的方法編寫如下: 

  1. def pd_ztjytime():#判斷是否是交易時(shí)間  
  2.     now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  
  3.     now_datetime = datetime.datetime.strptime(now_time, '%Y-%m-%d %H:%M:%S')  
  4.     d1 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 11:30:01', '%Y-%m-%d %H:%M:%S')  
  5.     d2 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 13:00:00', '%Y-%m-%d %H:%M:%S')  
  6.     delta1 = (now_datetime - d1).total_seconds() 
  7.     delta2 = (d2-now_datetime).total_seconds()  
  8.     if delta1>0 and delta2>0 : #在暫停交易的時(shí)間內(nèi)  
  9.         return True  #在暫停的交易時(shí)間范圍內(nèi),返回 True  
  10.     else:  
  11.         return False #不在暫停的交易時(shí)間范圍內(nèi),返回 False 

③ 編寫監(jiān)控股價(jià)的主體運(yùn)行程序

該模塊作為股價(jià)監(jiān)控與計(jì)算漲跌幅,判斷是否發(fā)送通知的核心程序,為了與早間9:30定時(shí)運(yùn)行程序的模塊相配合,故該模塊寫成獨(dú)立的方法,完整程序如下: 

  1. def do_programe(code):  
  2.     if pd_ztjytime()==False: #判斷是否在暫停交易的時(shí)間范圍內(nèi)  
  3.         info=get_now_jiage(code) #調(diào)用方法獲取當(dāng)前的DataFrame  
  4.         now_jiage=float(info['price'][0]) #獲取現(xiàn)價(jià)  
  5.         name=info['name'][0] #獲取證券名稱  
  6.         pre_close=float(info['pre_close'][0]) #獲取昨日收盤價(jià)  
  7.         riqi=info['date'][0] #獲取現(xiàn)價(jià)對(duì)應(yīng)的日期  
  8.         sj=info['time'][0] #獲取價(jià)格對(duì)應(yīng)的時(shí)間  
  9.         now_zdie=round((now_jiage-pre_close)/pre_close*100,2) #計(jì)算現(xiàn)在的漲跌幅  
  10.         all_zdie=round((now_jiage-cbj)/cbj*100,2)  #計(jì)算股票持有期間內(nèi)總的漲跌幅,其中cbj為購(gòu)買時(shí)候的成本價(jià),需要約定全局變量  
  11.         now_shizhi=round(shuliang*now_jiage,2) #計(jì)算股票現(xiàn)在的市值,其中shuliang為購(gòu)買股票的數(shù)量,需要約定為全局變量  
  12.         ykui=round(now_shizhi-cbj*shuliang,2)  #計(jì)算股票現(xiàn)在總的盈虧  
  13.         if (abs(now_zdie)>=3 and abs(now_zdie)<3.09) or (abs(now_zdie)>=6  and abs(now_zdie)<6.05)  or (abs(now_zdie)>=9 and  abs(now_zdie)<9.1) : #判斷現(xiàn)在的漲跌幅是否在目標(biāo)范圍內(nèi) 
  14.              email_comment = []  
  15.             email_comment.append('<html>')  
  16.             email_comment.append('<b><p><h3><font size="2" color="black">您好:</font></h4></p></b>')  
  17.             email_comment.append('<p><font size="2" color="#000000">根據(jù)設(shè)置參數(shù),現(xiàn)將監(jiān)控到'+name+'('+str(code)+')的證券價(jià)格異動(dòng)消息匯報(bào)如下:</font></p>')  
  18.             email_comment.append('<table border="1px" cellspacing="0px"   width="600" bgcolor=' + color_bg_fg + ' style="border-collapse:collapse">')  
  19.             email_comment.append('<tr>')  
  20.             email_comment.append('<td align="center"><b>序號(hào)</b></td>')  
  21.             email_comment.append('<td align="center"><b>購(gòu)買單價(jià)</b></td>')  
  22.             email_comment.append('<td align="center"><b>持股數(shù)</b></td>')  
  23.             email_comment.append('<td align="center"><b>現(xiàn)價(jià)</b></td>')  
  24.             email_comment.append('<td align="center"><b>現(xiàn)漲跌幅</b></td>')  
  25.             email_comment.append('<td align="center"><b>總漲跌幅</b></td>')  
  26.             email_comment.append('<td align="center"><b>現(xiàn)市值</b></td>')  
  27.             email_comment.append('<td align="center"><b>盈虧額</b></td>')  
  28.             email_comment.append('<td align="center"><b>異動(dòng)時(shí)間</b></td>')  
  29.             email_comment.append('</tr>')  
  30.             email_comment.append('<tr>')  
  31.             email_comment.append('<td align="center">'+str(1)+'</td>')  
  32.             email_comment.append('<td align="center">'+str(cbj) + '</td>')  
  33.             email_comment.append('<td align="center">' + str(shuliang) + '</td>')  
  34.             email_comment.append('<td align="center">' + str(now_jiage) +'</td>')  
  35.             email_comment.append('<td align="center">' + str(now_zdie) + '%</td>')  
  36.             email_comment.append('<td align="center">' + str(all_zdie) + '%</td>')  
  37.             email_comment.append('<td align="center">' + str(now_shizhi) + '元</td>')  
  38.             email_comment.append('<td align="center">' + str(ykui) + '元</td>')  
  39.             email_comment.append('<td align="center">' + str(riqi) +' '+str(sj) +'</td>')  
  40.             email_comment.append('</tr>')  
  41.             email_comment.append('</table>')  
  42.             email_comment.append('<p><font size="2" color="black">祝:股市天天紅,日日發(fā)大財(cái)!</font></p>')  
  43.             email_comment.append('</html>')  
  44.             send_msg = '\n'.join(email_comment)  
  45.             send_Email(email_add[0], send_msg) 

在上述程序中,判斷是否發(fā)送通知的判斷語(yǔ)句為: 

  1. if (abs(now_zdie)>=3 and abs(now_zdie)<3.1) or (abs(now_zdie)>=6  and abs(now_zdie)<6.1)  or (abs(now_zdie)>=9 and  abs(now_zdie)<9.1)  

上述if判斷語(yǔ)句表示現(xiàn)在漲跌幅的絕對(duì)值在3%(含)至3.1%(不含)(使用絕對(duì)值可以同時(shí)兼顧漲和跌的幅度),或6%(含)至6.1%(不含),或9%(含)至9.1%(不含)之間時(shí),便通過(guò)發(fā)送電子郵件的形式發(fā)送通知,具體的漲跌幅觸發(fā)參數(shù)讀者可以自行修改。

電子郵件發(fā)送的關(guān)鍵程序?yàn)椋?nbsp;

  1. send_Email(email_add[0], send_msg) 

其中,email_add為列表形式,可以存放多個(gè)接收通知的電子郵件地址,此例中僅設(shè)置一個(gè)接收地址,全局變量email_add=['......'],故獲取該地址的程序?yàn)閑mail_add[0]。send_msg即為要發(fā)送的郵件內(nèi)容,郵件內(nèi)容使用列表email_comment進(jìn)行添加,這里發(fā)送的郵件格式為html格式,使用html格式是為了方便繪制表格。html文件的開(kāi)頭應(yīng)當(dāng)是,而結(jié)尾則是與之配對(duì)的,其中繪制表格的標(biāo)簽是<table>及配對(duì)的</table>,表格行的標(biāo)簽是<tr>,而列的標(biāo)簽則是<td>。

發(fā)送電子郵件send_Email方法的程序如下: 

  1. def send_Email(Email_address, email_text):  
  2.     from_addr = '*****' #發(fā)出電子郵件的地址  
  3.     password = '*****'   #發(fā)出電子郵件的密碼  
  4.     title = '股票價(jià)格異動(dòng)監(jiān)控消息-' + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  #電子郵件的標(biāo)題  
  5.     msg = MIMEText(email_text, 'html', 'utf-8') #電子郵件的格式是HTML  
  6.     msg['From'] = from_addr  
  7.     msg['To'] = Email_address  
  8.     msg['Subject'] = title  
  9.     try:  
  10.         server = smtplib.SMTP_SSL('smtp.qq.com', 465)  
  11.         server.login(from_addr, password)  # 發(fā)送郵件  
  12.         server.send_message(msg)  
  13.         server.quit()  
  14.         # print(Email_address+'  send success!')  
  15.         #send_info.append(Email_address + '  send success!\n')  
  16.     except Exception as e:  
  17.         a+1  
  18.         # print(e)  
  19.         #send_info.append(e + '\n')  
  20.         #send_info.append(Email_address + ' send failed!\n')  
  21.         # print(Email_address+' send failed!') 

from_addr為發(fā)件人的郵箱地址,而password則是發(fā)件人的授權(quán)碼,這里需要根據(jù)實(shí)際情況進(jìn)行修改和填寫。

另外,程序中的:

server = smtplib.SMTP_SSL('smtp.qq.com', 465)

是選擇QQ郵箱的SMTP服務(wù)器地址smtp.qq.com,默認(rèn)端口為465,如果是其他郵箱,則應(yīng)該進(jìn)行相應(yīng)的服務(wù)器和端口號(hào)進(jìn)行修改。

如何獲取發(fā)件人的授權(quán)碼呢?以QQ郵箱為例說(shuō)明:

第一步:登錄QQ郵箱,單擊頂部的“設(shè)置”鏈接,然后單擊“賬戶”標(biāo)簽,如下圖所示。

第二步:在“賬戶”選項(xiàng)卡中向下滾動(dòng),直到看到如下圖所示的選項(xiàng),單擊“POP3/SMTP服務(wù)”右側(cè)的“開(kāi)啟”鏈接,如下圖所示。

第三步:?jiǎn)螕?ldquo;開(kāi)啟”鏈接后,會(huì)有一個(gè)驗(yàn)證密保的過(guò)程。按照頁(yè)面中的說(shuō)明,向指定號(hào)碼發(fā)送指定內(nèi)容的手機(jī)短信,發(fā)送完畢后單擊頁(yè)面中的“我已發(fā)送”按鈕,會(huì)彈出一個(gè)框,里面就包含SMTP授權(quán)碼,把它復(fù)制并存儲(chǔ)起來(lái),方便以后調(diào)用。

④ 編寫調(diào)用do_programe(code)的監(jiān)控程序

為了實(shí)現(xiàn)主體程序的調(diào)用,編寫run()方法入下所示: 

  1. def run():  
  2.     while True:  
  3.         do_programe('600905')  
  4.         now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  
  5.         d1 = datetime.datetime.strptime(now_time, '%Y-%m-%d %H:%M:%S')  
  6.         d2 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d')+' 15:00:00', '%Y-%m-%d %H:%M:%S')  
  7.         delta = d2 - d1  
  8.         if delta.total_seconds()<=0:  
  9.           sys.exit()  
  10.         time.sleep(1) 

⑤ 編寫每天9點(diǎn)30分開(kāi)始監(jiān)控的主程序

為了實(shí)現(xiàn)每個(gè)交易日交易時(shí)點(diǎn)開(kāi)始監(jiān)控,需要的程序如下所示: 

  1. if __name__ == '__main__':  
  2.     schedule.every().day.at("09:30").do(run)  
  3.     while True:  
  4.         schedule.run_pending()  
  5.         time.sleep(1) 

⑥ 程序打包與自動(dòng)運(yùn)行

當(dāng)編寫完程序以后,就需要通過(guò)打包的形式把程序轉(zhuǎn)化為exe格式,該格式下的程序可以點(diǎn)擊或者設(shè)置自動(dòng)運(yùn)行,打包的庫(kù)是pyinstaller ,使用命令pyinstaller -w -F程序路徑\程序名.py 即可。其中-w表示生成的exe文件運(yùn)行時(shí)不出現(xiàn)黑色的DOS界面,我們只需要該程序 “悄悄” 在后臺(tái)運(yùn)行即可。

為了實(shí)現(xiàn)程序在電腦開(kāi)機(jī)的時(shí)候自動(dòng)運(yùn)行,可以將生成的exe文件復(fù)制到windwos系統(tǒng)的Startup文件夾下,點(diǎn)擊windows的開(kāi)始菜單-所有程序,找到“啟動(dòng)”或者“Startup”的文件夾,將exe文件復(fù)制到該文件夾內(nèi),每次開(kāi)機(jī),電腦就可以自動(dòng)運(yùn)行該監(jiān)控程序。

因?yàn)槌绦蜻\(yùn)行不出現(xiàn)任何界面,為了查看程序是否在運(yùn)行,可以用快捷鍵“Ctrl Alt Delete”的快捷鍵打開(kāi)任務(wù)管理器,在進(jìn)程里面可以查看到“股票監(jiān)控.exe”(這里的文件名是作者改的文件名)的文件,表明程序在監(jiān)控中。

展望

該程序只是設(shè)置了一只股票來(lái)作為簡(jiǎn)單功能實(shí)現(xiàn)的案例,仍然有一定的改進(jìn)空間,說(shuō)明如下。

一是在實(shí)踐中,往往都是構(gòu)建一個(gè)股票池(數(shù)只股票)來(lái)動(dòng)態(tài)監(jiān)測(cè)股價(jià)和自動(dòng)判斷交易時(shí)點(diǎn)(比如MACD,均線,KDJ指標(biāo)等),往往需要結(jié)合數(shù)據(jù)庫(kù)技術(shù),才能便于靈活構(gòu)造股票池。

二是對(duì)于發(fā)送短信的功能,本文中并未做介紹,僅介紹了電子郵件,其實(shí)短信通知的思路和郵件的思路一致。如果要實(shí)現(xiàn)免費(fèi)發(fā)短信功能,讀者可以在twilio 網(wǎng)站上(https://www.twilio.com)上注冊(cè)和調(diào)用相應(yīng)功能即可,讀者可以再網(wǎng)上搜索。

三是關(guān)于Tushare數(shù)據(jù)接口,本文中用的是Tushare老的接口API,目前官方主要維護(hù)的是Tushare Pro接口,相應(yīng)的調(diào)用功能要達(dá)到一定的積分才可以,但是相比其他收費(fèi)接口,Tushare是屬于業(yè)界的良心之作,關(guān)于Tushare Pro,參考的網(wǎng)址詳見(jiàn)https://waditu.com/document/2。

四是其他商業(yè)的量化接口,可以推薦聚寬量化接口,大約有半年左右的免費(fèi)試用期,但是免費(fèi)過(guò)后,每個(gè)月還是有幾千元的收費(fèi),讀者可選擇使用聚寬網(wǎng)址https://www.joinquant.com/view/community/list?listType=1。

五是關(guān)于爬蟲獲取證券交易數(shù)據(jù),現(xiàn)在證券交易數(shù)據(jù)比較豐富的網(wǎng)站有東方財(cái)富、同花順、新浪財(cái)經(jīng)以及和訊網(wǎng)等。通過(guò)爬蟲也可以獲取相應(yīng)的數(shù)據(jù),但是應(yīng)當(dāng)注意的是,像本文中每個(gè)交易日每秒鐘調(diào)用一次API,如果用爬蟲來(lái)實(shí)現(xiàn),就不理想,因?yàn)檎{(diào)用太頻繁可能觸發(fā)網(wǎng)站的反爬蟲機(jī)制。

六是該程序設(shè)置的是在本地計(jì)算機(jī)上自動(dòng)開(kāi)機(jī)運(yùn)行,在程序不斷優(yōu)化和增加功能后,感興趣的讀者可以了解購(gòu)買云服務(wù)器部署監(jiān)控程序。 

 

責(zé)任編輯:龐桂玉 來(lái)源: Python之禪
相關(guān)推薦

2021-08-19 10:22:03

Python股票編程語(yǔ)言

2022-09-30 13:55:46

Python機(jī)器人

2021-04-01 10:51:44

機(jī)器人人工智能編程

2015-05-22 11:40:00

希捷

2020-12-02 13:00:17

Recast.AI聊天機(jī)器人人工智能

2020-02-26 17:39:18

Python機(jī)器人Word

2019-04-19 14:40:15

代碼Python機(jī)器人

2023-10-29 18:14:08

GPT4機(jī)器人算法

2016-10-09 13:40:44

PythonSlack聊天機(jī)器人

2018-06-08 16:48:09

PythonQQ機(jī)器人

2020-02-18 10:26:58

機(jī)器人人工智能系統(tǒng)

2018-07-05 17:01:42

人工智能機(jī)器學(xué)習(xí)機(jī)器人

2020-09-15 13:56:08

公眾號(hào)機(jī)器人圖靈機(jī)器人

2021-11-30 10:56:43

ChatterBot機(jī)器人人工智能

2021-05-24 15:29:24

人工智能機(jī)器人聊天

2012-06-21 14:20:16

CSS3

2020-08-07 14:40:09

Python聊天機(jī)器人編程語(yǔ)言

2020-07-30 08:06:34

Python開(kāi)發(fā)工具

2018-12-29 14:50:06

人工智能機(jī)器人編程語(yǔ)言

2016-08-04 10:04:49

PythonFlaskFacebook Me
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)