r - 计算最佳复利期(加密货币)

标签 r math optimization logic cryptocurrency

我有一个有趣的问题,我不确定将其放在此处或堆栈数学中的最佳位置,但由于我尝试以编程方式解决它(在 R 中,但任何编程语言都可以)也许 StackOverflow 是最好的地方。这个问题涉及复合加密货币。 问题如下: 您在流动性池中质押“K”数量的代币以获得利息。 流动性池为您的代币提供“年利率”(APR),即年利息,APR 不复利。 您可以随时复利您的利息,但每次您都必须支付少量费用。

我最初尝试用一些 for 循环来解决这个问题,如果假设的用户每隔“D”天进行复利,则估计最终返回。 当前示例使用 CAKE 和 BNB 代币。一些简化解决方案的假设。想象一下 APR、bnb_value 和 cake_value 是固定值(它们不是现实中的)。

APR=1.349  ## the interest value showed in the pool, divided by 100
APR_day=APR/365.0 ## the daily APR
bnb_value=210 ## current value of the BNB token, in euro or dollar or any FIAT
fee_bnb=0.002*bnb_value ## current fee in euro or dollar or any FIAT
initial_cakes=10
cake_value=10

adf=data.frame(col1=NULL, col2=NULL, col3=NULL, col4=NULL)
## we generate a sequence containing fractional days up to the third day
## and then full days starting from the fourth day
comp_intervals=c(seq(0.1, 3, 0.1), 4:30)
for(j in comp_intervals){
  acquired_int=0  ## acquired interest in "j" days
  current_val=initial_cakes  ## current value of the capital
  all_fees=0  ## fees paid for the transactions
  aseq=seq(j, 365, j)  ## list of the compounding events in days
  
  # apr_seq is APR for the "j" period. If "j" is 1 it's the daily APR,
  # but for longer compounding intervals the APR for the "j" period
  # become larger
  apr_seq=APR_day*j
  for(i in aseq){
    acquired_int=current_val*apr_seq
    current_val=current_val+acquired_int
    all_fees=all_fees+fee_bnb
    acquired_int=0
  }
  
  ## we add the interest for the remaining days of the year, if any, to current_val
  acquired_int=(365-max(aseq))*APR_day*current_val
  current_val=current_val+acquired_int
  
  final_gain=round(current_val*cake_value - all_fees, 2)
  # msg=paste0("Final gain in Euro minus fees: ", final_gain)
  # print(msg)
  apy_i_day= round(final_gain/(initial_cakes*cake_value), 5)
  # msg=paste0("apy compounding every ", j, " days is: ", apy_i_day)
  # print(msg)
  # cat("\n")
  adf=rbind(adf, data.frame(fiat_value=final_gain,
      APY_val=100*apy_i_day, compounding_days=j, cakes=current_val))
  
}
# finally we show, who, among the various compounding, had the hiest yield
adf[adf$APY_val==max(adf$APY_val), ]

问题在于,您刚刚看到的代码并没有真正告诉您复合兴趣的最佳时期。它更多地告诉您如果用户每“D”天复利一次, yield 是多少。它接近真正的解决方案,但事实并非如此! 你可以直观地了解到延长时间是错误的。您从少量资本开始,因此为了获得良好的返回,您由于费用而“很少”复利,但随着时间的推移,您的资本会增长更多。您的资本增长得越多,您就应该复利。

然后我尝试了不同的方法。

给出“年 yield ”的一般公式如下:

APY = (1 + APR/N)^N -1

如果您还考虑费用和您拥有的初始资本:

Final_capital=Initial_capital*APY - single_fee*N

其中 APR 是百分比,N 是复合事件的数量(在此公式中,它们在时间上均匀分布)。

通过将 Final_capital 除以“dN”并找到方程的零点,您可以获得最佳的复合事件数。如果将 365 除以最佳复利事件数,您应该在应该复利代币的天数后得到结果。 我从微分公式得到的结果与第一个解不同,我不确定为什么。我也认为,但我不确定,后一种解决方案与前一种解决方案具有相同的局限性。

library(utils)
### interest APY formula minus fees
final_v=function(x, APR, fee_bnb, initial_value){
  return(  initial_value*( (1+APR/x)^x - 1 ) -fee_bnb*x   ) 
}

## differential respect to X of the interest APY formula minus the fees
a_diff_comp=function(x, APR, fee_bnb, initial_value){
  return( (initial_value*( (APR/x + 1)^x )*(  log(APR/x + 1) - APR/(  ((1/x)+1)*x  ) ) ) - fee_bnb )
}

x=3:40
y=sapply(x, a_diff_comp, APR=APR, fee_bnb=fee_bnb, initial_value=(initial_cakes*cake_value))
plot(x,y)

y2=sapply(x, final_v, APR=APR, fee_bnb=fee_bnb, initial_value=(initial_cakes*cake_value))
plot(x,y2)

xmin <- uniroot(a_diff_comp, c(1, 100), tol = 0.000001, APR=APR, fee_bnb=fee_bnb, initial_value=(initial_cakes*cake_value))
xmin$root

那么,如何正确计算最佳复利间隔呢?

最佳答案

我在 GitHub 页面上发表了评论 https://github.com/amendez/cakecalc/issues/2#issuecomment-806364370 .

但我想我现在明白你的意思了。我同意你的观点,甚至我的个人经历也证明了你的观点。 cakeCalc 为您提供最佳配比的方式存在一些问题。在计算最终结果时,它认为你的余额在每次复利后都是固定的,这似乎是有问题的。因此,每次您复合蛋糕时,即使您完全按照 cakeCalc 建议的说明进行操作,cakeCalc 也会给出不同的结果,因为您的余额现已更新

我从未尝试写下方程式来推导最佳复利间隔,但我确信的一件事是,最佳复利间隔不会是固定的。例如,您可能期望找到类似于以下答案的最佳结果:

第 20 天的化合物,第 38 天的化合物,第 53 天的化合物,...

因此,找到数字 N 作为复合数并不能给出最佳答案。 解决该问题的一种方法可能是:考虑您正在寻找一年内的最佳复利率。并假设您想在此期间复利“m”次。现在,您有“m”个变量和一个您希望最大化的表达式。我现在不确定,但也许你可以使用简单的凸优化方法来解决它(只需之前检查方程的凸性,因为变量之间的约束都是仿射的)。然后对不同数量的“m”进行相同的尝试,并找到其中的最大数量。 这个解决方案很实用,因为数字“m”是有界的(显然它是一个整数!),并且您可能期望找到“m”与 cakeCalc 方法的结果如此接近。我想答案不会有太大不同。因此,您可以更改“m”例如少于 10 次并找到最佳解决方案。

关于r - 计算最佳复利期(加密货币),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66457308/

相关文章:

r - 在带有 data.table 的函数中使用 by

javascript - 巨大的整数 JavaScript 库

javascript - 使用 javascript 或 jquery 以 24 小时格式减去时间

c++ - 访问 bool 变量是否比访问 int 标志更快?

multithreading - Mahout优化: Multithreading TopItems. getTopUsers()和TopItems.getTopItems()

android - xml数据存储的最佳方法

通过引用 data.table r 中的列值删除行

r - 如何通过R中的第二个分组变量分配 "reseting"组号?

r - 使用与表达式对应的字符向量作为函数的参数

math - 给定起点,每个旋转轴的角度和方向,计算终点