【发布时间】:2011-06-11 17:05:03
【问题描述】:
我正在尝试创建一个函数来创建一个索引(从 100 开始),然后根据投资结果调整该索引。因此,简而言之,如果第一次投资的利润为 5%,那么该指数将为 105,如果第二个结果为 -7%,则该指数为 97.65。在这个问题中,当我使用“索引”一词时,我不是指的是zoo 包的index 函数。
除了创建这个索引之外,我的目标也是创建一个可以应用于我的完整数据集的各种子集的函数(即使用sapply 和它的朋友)。
这是我目前拥有的功能(本问题末尾的数据):
CalculateIndex <- function(x){
totalAccount <- accountValueStart
if(x$TradeResult.Currency == head(x$TradeResult.Currency., n = 1)){
indexedValues <- 100 + ( 100 *((((x$Size.Units. * x$EntryPrice) / totalAccount) * x$TradeResult.Percent.) / 100))
# Update the accountvalue
totalAccount <- totalAccount + x$TradeResult.Currency.
}
else{ # the value is not the first
indexedValues <- c(indexedValues,
indexedValues[-1] + (indexedValues[-1] *(((x$Size.Units. * x$EntryPrice) / totalAccount) * x$TradeResult.Percent.) / 100)
)
# Update the accountvalue
totalAccount <- totalAccount + x$TradeResult.Currency.
}
return(indexedValues)
}
函数执行(阅读:旨在执行)以下操作:
如果值是第一个,则使用100 作为索引的起点。如果该值不是第一个,则以之前计算的索引值作为计算新索引值的起点。除此之外,该函数还取单个结果的权重(与totalAccount值相比) ) 考虑在内。
问题:
在 theData 数据帧上使用此 CalculateIndex 函数会产生以下错误输出:
> CalculateIndex(theData)
[1] 99.97901 99.94180 99.65632 101.88689 100.89309 98.92878 102.02911 100.49159 98.52955 102.02243 98.43655 100.76502 99.34869 100.76401 101.18014 99.75136 97.90130
[18] 100.39935 99.81311 101.34961
Warning message:
In if (x$TradeResult.Currency == head(x$TradeResult.Currency., n = 1)) { :
the condition has length > 1 and only the first element will be used
编辑: 哇,我已经投了反对票,尽管我认为我的问题已经太长了。抱歉,我认为/认为问题出在我的循环中,所以我不想让你厌烦细节,我认为这些细节只会给出更少的答案。抱歉,我的判断有误。
问题是,对于CalculateIndex 的上述输出,结果与 Excel 大不相同。尽管这可能是由于舍入错误造成的(正如 Joris 在下面提到的那样),但我对此表示怀疑。与 Excel 的结果相比,R 的结果有很大的不同:
R output Excel calculate values
99,9790085700 99,97900857
99,9418035700 99,92081189
99,6563228600 99,57713687
101,8868850000 101,4639947
100,8930864300 102,3570786
98,9287771400 101,2858564
102,0291071400 103,3149664
100,4915864300 103,806556
98,5295542900 102,3361186
102,0224285700 104,3585552
98,4365550000 102,795089
100,7650171400 103,5601228
99,3486857100 102,9087897
100,7640057100 103,6728077
101,1801400000 104,8529634
99,7513600000 104,6043164
97,9013000000 102,5055298
100,3993485700 102,9048999
99,8131085700 102,7179995
101,3496071400 104,0676555
我认为公平地说,输出的差异不是 R 与 Excel 问题的结果,而是我的函数中的错误。所以,让我们专注于函数。
函数的手动计算 该函数使用不同的变量:
-
Size.Units.;这是在EntryPrice购买的单位数量。 -
EntryPrice:买入股票的价格, -
TradeResult.Percent.:投资产生的收益或损失百分比, -
TradeResult.Currency.:投资收益或损失的货币价值(美元),
这些变量用于函数的以下部分:
100 + ( 100 *((((x$Size.Units. * x$EntryPrice) / totalAccount) * x$TradeResult.Percent.) / 100))
和
indexedValues[-1] + (indexedValues[-1] *(((x$Size.Units. * x$EntryPrice) / totalAccount) * x$TradeResult.Percent.) / 100)
两个公式基本相同,不同之处在于第一个从100 开始,第二个使用previous value 计算新的索引值。
公式可以分为不同的步骤:
首先,x$Size.Units. * x$EntryPrice 确定所持有的总头寸,即以 48.98 的价格购买 100 股股票会获得 4898 美元的头寸。
得到的总头寸然后除以总账户规模(即totalAccount)。这是纠正一个头寸相对于整个投资组合的影响所必需的。例如,如果我们以 48.98 买入的 100 股下跌 10%,则计算出的指数(即CalculateIndex 函数)不一定必须下跌 10%,因为当然不是所有的钱都在 @ 987654344@投资一只股票。因此,通过将总头寸除以totalAccount,我们得到一个比率,它告诉我们投资了多少资金。例如,如果股票下跌 10%,则规模为 4898 美元(总账户为 14000)的头寸导致总账户损失为 3.49%。 (即4898 / 14000 = 0.349857. 0.349857 * 10% = 3.49857%)
这个比率(投资金额与总金额的比率)然后在公式中乘以x$TradeResult.Percent.,从而得到对总账户的百分比影响(参见上一段中的计算示例) .
作为最后一步,总账户的百分比损失应用于指数值(从100 开始)。在这种情况下,第一次投资 100 股以 48.89 美元买入,让指数从 100 的起点跌至 99.97901,反映亏损交易对总账户的影响。
编辑结束
将函数剥离干净,然后一次添加一部分公式,为了发现错误,我来到了错误所在的以下步骤:
CalculateIndex <- function(x){
totalAccount <- accountValueStart
if(x$TradeResult.Currency == head(x$TradeResult.Currency., n = 1)){
indexedValues <- totalAccount
# Update the accountvalue
totalAccount <- totalAccount + x$TradeResult.Currency.
}
else{ # the value is not the first
indexedValues <- c(indexedValues, totalAccount)
# Update the accountvalue
totalAccount <- totalAccount + x$TradeResult.Currency.
}
return(indexedValues)
}
> CalculateIndex(theData)
[1] 14000
Warning message:
In if (x$TradeResult.Currency == head(x$TradeResult.Currency., n = 1)) { :
the condition has length > 1 and only the first element will be used
所以,如果我只使用 totalAccount 变量,函数似乎无法正确更新。这似乎表明if else 语句的基础存在一些错误,因为它只输出第一个值。
如果我从函数中删除else 语句,我会得到theData 中每一行的值。然而,这些然后被错误地计算。所以,在我看来,这个函数如何更新totalAccount 变量存在一些错误。我看不出我在哪里犯了错误,所以任何建议都会受到高度赞赏。我做错了什么?
数据
我的数据如下所示:
> theData
Size.Units. EntryPrice TradeResult.Percent. TradeResult.Currency.
1 100 48.98 -0.06 -3
11 100 32.59 -0.25 -8
12 100 32.51 -1.48 -48
2 100 49.01 5.39 264
13 100 32.99 3.79 125
14 100 34.24 -4.38 -150
3 100 51.65 5.50 284
4 100 48.81 1.41 69
15 100 35.74 -5.76 -206
5 100 49.50 5.72 283
6 100 46.67 -4.69 -219
16 100 33.68 3.18 107
7 100 44.48 -2.05 -91
17 100 32.61 3.28 107
8 100 45.39 3.64 165
9 100 47.04 -0.74 -35
10 100 47.39 -6.20 -294
18 100 33.68 1.66 56
19 100 33.12 -0.79 -26
20 100 32.86 5.75 189
theData <- structure(list(X = c(1L, 11L, 12L, 2L, 13L, 14L, 3L, 4L, 15L,
5L, 6L, 16L, 7L, 17L, 8L, 9L, 10L, 18L, 19L, 20L), Size.Units. = c(100L,
100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L,
100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L), EntryPrice = c(48.98,
32.59, 32.51, 49.01, 32.99, 34.24, 51.65, 48.81, 35.74, 49.5,
46.67, 33.68, 44.48, 32.61, 45.39, 47.04, 47.39, 33.68, 33.12,
32.86), TradeResult.Percent. = c(-0.06, -0.25, -1.48, 5.39, 3.79,
-4.38, 5.5, 1.41, -5.76, 5.72, -4.69, 3.18, -2.05, 3.28, 3.64,
-0.74, -6.2, 1.66, -0.79, 5.75), TradeResult.Currency. = c(-3L,
-8L, -48L, 264L, 125L, -150L, 284L, 69L, -206L, 283L, -219L,
107L, -91L, 107L, 165L, -35L, -294L, 56L, -26L, 189L)), .Names = c("X",
"Size.Units.", "EntryPrice", "TradeResult.Percent.", "TradeResult.Currency."
), class = "data.frame", row.names = c(NA, -20L))
# Set the account start @ 14000
> accountValueStart <- 14000
【问题讨论】:
-
@Jura25:我尝试通过添加数据对象的 ASCII 表示(使用:
dput())来编辑您的问题,以便能够更轻松地读取 R 中的数据框。 -
@Jura - 您需要确保您的数据正确排序吗?我没有关注您的索引的所有详细信息,但 indexedValues[k] 的值依赖于 indexedValues[k - 1] 上的计算值。您在上面发布的数据似乎表明行顺序可能不符合..即1、11、12、2、13、14 等...另外,为什么不将
accountStartValue作为第二个参数传递给您的函数? -
@Jura 您用文字描述的内容与您尝试编写的代码几乎没有关系。有一个货币变量,一些您没有描述但似乎与您尝试做的事情不可或缺的单位和价格。您的代码也很难阅读。你能解释一下
Size.Units.、EntryPrice和TradeResult.Currency.是什么以及它们是如何进入问题的。 -
@ 反对者:没有理由反对这个问题。这并不是因为 OP 出现了一些编码错误,这不是一个坏问题。他提供了足够的信息,说明他拥有什么、他想做什么以及他的数据。我怎么能在 10 分钟内解决这个问题?
-
@Gavin:在 R 编程考试中提问会是一个很好的难题:优化以下代码 :-)
标签: function r if-statement