在SQLite中按组计算加权平均值

时间:2019-03-13 10:26:48

标签: sql sqlite

我有投资组合持有量的季度数据,我们将其称为表holdings

portfolio date         security    dollar_amount
p1        03/31/2001   security1   50
p1        03/31/2001   security2   100
p2        03/31/2001   security1   25
p2        03/31/2001   security2   50

p1        06/30/2001   security1   50
p1        06/30/2001   security2   100
p1        06/30/2001   security3   50
p2        06/30/2001   security1   25
p2        06/30/2001   security3   50

以及每种证券的月度收益数据,我们将其称为returns

security    date         return
security1   03/31/2001   1
security2   03/31/2001   -1
security3   03/31/2001   2

security1   04/30/2001   3
security2   04/30/2001   -1
security3   04/30/2001   2

security1   05/31/2001   1
security2   05/31/2001   2
security3   05/31/2001   -1

security1   06/30/2001   2
security2   06/30/2001   -1
security3   06/30/2001   3

security1   07/31/2001   2
security2   07/31/2001   -3
security3   07/31/2001   1

security1   08/30/2001   2
security2   08/30/2001   -3
security3   08/30/2001   2

对于每个投资组合,在这里p1p2,我想计算每个投资组合的每月加权平均收益:SUM(dollar_amount * return) / SUM(dollar_amount)。但是,我想考虑一下持股量的季度变化,即权重应该每季度调整一次。

所需的输出:

portfolio date        return
p1        03/31/2001  1/3*1 + 2/3*(-1) = -1/2
p2        03/31/2001  1/3*1 + 2/3*(-1) = -1/2
p1        04/30/2001  1/3*3 + 2/3*(-1) = 1/3
p2        04/30/2001  1/3*3 + 2/3*(-1) = 1/3
p3        05/31/2001  1/3*1 + 2/3*2 = 5/3
p4        05/31/2001  1/3*1 + 2/3*2 = 5/3

-- rebalancing, i.e. adjusting the weights according to holding data --

p1        06/30/2001  1/4*2 + 1/2*(-1) + 1/4*3 = 3/4
p2        06/30/2001  1/3*2 + 2/3*3 = 8/3
p1        07/31/2001  1/4*2 + 1/2*(-3) + 1/4*1 = -3/4
p2        07/31/2001  1/3*2 + 2/3*1 = 4/3
p3        08/30/2001  1/4*2 + 1/2*(-3) + 1/4*2 = -1/2
p4        08/30/2001  1/3*2 + 2/3*2 = 2

我的最终查询将不得不处理53个季度的持股数据,因此需要159个月。独特的投资组合和证券数量高达13,000。

我的问题是在单个SQLite查询中是否有有意义的方法来做到这一点。如果没有,您认为什么是最好的方法?

对我来说问题是

  • 仅加入每个季度的相关(每月)返回数据,例如从03/31/2001返回的投资组合权重,从04/30/200105/31/200103/31/2001返回;否则数据会爆炸。
  • 必须按组计算加权平均回报,其中组由季度和投资组合定义。

我唯一想到的方法是查询每个日期和投资组合的加权平均收益 ,这样我就不得不遍历所有这些组合。我知道这是一项需要大量计算的工作,但是我正在这里寻找最快的解决方案。

感谢您的帮助!我正在使用Python,sqlalchemy,sqlite3。

1 个答案:

答案 0 :(得分:0)

这是我的观点,但是Sqlite对日期的处理没有太多支持,因此感觉效率低下。我无法使其与您的日期格式配合使用,因此我不得不更改为“ yyyy-mm-dd”,但这也许是特定于安装的

$relation_sort = 'asc';
$nested_sort = 'desc';

$result = Model::with([
   'relation' => function($query) use($relation_sort){
      $query->orderBy('relation_column', $relation_sort);
   },
   'relation.nested' => function($query) use($nested_sort){
      $query->orderBy('nested_relation_column', $nested_sort);
   }
])->whereHas('relation', function($query){
    //Relation exists check.
    $query->where('price', '>', 100);
})->whereHas('relation.nested', function($query) use($search_param){
    //Nested Relation search.
    $query->where('search_column', 'LIKE', $search_param);
})->get();