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
也许如果你发布的循环代码符合你的要求,那么对某些人来说矢量化可能会更容易