使用熊猫的利润和损失

时间:2016-08-17 12:45:18

标签: python pandas numpy

我有一个包含如下数据的数据框:

                       open   close  signal
date_time                                                          
2011-01-03 01:04:00  1.5560  1.5556    0.0
2011-01-03 01:05:00  1.5557  1.5556    0.0
2011-01-03 01:06:00  1.5557  1.5556    1.0
2011-01-03 01:07:00  1.5556  1.5545    1.0
2011-01-03 01:08:00  1.5546  1.5548    1.0
2011-01-03 01:09:00  1.5549  1.5547    0.0
2011-01-03 01:10:00  1.5548  1.5549    0.0
2011-01-03 01:11:00  1.5549  1.5551    1.0
2011-01-03 01:12:00  1.5550  1.5552    1.0
2011-01-03 01:13:00  1.5553  1.5553    0.0
2011-01-03 01:14:00  1.5552  1.5553    0.0

这是在Python中表示金融时间序列的一种相当标准的方式。

现在,我想使用信号列进行交易。当信号== 1然后买入,当它回到0然后卖出。该信号在当前分钟结束时已知,因此当我们说“购买”时,它实际上意味着在下一分钟开放时购买。

让我们说我们投资组合的初始值是1.0。我想要一个输出时间序列:

                       pnl
date_time                                                          
2011-01-03 01:04:00    1.0
2011-01-03 01:05:00    1.0
2011-01-03 01:06:00    1.0
2011-01-03 01:07:00    0.999292877 # Buy: pnl = (1.0 * 1.5545 / 1.5556)
2011-01-03 01:08:00    0.999485729 # Hold: pnl = (1.0 * 1.5548 / 1.5556)
2011-01-03 01:09:00    0.999421445 # Hold: pnl = (1.0 * 1.5547 / 1.5556)
2011-01-03 01:10:00    0.999485729 # Sell: pnl = (1.0 * 1.5548 / 1.5556)
2011-01-03 01:11:00    0.999485729 # Wait
2011-01-03 01:12:00    0.999614280 # Buy: pnl = (0.999485729 * 1.5552 / 1.5550)
2011-01-03 01:13:00    0.999678556 # Hold: pnl = (0.999485729 * 1.5553 / 1.5550)
2011-01-03 01:14:00    0.999614280 # Sell: pnl = (0.999485729 * 1.5552 / 1.5550)
2011-01-03 01:15:00    0.999614280 # Wait

任何想法如何使用pandas 执行此操作而不通过数据框循环?

1 个答案:

答案 0 :(得分:1)

我不太了解买入/卖出持有(也许你的卖出时间有误?),但这应该让你接近一个想法。关键是计算一个数组'单位'这表明你是否持有股票。其余的应该工作正常。每天您可以更改值(.99或1.01,例如基于股票收盘价),或保持价值(1.0)。然后cumprod()函数累积这些更改。由于您是在公开场合购买,因此需要增加一些复杂性。你可以创建一个' buy'像signal[1:0]-signal[0:-1]这样的数组,如果你需要在那些时候做一些特别的事情。

#!/usr/bin/env python
import pandas as pd
import numpy as np
df=pd.DataFrame([[ 1.5560,  1.5556,    0.0],
                [ 1.5557,  1.5556,    0.0],
                [ 1.5557,  1.5556,    1.0],
                [ 1.5556,  1.5545,    1.0],
                [ 1.5546,  1.5548,    1.0],
                [ 1.5549,  1.5547,    0.0],
                [ 1.5548,  1.5549,    0.0],
                [ 1.5549,  1.5551,    1.0],
                [ 1.5550,  1.5552,    1.0],
                [ 1.5553,  1.5553,    0.0],
                 [ 1.5552,  1.5553,    0.0]], columns=['open','close','signal'])

#You will need to adjust units based on your exact buy/sell times.  Assuming here that
#units are signal delayed by 1 time slot.
units=np.insert(df['signal'].values,0,[0])[0:-1]
#change is relative change in price from day before.  Insert 1.0 in first day to represent start
change_close=np.insert(df['close'].values[1:]/df['close'].values[0:-1],0,[1])
#hold is 1,0 flag whether you are holding stock
hold=(units>0)
#relative change in value is either change_close or 1.0 (no change)
change_value=hold*change_close + ~hold*1.0
#cumulative product of changes gives current value
pnl=change_value.cumprod()
#insert back into dataframe as new column
df['pnl']=pnl
df

open   close  signal       pnl
0   1.5560  1.5556     0.0  1.000000
1   1.5557  1.5556     0.0  1.000000
2   1.5557  1.5556     1.0  1.000000
3   1.5556  1.5545     1.0  0.999293
4   1.5546  1.5548     1.0  0.999486
5   1.5549  1.5547     0.0  0.999421
6   1.5548  1.5549     0.0  0.999421
7   1.5549  1.5551     1.0  0.999421
8   1.5550  1.5552     1.0  0.999486
9   1.5553  1.5553     0.0  0.999550
10  1.5552  1.5553     0.0  0.999550

也许如果您发布了符合您需要的循环代码,那么某人可能更容易进行矢量化。