如何为 fPortfolio 设置库并调用 pfolioTargetReturn

How to set up libraries for fPortfolio and call pfolioTargetReturn

我正在调试另一个作者的代码。我认为代码是正确的,但我的系统设置错误。它正在从一个包中调用一个函数,并收到一条错误消息:

> fPortfolio::pfolioTargetReturn( Data, weights = wgts )
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘series<-’ for signature ‘"numeric", "matrix"’

错误消息本身说找不到这个函数签名的方法,这意味着函数调用签名错误,或者该方法未加载或被遮盖。

参数(数据和 wgts)的格式似乎正确:

> str(Data)
Time Series:          
 Name:               object
Data Matrix:        
 Dimension:          431 13
...
> str( wgts )
 Named num [1:13] 0.038 0.1467 0.038 0.3 0.0228 ...

发送到 pfolioTargetRisk 的相同参数似乎工作正常:

> fPortfolio::pfolioTargetRisk( Data, weights = wgts )
 TargetRisk 
0.002415664 

如果我用更简单的向量替换 wgts,我会得到同样的错误:

> pfolioTargetReturn(Data, weights = rep(x=1/13, times=13))
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘series<-’ for signature ‘"numeric", "matrix"’

我以多种不同的方式安装了该库:最初来自我前任的 packrat;最近根据 https://wiki.rmetrics.org/install_rmetrics 上的贡献者维基百科。所以我想我已经设置了所有依赖项。我认为问题出在我的搜索路径上:在另一个包中设置了另一个 "series <-" 函数,掩盖了我的。我的搜索路径是:

> search()
 [1] ".GlobalEnv"         "package:fPortfolio" "package:fAssets"    "package:fBasics"   
 [5] "package:xts"        "package:zoo"        "package:timeSeries" "package:timeDate"  
 [9] "package:knitr"      "tools:rstudio"      "package:stats"      "package:graphics"  
[13] "package:grDevices"  "package:utils"      "package:datasets"   "package:methods"   
[17] "Autoloads"          "package:base"  

如何解决此错误消息?


更新: 我逐步执行了 fPortfolio 库中的函数,并到达了我得到相同结果的那一行

> series( Return ) <- x %*% weights
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘series<-’ for signature ‘"numeric", "matrix"’

这显然符合我们目前所见的一切。 x 早已投as.matrix(Data),权重是我的 rep(x=1/13, times=13) 向量。

> dim(x)
[1] 431  13
> length(weights)
[1] 13
> str( x %*% weights )
 num [1:431, 1] 0.002000 -0.000000 -0.001000 0.002000 0.002000 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:431] "2012-05-17" "2012-05-20" "2012-05-21" "2012-05-22" ...
  ..$ : NULL

但在我看来,一个 431x13 矩阵矩阵乘以一个 13 长度向量应该得到一个 431x1 矩阵或一个 431 长度向量,看起来 R 将它作为一个 431x1 矩阵。在我看来 series(Return) 也同样失败了

> series(Return)
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘series’ for signature ‘"numeric"’
> str(Return)
 Named num [1:431] -0.00100 -0.00200 -0.00500 -0.00200 0.00800 ...
 - attr(*, "names")= chr [1:431] "2012-05-17" "2012-05-20" "2012-05-21" "2012-05-22" ...

所以通过图书馆追踪,我发现我的电话

pfolioTargetReturn( Data, weights = wgts )

被发送到

> pfolioTargetReturn
function (x, weights = NULL) 
{
    x = as.matrix(x)
    ans = mean(pfolioReturn(x = x, weights = weights))
    names(ans) = "TargetReturn"
    ans
}
<environment: namespace:fPortfolio>
> pfolioReturn
function (x, weights = NULL, geometric = FALSE) 
{
    weights <- as.vector(weights)
    if (geometric) {
        X <- t(colCumprods(1 + x) - 1)
        X <- rbind(diff(t(X * weights)))
        Return <- x[, 1]
        series(Return[+1, ]) <- x[1, ] %*% weights
        series(Return[-1, ]) <- rowSums(X)
    }
    else {
        Return <- x[, 1]
        series(Return) <- x %*% weights
    }
    colnames(Return) <- "pfolioRet"
    Return
}
<environment: namespace:fPortfolio>

首先将我的 Data 发送到 x,然后将其转换为 x = as.matrix(x) 中的矩阵,然后将其发送到 pfolioReturn,其中(因为我离开 geometric出来,默认为FALSE)。我的 wgts 被发送到 weights,它被转换为 weights <- as.vector(weights) 中的向量。然后

Return <- x[, 1]
series(Return) <- x %*% weights

Return 作为 431 长度向量返回。 x %*% weights 变成 431x1 矩阵(上面讨论过),这就是我们需要的。 series <- 调用 timeSeries 和矩阵。我有一个向量和一个矩阵。所以现在我认为问题是向量 Return 不是 timeSeries。我的 Data 以时间序列开始,fPortfolio 库将其更改为 Return <- x[, 1].

中的向量

如果我没有出现某种安装错误(我仍然有点不敢相信),那么您刚刚帮我找到了库中的错误。我在 pfolioReturn 函数中添加了一行 Return <- as.timeSeries(Return),现在我得到了答案。

我得到了同样的错误。 timeSeries::'series<-' 需要一个矩阵,而您却没有给它一个。先在报错信息中找到问题函数:

getAnywhere(`series<-`)
#----------
A single object matching ‘series<-’ was found
It was found in the following places
  namespace:timeSeries
# snipped rest of output-----------

然后看看它期望的参数是什么:

showMethods(timeSeries::`series<-`,  includeDefs=TRUE)
#-------------------
Function: series<- (package timeSeries)
x="timeSeries", value="ANY"
function (x, value) 
{
    callGeneric(x, as(value, "matrix"))
}


x="timeSeries", value="matrix"
function (x, value) 
{
    if (identical(dim(x), dim(value))) {
        x@.Data <- value
        if (!is.null(cn <- colnames(value))) 
            colnames(x) <- cn
        return(x)
    }
 #snipped rest of definiton:

它做的第一件事是检查维度一致性,尽管由于不满足签名而代码从未到达那里: