Рассчитать в Python 2.7 правильные индексы MACD и RSI, как они отображаются в веб-интерфейсе binance

Я пытался вычислить и построить графики цен, индексов MACD и RSI для криптовалют на Binance (данные получены с помощью этот пакет), но я боюсь, что либо мои индексы не точны, либо Binance использует другие алгоритмы. Я использовал функции MACD и RSI из учебника Matplotlib, которые дают те же результаты, что и другие алгоритмы, которые я нашел в другом месте, поэтому алгоритм должен быть точным, но я получаю неправильные результаты (как вы можете видеть из сравнения графиков). В частности, RSI кажется правильным, но MACD (а также MACD и сигнальные линии) отличаются от отображаемых в торговом представлении сайта binance (см. рисунки)

Что я делаю не так?

#!/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()

вывод сценария


person DaniPaniz    schedule 20.02.2018    source источник


Ответы (1)


Я попробовал talib, и это дает то, что я хочу :) (второе изображение) Я думаю, это два разных способа вычисления MACD (но я пробовал неэкспоненциальное среднее раньше и все равно не работал, так что я до сих пор не знаю причину лежащие в основе различия).

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

bad хорошо

person DaniPaniz    schedule 20.02.2018
comment
Могу я спросить, что вы сделали, чтобы привести свои ценности в соответствие с ценностями Binance? Я борюсь с той же задачей, и у меня есть библиотека, которая дает те же результаты, что и talib (я проверил, потому что думал, что в библиотеках действительно есть различия), изменяя количество входных параметров (вы также использовали 100)... но для меня выходные значения все еще отличаются от того, что я вижу на Binance. Может быть, сейчас, 3 года спустя, они используют другие параметры, чем когда вы опубликовали это? - person YetiCGN; 15.02.2021
comment
@YetiCGN, извини, чувак, я очень мало всего этого помню :D - person DaniPaniz; 15.02.2021
comment
Это уже. Я убедился, что в моей библиотеке точно такие же значения, как и в talib, и сейчас меня это устраивает. - person YetiCGN; 16.02.2021