Reputation: 21893
I am scraping a number every 1 minute and I want to know when this number changes by a lot compared to it's previous values. I've decided to use the Stochastic indicator (maybe not the best way).
I am trying to implement the Stochastic indicator in python but the results is always 100. I think i am doing something wrong.
The formula:
Here is my code
def get_k():
global c_last_count
c_last_count = int(data[0])
highest = int(max(data))
lowest = int(min(data))
try:
k = ((c_last_count - lowest) / (highest - lowest)) * 100
except:
k = 0
k_arr.insert(0, k)
if len(k_arr) >= 0:
k_smoothing_3 = np.mean(k_arr[0:3])
print("k_smoothing_3 ", k_smoothing_3)
global stoch
stoch.insert(0, k_smoothing_3)
print("stoch ", k_smoothing_3)
store_stoch(k_smoothing_3)
Data k_arr
:
['5169', '5169', '5168', '5168', '5167', '5166', '5165', '5165', '5165', '5165', '5165', '5165', '5165', '5165', '5164', '5165', '5164', '5163', '5162', '5163', '5162', '5162', '5162', '5163', '5162', '5162', '5160', '5160', '5162', '5162', '5160', '5160', '5160', '5160', '5160', '5160', '5160', '5159', '5159', '5159', '5159', '5158', '5156', '5155', '5154', '5154', '5154', '5153', '5153', '5153', '5153', '5153', '5154', '5154', '5153', '5152', '5152', '5152', '5151', '5150', '5150', '5150', '5149', '5150', '5150', '5150', '5150', '5150', '5151', '5151', '5151', '5151', '5151', '5152', '5152', '5152', '5152', '5152', '5152', '5152', '5153', '5152', '5151', '5151', '5152', '5151', '5150', '5148', '5148', '5148', '5148', '5148', '5147', '5147', '5147', '5147', '5146', '5146', '5145', '5144', '5145', '5145', '5145', '5145', '5144', '5144', '5144', '5144', '5143', '5143', '5143', '5143', '5143', '5143', '5143', '5143', '5142', '5142', '5141', '5141', '5140', '5140', '5140', '5140', '5139', '5139', '5139', '5139', '5140', '5140', '5140', '5139', '5008', '5007', '5007', '5006', '5004', '5004', '5003', '5002', '5002', '5002', '5002', '5003', '5002', '5002', '5000', '5000', '5000', '5000', '5000', '5000', '4999', '4999', '4999', '4999', '4999', '4999', '4999', '4997', '4997', '4998', '4996', '4996', '4997', '4996', '4996', '4996', '4996', '4997', '4997', '4997', '4996', '4996', '4996', '4995', '4995', '4993', '4993', '4994', '4994', '4994', '4993', '4993', '4992', '4992', '4992', '4992', '4990', '4990', '4988', '4989', '4990', '4991', '4991', '4992', '4993', '4993', '4993', '4993', '4993', '4993', '4993', '4991', '4991', '4991', '4991', '4992', '4991', '4989', '4989', '4989', '4988', '4987', '4986', '4985', '4985', '4985', '4985', '4985', '4985', '4985', '4987', '4987', '4986', '4985', '4985', '4985', '4985', '4985', '4984', '4984', '4984', '4984', '4984', '4983', '4983', '4983', '4983', '4982', '4980', '4980', '4980', '4981', '4979', '4978', '4977', '4976', '4977', '4977', '4976', '4977', '4977', '4976', '4974', '4973', '4971', '4971', '4970', '4970', '4970', '4969', '4969', '4968', '4968', '4967', '4967', '4967', '4967', '4967', '4967', '4967', '4965', '4963', '4964', '4965', '4965', '4965', '4964', '4964', '4962', '4962', '4962', '4961', '4960', '4960', '4959', '4959', '4959', '4960', '4959', '4959', '4958', '4958', '4958', '4958', '4958', '4956', '4955', '4955', '4954', '4954', '4954', '4954']
Upvotes: 1
Views: 2019
Reputation: 15505
A few comments:
Do not use global variables. Include the variables that are needed as input in the arguments of the function (between the two brackets on the def
line). For the output, use the return
keyword. That would make it a lot easier for other people to read and understand your code.
highest = int(max(data))
: That line is highly suspicious. You're converting the result to int
because data
is a list of strings rather than a list of integers. But if it's a list of strings, how is max
going to be able to identify the maximum value correctly? You need to convert to int
before calling max
, not after. String comparison is lexicographical: for instance, with strings '934' > '5169'
, whereas with ints 934 < 5169
.
It appears your function manipulates several lists: data
, k_arr
, stoch
. The formula that you're trying to implement is only expecting one list. The code you've shown us appears to do a lot more than just calculate the value for that formula.
Regarding "the result is always 100": you should expect the result to be 100 when the most recent closing price is the highest price of the 14 previous sessions, and to be less than 100 when the most recent closing price is not the highest price.
When L14 == H14
, you cannot divide by (H14 - L14)
because that would be a division by 0. Currently, your code handles that with a try / except
block, which chooses the arbitrary value 0 as the indicator in this case. Note that the value 0 is also the value of the indicator when C == L14
. I think a distinction should be made and since I see no reason, according to your formula, to return 0 when L14 == H14
, your function could return "not a number" when the indicator cannot be calculated because of the division by 0.
With all that in mind, I suggest to rewrite your function so that it accepts a list of int
as argument; extracts the last 14 values from that list; calculates L14 and H14 and C; calculates K; and returns K with the return
keyword.
def stochastic_indicator(data):
last_14 = data[-14:]
l14 = min(last_14)
h14 = max(last_14)
c = last_14[-1]
if h14 > l14:
return 100 * (c - l14) / (h14 - l14)
else:
return float('nan')
# TESTING
str_data = ['5169', '5169', '5168', '5168', '5167', '5166', '5165', '5165', '5165', '5165', '5165', '5165', '5165', '5165', '5164', '5165', '5164', '5163', '5162', '5163', '5162', '5162', '5162', '5163', '5162', '5162', '5160', '5160', '5162', '5162', '5160', '5160', '5160', '5160', '5160', '5160', '5160', '5159', '5159', '5159', '5159', '5158', '5156', '5155', '5154', '5154', '5154', '5153', '5153', '5153', '5153', '5153', '5154', '5154', '5153', '5152', '5152', '5152', '5151', '5150', '5150', '5150', '5149', '5150', '5150', '5150', '5150', '5150', '5151', '5151', '5151', '5151', '5151', '5152', '5152', '5152', '5152', '5152', '5152', '5152', '5153', '5152', '5151', '5151', '5152', '5151', '5150', '5148', '5148', '5148', '5148', '5148', '5147', '5147', '5147', '5147', '5146', '5146', '5145', '5144', '5145', '5145', '5145', '5145', '5144', '5144', '5144', '5144', '5143', '5143', '5143', '5143', '5143', '5143', '5143', '5143', '5142', '5142', '5141', '5141', '5140', '5140', '5140', '5140', '5139', '5139', '5139', '5139', '5140', '5140', '5140', '5139', '5008', '5007', '5007', '5006', '5004', '5004', '5003', '5002', '5002', '5002', '5002', '5003', '5002', '5002', '5000', '5000', '5000', '5000', '5000', '5000', '4999', '4999', '4999', '4999', '4999', '4999', '4999', '4997', '4997', '4998', '4996', '4996', '4997', '4996', '4996', '4996', '4996', '4997', '4997', '4997', '4996', '4996', '4996', '4995', '4995', '4993', '4993', '4994', '4994', '4994', '4993', '4993', '4992', '4992', '4992', '4992', '4990', '4990', '4988', '4989', '4990', '4991', '4991', '4992', '4993', '4993', '4993', '4993', '4993', '4993', '4993', '4991', '4991', '4991', '4991', '4992', '4991', '4989', '4989', '4989', '4988', '4987', '4986', '4985', '4985', '4985', '4985', '4985', '4985', '4985', '4987', '4987', '4986', '4985', '4985', '4985', '4985', '4985', '4984', '4984', '4984', '4984', '4984', '4983', '4983', '4983', '4983', '4982', '4980', '4980', '4980', '4981', '4979', '4978', '4977', '4976', '4977', '4977', '4976', '4977', '4977', '4976', '4974', '4973', '4971', '4971', '4970', '4970', '4970', '4969', '4969', '4968', '4968', '4967', '4967', '4967', '4967', '4967', '4967', '4967', '4965', '4963', '4964', '4965', '4965', '4965', '4964', '4964', '4962', '4962', '4962', '4961', '4960', '4960', '4959', '4959', '4959', '4960', '4959', '4959', '4958', '4958', '4958', '4958', '4958', '4956', '4955', '4955', '4954', '4954', '4954', '4954']
int_data = list(map(int, str_data))
# = [5169, 5169, 5168, 5168, 5167, 5166, 5165, 5165, 5165, 5165, 5165, 5165, 5165, 5165, 5164, 5165, 5164, 5163, 5162, 5163, 5162, 5162, 5162, 5163, 5162, 5162, 5160, 5160, 5162, 5162, 5160, 5160, 5160, 5160, 5160, 5160, 5160, 5159, 5159, 5159, 5159, 5158, 5156, 5155, 5154, 5154, 5154, 5153, 5153, 5153, 5153, 5153, 5154, 5154, 5153, 5152, 5152, 5152, 5151, 5150, 5150, 5150, 5149, 5150, 5150, 5150, 5150, 5150, 5151, 5151, 5151, 5151, 5151, 5152, 5152, 5152, 5152, 5152, 5152, 5152, 5153, 5152, 5151, 5151, 5152, 5151, 5150, 5148, 5148, 5148, 5148, 5148, 5147, 5147, 5147, 5147, 5146, 5146, 5145, 5144, 5145, 5145, 5145, 5145, 5144, 5144, 5144, 5144, 5143, 5143, 5143, 5143, 5143, 5143, 5143, 5143, 5142, 5142, 5141, 5141, 5140, 5140, 5140, 5140, 5139, 5139, 5139, 5139, 5140, 5140, 5140, 5139, 5008, 5007, 5007, 5006, 5004, 5004, 5003, 5002, 5002, 5002, 5002, 5003, 5002, 5002, 5000, 5000, 5000, 5000, 5000, 5000, 4999, 4999, 4999, 4999, 4999, 4999, 4999, 4997, 4997, 4998, 4996, 4996, 4997, 4996, 4996, 4996, 4996, 4997, 4997, 4997, 4996, 4996, 4996, 4995, 4995, 4993, 4993, 4994, 4994, 4994, 4993, 4993, 4992, 4992, 4992, 4992, 4990, 4990, 4988, 4989, 4990, 4991, 4991, 4992, 4993, 4993, 4993, 4993, 4993, 4993, 4993, 4991, 4991, 4991, 4991, 4992, 4991, 4989, 4989, 4989, 4988, 4987, 4986, 4985, 4985, 4985, 4985, 4985, 4985, 4985, 4987, 4987, 4986, 4985, 4985, 4985, 4985, 4985, 4984, 4984, 4984, 4984, 4984, 4983, 4983, 4983, 4983, 4982, 4980, 4980, 4980, 4981, 4979, 4978, 4977, 4976, 4977, 4977, 4976, 4977, 4977, 4976, 4974, 4973, 4971, 4971, 4970, 4970, 4970, 4969, 4969, 4968, 4968, 4967, 4967, 4967, 4967, 4967, 4967, 4967, 4965, 4963, 4964, 4965, 4965, 4965, 4964, 4964, 4962, 4962, 4962, 4961, 4960, 4960, 4959, 4959, 4959, 4960, 4959, 4959, 4958, 4958, 4958, 4958, 4958, 4956, 4955, 4955, 4954, 4954, 4954, 4954]
for t in range(25, 304, 25):
print('# Stochastic indicator at time t={:3d}: {:6.2f}'.format(t, stochastic_indicator(int_data[:t])))
# Stochastic indicator at time t= 25: 0.00
# Stochastic indicator at time t= 50: 0.00
# Stochastic indicator at time t= 75: 100.00
# Stochastic indicator at time t=100: 0.00
# Stochastic indicator at time t=125: 0.00
# Stochastic indicator at time t=150: 0.00
# Stochastic indicator at time t=175: 0.00
# Stochastic indicator at time t=200: 100.00
# Stochastic indicator at time t=225: 25.00
# Stochastic indicator at time t=250: 14.29
# Stochastic indicator at time t=275: 16.67
# Stochastic indicator at time t=300: 0.00
Upvotes: 1