Reputation: 424
assume i have a stock price sequence and a buy/sell signal sequence.
I want to calculate the profit and loss for each signal.
for example:
price = [100, 99, 98, 99, 101, 102]
signal= [1, -1, 1, 1, -1, 0] # 1 -> buy 1, -1 -> sell 1
these two sequence means: i buy the stock in time 1(bc the first element of signal is 1), sell it in time2, ....
i need a function to return the profit or loss for each signal, the function looks like:
def calculate(price, signal):
pnl = []
# wait to be written
return pnl
here is the expected return:
[0, -1, ......]
for the first element of signal, that's a buy signal, which means i buy in time1, it produce no profit or loss, because i dont close the trade(close means buy then sell, or vice verse), i just buy one(open the trade). so the first element of pnl(the expected return array) should be 0, or nan.
when the second signal comes, that's a sell, so, it causes close trade(this sell, last buy), we can calculate the pnl=sell price(99) - buy price(100) = -1, which means i loss one unit, so the second element is -1, ....
the tough part of the problem is:
i may open several times, then close one by one or close all.
for example:
price = [100, 99, 98, 99, 101, 102]
signal= [1, 1, -1, -1, -1, 0] # 1 -> buy 1, -1 -> sell 1
i buy 100 at time1, buy 99 at time2, sell one at 98.
the expected result of sell should be
[0, 0, -1.5, -0.5, ....]
98(this sell price) - 99.5(average price of buy) = -1.5 99 - 99.5 = -0.5
i know this can be implemented using loop in python, since the purpose is so clear.
but i want to ask you for help about is there is any elegant and fast method can do this(like python rolling method or other)?
i do care about the algorithm performance, because i need to use it in a very huge dataset.
Upvotes: 1
Views: 1840
Reputation: 4772
This is a Python generator function. If you arrange for both the price and signal to be generators themselves then it will generate results at every signal without having to consume memory saving all of the inputs, or outputs - you can stream data through the function.
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]:
Upvotes: 2