ta-lib-python
ta-lib-python copied to clipboard
bollinger bands are the same for upper, middle and lower
Hi,
I tried to get the bollinger bands, my data are valid since the EMA and RSI are good :
ta_lib_data = data_table.get_talib_compatible_structure()
complete_ema20 = talib.abstract.EMA(ta_lib_data, timeperiod=20, price='average')
complete_ema40 = talib.abstract.EMA(ta_lib_data, timeperiod=40, price='average')
complete_rsi = talib.abstract.RSI(ta_lib_data, timeperiod=14)
upperBB, middleBB, lowerBB = talib.BBANDS(ta_lib_data['close'], nbdevup=2, nbdevdn=2, timeperiod=5) #matype=talib.MA_Type.T3
However the upperBB == middleBB == lowerBB here, why is that? I also tried without nbdevup=2, nbdevdn=2.
Thanks.
Without seeing your test case data, I'm not sure. You can look at the BBANDS source code which might help:
https://sourceforge.net/p/ta-lib/code/HEAD/tree/trunk/ta-lib/c/src/ta_func/ta_BBANDS.c
Here,
Json data + python script that load the json and then compute, ema, rsi and bollinger bands. upper == middle == lower, weird.
https://www.dropbox.com/s/mn70t24t9u3puct/forBB.json?dl=0 https://www.dropbox.com/s/lnkkbqvacw4yz8o/bollinger.py?dl=0
I have the same issue. I'm dealing with small numbers < .0002 stored in a numpy array, float64. Working in Python 2.7. array([ 0.00018185, 0.00017552, 0.00017599, ..., 0.00017896, 0.00017378, 0.00017192])
By total coincidence, I just ran into the same exact problem with something I was coding completely separately from talib. While I don't have the skills to code a solution for you, I believe the answer to fixing this bug may be in this thread...https://stackoverflow.com/questions/35906411/list-on-python-appending-always-the-same-value. In other words, it must be an issue with the memory address for each element in the bbands array.
Hello, iv'e discovered this:
#arr = np.array([0.00282, 0.00242, 0.00202, 0.0028, 0.0019, 0.0021, 0.0030, 0.0040], dtype=float) #this works
#arr = np.array([0.00282011, 0.00242011, 0.00202011, 0.00282011, 0.00192011, 0.00212011, 0.00302011, 0.00402011], dtype=float) this works
arr = np.array([0.000282, 0.000242, 0.000202, 0.00028, 0.00019, 0.00021, 0.00030, 0.00040], dtype=float) #this doesnt. it returns the same numbers for all bands
upper, middle, lower = talib.BBANDS(arr, timeperiod=2, nbdevup=2, nbdevdn=2, matype=0)
So if it's more than three zeroes it doesn't work. Do anyone know what's up then? How do i fix this.
Probably has something to do with float precision and representing small numbers. If you take your numbers and scale them up by 1000 then it works:
arr = np.array([0.282, 0.242, 0.202, 0.28, 0.19, 0.21, 0.30, 0.40], dtype=float)
I have to scale them up by 100 000 because some of the numbers are 0.00000001. Anyway, won't this mess up the bollinger calculation? (also am i doing this right, and isnt this a bug?)
My attempt:
closehack = np.array([])
for x in close:
closehack = np.append(close, x * 100000)
upper, middle, lower = talib.BBANDS(closehack, timeperiod=2, nbdevup=2, nbdevdn=2, matype=0)
for x in upper:
upperhack = np.append(upper, x / 100000)
plt.plot(upperhack)
But that doesn't give correct plot. Please help because i feel i am so close now.
I'm not sure why you use append instead of just passing close * 100000 and then doing upper / 100000.
Also your code would have he upper array contain two sets of vaues since you don't initialize and "upperhack" the way you do with "closehack".
Yeah that's what i did(the close * 100000 thing) :D sorry, i was a bit tired but i was just about to post that that is what i ended up doing.
I am still wondering if i have to do this kind of acrobatics with other indicators too and if this is considered a bug and will be fixed.
Ok. So doing the close * 100000 i now end up with numbers like 0.00045050653989108142578184912352412538893986493349 when i do close / 100000 again. Am i supposed to round this up or down or what should i do to get correct numbers?
You might lose a small amount of precision but I wouldn't think it would be a huge deal. That number has a lot of "apparent" precision but not in actuality I would guess.
Ok. Do you know if this is a limitation of the underlaying ta-lib or is it an issue with the python interface?
Same problem here, i didn't understand why my strategy doesn't work, after some log i saw values was same...
So i use this before
upperband, middleband, lowerband = ta.BBANDS(close*100000, timeperiod=20, nbdevup=2, nbdevdn=2,matype=0)
upVal =upperband[i]/100000
middleVal = middleband[i]/100000
lowVal = lowerband[i]/100000
What assets are you working with that have such low value prices? Are these altcoins? Although it should be doing work on double-precision floating point numbers, it might have some mathematical errors as you are discovering with very small numbers. I haven't spent much time looking at the underlying C code, but you could look it over if you want:
https://sourceforge.net/p/ta-lib/code/HEAD/tree/trunk/ta-lib/c/src/ta_func/ta_BBANDS.c
As far as I'm aware, this lightweight Python wrapper for that underlying TA-Lib C library should not be doing any kind of conversion, and should just be passing through the numpy array of floats into the TA_BBANDS function call.
There's no problem with the library or the wrapper.
from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import datetime as datetime
import numpy as np
import talib
quotes = np.array([ (1459388100, 29.799999237060547, 29.799999237060547, 29.799999237060547, 29.799999237060547, 148929.0, 450030016.0),
(1459388400, 29.799999237060547, 29.979999542236328, 29.709999084472656, 29.920000076293945, 10395.0, 31069984.0),
(1459388700, 29.959999084472656, 30.18000030517578, 29.719999313354492, 30.149999618530273, 38522.0, 114999968.0),
(1459389000, 30.170000076293945, 30.479999542236328, 30.0, 30.149999618530273, 29823.0, 90220032.0),
(1459389300, 30.149999618530273, 30.75, 30.1299991607666, 30.549999237060547, 38903.0, 118620032.0),
(1459389600, 30.59000015258789, 30.93000030517578, 30.559999465942383, 30.65999984741211, 42308.0, 130000000.0),
(1459389900, 30.6200008392334, 30.690000534057617, 30.3799991607666, 30.3799991607666, 20209.0, 61689984.0),
(1459390200, 30.3700008392334, 30.489999771118164, 30.18000030517578, 30.18000030517578, 18491.0, 56169984.0),
(1459390500, 30.190000534057617, 30.329999923706055, 30.010000228881836, 30.010000228881836, 17641.0, 53200000.0),
(1459390800, 30.030000686645508, 30.399999618530273, 30.030000686645508, 30.280000686645508, 9526.0, 28899968.0),
(1459391100, 30.299999237060547, 30.31999969482422, 30.200000762939453, 30.209999084472656, 9282.0, 28100096.0),
(1459391400, 30.190000534057617, 30.280000686645508, 30.049999237060547, 30.1200008392334, 8663.0, 26099968.0),
(1459391700, 30.110000610351562, 30.110000610351562, 29.959999084472656, 30.100000381469727, 15677.0, 47099904.0),
(1459392000, 30.1200008392334, 30.260000228881836, 30.0, 30.059999465942383, 5649.0, 17000064.0),
(1459392300, 30.079999923706055, 30.299999237060547, 30.0, 30.280000686645508, 6057.0, 18199936.0),
(1459392600, 30.290000915527344, 30.34000015258789, 30.1200008392334, 30.1200008392334, 7914.0, 24000000.0),
(1459392900, 30.1299991607666, 30.15999984741211, 30.079999923706055, 30.139999389648438, 4521.0, 13600000.0),
(1459393200, 30.139999389648438, 30.139999389648438, 29.829999923706055, 29.899999618530273, 16255.0, 48600064.0),
(1459393500, 29.93000030517578, 30.1200008392334, 29.889999389648438, 30.1200008392334, 6877.0, 20600064.0),
(1459393800, 30.1299991607666, 30.15999984741211, 29.979999542236328, 30.030000686645508, 3803.0, 11499904.0),
(1459394100, 30.040000915527344, 30.1299991607666, 30.0, 30.030000686645508, 4421.0, 13300096.0),
(1459394400, 29.989999771118164, 30.389999389648438, 29.989999771118164, 30.389999389648438, 7011.0, 21099904.0),
(1459394700, 30.399999618530273, 30.450000762939453, 30.270000457763672, 30.299999237060547, 12095.0, 36800000.0),
(1459395000, 30.34000015258789, 30.450000762939453, 30.280000686645508, 30.43000030517578, 9284.0, 28099968.0),
(1459400700, 30.510000228881836, 30.729999542236328, 30.5, 30.600000381469727, 17139.0, 52500096.0),
(1459401000, 30.600000381469727, 30.799999237060547, 30.530000686645508, 30.790000915527344, 11888.0, 36400000.0),
(1459401300, 30.809999465942383, 31.100000381469727, 30.809999465942383, 31.049999237060547, 30692.0, 95099904.0),
(1459401600, 31.06999969482422, 31.559999465942383, 30.93000030517578, 31.559999465942383, 24473.0, 76200064.0),
(1459401900, 31.600000381469727, 31.860000610351562, 31.299999237060547, 31.450000762939453, 34497.0, 109200000.0),
(1459402200, 31.43000030517578, 31.600000381469727, 31.18000030517578, 31.18000030517578, 18525.0, 58200064.0),
(1459402500, 31.18000030517578, 31.350000381469727, 31.040000915527344, 31.18000030517578, 10153.0, 31599872.0),
(1459402800, 31.200000762939453, 31.399999618530273, 31.010000228881836, 31.389999389648438, 9668.0, 30100096.0),
(1459403100, 31.399999618530273, 31.399999618530273, 31.110000610351562, 31.360000610351562, 8445.0, 26499968.0),
(1459403400, 31.360000610351562, 31.399999618530273, 31.040000915527344, 31.100000381469727, 9538.0, 29799936.0),
(1459403700, 31.1200008392334, 31.399999618530273, 31.100000381469727, 31.270000457763672, 7996.0, 25000064.0),
(1459404000, 31.270000457763672, 31.399999618530273, 31.15999984741211, 31.399999618530273, 6760.0, 21100032.0),
(1459404300, 31.389999389648438, 32.400001525878906, 31.389999389648438, 32.189998626708984, 26108.0, 83700096.0),
(1459404600, 32.209999084472656, 32.400001525878906, 31.860000610351562, 32.29999923706055, 15736.0, 50599936.0),
(1459404900, 32.29999923706055, 32.310001373291016, 31.489999771118164, 31.489999771118164, 12945.0, 41399808.0),
(1459405200, 31.5, 32.0, 31.40999984741211, 31.81999969482422, 11901.0, 37700096.0),
(1459405500, 31.809999465942383, 31.940000534057617, 31.719999313354492, 31.770000457763672, 6503.0, 20700160.0),
(1459405800, 31.760000228881836, 31.790000915527344, 31.399999618530273, 31.790000915527344, 10103.0, 31899904.0),
(1459406100, 31.780000686645508, 32.029998779296875, 31.780000686645508, 31.850000381469727, 12033.0, 38500096.0),
(1459406400, 31.809999465942383, 33.310001373291016, 31.809999465942383, 33.029998779296875, 58238.0, 192199936.0),
(1459406700, 33.029998779296875, 33.310001373291016, 32.79999923706055, 32.79999923706055, 36689.0, 121900032.0),
(1459407000, 32.79999923706055, 32.869998931884766, 32.61000061035156, 32.70000076293945, 15245.0, 49799936.0),
(1459407300, 32.68000030517578, 32.689998626708984, 31.799999237060547, 32.0099983215332, 20507.0, 65999872.0),
(1459407600, 32.02000045776367, 32.02000045776367, 31.760000228881836, 31.799999237060547, 29610.0, 94300160.0)],
dtype=[('time', '<i4'), ('open', 'd'), ('high', 'd'), ('low', 'd'), ('close', 'd'), ('volume', 'd'), ('amount', 'd')])
fig, ax = plt.subplots()
candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)
xdate = [datetime.datetime.fromtimestamp(i) for i in quotes['time']]
def mydate(x,pos):
try:
return xdate[int(x)]
except IndexError:
return ''
fig.autofmt_xdate()
fig.tight_layout()
plt.show()
o, h, l, c = quotes['open'], quotes['high'], quotes['low'], quotes['close']
upper, middle, lower = talib.BBANDS(c)
upper[47], middle[47],lower[47]
IN[284}: upper[47], middle[47],lower[47]
Out[284]: (33.421259371477881, 32.467999267578122, 31.51473916367836)
pcawthron: try that with numbers like 0.0002.
It might have something to do with this in the original lib: USE_SINGLE_PRECISION_INPUT but i don't speak c so that's just a guess.
@mrjbq7 :
It's Altcoin yes.
I use numpy :
close = np.append(close,r['C'])
with this for example
C | 0.00020201
I must change the precision of array ?
On MACD function, no problem.
Are you using 64-bit? I think the dtype of your array is probably float which should be double precision on 64-bit.
Just to add, I am having this issue while looping through regular forex values. I loop through the close price on a number of markets (for example EUR-USD, EUR-GBP, GBP-HKD etc etc) calculating the bollinger values. It seems completely random as to when I get the same numbers for upper, middle and lower but what seems certain is that the longer my program is running, the more likely I am to get this error.
I have tried to clear out/delete the dictionary I am holding the values in on each loop - no guarantee of success. I have also tried multiplying/dividing the values as suggested above but again, no luck.
Same last value for upper, middle, and lower? Or same all values?
Yeah same value for upper middle and lower. I have since noticed the granularity of the candle information I was requesting was defaulting to 5 seconds (rather than say 30 minutes or 5 minutes). That might have been having an impact but I would expect even on 5 seconds, the upper, middle and lower are different.
With the correct granularity, I am currently getting the correct values.
Same problem here. Multiplying the input values 'fixes' the issue... Also ran into the same thing with the RSI indicator. When values are too low (0.00000140-ish), RSi spits out a 0.0
@mrjbq7 : Yes i am in 64 Bits. sorry for late answer
Small values are a result of this feature in the underlying TA-Lib C library:
https://github.com/mrjbq7/ta-lib/issues/157#issuecomment-338589408
Facing the same issue. The following produces three identical arrays for upper, middle and lower on 64 bit Python 2.7.14:
import numpy from talib import func
data = numpy.arange(0.08, 0.081, 0.00001, dtype=float)
bbands = func.BBANDS(data, timeperiod=10, nbdevup=2, nbdevdn=2, matype=0)
I appreciate the report, but its not an issue I am able to workaround easily in this python wrapper. The underlying C library has a feature around "almost zero" values.
https://github.com/mrjbq7/ta-lib/issues/157#issuecomment-338589408
@mrjbq7 Appreciate your efforts and that your hands are tied in this regard. Without having looked into the underlying C library, it seems strange that it would fail for "almost zero" values of this order of magnitude. I would expect that data sets several orders of magnitude smaller are a common occurrence in the context of bbands.
Well, the code is the best place to look, which is not exactly easy to read, but...
https://github.com/stoni/ta-lib/blob/master/src/ta_func/ta_BBANDS.c
BBANDS uses STDDEV, which you can see is zero for some "weird" reason:
>>> talib.STDDEV(data)
array([nan, nan, nan, nan, 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
And if you look at the code for STDDEV:
https://github.com/stoni/ta-lib/blob/master/src/ta_func/ta_STDDEV.c
You can see that it calls to VAR, which are really small numbers:
>>> talib.VAR(data)
array([ nan, nan, nan, nan,
2.00000002e-10, 2.00000004e-10, 2.00000003e-10, 2.00000004e-10,
2.00000003e-10, 2.00000004e-10, 2.00000003e-10, 2.00000003e-10,
2.00000002e-10, 2.00000002e-10, 2.00000001e-10, 2.00000003e-10,
2.00000002e-10, 2.00000005e-10, 2.00000002e-10, 2.00000002e-10,
2.00000003e-10, 2.00000004e-10, 2.00000004e-10, 2.00000003e-10,
2.00000003e-10, 2.00000005e-10, 2.00000004e-10, 2.00000003e-10,
2.00000004e-10, 2.00000003e-10, 2.00000003e-10, 2.00000001e-10,
2.00000002e-10, 2.00000004e-10, 2.00000003e-10, 2.00000003e-10,
2.00000003e-10, 2.00000003e-10, 2.00000003e-10, 2.00000003e-10,
2.00000002e-10, 2.00000004e-10, 2.00000001e-10, 2.00000001e-10,
2.00000000e-10, 2.00000001e-10, 2.00000000e-10, 2.00000001e-10,
2.00000001e-10, 2.00000004e-10, 2.00000002e-10, 2.00000001e-10,
2.00000001e-10, 2.00000000e-10, 2.00000001e-10, 2.00000000e-10,
1.99999999e-10, 2.00000001e-10, 1.99999997e-10, 1.99999997e-10,
1.99999998e-10, 1.99999998e-10, 1.99999998e-10, 1.99999998e-10,
1.99999998e-10, 2.00000001e-10, 1.99999998e-10, 1.99999999e-10,
1.99999998e-10, 1.99999998e-10, 1.99999997e-10, 1.99999997e-10,
1.99999997e-10, 1.99999999e-10, 1.99999998e-10, 1.99999998e-10,
1.99999998e-10, 1.99999998e-10, 1.99999997e-10, 1.99999997e-10,
1.99999997e-10, 1.99999999e-10, 1.99999997e-10, 1.99999997e-10,
1.99999996e-10, 1.99999997e-10, 1.99999996e-10, 1.99999994e-10,
1.99999994e-10, 1.99999997e-10, 1.99999995e-10, 1.99999994e-10,
1.99999994e-10, 1.99999994e-10, 1.99999993e-10, 1.99999994e-10,
1.99999995e-10, 1.99999997e-10, 1.99999995e-10, 1.99999995e-10,
1.99999996e-10])
And if you look further at the code in ta_STDDEV.c, you can see this:
for( i=0; i < (int)VALUE_HANDLE_DEREF(outNBElement); i++ )
{
tempReal = outReal[i];
if( !TA_IS_ZERO_OR_NEG(tempReal) )
outReal[i] = std_sqrt(tempReal);
else
outReal[i] = (double)0.0;
}
So, if you look at the definition of TA_IS_ZERO_OR_NEG, you can see where the "small numbers" issue comes up:
ta_func/ta_utility.h
259:#define TA_IS_ZERO_OR_NEG(v) (v<0.00000001)
So, basically your numbers are all really close together in a way that the underlying C library thinks is too small precision (for some reason that I don't know since I've never talked to the author, maybe they had to work with small precision floats or something).
Your workaround is probably to either change TA_IS_ZERO_OR_NEG and recompile the underlying library, or fudge your data up and then down:
import numpy
import talib
data = numpy.arange(0.08, 0.081, 0.00001, dtype=float)
bbands = talib.BBANDS(data * 1000, timeperiod=10, nbdevup=2, nbdevdn=2, matype=0)
bbands = [b / 1000 for b in bbands]
I'm not sure if there's anything else I can or should be doing here... sorry!