【问题标题】:Profit and loss using pandas使用 pandas 的盈亏
【发布时间】:2016-08-18 04:45:30
【问题描述】:

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

                       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 做到这一点吗?

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    我不太了解买入/卖出持有(也许您的卖出时间有误?),但这应该会让您很接近。关键是计算一个数组“单位”,表明你是否持有股票。然后其余的应该可以正常工作。每天你要么改变价值(0.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
    

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

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 2015-07-14
      • 2021-11-09
      • 1970-01-01
      • 2021-02-01
      • 2022-01-13
      相关资源
      最近更新 更多