Python: построение подсвечников с автоматическим увеличением Y - PullRequest
0 голосов
/ 03 июля 2018

Я ищу библиотеку для построения графиков Python, которая позволяла бы мне строить подсвечники (предпочтительно вариант баров OHLC) с масштабированием по X с помощью прокрутки колесиком мыши (или аналогичным способом) и автоматически масштабируемой осью Y при масштабировании.

В качестве примера того, что я ищу, tradingview.com делает это отлично. См. https://uk.tradingview.com/chart/?symbol=NASDAQ:NDX. Бары OHLC можно увидеть, щелкнув значок подсвечника в верхнем левом углу и выбрав «Бары».

Plotly почти способен сделать это. Класс Ohlc в plotly.graph_objs предоставляет полосы OHLC, а ползунок диапазона по умолчанию является хорошей функцией для увеличения X (прокрутка колесиком мыши также может быть легко включена). Однако, насколько я вижу, автоматическое масштабирование по Y в Python недоступно ( автоматическое масштабирование по оси Y с ползунками x-range в сюжете ), поэтому при увеличении масштаба часть данных выглядит плоской. Пример кода - https://plot.ly/python/ohlc-charts/

Другой вариант, с которым я знаком, - это PyQtGraph, который имеет хорошие функции масштабирования, но не поддерживает подсвечники. Использование этого потребовало бы кодирования моего собственного объекта подсвечника.

Существует множество библиотек Python, которые я не знаю. Есть ли что-нибудь, что имеет встроенную поддержку для этого? Кто-нибудь может предоставить пример кода, чтобы сделать это чисто?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Я изо всех сил пытался заставить график графиков свечей работать так, как я хотел, поэтому я разработал пример кода для обмена.

Это не зависит от каких-либо дополнительных javascript или других библиотек, кроме Dash, Plotly и библиотеки дат, называемой pytz. Пример кода обеспечивает автоматическое обновление диапазона Yaxis, когда и ползунок диапазона X обновляется. Ось Y настроена так, чтобы показывать только ценовой диапазон баров, которые находятся на графике с двумя тиковыми отступами.

Это хорошо сработало для меня, и я потенциально могу добавить любое количество наложений трассировки в верхнюю часть графика. Кроме того, я могу запустить его локально, не пользуясь сюжетными услугами. Смотрите репозиторий Gitub здесь:

https://github.com/gersteing/DashCandlestickCharting/blob/master/README.md

Для кого когда-либо хочет попробовать это. Работает локально, используя Flask. Наслаждайтесь!

0 голосов
/ 08 июля 2018

Лучшее решение, которое я нашел, это использовать Bokeh. Здесь есть связанный вопрос - Боке, масштаб только по одной оси, соответственно отрегулируйте другую ось . Один ответ связывает гист , который дает пример настройки подсвечников с автоматическим увеличением Y.

К сожалению, это далеко не готовое решение, поскольку оно включает в себя кодирование пользовательского обратного вызова JavaScript. Однако решение все еще довольно простое. Я не смог заставить работать код, в основном из-за проблем с Pandas DataReader. Вот обновленная версия кода, которая использует пример данных, которые предоставляет Bokeh (согласно примеру Bokeh Candlesicks ), добавляет больше сходства с TradingView и устраняет некоторые другие обнаруженные мной проблемы:

import pandas as pd

from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.sampledata.stocks import MSFT


def candlestick_plot(df):
    fig = figure(sizing_mode='stretch_both',
                 tools="xpan,xwheel_zoom,undo,redo,reset,crosshair,save",
                 active_drag='xpan',
                 active_scroll='xwheel_zoom',
                 x_axis_type='datetime')

    inc = df.close > df.open
    dec = ~inc

    fig.segment(df.date[inc], df.high[inc], df.date[inc], df.low[inc], color="green")
    fig.segment(df.date[dec], df.high[dec], df.date[dec], df.low[dec], color="red")
    width_ms = 12*60*60*1000 # half day in ms
    fig.vbar(df.date[inc], width_ms, df.open[inc], df.close[inc], color="green")
    fig.vbar(df.date[dec], width_ms, df.open[dec], df.close[dec], color="red")

    source = ColumnDataSource({'date': df.date, 'high': df.high, 'low': df.low})
    callback = CustomJS(args={'y_range': fig.y_range, 'source': source}, code='''
        clearTimeout(window._autoscale_timeout);

        var date = source.data.date,
            low = source.data.low,
            high = source.data.high,
            start = cb_obj.start,
            end = cb_obj.end,
            min = Infinity,
            max = -Infinity;

        for (var i=0; i < date.length; ++i) {
            if (start <= date[i] && date[i] <= end) {
                max = Math.max(high[i], max);
                min = Math.min(low[i], min);
            }
        }
        var pad = (max - min) * .05;

        window._autoscale_timeout = setTimeout(function() {
            y_range.start = min - pad;
            y_range.end = max + pad;
        });
    ''')

    fig.x_range.callback = callback
    show(fig)

df = pd.DataFrame(MSFT)
df["date"] = pd.to_datetime(df["date"])
output_file("candlestick.html")
candlestick_plot(df)
...