python 如何优雅地设计一个交易计算器?

how to design a trade calculator by python elegantly?

假设我有一个股票价格序列和一个buy/sell信号序列。

我想计算每个信号的盈亏。

例如:

price = [100, 99, 98, 99, 101, 102]
signal= [1,   -1,  1,  1,  -1,   0]  # 1 -> buy 1, -1 -> sell 1

这两个序列的意思是:我在时间 1 买入股票(bc 信号的第一个元素是 1),在时间 2 卖出,....

我需要一个函数来 return 每个信号的利润或损失,函数如下所示:

def calculate(price, signal):
  pnl = []
  # wait to be written
  return pnl

这是预期的 return:

[0, -1, ......]

对于信号的第一个元素,这是一个买入信号,这意味着我在 time1 买入,它不会产生利润或损失,因为我没有关闭交易(关闭意味着先买后卖,反之亦然),我只买一个(打开交易)。所以 pnl(预期的 return 数组)的第一个元素应该是 0,或者 nan.

当第二个信号来的时候,那是卖出,所以,它导致平仓(这次卖出,最后买入),我们可以计算出pnl=卖出价(99) - 买入价(100) = -1,这意味着我损失了一个单位,所以第二个元素是-1,....

问题的难点在于:

我可能会打开几次,然后一个一个关闭或者全部关闭。

例如:

price = [100, 99, 98, 99, 101, 102]
signal= [1,   1,  -1,  -1,  -1,   0]  # 1 -> buy 1, -1 -> sell 1

我在时间 1 买入 100,在时间 2 买入 99,在 98 卖出一个。

卖出的预期结果应该是

[0, 0, -1.5, -0.5, ....] 

98(本次卖出价) - 99.5(买入均价) = -1.5 99 - 99.5 = -0.5

我知道这可以在 python 中使用循环来实现,因为目的很明确。

但我想请您帮忙,是否有任何优雅快速的方法可以做到这一点(如 python 滚动方法或其他方法)?

我很关心算法的性能,因为我需要在非常庞大的数据集中使用它。

这是一个 Python 生成器函数。如果您将价格和信号都安排为生成器本身,那么它将在每个信号处生成结果,而无需消耗内​​存来保存所有输入或输出 - 您可以通过函数流式传输数据。

In [31]: def trade(price, signal):
    ...:     n, t, result = 0, 0, []
    ...:     for p, s in zip(price, signal):
    ...:         if s == 1:
    ...:             n, t = n+1, t+p
    ...:             yield 0
    ...:         elif s== 0:
    ...:             yield 0
    ...:         elif s == -1:
    ...:             avg = t/n
    ...:             n, t = n-1, t-avg
    ...:             yield p - avg
    ...:         else:
    ...:             assert s in (1, 0, -1), f"Signal {s} error"

In [32]: price = [100, 99, 98, 99, 101, 102]
    ...: signal= [1,   -1,  1,  1,  -1,   0]

In [33]: list(trade(price, signal))
Out[33]: [0, -1.0, 0, 0, 2.5, 0]

In [34]: