谷葆春
(北京信息科技大學(xué)計算機(jī)學(xué)院,北京100101)
對于短線的股票交易者來說,每天的復(fù)盤工作是重要的環(huán)節(jié),第二天買和賣的股票大部分都是在復(fù)盤的時候發(fā)現(xiàn)并做好交易計劃的。而每天漲停的股票是市場的焦點票,吸引了游資和眾多交易者的關(guān)注,因此每天對漲停的股票進(jìn)行復(fù)盤和分析,是短線交易員非常基礎(chǔ)和重要的工作。用手工的方法復(fù)盤,對漲停股票進(jìn)行梳理和分析,會花費(fèi)大量的時間和人力成本,用軟件來實現(xiàn)每天的漲停板股票分析則能有效地解決這一問題。
目前市面上的交易軟件很多,它們包含每天的股票數(shù)據(jù),也能提供選股器方便用戶的選股操作,但能自動實現(xiàn)每天復(fù)盤工作的軟件基本沒有。所以本項目開發(fā)了一個自動的漲停板復(fù)盤軟件,系統(tǒng)通過爬蟲抓取東方財富網(wǎng)上提供的漲停股票數(shù)據(jù),包括價格、漲跌幅、成交量、換手率、漲停時間等,確定各支股票所屬的板塊,然后給出各板塊的龍頭股。
由于一支股票的漲停可能是多個原因造成的,而漲停的原因?qū)τ诜治龉善苯酉聛淼某掷m(xù)性有很大的影響,所以系統(tǒng)通過爬取新浪財經(jīng)里的各股票的財報、研報和公司公告,判斷是否由于基本面和股權(quán)變更等原因漲停;爬取新浪搜索內(nèi)的股票新聞,判斷是否由于消息面和政策面漲停。
對于多數(shù)據(jù)源爬蟲來說,最重要的是設(shè)置合理的URL 隊列。系統(tǒng)對公告、財報和研報的爬取采取廣度優(yōu)先遍歷策略,首先確定這三個數(shù)據(jù)加入URL 隊列中的順序,由于每只股票的公告、財報和研報數(shù)據(jù)有很多條,而判斷漲停原因只需要最近的數(shù)據(jù),所以系統(tǒng)只爬取前五條的信息。接著依次將公告、財報和研報頁面的前五個URL 加入隊列,第五條之后的數(shù)據(jù)和其他與主題無關(guān)的數(shù)據(jù)則不進(jìn)入URL 隊列。
每篇公告、研報或新聞的數(shù)據(jù)量通常都很多,所以系統(tǒng)對每個公告、研報和新聞采取抽取摘要的方法簡化數(shù)據(jù)。目前主流的文本摘要自動生成有兩種方式,分別是抽取式和生成式。抽取式是從整篇文章中獲取一些關(guān)鍵句,將這些句子有機(jī)組合,得到一篇文章摘要,期間不修改句子本身。而生成式則是計算機(jī)通過自然語言處理對文章的內(nèi)容進(jìn)行分析和理解,再使用自然語言生成技術(shù),生成不同于文章中原有句子的自動文章摘要。本系統(tǒng)的摘要采用抽取式中的TextRank算法。
系統(tǒng)整體結(jié)構(gòu)圖如圖1 所示。

