Constantin Picoron
Constantin Picoron

Reputation: 33

What is the fastest way in python to identify the greatest cumulated differences in python array or list?

Let's say I have the following list, corresponding to stock prices in time:

prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11]

and I want to identify the following greatest cumulative difference overall, like the greatest return:

[(1,10), (3,12), (6,13), (4,11)]

as cumulative difference is = 9+9+7+7 = 32

Now from this result, I want to assign a long position (1) between thoses prices, and a short position (0) the rest of the time:

prices   = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11]
position = [1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1]

So far, I managed to identify the greatest differences in the list with this code:

print(nlargest(20, combinations(prices, 2), key = lambda x: abs(x[0]-x[1])))
[(1, 13), (1, 12), (1, 11), (3, 13), (3, 13), (1, 10), (1, 10), (3, 12), (3, 12), (13, 4)]

but I can't make it take into consideration that it should "read" the list and not further use the previous elements when trying a combination, as time goes.

I also tried this, which identifies in a vectorial way, the only greatest difference:

cummin = np.minimum.accumulate
print(np.max(prices - cummin(prices)))
12

and also this, which seems to be my closest guess:

l = np.array(list)
a = np.tile(l,(len(l),1))
print(a - a.T)
[[  0   2   6   9   8   7   4   2   5   7  11   8   5   9  12   7   3  10]
 [ -2   0   4   7   6   5   2   0   3   5   9   6   3   7  10   5   1   8]
 [ -6  -4   0   3   2   1  -2  -4  -1   1   5   2  -1   3   6   1  -3   4]
 [ -9  -7  -3   0  -1  -2  -5  -7  -4  -2   2  -1  -4   0   3  -2  -6   1]
 [ -8  -6  -2   1   0  -1  -4  -6  -3  -1   3   0  -3   1   4  -1  -5   2]
 [ -7  -5  -1   2   1   0  -3  -5  -2   0   4   1  -2   2   5   0  -4   3]
 [ -4  -2   2   5   4   3   0  -2   1   3   7   4   1   5   8   3  -1   6]
 [ -2   0   4   7   6   5   2   0   3   5   9   6   3   7  10   5   1   8]
 [ -5  -3   1   4   3   2  -1  -3   0   2   6   3   0   4   7   2  -2   5]
 [ -7  -5  -1   2   1   0  -3  -5  -2   0   4   1  -2   2   5   0  -4   3]
 [-11  -9  -5  -2  -3  -4  -7  -9  -6  -4   0  -3  -6  -2   1  -4  -8  -1]
 [ -8  -6  -2   1   0  -1  -4  -6  -3  -1   3   0  -3   1   4  -1  -5   2]
 [ -5  -3   1   4   3   2  -1  -3   0   2   6   3   0   4   7   2  -2   5]
 [ -9  -7  -3   0  -1  -2  -5  -7  -4  -2   2  -1  -4   0   3  -2  -6   1]
 [-12 -10  -6  -3  -4  -5  -8 -10  -7  -5  -1  -4  -7  -3   0  -5  -9  -2]
 [ -7  -5  -1   2   1   0  -3  -5  -2   0   4   1  -2   2   5   0  -4   3]
 [ -3  -1   3   6   5   4   1  -1   2   4   8   5   2   6   9   4   0   7]
 [-10  -8  -4  -1  -2  -3  -6  -8  -5  -3   1  -2  -5  -1   2  -3  -7   0]]

but I can't manage to identify from this matrice the best combination which would have been these trades [(1,10), (3,12), (6,13), (4,11)]

Can anyone please help me?

Upvotes: 3

Views: 65

Answers (2)

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48067

You can get your desired pairs using itertools.groupby as:

from itertools import groupby
prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11]

incr_pairs = [list(g) for i, g in groupby(zip(prices, prices[1:]), lambda x: x[0] < x[1]) if i]
greatest_diff = [(x[0][0], x[-1][-1]) for x in incr_pairs]

where greatest_diff will give you:

[(1, 10), (3, 12), (6, 13), (4, 11)]

Now to get your cumulative diff, you can use sum as:

my_sum = sum(j-i for i, j in greatest_diff)
# where `my_sum` will give you: 32

Upvotes: 2

mozway
mozway

Reputation: 260530

Don't do complicated things. To compute the cumulated positive differences, you just want to sum the diff ignoring the negative values (with clip).

Let's just do that:

prices = np.array([1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11])

np.diff(prices).clip(0).sum()

output: 32 (= 9+9+7+7)

Upvotes: 0

Related Questions