DaniPaniz
DaniPaniz

Reputation: 1068

Calculate in Python 2.7 correct MACD and RSI indexes as they appear in binance web interface

I've been trying to compute and plot the prices, MACD and RSI indexes from cryptocoins on Binance (data obtained with this package), but I'm afraid either my indexes are not accurate or Binance is using different algorithms. I've been using the MACD and RSI functions from Matplotlib tutorial, which yield the same results as other algorithms I found elsewhere, so the algorithm should be accurate but I get the wrong results (as you can see from comparing the plots). In particular, the RSI seems to be correct, but the MACD (and the MACD and signal lines) are different from those displayed by the binance website trading view (see the pics)

what am I doing wrong?

#!/usr/bin/python
# -*- coding: utf8 -*-


import numpy as np
import matplotlib.pyplot as plt



######   data


prices = np.array([ 0.00061422,  0.00061422,  0.00061593,  0.00061672,  0.0006161 ,
        0.00061233,  0.000615  ,  0.00061305,  0.00061346,  0.00061417,
        0.00061428,  0.00061418,  0.0006115 ,  0.00061203,  0.0006125 ,
        0.00061295,  0.00061296,  0.00061295,  0.00061242,  0.00061144,
        0.00060874,  0.00060661,  0.00060512,  0.00060931,  0.000611  ,
        0.0006129 ,  0.00061296,  0.000613  ,  0.00061138,  0.0006115 ,
        0.0006123 ,  0.0006123 ,  0.00061288,  0.00061494,  0.000615  ,
        0.0006146 ,  0.00061488,  0.00061399,  0.00061285,  0.0006129 ,
        0.0006129 ,  0.00061291,  0.0006134 ,  0.00061338,  0.00061355,
        0.0006139 ,  0.00061475,  0.0006167 ,  0.0006158 ,  0.000617  ,
        0.00061638,  0.00061452,  0.0006164 ,  0.00061641,  0.00061646,
        0.00061898,  0.0006198 ,  0.00061818,  0.00061922,  0.00061979,
        0.00061977,  0.00061924,  0.00061626,  0.00061488,  0.000616  ,
        0.000616  ,  0.00061693,  0.0006165 ,  0.0006165 ,  0.00061699,
        0.00061685,  0.00061687,  0.00061691,  0.000617  ,  0.00061784,
        0.00061899,  0.0006177 ,  0.000617  ,  0.00061732,  0.0006176 ,
        0.0006174 ,  0.00061739,  0.00061739,  0.00061794,  0.0006185 ,
        0.0006185 ,  0.00061785,  0.00061735,  0.00061743,  0.00061742,
        0.00061429,  0.0006152 ,  0.00061451,  0.00061514,  0.0006143 ,
        0.000614  ,  0.0006154 ,  0.0006148 ,  0.00061444,  0.00061572])


######   functions


def moving_average(x, n, type='simple'):
    """
    compute an n period moving average.

    type is 'simple' | 'exponential'

    """
    x = np.asarray(x)
    if type == 'simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))

    weights /= weights.sum()

    a = np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a


def relative_strength(prices, n=14):
    """
    compute the n period relative strength indicator
    http://stockcharts.com/school/doku.php?id=chart_school:glossary_r#relativestrengthindex
    http://www.investopedia.com/terms/r/rsi.asp
    """

    deltas = np.diff(prices)
    seed = deltas[:n+1]
    up = seed[seed >= 0].sum()/n
    down = -seed[seed < 0].sum()/n
    rs = up/down
    rsi = np.zeros_like(prices)
    rsi[:n] = 100. - 100./(1. + rs)

    for i in range(n, len(prices)):
        delta = deltas[i - 1]  # cause the diff is 1 shorter

        if delta > 0:
            upval = delta
            downval = 0.
        else:
            upval = 0.
            downval = -delta

        up = (up*(n - 1) + upval)/n
        down = (down*(n - 1) + downval)/n

        rs = up/down
        rsi[i] = 100. - 100./(1. + rs)

    return rsi


def moving_average_convergence(x, nslow=26, nfast=12):
    """
    compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg'
    return value is emaslow, emafast, macd which are len(x) arrays
    """
    emaslow = moving_average(x, nslow, type='exponential')
    emafast = moving_average(x, nfast, type='exponential')
    return emaslow, emafast, emafast - emaslow


######   code


nslow = 26
nfast = 12
nema = 9
emaslow, emafast, macd = moving_average_convergence(prices, nslow=nslow, nfast=nfast)
ema9 = moving_average(macd, nema, type='exponential')
rsi = relative_strength(prices)

wins = 80


plt.figure(1)

### prices

plt.subplot2grid((8, 1), (0, 0), rowspan = 4)
plt.plot(prices[-wins:], 'k', lw = 1)


### rsi

plt.subplot2grid((8, 1), (5, 0))
plt.plot(rsi[-wins:], color='black', lw=1)
plt.axhline(y=30,     color='red',   linestyle='-')
plt.axhline(y=70,     color='blue',  linestyle='-')


## MACD

plt.subplot2grid((8, 1), (6, 0))

plt.plot(ema9[-wins:], 'red', lw=1)
plt.plot(macd[-wins:], 'blue', lw=1)


plt.subplot2grid((8, 1), (7, 0))

plt.plot(macd[-wins:]-ema9[-wins:], 'k', lw = 2)
plt.axhline(y=0, color='b', linestyle='-')

plt.show()

script output

Upvotes: 1

Views: 4653

Answers (1)

DaniPaniz
DaniPaniz

Reputation: 1068

I tried talib and that gives what I want :) (second picture) I guess they are two different ways to compute the MACD (but I tried non-exponential average before and did not work anyway, so I still don't know the reason underlying the difference).

import talib
macd, macdsignal, macdhist = talib.MACD(prices, fastperiod=12, slowperiod=26, signalperiod=9)

bad good

Upvotes: 1

Related Questions