Python 使用熊猫的损益

Python 使用熊猫的损益,python,pandas,numpy,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

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

                       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。我想要一个输出以下内容的timeseries:

                       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实现这一点吗?

我不太理解买入/卖出持有(也许你的卖出时间有错误?),但这应该可以让你接近这个想法。关键是计算一个数组“单位”,它指示你是否持有股票。那么剩下的就行了。每天您要么更改价值(.99或1.01,例如基于股票收盘价),要么保留价值(1.0)。然后,cumprod()函数累积这些更改。由于你是在公开场合购买,你需要增加一些复杂性。如果您需要在这些时候做一些特殊的事情,您可以创建一个“购买”数组,如
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
也许如果你发布的循环代码符合你的要求,那么对某些人来说矢量化可能会更容易