Target Labeling Using Sliding Window On Stock Data In Python - python-3.x

I'm trying to label BUY, SELL, and HOLD values to the closing stock prices based on the algorithm I found in a paper. I'm not quite able to figure out the error I'm getting. I'd very much appreciate your help. Thank you.
Algorigthm:
[EDITED]
My implementation:
window_size = 11
counter = 0
result = []
window_begin_idx=0; window_end_idx=0; window_middle_idx=0; min_idx=0; max_idx=0;
while counter < len(closing_price):
if counter > window_size:
window_begin_idx = counter - window_size
window_end_idx = window_begin_idx + window_size - 1
window_middle_idx = (window_begin_idx + window_end_idx)//2
for i in range(window_begin_idx, window_end_idx+1):
rng = closing_price[window_begin_idx:window_end_idx+1]
number = closing_price[i]
mins = rng.min()
maxs = rng.max()
if number < mins:
mins=number
min_idx = np.argmin(rng)
if number > maxs:
maxs=number
max_idx = np.argmax(rng)
if max_idx == window_middle_idx:
result.append("SELL")
elif min_idx == window_middle_idx:
result.append("BUY")
else:
result.append("HOLD")
mins = 0.0
maxs = 10000.0
counter+=1
After the edit based on the author's JAVA code, I'm only getting the HOLD label. The author's implementation is here.

You need to initialize mins, maxs, min_idx and max_idx with appropriate values before the main loop.
In your case if max_idx == occurs earlier than any max_idx assignment
Edit after questing change:
Seems in Python you can make similar behavior replacing the whole for-loop with:
rng = closing_price[window_begin_idx:window_end_idx+1]
mins = rng.min()
maxs = rng.max()
min_idx = rng.index(mins)
max_idx = rng.index(maxs)

After reading through the author's implementation and following the suggestions provided by MBo, I have managed to solve this issue. So, now anyone who wants this algorithm in python, below is the code:
window_size = 11
counter = 0
result = []
window_begin_idx=0; window_end_idx=0; window_middle_idx=0; min_idx=0; max_idx=0;
number=0.0; mins=10000.0; maxs=0.0
while counter < len(closing_price):
if counter > window_size:
window_begin_idx = counter - window_size
window_end_idx = window_begin_idx + window_size - 1
window_middle_idx = (window_begin_idx + window_end_idx)//2
for i in range(window_begin_idx, window_end_idx+1):
number = closing_price[i]
if number < mins:
mins=number
min_idx = np.where(closing_price==mins)[0][0]
if number > maxs:
maxs=number
max_idx = np.where(closing_price==maxs)[0][0]
if max_idx == window_middle_idx:
result.append("SELL")
elif min_idx == window_middle_idx:
result.append("BUY")
else:
result.append("HOLD")
mins = 10000.0
maxs = 0.0
counter+=1

Related

How do i speed up nested for loop in python?

i'm working on a voxel raycast based engine. For that i need for each pixel of the screen to run a raycast. To do that, i make a for loop like that :
distanceToScreen = math.tan(math.radians(self.FOV/2))
increment = 1/self.resolution[1]
xScreen = 1/-2
yScreen = 1/-2
for x in range(0,self.resolution[0]):
yScreen = 1/-2
for y in range(0,self.resolution[1]):
info = self.raycast([xScreen,distanceToScreen,yScreen],4)
if info != 0:
'''collect info '''
yScreen+=increment
xScreen+=increment
But this technique is horribly slow. I use pyglet for displaying. Here's also the raycast algorithm :
Step = [0,0,0]
invDir = [0,0,0]
T = [0,0,0]
DeltaT = [0,0,0]
VoxelIncr = [0,0,0]
CurrentV = [self.position[0],self.position[1],self.position[2]]
for i in range(0,3):
if direction[i]!= 0:
Step[i] = int(direction[i]<0) * -1 + int(direction[i]>=0)
T[i] = abs(1/direction[i])
invDir[i] = abs(1/direction[i])
else:
invDir[i] = 100000000000000
T[i] = 100000000000000
DeltaT[i] = invDir[i]
while math.sqrt((CurrentV[0]-int(self.position[0]))**2+(CurrentV[1]-int(self.position[1]))**2+(CurrentV[2]-int(self.position[2]))**2)<=length:
if T[0]<T[1]:
if T[0]<T[2]:
T[0]+=DeltaT[0]
CurrentV[0]+=Step[0]
else:
T[2]+=DeltaT[2]
CurrentV[2]+=Step[2]
else:
if T[1]<T[2]:
T[1]+=DeltaT[1]
CurrentV[1]+=Step[1]
else:
T[2]+=DeltaT[2]
CurrentV[2]+=Step[2]
if int(CurrentV[2]) < len(Map) and int(CurrentV[1]) < len(Map[0]) and int(CurrentV[0]) < len(Map[0][0]) and int(CurrentV[2]) >= 0 and int(CurrentV[1]) >= 0 and int(CurrentV[0]) >= 0 and Map[int(CurrentV[2])][int(CurrentV[1])][int(CurrentV[0])] != 0:
info = Map[int(CurrentV[2])][int(CurrentV[1])][int(CurrentV[0])][1]
break
return info

