【问题标题】:how to design a trade calculator by python elegantly?如何优雅地用python设计一个交易计算器?
【发布时间】:2021-03-26 00:11:25
【问题描述】:

假设我有一个股票价格序列和一个买入/卖出信号序列。

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

例如:

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

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

我需要一个函数来返回每个信号的盈亏,函数如下所示:

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

这是预期回报:

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

对于信号的第一个元素,这是一个买入信号,这意味着我及时买入,它不会产生任何利润或损失,因为我没有关闭交易(关闭意味着买入然后卖出,反之亦然),我只是买入一(开仓)。所以 pnl 的第一个元素(预期的返回数组)应该是 0 或 nan。

当第二个信号到来时,就是卖出,所以,它导致平仓(这次卖出,最后一次买入),我们可以计算 pnl=sell price(99) - buy price(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滚动方法或其他)?

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

【问题讨论】:

  • 您现在或将来会考虑税收,还是纯粹的理论练习?
  • 您的总利润为sum(p*s for p,s in zip(price, signal))。我希望这对你来说足够“优雅”。但我应该说我不明白你的大部分解释;特别是我不明白您-1.5 计算背后的逻辑;所以我不会对此发表评论。
  • 请注意,如果您的“非常大的数据集”是一个 numpy 数组,那么您可能应该使用 numpy 函数。如果它是 pandas 数据集,那么您可能应该使用 pandas 函数。如果它是 spark 数据集,那么您可能应该使用 pyspark 函数。
  • @PaulBrennan 以后我会,但现在,可以忽略它
  • @Stef 我想我可能解释得不好。我想说的是,pnl只在一轮交易发生时计算,一轮意味着一买一卖,只在最后一个计算,第一个没有pnl,因为它是一个未完成的状态

标签: python pandas algorithm trading


【解决方案1】:

这是一个 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]: 

【讨论】:

    猜你喜欢
    • 2011-02-14
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 2011-05-23
    • 2016-10-02
    相关资源
    最近更新 更多