124697
124697

Reputation: 21893

Stochastic indicator formula

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:

enter image description here

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

Answers (1)

Stef
Stef

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

Related Questions