How to iterate over PyTorch tensor

I have a tensor data of size (1000,110) and I want to iterate over the first index of the tensor and calculate the following.
data = torch.randn(size=(1000,110)).to(device)
male_poor = torch.tensor(0).float().to(device)
male_rich = torch.tensor(0).float().to(device)
female_poor = torch.tensor(0).float().to(device)
female_rich = torch.tensor(0).float().to(device)
for i in data:
if torch.argmax(i[64:66]) == 0 and torch.argmax(i[108:110]) == 0:
female_poor += 1
if torch.argmax(i[64:66]) == 0 and torch.argmax(i[108:110]) == 1:
female_rich += 1
if torch.argmax(i[64:66]) == 1 and torch.argmax(i[108:110]) == 0:
male_poor += 1
if torch.argmax(i[64:66]) == 1 and torch.argmax(i[108:110]) == 1:
male_rich += 1
disparity = ((female_rich/(female_rich + female_poor))) / ((male_rich/(male_rich + male_poor)))
Is there a faster way than for loop to do this?
The key in pytorch (as well as numpy) is vectorizataion, that is if you can remove loops by operating on matrices it will be a lot faster. Loops in python are quite slow compared to the loops in the underlying compiled C code. On my machine the execution time for your code was about 0.091s, the following vectorized code was about 0.002s so about x50 faster:
import torch
torch.manual_seed(0)
device = torch.device('cpu')
data = torch.randn(size=(1000, 110)).to(device)
import time
t = time.time()
#vectorize over first dimension
argmax64_0 = torch.argmax(data[:, 64:66], dim=1) == 0
argmax64_1 = torch.argmax(data[:, 64:66], dim=1) == 1
argmax108_0 = torch.argmax(data[:, 108:110], dim=1) == 0
argmax108_1 = torch.argmax(data[:, 108:110], dim=1) == 1
female_poor = (argmax64_0 & argmax108_0).sum()
female_rich = (argmax64_0 & argmax108_1).sum()
male_poor = (argmax64_1 & argmax108_0).sum()
male_rich = (argmax64_1 & argmax108_1).sum()
disparity = ((female_rich / (female_rich + female_poor))) / ((male_rich / (male_rich + male_poor)))
print(time.time()-t)
print(disparity)

Code fails on Test case. (InterQuartile Range)

