如何识别熊猫数据集中的特定序列(往返)?

时间:2016-03-15 00:51:11

标签: python algorithm pandas finance

我有一个简单但具有挑战性的算法问题需要解决。

我有一个交易者 - 股票 - 日级别的数据集,我想确定数据中的往返行程。往返只是数据中的特定序列。也就是说,如果随着时间累积个人i的股票持有头寸,则往返开始并以零净持仓结束。

一个例子:

pd.DataFrame({'trader' : ['a','a','a','a','a','a','a'],
              'stock' : ['a','a','a','a','a','a','b'],
              'day' :[0,1,2,4,5,10,1],
              'delta':[10,-10,15,-10,-5,5,6],
              'cumq' : [10,0,15,5,0,5,6] ,
              'tag': [1,1,2,2,2,0,0]})

输出

 Out[15]: 
   cumq  day  delta stock  tag trader
0    10    0     10     a    1      a
1     0    1    -10     a    1      a
2    15    2     15     a    2      a
3     5    4    -10     a    2      a
4     0    5     -5     a    2      a
5     5   10      5     a    0      a
6     6    1      6     b    0      a

在这里,您可以看到交易者a购买了两只股票(ab)。 delta对应于指定日期购买或出售的数量。所以你可以看到我们在stock a( - 10 +10 = 0)和(+15 - 10 -5 = 0)以及两次未完成的往返({+上{ {1}}和stock a上的+6。)

我希望能够创建一个变量stock b来告诉我这一点。也就是说,每当往返未终止时变量为0,并且在给定的股票交易者组合中识别的第一,第二,第三等往返行程中取值1,2,3。

知道如何以有效的方式做到这一点吗? 非常感谢!

编辑:

  • 卖空是可能的。例如卖10,买25,卖25和买10将是一次往返。
  • 可以在同一天实施往返:在这种情况下,delta将为零(实际上,您当天购买和销售相同的数量)。这意味着每天的几次往返可以在数据中相互跟随。所以往返的0边界是包容性的。例如:你买10并且今天卖10(delta = 0),然后你买15并且明天卖15(delta = 0再次)。这些对应于两个不同的连续往返

建议的解决方案 - 看上去非常慢 -

tag

有什么想法吗? 非常感谢!!!!

1 个答案:

答案 0 :(得分:1)

我会做这样的事情:

import pandas as pd
import numpy as np

df = pd.DataFrame({'trader' : ['a','a','a','a','a','a','a'],'stock' : ['a','a','a','a','a','a','b'], 'day' :[0,1,2,4,5,10,1],'delta':[10,-10,15,-10,-5,5,6], 'cumq' : [10,0,15,5,0,6,11] ,'tag': [1,1,2,2,2,0,0]})

def proc_trader(_df):
    if _df.shape[0] == 1:
        _df['tag'] = _df['delta'] == 0
        return _df

    _df['tag'] = np.nan
    # make every ending of a roundtrip with its index
    _df['tag'][df.cumq == 0] = range(1, (df.cumq == 0).sum() + 1)
    # backfill the roundtrip index until previous roundtrip;
    # then fill the rest with 0s (roundtrip incomplete for most recent trades)
    _df['tag'] = _df['tag'].fillna(method = 'bfill').fillna(0)
    return _df

df = df.groupby(['trader', 'stock']).apply(proc_trader)

这个想法是每个交易者的记录都包含一系列往返,除非最终可能;假设应该如何计算零增量时期。我们检测往返周期的所有结束,反向提取索引并用0填充其余部分。