我有一个包含如下数据的数据框:
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 执行此操作而不通过数据框循环?
答案 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
也许如果您发布了符合您需要的循环代码,那么某人可能更容易进行矢量化。