圖1 系統(tǒng)結(jié)構(gòu)圖
系統(tǒng)有兩個爬蟲,一個是爬取股票的數(shù)據(jù),另一個是為了判斷漲停原因而爬取的企業(yè)的新聞、公告、財報(包括年報和季報)、研報等信息。
股票數(shù)據(jù)主要是通過爬取東方財富網(wǎng)站的漲停股池、昨日漲停股池和炸板股池三個數(shù)據(jù)來實現(xiàn)后面的復(fù)盤工作。經(jīng)過分析,這三頁股票數(shù)據(jù)都采用了AJAX技術(shù),AJAX 是指Asynchronous JavaScript and XML,即異步JavaScript and XML 技術(shù),通過在后臺與服務(wù)器進(jìn)行少量的數(shù)據(jù)交換,AJAX 可以使網(wǎng)頁實現(xiàn)異步更新,這意味著可以在不重新加載整個網(wǎng)頁的情況下,對網(wǎng)頁的部分?jǐn)?shù)據(jù)進(jìn)行更新。
對于采用了AJAX 技術(shù)的網(wǎng)頁,可通過分析AJAX請求,找到對應(yīng)的加載數(shù)據(jù)的JavaScript 腳本,從而獲得該頁面上JSON 格式的數(shù)據(jù)。在Python 中裝載該數(shù)據(jù)后,即可獲得股票的各數(shù)據(jù),包括:股票代碼、股票名稱、漲跌幅、最新價格、成交額、換手率、封板資金、封板時間、總板數(shù)、第幾板、連板數(shù)和所屬行業(yè),等等,最后將這些數(shù)據(jù)保存在一個Excel 文件里,為了方便處理也同時保存一份在數(shù)據(jù)庫里。
由于新上市的股票經(jīng)常得到投資者的額外關(guān)注,所以會產(chǎn)生一定的情緒溢價,新股和次新股也經(jīng)常被作為一個獨(dú)立的板塊進(jìn)行處理。因此在獲得股票的數(shù)據(jù)后,對于新股和次新股的股票進(jìn)行標(biāo)記,把它們歸屬到新股和次新股板塊。
股票數(shù)據(jù)爬蟲的流程圖如圖2 所示。

圖2 股票數(shù)據(jù)爬蟲流程圖
系統(tǒng)關(guān)于股票的新聞信息在新浪搜索里爬取,而公告、財報和研報信息則在新浪財經(jīng)里爬取,系統(tǒng)對這三個數(shù)據(jù)的爬取采取廣度優(yōu)先遍歷策略。
對于一只股票來說,先將它的公告URL 加入隊列,由于該頁面內(nèi)部的URL 眾多,而系統(tǒng)是只爬取前五個公告的信息,前五條后面的公告和其他的非公告信息忽略掉,所以將該頁面上的前5 個公告的URL 加入隊列,并設(shè)置狀態(tài)為False,表示沒有訪問過。然后隊頭的URL 出列,加入已完成隊列FinishedQueue,并設(shè)置它的狀態(tài)為True,表示該鏈接已被訪問。爬取到前5 個公告頁面的數(shù)據(jù),提取摘要后存入數(shù)據(jù)庫。再依次將財報和研報的URL 加入當(dāng)前訪問隊列,分別獲得前五個財報和研報的數(shù)據(jù)[2]。
對于新聞數(shù)據(jù)的爬取與公告等信息有所不同,需要使用Selenium 工具模擬用戶的登錄操作。在新浪搜索頁面中輸入某只股票的名稱,點擊搜索后會搜出很多近期關(guān)于這只股票的新聞消息,為了獲得這些消息頁面的URL 地址,系統(tǒng)采取動態(tài)抓取的方法,使用Selenium 工具。Selenium 是在程序中通過代碼調(diào)用瀏覽器,模擬用戶輸入關(guān)鍵詞并查找的過程。Selenium 首先在新浪搜索頁面查找輸入框輸入關(guān)鍵詞,再點擊搜索按鈕實現(xiàn)搜索功能,這時候?qū)@得結(jié)果頁面的前五個新聞URL 加入隊列。
算法的實現(xiàn)過程如下:
Step 1:公告進(jìn)入URL 隊列。
Step 2:獲取前5 個數(shù)據(jù)的URL,依次加入URL隊列。
Step 3:隊頭URL 出列,標(biāo)記為True。
Step 4:獲取前5 條的信息存入數(shù)據(jù)庫。
Step 5:若未獲得財報的數(shù)據(jù),則財報的URL 入隊列,轉(zhuǎn)至Step2;若已獲得,則轉(zhuǎn)至Step6。
Step 6:若未獲得研報的數(shù)據(jù),則研報的URL 入隊列,轉(zhuǎn)至Step2;若已獲得,則轉(zhuǎn)至Step7。
Step 7:若未獲得新聞的數(shù)據(jù),則對新聞頁面使用Selenium 工具進(jìn)行處理,然后將新聞的URL 入隊列,轉(zhuǎn)至Step3;若已獲得,則轉(zhuǎn)至Step8。
Step 8:任務(wù)結(jié)束。
漲停的原因分析需要獲得股票的公告、新聞、研報和財報等數(shù)據(jù),這些數(shù)據(jù)內(nèi)容較多,逐一閱讀較為繁瑣也沒有必要,這時候可對這些內(nèi)容進(jìn)行自動摘要處理,這屬于自然語言處理的范疇。目前主流的文本摘要自動生成有兩種方式,分別是抽取式和生成式。本系統(tǒng)的摘要采用抽取式中的TextRank 算法。
TextRank 是一種文本排序算法,由谷歌的網(wǎng)頁重要性排序算法PageRank 算法改進(jìn)而來,它能夠從一個給定的文本中提取出該文本的關(guān)鍵詞和關(guān)鍵詞組,并使用抽取式的自動文摘方法提取出該文本的關(guān)鍵句。
PageRank 算法早期主要用于對在線搜索結(jié)果中的網(wǎng)頁進(jìn)行排序,它根據(jù)互聯(lián)網(wǎng)上頁面之間的鏈接關(guān)系給出一個正實數(shù),即PageRank 值,表示每個頁面的重要程度。PageRank 值越高,說明網(wǎng)頁越重要,在互聯(lián)網(wǎng)搜索的排序中越可能被排在前面。
若整個互聯(lián)網(wǎng)是一個有向圖,節(jié)點是網(wǎng)頁,每條邊是轉(zhuǎn)移概率。網(wǎng)頁瀏覽者在每個頁面上依照連接出去的超鏈接,以等概率跳轉(zhuǎn)到下一個網(wǎng)頁,并且在網(wǎng)頁上持續(xù)不斷地進(jìn)行這樣的隨機(jī)跳轉(zhuǎn),這個過程形成了一階馬爾科夫鏈。在不斷地跳轉(zhuǎn)之后,這個馬爾科夫鏈會形成一個平穩(wěn)分布,而PageRank 就是這個平穩(wěn)分布,每個網(wǎng)頁的PageRank 值就是平穩(wěn)概率。
隨機(jī)瀏覽模型中每個網(wǎng)頁的PR(PageRank)值,可通過以下公式計算:

其中:PR(i)為網(wǎng)頁i 的PR 值,L(j)為網(wǎng)頁j 的對外鏈出數(shù),Bi 為所有鏈接到網(wǎng)頁i 的網(wǎng)頁集合,n 為網(wǎng)絡(luò)中網(wǎng)頁的總數(shù),d 為阻尼系數(shù),即按照超鏈接進(jìn)行瀏覽的概率,一般取經(jīng)驗值為0.85,1-d 為瀏覽者隨機(jī)跳轉(zhuǎn)到一個新網(wǎng)頁的概率。一個網(wǎng)頁的PR 值是由其他網(wǎng)頁的PR 值計算得到的。由于PR=A*PR(A 為概率轉(zhuǎn)移矩陣)滿足馬爾科夫鏈的性質(zhì),那么通過迭代可以得到所有網(wǎng)頁的PR 值。經(jīng)過重復(fù)計算,這些網(wǎng)頁的PR 值會趨于正常和穩(wěn)定。
TextRank 算法是由PageRank 算法改進(jìn)而來的,它用句子代替網(wǎng)頁,任意兩個句子的相似性等價于網(wǎng)頁轉(zhuǎn)換概率,相似性得分存儲在一個方形矩陣中,類似于PageRank 中的矩陣A。用句子的相似度代替網(wǎng)頁的轉(zhuǎn)移概率,用歸一化的句子相似度代替了PageRank 中相等的轉(zhuǎn)移概率,這意味著在TextRank 中,所有節(jié)點的轉(zhuǎn)移概率不會完全相等。它的核心公式如下:

其中i=1,2,…n,ωji表示邊的權(quán)重,也就是句子之間的相似度。in(Vi)是指向網(wǎng)頁Vi 的網(wǎng)頁集合,Out(Vi)是網(wǎng)頁Vi 鏈接出去的網(wǎng)頁集合[3]。
Step 1:把所有文章整合成文本數(shù)據(jù),并把文本分割成單個句子。
Step 2:文本預(yù)處理,包括去除停用詞和非漢字字符,并進(jìn)行分詞。
Step 3:加載Word2Vec 詞向量,先得到句子中的所有詞語的詞向量,然后求詞向量的平均值,作為該句子的向量表示。
Step 4:計算句子向量間的相似性并存放在矩陣中,作為轉(zhuǎn)移概率矩陣A。
Step 5:然后將轉(zhuǎn)移概率矩陣轉(zhuǎn)換為以句子為節(jié)點、相似性得分為邊的圖結(jié)構(gòu),用于句子的TextRank計算。
Step 6:對句子按照TextRank 值進(jìn)行排序,排名最靠前的10 個句子作為摘要[1]。
每只股票的漲停都是有原因的,可能是基本面、消息面、股權(quán)相關(guān)原因,還可能是資金面,或是新股或次新股的原因。
獲得了某只股票的各種信息后,可綜合判斷漲停的原因,如2020 年9 月7 日的海立股份漲停,它的板塊屬性有:大數(shù)據(jù)、廣東板塊、國家安防、軍工、量子通信、區(qū)塊鏈、人工智能、軟件服務(wù)、網(wǎng)絡(luò)安全、云計算等,最后通過該股票的新聞,發(fā)現(xiàn)它成功地收購了馬瑞利汽車空調(diào)的相關(guān)資產(chǎn),所以它的漲停原因是并購,所屬的板塊應(yīng)為泛股權(quán)。
有了漲停股池的數(shù)據(jù),各股票漲停的原因和所屬板塊也判斷出來后,就可以確定每個板塊的龍頭股了。龍頭股確定的方法是,漲停板數(shù)最多的股票為龍頭股,如果板數(shù)相同則通過比較股票的漲停時間來確定,如同樣都是3 板,漲停時間早的就是龍頭股。每天也會有股票漲停,但因為某些原因最后沒有封住,又出現(xiàn)了下跌,這些漲停被砸的股票可直接通過爬蟲獲取數(shù)據(jù)后,也顯示出來,從而分析漲停又開板的原因,對整個股市的行情有一個綜合的認(rèn)知。
2020 年9 月7 日部分復(fù)盤結(jié)果如表1 所示。

表1 復(fù)盤結(jié)果
漲停板股票的復(fù)盤難點在于,股票漲停原因的分析和所屬板塊的確定。股票漲停的原因有很多,有時即使?jié)q停,對其原因的分析也是智者見智,不同的機(jī)構(gòu)常給出不同的結(jié)論,所以股票漲停所屬的板塊也經(jīng)常產(chǎn)生分歧,對它的分析也可結(jié)合次日股票的走勢情況來繼續(xù)進(jìn)一步判斷。本文中對股票新聞等信息的自動摘要生成采取了抽取式,還可以采取生成式,基于神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)的方法實現(xiàn)。獲得更為準(zhǔn)確的股票數(shù)據(jù)摘要信息,對于判斷股票漲停的原因也會產(chǎn)生更加有益的幫助。