使用Python计算基本体积(OBV)

2024-10-04 05:20:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个交易数据框架,其中包括“收盘”和“成交量”。我想计算平衡容积(OBV)。我让它在整个数据集上运行,但我希望它是在10个滚动序列上计算的

当前函数如下所示

def calculateOnBalanceVolume(df):
    df['obv'] = 0

    index = 1
    while index <= len(df) - 1:
        if(df.iloc[index]['close'] > df.iloc[index-1]['close']):
            df.at[index, 'obv'] += df.at[index-1, 'obv'] + df.at[index, 'volume']

        if(df.iloc[index]['close'] < df.iloc[index-1]['close']):           
            df.at[index, 'obv'] += df.at[index-1, 'obv'] - df.at[index, 'volume']

        index = index + 1

    return df

这将创建“obv”列并计算出300个条目的obv

理想情况下,我想做这样的事情

data['obv10'] = data.volume.rolling(10, min_periods=1).apply(calculateOnBalanceVolume)

这看起来有可能奏效,但问题是“应用”只在“交易量”列中传递,因此无法计算收盘价的变化

我也试过这个

data['obv10'] = data[['close','volume']].rolling(10, min_periods=1).apply(calculateOnBalanceVolume)

哪种方式有效,但它尝试更新“close”和“volume”列,而不是添加新的“obv10”列

这样做的最佳方式是什么?还是只需对数据进行10批迭代

通过此链接,我找到了执行上述代码的更有效方法: Calculating stocks's On Balance Volume (OBV) in python

import numpy as np

def calculateOnBalanceVolume(df):
    df['obv'] = np.where(df['close'] > df['close'].shift(1), df['volume'], 
    np.where(df['close'] < df['close'].shift(1), -df['volume'], 0)).cumsum()

    return df

问题是这仍然会影响整个数据集。这看起来很好,但是我如何一次10批地循环使用它,而不循环或迭代整个数据集呢

***更新***

我离这项工作还有一点距离。我已经成功地计算了10人一组的OBV

for gid,df in data.groupby(np.arange(len(data)) // 10):
    df['obv'] = np.where(df['close'] > df['close'].shift(1), df['volume'], 
    np.where(df['close'] < df['close'].shift(1), -df['volume'], 0)).cumsum()

我希望这是计算滚动,而不是分组。你知道如何有效地利用熊猫来做到这一点吗

***更新***

事实证明,OBV应该在整个数据集上进行计算。我已经确定了下面的代码,现在看起来是正确的

# calculate on-balance volume (obv)
self.df['obv'] = np.where(self.df['close'] > self.df['close'].shift(1), self.df['volume'], 
np.where(self.df['close'] < self.df['close'].shift(1), -self.df['volume'], self.df.iloc[0]['volume'])).cumsum()

Tags: 数据selfdfclosedataindexshiftnp