R語言為量化而生
前言
做數據分析的朋友,一定聽說過R語言。R語言是一門統計語言,在數據分析領域優勢是非常明顯的。
本文以 「R語言,為量化而生」為題,說明R語言真的很適合做金融做量化策略。金融本身是玩數據行業,R的最大的優勢就是數據分析,所以用R來做量化投資的策略,真是很配,不僅順手而且方便,用了你就會知識。
本文將由3個方面來介紹,R語言做量化是多麼的適合。
目錄
- 為什麼是R語言?
- R語言的數據處理和時間序列
- R語言和金融模型
1. 為什麼是R語言?
那麼為什麼是R語言,而不是其他的語言? 先簡單介紹一下,我們的個人經歷。
我是一個程序員,從2004年開始接觸Java寫了10多年的Java程序,期間還嘗試過多種編程語言,VB、PHP、Python、SAS、R、Nodejs,最後把自己鎖定在R,Nodejs和Java。談不上對每一種語言都有很深的理解,但是每種語言的特點還是有點心得。
之所以選擇R,Nodejs和Java這3種語言,有一部分情懷,更多的是理性。從技術發展來看,編程開發變得越來越簡單,10年前用JavaEE做一個簡單的web項目至少要2人月,現在用Nodejs新人邊學邊搞只需10人天。而且隨著業務的多樣化,單一的技術已經不足以支撐業務的發展,業務在從傳統的軟體開發向互聯網和數據產品的方向在進化。根據不同語言的特點,每種都將在開發中佔據一席之地,而很難在出現一種語言統一天下的情況。
R語言將在數據分析領域發揮著重要的作用。R語言的3個特性,數學計算、數據建模和數據可視化。R語言封裝了多種基礎學科的計算函數,我們在R語言編程的過程中只需要調用這些計算函數,就可以構建出面向不同領域、不同業務的、複雜的數學模型。
另外,R的知識體系結構是複雜的,要想學好R,就必須把多學科的知識綜合運用,而最大的難點不在於R語言本身,在於使用者的知識基礎和綜合運用的能力。
圖中我將R語言知識體系結構分為3個部分:IT技術 + 業務知識 + 基礎學科。
- IT技術:是數據大發展時代必備的技術之一,R語言就是我們應該要掌握的一門技術。
- 業務知識:是市場經驗和法則,不管你在什麼公司,你都了解業務是什麼,產品是什麼,用戶是誰,公司的價值在哪裡!
- 基礎學科:是我們在學校里學到的理論知識,雖然當初學的時候並不理解,工作中如果你還能掌握並實際運用,那麼這將是你最有價值的競爭力。
關於R的知識體系,可以參考文章,R語言知識體系概覽
對於金融量化投資來說,剛好是一個交叉學科,你需要懂IT技術,熟悉金融市場的規則,有數學建模的能力。R語言,正好可以幫我們來解決這樣的問題,所以「R語言,為量化而生」!
對於做過數據分析的人來說,大家都了解什麼是最費時間的!!無疑就是數據處理的部分。
2. R語言的數據處理和時間序列
第二部分,我們來介紹一下R語言的數據類型和數據處理的一些方法。當然,本文並沒有介紹如何入門R語言,新手入門請參考文章R的極客理想系列文章
2.1 基本數據類型
在R語言中,數據類型包括向量類型,字元串類型,數字類型,布爾類型,矩陣類型,數據框類型,list類型等,通常我們在使用R語言里做數據處理的時候,大部分都會以數據框(data.frame)類型為一個主要的數據內存類型來使用。
數據框(data.frame)類型是R語言內置的一種數據類型,我們可以簡單地把它理解為,與關係型資料庫中表的結構是類似的,是一種二維的數據結構。
# 新建一個數據框n> data.frame(A=1:6,B=LETTERS[1:6])n A Bn1 1 An2 2 Bn3 3 Cn4 4 Dn5 5 En6 6 Fn
正是由於R語言內置了這樣的數據類型,使我們從資料庫讀取數據或導入CSV格式的數據時,與R語言有了一個很好的映射關係,直接載入到R語言的內存中變成標準化數據格式。
然後,就可以基於標準化的數據格式,用R語言的功能函數來處理數據了。比如,對於做資料庫開發的人員來說,他可以使用sqldf包,在R語言中通過SQL語句對數據進行數據變換。同時,也可以按著數據框(data.frame)的標準方法進行數據處理,通過約定的向量索引下標的方式來按行按列來讀取數據,或使用功能函數處理數據。
# sqldf包的使用n> library(sqldf)n> sqldf(select * from iris limit 6)n Sepal.Length Sepal.Width Petal.Length Petal.Width Speciesn1 5.1 3.5 1.4 0.2 setosan2 4.9 3.0 1.4 0.2 setosan3 4.7 3.2 1.3 0.2 setosan4 4.6 3.1 1.5 0.2 setosan5 5.0 3.6 1.4 0.2 setosan6 5.4 3.9 1.7 0.4 setosann# 向量索引n> iris[1:6,]n Sepal.Length Sepal.Width Petal.Length Petal.Width Speciesn1 5.1 3.5 1.4 0.2 setosan2 4.9 3.0 1.4 0.2 setosan3 4.7 3.2 1.3 0.2 setosan4 4.6 3.1 1.5 0.2 setosan5 5.0 3.6 1.4 0.2 setosan6 5.4 3.9 1.7 0.4 setosann# head函數使用n> head(iris)n Sepal.Length Sepal.Width Petal.Length Petal.Width Speciesn1 5.1 3.5 1.4 0.2 setosan2 4.9 3.0 1.4 0.2 setosan3 4.7 3.2 1.3 0.2 setosan4 4.6 3.1 1.5 0.2 setosan5 5.0 3.6 1.4 0.2 setosan6 5.4 3.9 1.7 0.4 setosan
我們經常還會對數據進行轉型處理,把數據框(data.frame)類型和其他數據類型的進行轉化。我們有時會使用矩陣計算,R語言中默認供了矩陣(matrix)數據類型,可以很方便地把數據框轉類型成矩陣類型,有時也需要把數據框的某一行或某一列轉型為一個向量類型數據,或者把數據框變成一個list類型。通過數據的格式變換,用標準化的數據結構來滿足數據分析的要求。
雖然R語言是統計語言,從性能上來說比C++/Java等語言慢不少。但對於數據分析的業務場景,用R語言來做數據處理的時候,你不用考慮程序如何架構,指針怎麼定義,內存是否會泄露,只要關注你的數據和演算法就行了。唯一需要注意的一點,不要直接用for循環的方式處理數據,盡量使用向量計算或矩陣計算的計算方法。當必須用循環的時候,你就需要用apply家族函數,代替for循環來做數據處理。關於apply家族函數的用法,請參考文章掌握R語言中的apply函數族
如果你的數據量比較大,1GB,10GB,甚至有100GB,對於這種規模比較大的數據集,apply的計算方式就不太能滿足計算性能的要求了。你依然可以用data.table包, bigmemory包, ff包等,或者並行計算的包加速R語言在單機上的計算的性能。data.table的使用方法,請參考文章超高性能數據處理包data.table。
那麼再大規模的數據,超過1TB這個量級,不只是R語言,每種語言都會遇到計算性能的瓶頸。這個時候,我們需要把數據放到分散式系統中,如Hadoop或其他大數據的引擎中進行存儲和計算。R語言與各種的大數據平台的通信介面都是通的,比如RHadoop,rhive, rhbase, rmongodb, rCassandra, SparkR, sparklyr等。如果你想了解hadoop的知識,請參考文章Hadoop家族系列文章,RHadoop實踐系列文章, R利劍NoSQL系列文章 之 Hive。
2.2 時間序列類型
除了R語言的內置基礎數據類型,對於金融的數據處理,一般我會把它變成標準的時間序列類型的數據,R語言中基本的時間序列的類型為 zoo 和 xts類型,當然還有一些其他包提供的數據類型。關於zoo和xts的詳細介紹,請參考文章 R語言時間序列基礎庫zoo,可擴展的時間序列xts
通過類型變換可以很方便地把的data.frame或者matrix等基礎類型數據,變成xts時間序列類型的數據。時間序列類型的好處是它默認會以時間作為索引,對於量化策略來說,每條數據記錄他都會有數據產生的時間,那這個時間就正好可以作為索引列的時間。
# 數據框n> df<-data.frame(A=1:6,B=rnorm(6))nn# xts時間序列類型n> xdf<-xts(df,order.by=as.Date(2016-01-01)+1:6);xdfn A Bn2016-01-02 1 -1.24013232n2016-01-03 2 -0.21014651n2016-01-04 3 -1.63251615n2016-01-05 4 -0.67279885n2016-01-06 5 0.01487863n2016-01-07 6 0.92012628nn# 類型檢查n> class(xdf)n[1] "xts" "zoo"n
那麼以時間作為數據的索引列的好處是,可以很方便地把數據以時間維度進行對齊。比如,你設計了一個股票交易策略和一個期貨交易策略,由於股票是T+1交易,今天買了明天才能賣;而期貨是T+0交易,今天買了馬上就可以賣出。針對不同的市場規則,在設計交易策略時,可能就會選擇不同的交易周期,那麼這時兩個策略的交易周期就會不一樣,那麼時間維度可能也不是對齊的。如果這兩個策略是對沖的,那麼我們就需要把它們以時間維度進行對齊,才能進行實現對策略模型對沖的準確計算。
把不同時間的維度的數據轉化成同一個時間維度,相當於做時間的標準化。通過標準化的操作,讓數據變成同一時間維度,數據之間才能夠進行計算。
舉個簡單的例子,我們做股票交易,在實盤交易過程中,你可能最關心的是每秒最新的價格數據,每一秒都會產生一條數據,這是屬於日內交易策略。另外,我們再做一個周期稍微長一點的策略,以日線為基礎的,那麼這裡一條記錄就是一天收盤價。對比日內策略,1秒鐘一條數據和1天一條數據,它們不同維度的數據,是不能直接進行計算。
我們要處理這種不同周期維度數據的時候,就需要把數據轉成同一個維度的。比如,我們對日線和周線的數據進行合併的時候,可以是把周線數據拆成日線數據,就是把一周分成五天。反過來,也可以把日線數據合併為周線數據,把5天的數據合併成一周。
所以這個時候就需要一個統一的數據格式進行標準化的數據定義,zoo和xts就是我們作為時間序列基礎數據類型。這兩個包是由第三方開發的,提供了很豐富的時間序列處理函數,我們可以直接使用這些函數來操作金融數據。很多其他的第三方金融演算法分析包,也都是以這兩個包作為基礎開發。
3. R語言和金融模型
當我們掌握了R語言處理數據的方法,了解了如何使用R語言的基礎數據類型和時間序列數據類型,下面我們就可以構建金融的策略模型。
金融建模跟其他行業的數據建模是類似的,只是由於行業不一樣,金融行業有很多背景知識和金融市場規則需要我們了解。金融本身就是一個玩數據的行業,你可以通過獲得交易數據,財務數據,上市公司的各種事件數據,基本面數據,宏觀數據,輿情數據,互聯網數據等,來構建你自己的交易策略。
我們需要把這些數據進行組合整理,結合你自己對業務的理解,使用R語言從數據中發現規律,並構建交易模型。用程序對歷史數據進行回測,來驗證規律的可靠性,是否會長期有效,並控制風險,最後把驗證過的規律變成演算法模型,這個就是金融策略建模的過程。
從金融交易分析的角度,可以從3個維度進行分析 基本面分析,技術面分析和消息面分析。
- 基本面:指對宏觀經濟、行業和公司基本情況的分析,包括公司經營理念策略、公司報表等的分析。長線投資一般用基本面分析,通過基本面可以判斷是否值去交易。
- 技術面:指通過技術指標變化,判斷股票走勢形態,進行K線組合等,通過技術面可以判斷如何進行交易。
- 消息面:指上市公司發布的利好和利空的消息,通過消息面可以判斷市場的情緒。
對於量化模型,大部分都是基於技術指標的模型,通過技術指標建模,跟蹤市場的表現。在不完全了解金融業務和金融市場的情況下,通過幾個技術指標來監控市場的走勢,發現市場的機會也是有可能的。
量化交易和主觀交易並不是對立的,量化交易是對主觀交易的補充,當我們以數據作為決策基礎的時候,其實可以盡量減少拍腦袋過程,創建數據模型也可以給我們心裡建立良好的信心。如果交易沒有使用量化的方法,那就跟我們平時做事一樣,你可能想到什麼就是什麼。沒有數據基礎,那完全就是感覺,這樣子交易就是很容易賠錢。
對於中國很多的散戶,聽到一個消息就跟著風的買賣股票,或者憑自己感覺大盤該漲了就跟進去,這些操作其實都是很不理性的。如果你通過量化的方法,即使再簡單,就靠幾條均線來進行判斷,這樣也是能給自己一個數據的基礎,建立信心,而不是完全拍腦袋的事兒。
量化交易模型主要是以技術指標為主,常用的技術指標有不少,雖然簡單但還是很有用的。對於很多實盤上運行的量化策略,大都會基於這些基礎的指標,但並不是把每個指標單獨使用。而是把多個指標通過變換組合使用,比如說MACD是均線模型,大部分的趨勢策略都以MACD做為基礎指標,通過變換再生成新的衍生指標。
常用的技術指標還包括KDJ、Boll、RSI、CCI等,當你直接使用這些指標的時候,可能效果並不是太好。因為市場上普遍接受了這些技術指標,已經被大量使用。單純地用一個指標,你掌握的信息並不比別人多,所以你可能抓不到市場上賺錢的機會。
我們需要把多種技術指標或者多個維度的指標進行結合,通過組合優化的方式來降低策略的不確定風險,同時提高收益率。如果你找到了一個只有你自己知道市場規律,你的策略產生的信號完全是跟別人有區別的,你抓住了別人看不到的機會,這個才是你的賺錢機會。你領先的越多,越少人知道這個規則,那你可能賺錢的機會就越多。
建立量化模型,其實和我們平時做數據分析的思考試是一樣的。要把這件事做好,我們需要把IT技術,業務知識和基礎學科知識做進一步的結合,當你發現這個結合是屬於你自己特有一個知識體系,你才能更好的發揮你的才能。
我們為什麼要用R來做這件事情?
首先,R語言本身提供了很多數學、統計的基礎包,讓數學計算變得非常容易。R語言提供了常用的數據結構,向量、數據框、矩陣等,把數據變成標準化的數據,你的關注點只在數據上就可以了。另外,R語言是免費開源的,很多的第三方開發者提供了豐富的數據挖掘包,讓你可以方便的使用各種演算法模型,短短几行代碼,就可以搞定一個複雜的事情。
R語言,在金融領域提供了很多交易框架或者計算模型,如果你了解了金融的理論知識以後,同時有一定的金融市場經驗,你可以很方便的利用這些別人提供的這些技術框架,來構建自己的交易模型。CRAN上發布的金融項目,你可以去 R的官方網站 (The Comprehensive R Archive Network),找到Task Views 菜單里的 Finance標籤。
通過調用第三方的程序包,自己的代碼量就變的非常少。我們做一個R語言的策略,如果是很複雜的,你可能要寫100-200行,但是如果你要實現同樣複雜的策略,放到C++/Java去實現,這個策略就是沒有1000-2000行是不可能實現的。在CRAN上面,簡單數一下Finance標籤下面列出的金融包就有141個,我相信沒有哪種語言會比R語言對金融行業支持的更多了。
雖然說R語言在性能上有些問題,但是我們會有多少了交易策略是基於一種高頻的模型,對性能要求極高的呢?其實很少。就算是高頻交易策略,幾秒鐘交易一次,R語言都可能滿足要求。
海量金融數據我們怎麼處理呢?
我們可以把基於海量數據的計算變成離線模型,金融行業每天都會產生大量的數據,像每日產生的交易數據,中國市場每天可能都是以GB的量來增長,跟互聯網比起來不是很快,但對於你程序載入10年的數據,他要GB或TB的一個量級。
R語言本身真的很難處理這種量級的數據,但是這種量級數據對於其他語言來說同樣是很難處理的。我們並不需要把這種體量的數據,都載入到內存中,進行實時數據計算。變成離線的計算模型,僅用於建模回測。把海量數據能變成離線的方式,放到hadoop或spark計算,用海量數據進行模型的訓練。
我們用到的實時數據,一般就是一天或幾天的數據,會不很大,每天從開盤到收盤可能也就1-2GB,對於這個大小,我們完全有能力放到內存中,進行各種各樣的計算。
做量化交易難點還是在於如何發現市場機會,R語言可以很好的滿足數據計算,建模,分析等的所有技術的部分。利用你的擅長,找到市場的機會,然後去實盤交易賺到錢,我們就完成了整個的交易過程。
本文並沒有介紹,如何用R語言真正的去實現一個交易策略,你可以通過下面的列表找到對應的文章。
- 二條均線打天下
- 均值回歸,逆市中的投資機會
- R語言構建追漲殺跌量化交易模型
- R語言構建配對交易量化模型
2015年我在創業,希望能推動R語言在金融量化領域的發展,但是由於種種原因項目沒有持續發展。接下來,我還會以個人的方式繼續努力,繼續推動R在金融領域的發展。R對我們的影響和改變是非常大的,我認識R是非常好的一門語言,我會把推動R的發展,當成一項事業來做。希望也能和各位業界朋友,一起努力,把這份事業做下去。
作者介紹:
張丹,R語言中文社區專欄特邀作者,《R的極客理想》系列圖書作者,民生銀行大數據中心數據分析師,前況客創始人兼CTO。
10年IT編程背景,精通R ,Java, Nodejs 編程,獲得10項SUN及IBM技術認證。豐富的互聯網應用開發架構經驗,金融大數據專家。個人博客 粉絲日誌, Alexa全球排名70k。
著有《R的極客理想-工具篇》、《R的極客理想-高級開發篇》,合著《數據實踐之美》,新書《R的極客理想-量化投資篇》(即將出版)。
《R的極客理想-工具篇》京東購買快速通道:《數據分析技術叢書:R的極客理想·工具篇》(張丹 )【摘要 書評 試讀】- 京東圖書
《R的極客理想-高級開發篇》京東購買快速通道:《R的極客理想 高級開發篇》(張丹)【摘要 書評 試讀】- 京東圖書
《數據實踐之美》京東購買快速通道:《數據實踐之美:31位大數據專家的方法、技術與思想》(天善智能)【摘要 書評 試讀】- 京東圖書
博客專欄:張丹的博客專欄
大家也可以加小編微信:tswenqu(備註:知乎),進R語言中文社區 交流群,可以跟各位老師互相交流
推薦閱讀: