題外話:
關於這篇文章 新手小白掙扎了很久 因為手上想寫的內容太多了
但很懶得做整理.....
前幾天決定開了一個粉絲頁 算是督促自己吧~ 於是今天就生了一篇文章出來
另外 此篇請配上一個文章一起服用
用R的 quantmod 和 TTR 套件來寫出和執行簡單的 交易策略
http://markjong001.pixnet.net/blog/post/182284907
關於"回測" 這件事情 其實要討論的點有很多
但簡單的一個想法就是:
假設我想好一個策略 那我要怎麼去評估它到底有沒有賺錢呢??
新手小白是這樣想的:
想像自己回到過去 我挑了一隻我認為不錯個股票
根據我的策略 一步一步的進行買賣
那到了今天 我會賺or賠多少錢?
先讓我們回到上一篇的買點跟賣點
UpBuy[UpBuy==1]
DownSell[DownSell==-1]
特別值得一題的是 因為沒有考慮資金分配的問題
所以我回測的時候是考慮一買一賣的情況
在這樣的情況 上一篇的買賣點就需要做一些修正
下圖可以表示我修正的概念
如果寫成code的話 如下
#給定一些起始參數
hbuy=UpBuy[UpBuy==1]
hbuy=as.Date(time(hbuy))
hsale=DownSell[DownSell==-1]
hsale=as.Date(time(hsale))
dbuy=hbuy[0]
dsale=hsale[0]
state=0
######## 定義一個算距離的FUN
fun1 <- function(x1,x2){
qq=0;des=c()
for(qq in 1:length(x2) ){
des[qq]=(x2[qq]-x1)
}
return(des)
}
###################################
qq=1
while(qq>0)
{
if(state==0)
{
if(is.null(hsale) ){ break }
if(is.null(hbuy)){ break }
dlen=fun1( time(hbuy[1]),time(hsale) );
dlen=dlen[dlen>0];
if( is.null(dlen)==FALSE &&is.na(dlen)==FALSE ){ state=1;
dbuy[qq]=hbuy[1];dsale[qq]=hbuy[1]+min(dlen)
}
}else{ ## 前一筆買賣成功 則 重新判斷下一筆買點(買點要是大於前一次出場點)
hbuy = hbuy[hbuy> dsale[qq-1] ];
dlen=fun1( hbuy[1] ,hsale);
dlen=dlen[dlen>0];
if( is.null(dlen)==FALSE&&is.na(dlen)==FALSE){
dbuy[qq]=hbuy[1];dsale[qq]=hbuy[1]+min(dlen)
}
}
if(is.na(dsale[qq]) || is.null(dsale[qq]) ){ break }
if(is.na(dbuy[qq]) || is.null(dbuy[qq]) ){ break }
qq=qq+1
}
稍微解釋一下
我給定了 dlen 和 一個算距離的FUN
這個目的是為了找出距離"買點" 最近的"賣點"
而所謂的距離當然就是 時間
因此我使用了 time() 這個套件裡的函數
把xts 這種類別的 時間抓出來
例如:
註: 如果是要取得xts中的矩陣部分可以用 coredata()
好啦~~ 我稍微修正買賣點 成為一買一賣
並且我有買進和賣出的時間 這樣我就可以來算一下 報酬 和其他參考的指標
先定義出 B 和 S 分別是 買進價和賣出價
B=as.numeric(stkclose[match(dbuy,time(stkclose))])
S=as.numeric(stkclose[match(dsale,time(stkclose))])
profit=sum(S-B) #總損益
ARR=mean((S-B)/B) #平均報酬
NW=length(which(S-B >0)) # 贏的個數
WR=length(which(S-B >0))/length(which(S-B <0)) # 輸贏比
WA=mean((S-B)[which(S-B >0)]) # 平均贏的錢
WL=mean((S-B)[which(S-B <0)]) #平均輸的錢
WLR=WA/abs(WL) #賺賠比
#以下是這次跑出來的結果
有點不盡理想 但總而言之是有賺錢的啦~~
損益 44.5元 平均報酬率 1.6%
再補充一下 這次還有用到的一些函數while 的用法
正式的寫法:
while ( 執行條件 )
{
要執行的事情
}
我在寫的時候 會先給一個 起始值 qq=0, 然後每次執行的時候 qq=qq+1, 執行條件為 qq>0
這樣while 就會一直執行下去了 和 for 不太一樣的是 while 不用一開始就輸入 到底要執行幾次
我們可以搭配 break 這個函數來結束
像我這次的寫法就變成
if(is.na(dbuy[qq]) || is.null(dbuy[qq]) ){ break }
我會去檢查 如果 買點 是 null 或 na 的時候 (也就是算不出來的時候) 跳出while 的迴圈
後記 : 因為新手小白認為測單支股票 對於策略來說 說服力會不太夠
所以下次 會來寫一個 可以把所有股票都一次測完的程式~~
請大家期待囉!!