This is a challenge from 10 Day statistics on Hackerrank.(https://www.hackerrank.com/challenges/s10-interquartile-range/problem?h_r=next-challenge&h_v=zen)
Task :
Task
The interquartile range of an array is the difference between its first (Q1) and third (Q3) quartiles (i.e., Q3 - Q1).
Given an array,X, of n integers and an array, F, representing the respective frequencies of X's elements, construct a data set, S, where each xi occurs at frequency fi. Then calculate and print S's interquartile range, rounded to a scale of 1 decimal place (i.e., 12.3 format).
Following is my code.
n = int(input())
x = list(map(int, input().split()))
f = list(map(int, input().split()))
s = []
for i in range(len(x)):
j = f[i]
for k in range(j):
s.append(x[i])
n = len(s)
s.sort()
if n%2 == 0:
Q21 = s[n//2]
Q22 = s[n//2 - 1]
Q2 = (Q21 + Q22) / 2
else:
Q2 = s[n//2]
LH = s[:n//2]
if n%2==0:
UH = s[n//2:]
else:
UH = s[n//2+1:]
Q1_len = len(LH)
Q3_len = len(UH)
if Q1_len%2 == 0:
Q11 = LH[Q1_len//2]
Q12 = LH[Q1_len//2 - 1]
Q1 = (Q11 + Q12) / 2
else:
Q1 = LH[Q1_len//2]
if Q3_len%2 == 0:
Q31 = UH[Q3_len//2]
Q32 = UH[Q3_len//2 - 1]
Q3 = (Q31 + Q32) / 2
else:
Q3 = UH[Q3_len//2]
print(round(Q3 - Q1,1))
# print(int(Q2))
# print(int(Q3))
Here is the test case: with std input.
5
10 40 30 50 20
1 2 3 4 5
Expected output:
30.0
My code output:
30.0 # I get this output on my code editor but not on Hackerrank
Can someone help me on this where I am wrong ?
I get the output what is expected but it shows as failed.
print(float(Q3 - Q1))
Basically is the answer.

Python confusion toward class instance

[Class of players that accept a list then proceed to find the player with the highest score.]
class Player:
def __init__(self, name, score):
self.name = name
self.score = score
def best_score(list):
i = 0
while i < len(list):
n = list[i] #list[1] = (Bratt, 250) #list[2] = Lisa 150
s = list[i].score #list 1. score = 250 #list[2].score = 150
ace = list[0] #homer 50 #homer 50
hs = 0
if s > hs: #if s(250>0): #if s(list[2].score) > hs(250): nothing suppsoed to happen
ace = n #ace(homer) = n(list1) aka bratt #ace(bratt) != n because above
hs = s #hs(0) = s(list1) = 250 #hs(250) != list[2]150
#hs is now 250
i += 1
return ace
p1 = Player('Homer', 50)
p2 = Player('Bart', 250)
p3 = Player('Lisa', 150)
ls = [p1, p2, p3]
best = Player.best_score(ls)
msg = '{} has the best score, with {} points!'.format(best.name, best.score)
print(msg) # Bart has the best score, with 250 points!
For some reasons, my code does not return the highest player score and name. Instead, it gives me the latest player score and name instead.
I have tried checking it by going through the loop and it still does not make sense where did I go wrong.
We can focus on this part of the code:
while i < len(list):
hs = 0
if s > hs:
ace = n
hs = s
As it's written, s > hs is the same as s > 0, so the condition will be true for all items of the list that have a score greater than zero.
To keep the greatest value, it should be defined once before entering the loop, like this:
hs = 0
while i < len(list):
if s > hs:
ace = n
hs = s
With this change, the value of hs will be keep during iterations of the while loop, and in the end it will keep the best score as hs.

Simple python loop doesn't work with many inner loops

I am struggling with a very simple loop that perfectly works if run "standalone", but doesn't work anymore if I use it as an outer loop for many other instructions (which also perfectly work if run standalone for only 1 iteration).
The simple outer loop is a
for i in range(0,somevalue):
do some inner instructions
Here is the full code, which perfectly works if I put a range of dimension 1, whilst it never ends if I put even a simple range of dimension 2:
import numpy as np
import numpy.ma as ma
import random
import matplotlib.pyplot as plt
i = int
x = np.zeros(1440)
class_x = np.zeros(1440)
w1 = np.array([0,6*60])
w2 = np.array([20*60,23*60])
x[w1[0]:(w1[1])] = np.full(np.diff(w1),0.001)
x[w2[0]:(w2[1])] = np.full(np.diff(w2),0.001)
x_masked = np.zeros_like(ma.masked_not_equal(x,0.001))
c = 10
func_time = 300
max_free_spot = int
i = 0
for i in range(0,1):
tot_time = 0
switch_count = 0
switch_ons = []
while
tot_time <= func_time:
switch_on = random.choice([random.randint(w1[0],(w1[1]-c)),random.randint(w2[0],(w2[1]-c))])
if x[switch_on] == 0.001:
if switch_on in range(w1[0],w1[1]):
if np.any(x[switch_on:w1[1]]!=0.001):
next_switch = [switch_on + k[0] for k in np.where(x[switch_on:]!=0.001)]
if (next_switch[0] - switch_on) >= c and max_free_spot >= c:
upper_limit = min((next_switch[0]-switch_on),min(func_time,w1[1]-switch_on))
elif (next_switch[0] - switch_on) < c and max_free_spot >= c:
continue
else: upper_limit = next_switch[0]-switch_on
else:
upper_limit = min(func_time,w1[1]-switch_on) #max random length of cycle
if upper_limit >= c:
indexes = np.arange(switch_on,switch_on+(random.randint(c,upper_limit)))
else:
indexes = np.arange(switch_on,switch_on+upper_limit)
else:
if np.any(x[switch_on:w2[1]]!=0.001):
next_switch = [switch_on + k[0] for k in np.where(x[switch_on:]!=0.001)]
if (next_switch[0] - switch_on) >= c:
upper_limit = min((next_switch[0]-switch_on),min(func_time,w2[1]-switch_on))
elif (next_switch[0] - switch_on) < c and max_free_spot >= c:
continue
else: upper_limit = next_switch[0]-switch_on
else:
upper_limit = min(func_time,w2[1]-switch_on)
if upper_limit >= c:
indexes = np.arange(switch_on,switch_on+(random.randint(c,upper_limit)))
else:
indexes = np.arange(switch_on,switch_on+upper_limit)
tot_time = tot_time + indexes.size
switch_ons.append(switch_on)
if tot_time > func_time:
indexes_adj = indexes[:-(tot_time-func_time)]
coincidence = random.randint(1,5)
np.put(x_masked,indexes_adj,(2*coincidence),mode='clip')
np.put(x,indexes_adj,(2*coincidence))
x_masked = np.zeros_like(ma.masked_greater_equal(x_masked,0.001))
tot_time = (tot_time - indexes.size) + indexes_adj.size
switch_count = switch_count + 1
break
else:
coincidence = random.randint(1,5)
np.put(x_masked,indexes,(2*coincidence),mode='clip')
np.put(x,indexes,(2*coincidence))
x_masked = np.zeros_like(ma.masked_greater_equal(x_masked,0.001))
tot_time = tot_time
switch_count = switch_count + 1
free_spots = []
for j in ma.notmasked_contiguous(x_masked):
free_spots.append(j.stop-j.start)
max_free_spot = max(free_spots)
class_x = class_x + x
plt.plot(class_x)
Any help is really really appreciated

Resources