3
$\begingroup$

I want to match talib's RSI with just python down to machine precision and I'm struggling. Out of curiosity I also tried a bunch of libraries like tulipy and pandas_ta and the gaps are similar.

enter image description here

Anyone has any suggestions?

In the code snippet below, you can comment out all the relevant tulipy lines if you don't want to install it.

edit: Switched from RSI to a simple moving average for simplicity. The machine precision numeric gaps between c and python are similar anyway. The simple moving average c source code by talib: https://pastebin.com/WuMWBFtF

outputs:

                                 talib                                mine                              errors
0                                  nan                                 nan                                 nan
1                                  nan                                 nan                                 nan
2                                  nan                                 nan                                 nan
3                                  nan                                 nan                                 nan
4                                  nan                                 nan                                 nan
5                                  nan                                 nan                                 nan
6                                  nan                                 nan                                 nan
7                                  nan                                 nan                                 nan
8                                  nan                                 nan                                 nan
9                                  nan                                 nan                                 nan
10                                 nan                                 nan                                 nan
11  0.15516036417806491898296883391595  0.15516036417806497449412006517377 -0.00000000000000005551115123125783
12  0.05205880767301387240797438948903  0.05205880767301387240797438948903  0.00000000000000000000000000000000
13 -0.11350055963883017018378751572527 -0.11350055963883017018378751572527  0.00000000000000000000000000000000
14 -0.15543593887235351846953790300176 -0.15543593887235351846953790300176  0.00000000000000000000000000000000
15 -0.01614653775592672646510550293897 -0.01614653775592670911787074317090 -0.00000000000000001734723475976807
16 -0.00741072772658941687079492410817 -0.00741072772658940819717754422413 -0.00000000000000000867361737988404
17  0.18007029396551640920698389436438  0.18007029396551640920698389436438  0.00000000000000000000000000000000
18  0.13157654447972574884850871512754  0.13157654447972577660408433075645 -0.00000000000000002775557561562891
19  0.23623677929370121009178262738715  0.23623677929370123784735824301606 -0.00000000000000002775557561562891
20  0.09932199565529327422996885843531  0.09932199565529331586333228187868 -0.00000000000000004163336342344337
21 -0.05095804509442600910285037230096 -0.05095804509442600910285037230096  0.00000000000000000000000000000000
22 -0.08092279219264598977279234759408 -0.08092279219264594813942892415071 -0.00000000000000004163336342344337
23 -0.23319625415699421489001963436749 -0.23319625415699415937886840310966 -0.00000000000000005551115123125783
24  0.00495671069283426524165747650841  0.00495671069283432075280870776623 -0.00000000000000005551115123125783
25  0.23119641920851810579229379527533  0.23119641920851816130344502653315 -0.00000000000000005551115123125783
26  0.25282673483697731819930254459905  0.25282673483697731819930254459905  0.00000000000000000000000000000000
27  0.03160457726895595648164416502368  0.03160457726895599117611368455982 -0.00000000000000003469446951953614
28  0.01566407883863546804392719025145  0.01566407883863554437176013323096 -0.00000000000000007632783294297951
29 -0.15181719995420131508190308977646 -0.15181719995420125957075185851863 -0.00000000000000005551115123125783
30 -0.18723656696915602637432129995432 -0.18723656696915602637432129995432  0.00000000000000000000000000000000
31 -0.07811486111860536929452081267300 -0.07811486111860532766115738922963 -0.00000000000000004163336342344337
32 -0.20444686349359716959206423325668 -0.20444686349359711408091300199885 -0.00000000000000005551115123125783
33 -0.24196515292630801918782879056380 -0.24196515292630796367667755930597 -0.00000000000000005551115123125783
34 -0.14324766151539661263036862237641 -0.14324766151539658487479300674750 -0.00000000000000002775557561562891
35 -0.01668741793313034682544326869902 -0.01668741793313028784484508548758 -0.00000000000000005898059818321144
36 -0.20155891969265707364122874878376 -0.20155891969265701813007751752593 -0.00000000000000005551115123125783
37 -0.33901998761756196865135848383943 -0.33901998761756191314020725258160 -0.00000000000000005551115123125783
38 -0.25610064767786538952876185248897 -0.25610064767786527850645938997332 -0.00000000000000011102230246251565
39 -0.00627059309831806688251276682422 -0.00627059309831808509710926458069  0.00000000000000001821459649775647

and the code:

import numpy as np
import pandas as pd
import talib
np.random.seed(999)
period = 12
ts = pd.Series(np.random.randn(1000))

pd.set_option('display.max_rows', 10000)
pd.set_option('display.max_columns', 10000)
pd.set_option('display.width', 1000)
pd.set_option('display.float_format', lambda x: '%.32f' % x)


def manual_sma(prices, n):
    prices = prices.astype(np.double)
    ma = np.zeros_like(prices)
    ma[:n] = np.nan

    for i in range(n-1, len(prices)):
        ma[i] = np.nanmean(prices[i-n+1:i+1])
    return pd.Series(ma)


my_sma = manual_sma(ts, period)
pandas_sma = ts.rolling(period, min_periods=period).mean()
talib_sma = talib.SMA(ts, timeperiod=period)

df = pd.concat((talib_sma, my_sma), axis=1)
df.columns = ['talib', 'mine']
df['errors'] = df['talib'] - df['mine']
print(df.iloc[:40])
$\endgroup$
  • $\begingroup$ Could you add the outputs you are achieving and the ones you are trying to replicate to your question? It would be helpful $\endgroup$ – amdopt Jul 19 at 16:06
  • $\begingroup$ Switched to simple moving average for simplicity and added the outputs! $\endgroup$ – user165494 Jul 20 at 17:23
  • $\begingroup$ To me the results look pretty accurate, aren't they? $\endgroup$ – noob2 Jul 20 at 17:52
  • $\begingroup$ On the third column you can see the difference between the two numbers and they are different on the ~14th decimal. The regularity of those errors makes me think that it has to do with fundamental differences between c and python computations. I was wondering if there was a way to emulate c computations at that level with python to get a perfect match. $\endgroup$ – user165494 Jul 20 at 18:05
  • $\begingroup$ @user165494 I was thinking the same thing but I am not familiar enough with the C compiler to contribute anything of value. I'd be curious to know why this exists. $\endgroup$ – amdopt Jul 20 at 18:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.