问候所有,我有两个系列的数据:每日原始股票价格回报(正或负浮动)和交易信号(买= 1,卖= -1,无交易= 0)。
原始价格回报只是今天价格的对数除以昨天的价格:
log(p_today / p_yesterday)
一个例子:
raw_return_series = [ 0.0063 -0.0031 0.0024 ..., -0.0221 0.0097 -0.0015]
交易信号系列如下:
signal_series = [-1. 0. -1. -1. 0. 0. -1. 0. 0. 0.]
根据交易信号获得每日回报:
daily_returns = [raw_return_series[i] * signal_series[i+1] for i in range(0, len(signal_series)-1)]
这些每日回报可能如下所示:
[0.0, 0.00316, -0.0024, 0.0, 0.0, 0.0023, 0.0, 0.0, 0.0] # results in daily_returns; notice the 0s
我需要使用daily_returns系列来计算复合回报系列。但是,鉴于daily_returns系列中有0个值,我需要将“通过时间”的最后一个非零复合返回到下一个非零复合返回。
例如,我像这样计算复合回报(注意我随着时间的推移“向后”):
compound_returns = [(((1 + compounded[i + 1]) * (1 + daily_returns[i])) - 1) for i in range(len(compounded) - 2, -1, -1)]
以及结果列表:
[0.0, 0.0, 0.0023, 0.0, 0.0, -0.0024, 0.0031, 0.0] # (notice the 0s)
我的目标是将最后的非零回报继续累积这些复合回报。也就是说,由于索引i处的返回取决于索引i + 1处的返回,因此索引i + 1处的返回应该是非零的。每次列表理解在daily_return系列中遇到零时,它基本上都会重新启动。
答案 0 :(得分:8)
有一个名为pandas的奇妙模块是由AQR(对冲基金)的一个人编写的,擅长这样的计算......你需要的是一种处理“缺失数据”的方法。如上所述,基础知识是使用scipy或numpy的nan(不是数字)功能;但是,即使这些库也不会使财务计算变得更容易......如果你使用pandas,你可以将你不想考虑的数据标记为nan
,然后任何未来的计算都会拒绝它,同时对其他数据执行正常操作。
我在我的交易平台上使用pandas大约8个月......我希望我早点开始使用它。
Wes(作者)在pyCon 2010上发表了关于模块功能的演讲......请参阅幻灯片和视频on the pyCon 2010 webpage。在该视频中,他演示了如何获得每日回报,在回报矩阵(在几分之一秒内),时间戳/图表数据上运行1000次线性回归...所有这些都是通过此模块完成的。结合psyco,这是一个财务分析工具的野兽。
它处理的另一件好事是横截面数据...所以你可以抓住每日收盘价,滚动价格等等......然后按时间戳计算每一个,并获得所有这些类似于python字典的东西(参见pandas.DataFrame
类)...然后你可以像下面那样访问数据片段:
close_prices['stdev_5d']
有关计算滚动stdev的更多信息,请参阅the pandas rolling moments doc。
由于我的分析要求,Wes已经不遗余力地使用cython加速模块了,尽管我会承认我正在考虑升级我的服务器(一个较旧的Xeon)。
编辑STRIMP的问题:
在将代码转换为使用pandas数据结构之后,我仍然不清楚你是如何在pandas数据框中索引数据以及复合函数处理缺失数据的要求(或者就此而言,返回0.0的条件......或者如果您在熊猫中使用NaN
..)。我将演示使用我的数据索引...随机挑选一天...... df
是一个数据框,其中包含ES期货报价...每秒索引...缺少的报价用{{填写1}}。 DataFrame索引是numpy.nan
个对象,由datetime
模块的时区对象偏移。
pytz
举一个简单的例子说明如何计算一个连续回报的列(在>>> df.info
<bound method DataFrame.info of <class 'pandas.core.frame.DataFrame'>
Index: 86400 entries , 2011-03-21 00:00:00-04:00 to 2011-03-21 23:59:59-04:00
etf 18390 non-null values
etfvol 18390 non-null values
fut 29446 non-null values
futvol 23446 non-null values
...
>>> # ET is a pytz object...
>>> et
<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>
>>> # To get the futures quote at 9:45, eastern time...
>>> df.xs(et.localize(dt.datetime(2011,3,21,9,45,0)))['fut']
1291.75
>>>
中),该列在10分钟前引用该报价(并填写缺失的刻度),我会这样做:
pandas.TimeSeries
在这种情况下不需要lambda,只需在600秒前将值列分开。那个>>> df['fut'].fill(method='pad')/df['fut'].fill(method='pad').shift(600)
部分是因为我的数据每秒被索引。
HTH, \麦克
答案 1 :(得分:3)
这个问题的累积回归部分在Wes McKinney出色的“Python for Data Analysis”一书第339页中讨论,并使用Pandas的cumprod()从计算出的价格变化中创建一个重新计算/索引的累积回报。
书中的例子:
import pandas.io.data as web
price = web.get_data_yahoo('AAPL', '2011-01-01')['Adj Close']
returns = price.pct_change()
ret_index = (1 + returns).cumprod()
ret_index[0] = 1 # Set first value to 1
答案 2 :(得分:1)
想象一下,我有一个DataMatrix收盘价,一些指标值,以及这样的交易信号:
>>> data_matrix
close dvi signal
2008-01-02 00:00:00 144.9 0.6504 -1
2008-01-03 00:00:00 144.9 0.6603 -1
2008-01-04 00:00:00 141.3 0.7528 -1
2008-01-07 00:00:00 141.2 0.8226 -1
2008-01-08 00:00:00 138.9 0.8548 -1
2008-01-09 00:00:00 140.4 0.8552 -1
2008-01-10 00:00:00 141.3 0.846 -1
2008-01-11 00:00:00 140.2 0.7988 -1
2008-01-14 00:00:00 141.3 0.6151 -1
2008-01-15 00:00:00 138.2 0.3714 1
我使用该信号根据交易信号创建一个返回的DataMatrix:
>>> get_indicator_returns()
indicator_returns
2008-01-02 00:00:00 NaN
2008-01-03 00:00:00 0.000483
2008-01-04 00:00:00 0.02451
2008-01-07 00:00:00 0.0008492
2008-01-08 00:00:00 0.01615
2008-01-09 00:00:00 -0.01051
2008-01-10 00:00:00 -0.006554
2008-01-11 00:00:00 0.008069
2008-01-14 00:00:00 -0.008063
2008-01-15 00:00:00 0.02201
我最终做的是:
def get_compounded_indicator_cumulative(self):
indicator_dm = self.get_indicator_returns()
dates = indicator_dm.index
indicator_returns = indicator_dm['indicator_returns']
compounded = array(zeros(size(indicator_returns)))
compounded[1] = indicator_returns[1]
for i in range(2, len(indicator_returns)):
compounded[i] = (1 + compounded[i-1]) * (1 + indicator_returns[i]) - 1
data = {
'compounded_returns': compounded
}
return DataMatrix(data, index=dates)
由于某些原因,我真的很难与这个... ...
我正在将所有价格系列转换为PyTables。到目前为止看起来很有希望。