пятница, 23 февраля 2018 г.

Python индикатор MACD

import numpy
import talib
import requests
import json
import time

from matplotlib.finance import candlestick2_ohlc
import matplotlib.animation as animation

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from datetime import datetime
import mysql.connector

PERIOD = 120 # Период в минутах для построения свечей

BEAR_PERC = 100
BULL_PERC =  0
PAIR = 'BTC_USD'

fig, ax = plt.subplots(3, sharex=True)
fig.comment = plt.figtext(.7,.05, '')

db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="exmo")
#db = mysql.connector.connect(host="10.8.1.1", user="u", passwd="secret", db="exmo")
cur = db.cursor()

def update_graph(interval):
    x=int(time.time())
    per = PERIOD * 60
    x= x - per*100
    _SQL = """SELECT
                    FLOOR(MIN(`date`)/%s)*%s AS date,
                    SUBSTRING_INDEX(MIN(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `open`,
                    MAX(price) AS high,
                    MIN(price) AS low,
                    SUBSTRING_INDEX(MAX(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `close`
              FROM trade              WHERE date >= %s
              GROUP BY FLOOR(`date`/%s)
              ORDER BY date"""
    cur.execute(_SQL,(per,per,x,per))
    chart_data = {} # сформируем словарь с ценой закрытия по PERIOD минут
    for item in cur.fetchall():
        d = item[0] # Округляем время сделки до PERIOD минут
        if not d in chart_data:
            chart_data[d] = {'open':0, 'close':0, 'high':0, 'low':0}
        chart_data[d]['close'] = float(item[4])
        chart_data[d]['open'] = float(item[1])
        chart_data[d]['high'] = float(item[2])
        chart_data[d]['low'] = float(item[3])
    quotes = {}
    quotes['open']=numpy.asarray([chart_data[item]['open'] for item in sorted(chart_data)])
    quotes['close']=numpy.asarray([chart_data[item]['close'] for item in sorted(chart_data)])
    quotes['high']=numpy.asarray([chart_data[item]['high'] for item in sorted(chart_data)])
    quotes['low']=numpy.asarray([chart_data[item]['low'] for item in sorted(chart_data)])
    xdate=[datetime.fromtimestamp(item) for item in sorted(chart_data)]
    ax[0].xaxis.set_major_locator(ticker.MaxNLocator(6))

    def chart_date(x,pos):
        try:
            return xdate[int(x)]
        except IndexError:
            return ''

    ax[0].clear()
    ax[0].xaxis.set_major_formatter(ticker.FuncFormatter(chart_date))
    ax[0].grid(True)
    ax[0].minorticks_on()
    # Customize the major grid
    ax[0].grid(which='major', linestyle='-', linewidth='0.5', color='red')
    # Customize the minor grid
    ax[0].grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    candlestick2_ohlc(ax[0], quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)
    fig.autofmt_xdate()
    fig.tight_layout()
    macd, macdsignal, macdhist = talib.MACD(quotes['close'], fastperiod=12, slowperiod=26, signalperiod=9)
    #macd, macdsignal, macdhist = talib.MACDFIX(quotes['close'], signalperiod=9)
    #real = talib.RSI(quotes['close'], timeperiod=14)
    #real = talib.AROONOSC(quotes['high'], quotes['low'], timeperiod=14)
    ax[1].clear()
    ax[1].grid(True)
    ax[1].minorticks_on()
    # Customize the major grid
    ax[1].grid(which='major', linestyle='-', linewidth='0.5', color='red')
    # Customize the minor grid
    ax[1].grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    ax[1].plot(macd, color="y")
    ax[1].plot(macdsignal)
    idx = numpy.argwhere(numpy.diff(numpy.sign(macd - macdsignal)) != 0).reshape(-1) + 0
    inters = []
    for offset, elem in enumerate(macd):
        if offset in idx:
            inters.append(elem)
        else:
            inters.append(numpy.nan)
    ax[1].plot(inters, 'ro')
    hist_data = []
    hist_data1 = []
    max_v = 0

    for offset, elem in enumerate(macdhist):
        activity_time = False
        curr_v = macd[offset] - macdsignal[offset]
        if abs(curr_v) > abs(max_v):
            max_v = curr_v
        perc = curr_v/max_v

        if ((macd[offset] > macdsignal[offset] and perc*100 > BULL_PERC)  or (macd[offset] < macdsignal[offset] and perc*100 < (100-BEAR_PERC)) ):
        #if       (   (macd[offset] - macdsignal[offset] > 0) # восходящий тренд
                #):
            #v = 1
            v=curr_v
            activity_time = True
        else:
            v = 0
            #v = -1
        hist_data.append(v)
        v1 = 0
        if curr_v < 0:
            v1 = curr_v
        hist_data1.append(v1)
        if offset in idx and not numpy.isnan(elem):
            # тренд изменился
            max_v = curr_v = 0 # обнуляем пик спреда между линиями
    ax[2].clear()
    ax[2].grid(True)
    ax[2].minorticks_on()
    # Customize the major grid
    ax[2].grid(which='major', linestyle='-', linewidth='0.5', color='red')
    # Customize the minor grid
    ax[2].grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    #ax[2].plot(real, color="y")
    ax[2].fill_between([x for x in range(len(macdhist))], 0, hist_data, facecolor='green', interpolate=True)
    ax[2].fill_between([x for x in range(len(macdhist))], 0, hist_data1, facecolor='red', interpolate=True)
    plt.gcf().texts.remove(fig.comment)
    fig.comment = plt.figtext(.6,.05, '%s %s%s' % (PAIR, time.ctime(), ' ТОРГУЕМ!!!! ' if activity_time else ''), style='italic', bbox={'facecolor':'red' if activity_time else 'green', 'alpha':0.5, 'pad':10})

ani = animation.FuncAnimation(fig, update_graph, interval=1000)
plt.show()

Комментариев нет:

Отправить комментарий