簡體   English   中英

如何概括該算法(符號模式匹配計數器)?

[英]How to generalize this algorithm (sign pattern match counter)?

我在R中有以下代碼:

corr = function(x, y) {
    sx = sign(x)
    sy = sign(y)

    cond_a = sx == sy && sx > 0 && sy >0
    cond_b = sx < sy && sx < 0 && sy >0
    cond_c = sx > sy && sx > 0 && sy <0
    cond_d = sx == sy && sx < 0 && sy < 0
    cond_e = sx == 0 || sy == 0

    if(cond_a) return('a')
    else if(cond_b) return('b')
    else if(cond_c) return('c')
    else if(cond_d) return('d')
    else if(cond_e) return('e')
}

它的作用是與R中的mapply函數結合使用,以便計算時間序列中存在的所有可能的符號模式。 在這種情況下,模式的長度為2,所有可能的元組為: (+,+)(+,-)(-,+)(-,-)

我以這種方式使用corr函數:

> with(dt['AAPL'], table(mapply(corr, Return[-1], Return[-length(Return)])) /length(Return)*100)

         a          b          c          d          e 
24.6129416 25.4466058 25.4863041 24.0174672  0.3969829 

> dt["AAPL",list(date, Return)]
      symbol       date     Return
   1:   AAPL 2014-08-29 -0.3499903
   2:   AAPL 2014-08-28  0.6496702
   3:   AAPL 2014-08-27  1.0987923
   4:   AAPL 2014-08-26 -0.5235654
   5:   AAPL 2014-08-25 -0.2456037

我想將corr函數概括為n參數。 這意味着對於每個n我將必須寫下與所有可能的n元組相對應的所有條件。 目前,我能想到的最好的方法是使python腳本使用循環來編寫代碼字符串,但是必須有一種正確執行此操作的方法。 您是否對如何概括條件性條件編寫有一個想法,也許我可以嘗試使用expand.grid但是如何進行匹配呢?

這是一種稍微不同的方法,但是它可以為您提供所需的內容,並允許您使用任意大小的n元組。 基本方法是為每個連續的n個返回集找到相鄰變化的符號,將n長度的符號變化轉換為1和0的n個元組,其中0 =負返回而1 =正返回。 然后計算每個n元組的十進制值作為二進制數。 對於每個不同的n元組,​​這些數字將明顯不同。 使用Zoo時間序列進行這些計算可提供幾個有用的函數,包括get.hist.quote()檢索股票價格,diff()計算收益,以及rollapply()函數用於計算n元組及其和。下面的代碼進行這些計算,將符號變化的總和轉換回二進制n位元組,並將結果收集到一個數據幀中。

library(zoo)
library(tseries)
n <- 3     # set size of n-tuple
#
#  get stock prices and compute % returns
#
dtz <- get.hist.quote("AAPL","2014-01-01","2014-10-01", quote="Close")
dtz <-  merge(dtz, (diff(dtz, arithmetic=FALSE ) - 1)*100)
names(dtz)  <-  c("prices","returns")
#
#  calculate the sum of the sign changes
#
dtz <- merge(dtz, rollapply( data=(sign(dtz$returns)+1)/2, width=n, 
                       FUN=function(x, y) sum(x*y), y = 2^(0:(n-1)), align="right" ))
dtz <- fortify.zoo(dtz)
names(dtz)  <-  c("date","prices","returns", "sum_sgn_chg")
#
#  convert the sum of the sign changes back to an n-tuple of binary digits
#
for( i in 1:nrow(dtz) ) 
    dtz$sign_chg[i] <- paste(((as.numeric(dtz$sum_sgn_chg[i]) %/%(2^(0:2))) %%2), collapse="")
#
#  report first part of result
#
head(dtz, 10)
#
#  report count of changes by month and type
#
table(format(dtz$date,"%Y %m"), dtz$sign_chg)

可能的輸出示例是一個表格,該表格顯示了每個月按類型進行的更改計數。

         000 001 010 011 100 101 110 111 NANANA
 2014 01   1   3   3   2   3   2   2   2      3
 2014 02   1   2   4   2   2   3   2   3      0
 2014 03   2   3   0   4   4   1   4   3      0
 2014 04   2   3   2   3   3   2   3   3      0
 2014 05   2   2   1   3   1   2   3   7      0
 2014 06   3   4   3   2   4   1   1   3      0
 2014 07   2   1   2   4   2   5   5   1      0
 2014 08   2   2   1   3   1   2   2   8      0
 2014 09   0   4   2   3   4   2   4   2      0
 2014 10   0   0   1   0   0   0   0   0      0

因此,這表明在2014年1月1日中,存在一組三天,其中000表示3個下降收益,3天001的變化表示兩個下降收益,然后是一個正收益,依此類推。 大多數月份似乎都具有相當隨機的分布,但是5月和8月顯示了3天正回報的7套和8套,這反映了AAPL的強勁月份。

我認為您最好在zoo軟件包中使用rollapply(...) 由於您似乎quantmod使用quantmod (加載xtszoo ),因此這里的解決方案不使用所有嵌套的if(...)語句。

library(quantmod)
AAPL    <- getSymbols("AAPL",auto.assign=FALSE)
AAPL    <- AAPL["2007-08::2009-03"]    # AAPL during the crash...
Returns <- dailyReturn(AAPL)

get.patterns <- function(ret,n) {
  f <- function(x) {  # identifies which row of `patterns` matches sign(x)
    which(apply(patterns,1,function(row)all(row==sign(x))))
  }
  returns  <- na.omit(ret)
  patterns <- expand.grid(rep(list(c(-1,1)),n))
  labels   <- apply(patterns,1,function(row) paste0("(",paste(row,collapse=","),")"))
  result   <- rollapply(returns,width=n,f,align="left")
  data.frame(100*table(labels[result])/(length(returns)-(n-1)))
}
get.patterns(Returns,n=2)
#      Var1     Freq
# 1 (-1,-1) 22.67303
# 2  (-1,1) 26.49165
# 3  (1,-1) 26.73031
# 4   (1,1) 23.15036

get.patterns(Returns,n=3)
#         Var1      Freq
# 1 (-1,-1,-1)  9.090909
# 2  (-1,-1,1) 13.397129
# 3  (-1,1,-1) 14.593301
# 4   (-1,1,1) 11.722488
# 5  (1,-1,-1) 13.636364
# 6   (1,-1,1) 13.157895
# 7   (1,1,-1) 12.200957
# 8    (1,1,1) 10.765550

基本思想是創建具有2^n行和n列的patterns矩陣,其中每一行代表一種可能的模式(例如,(1,1),(-1,1)等)。 然后使用rollapply(...)將每日收益率n傳遞給該函數,並確定patterns中的哪一行與sign(x)完全匹配。 然后使用該行號向量和一個labels索引,該索引包含模式的字符表示,然后像您一樣使用table(...)

這是n天模式的常規設置,但它忽略了任何收益恰好為零的情況,因此$Freq列的$Freq$Freq 100。如您所見,這種情況很少發生。

有趣的是,即使在墜機事故中,連續兩個工作日(而不是兩個休息日)的可能性(非常小)。 如果在此期間查看plot(Cl(AAPL)) ,您會發現這是一個非常瘋狂的旅程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM