Блог им. AlekseyManin

Данные из QUIK в Python. Построение Дельта графика.

Данные из QUIK в Python. Построение Дельта графика.Построение нестандартных графиков в Python при помощи библиотеки finplot.
Можно строить почти любые нестандартные графики: Range, Renco, Delta.
В качестве примера скрипт для построения Дельта графика.
График строиться с момента запуска по поступающим данным из таблицы обезличенных сделок.
Для получения данных из КВИКа используется PythonServer Евгения Шибаева (огромное спасибо автору!!!)

Тапками не кидайтесь, программировать только учусь.

# В КВИКе запускаем луа-скрипт QuikLuaPython.lua
import socket
import threading
from datetime import datetime, timezone
import pandas as pd
import finplot as fplt

fplt.display_timezone = timezone.utc


class DeltaBar():
    def __init__(self):
        self.df = pd.DataFrame(columns='date_time open high low close delta delta_time_sec'.split(' '))
        self.df.loc[len(self.df)] = [0, 0, 0, 0, 0, 0, 0]

    def parser(self, parse):
        if parse[0] == '1' and parse[1] == 'RIH1':
            if abs(self.df.iloc[len(self.df) - 1]['delta']) >= 500:
                self.df.loc[len(self.df)] = [0, 0, 0, 0, 0, 0, 0]  # Добавляем строку в DF

            self.df.iloc[len(self.df) - 1]['close'] = float(parse[4])  # Записываем последнюю цену как цену close бара

            if self.df.iloc[len(self.df) - 1]['date_time'] == 0:
                self.df.iloc[len(self.df) - 1]['date_time'] = \
                    datetime.strptime(f'{parse[7]} {parse[8][0:-1]}', "%d.%m.%Y %H:%M:%S.%f").replace(microsecond=0)

            if self.df.iloc[len(self.df) - 1]['open'] == 0:
                self.df.iloc[len(self.df) - 1]['open'] = float(parse[4])

            if float(parse[4]) > self.df.iloc[len(self.df) - 1]['high']:
                self.df.iloc[len(self.df) - 1]['high'] = float(parse[4])

            if (float(parse[4]) < self.df.iloc[len(self.df) - 1]['low']) or \
                    (self.df.iloc[len(self.df) - 1]['low'] == 0):
                self.df.iloc[len(self.df) - 1]['low'] = float(parse[4])

            if parse[5] == '1026':
                self.df.iloc[len(self.df) - 1]['delta'] += float(parse[6])

            if parse[5] == '1025':
                self.df.iloc[len(self.df) - 1]['delta'] -= float(parse[6])

            self.df.iloc[len(self.df) - 1]['delta_time_sec'] = \
                datetime.strptime(f'{parse[7]} {parse[8][0:-1]}', "%d.%m.%Y %H:%M:%S.%f") - \
                self.df.iloc[len(self.df) - 1]['date_time']
            self.df.iloc[len(self.df) - 1]['delta_time_sec'] = self.df.iloc[len(self.df) - 1]['delta_time_sec'].seconds


def service():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('127.0.0.1', 3587))  # Хост-этот компьютер, порт - 3587
    while True:
        res = sock.recv(2048).decode('utf-8')
        if res == '<qstp>\n':  # строка приходит от клиента при остановке луа-скрипта в КВИКе
            break
        else:
            delta_bar.parser(res.split(' '))  # Здесь вызываете свой парсер. Для примера функция: parser (parse)
    sock.close()


def update():

    df = delta_bar.df
    # Меняем индекс и делаем его типом datetime
    df = df.set_index(pd.to_datetime(df['date_time'], format='%Y-%m-%d %H:%M:%S'))
    # print(delta_bar.df)

    # pick columns for our three data sources: candlesticks and TD
    candlesticks = df['open close high low'.split()]
    volumes = df['open close delta_time_sec'.split()]
    if not plots:
        # first time we create the plots
        global ax
        plots.append(fplt.candlestick_ochl(candlesticks))
        plots.append(fplt.volume_ocv(volumes, ax=ax.overlay()))
    else:
        # every time after we just update the data sources on each plot
        plots[0].update_data(candlesticks)
        plots[1].update_data(volumes)


if __name__ == '__main__':
    delta_bar = DeltaBar()
    # Запускаем сервер в своем потоке
    t = threading.Thread(name='service', target=service)
    t.start()

    plots = []
    ax = fplt.create_plot('RIH1', init_zoom_periods=100, maximize=False)
    update()
    fplt.timer_callback(update, 2.0)  # update (using synchronous rest call) every N seconds

    fplt.show()
  • обсудить на форуме:
  • QUIK
4.8К | ★23
23 комментария
Для получения данных из КВИКа используется PythonServer Евгения Шибаева (огромное спасибо автору!!!)

В КВИКе запускаем луа-скрипт QuikLuaPython.lua


это, пожалуй, самое интересное.

А свечки рисовать, так ли уж они и нужны, эти свечки.

avatar
В Python и Pandas в частности поддерживаются отрицательные индексы. Чтобы взять или положить последний элемент не надо писать 
self.df.iloc[len(self.df) - 1]
Достаточно просто 
self.df.iloc[-1]
avatar
Михаил, спасибо, за информацию.
avatar
а ссылочку на питон сервер продублируйте плиз
avatar
Glago, я не помню правила, можно ли здесь ссылки на сторонние ресурсы вставлять. На яндексе наберите jatotrade и там в разделе «Скачать» есть и Python сервер
avatar
Алексей Манин, спасибо. Собственно это вопрос был не к вам. В последнее время что-то перестали работать переходы с этого сайта на другие ресурсы. Если это только  меня — буду разбираться, а если нет это вопрос к администрации ресурса. 
avatar
Что такое «Дельта график»?
avatar
technic, это когда бар (свеча) закрывается при достижении определенной дельты (в скрипте 500 и -500 для RIH1
avatar
Алексей Манин, т. е. термин Range Bar означает, что некий параметр, в нашем случае маркет-дельта, превысил некое значение, в скрипте это 500?
avatar
Glago, думаю, что вы правильно понимаете.
avatar
Кто что только не называет этим умным словом дельта. А вы что?
the Rolling Stones, так то оно и конечно, но для меня всё просто. Есть индикаторы дельты, которые показывают какое было преобладание рыночных покупок или продаж в: баре, кластере, сессии, контракте… А есть просто график дельты, вот именно его и создает скрипт в режиме реал-тайм.
avatar
А на lua у вас случайно дельты нет, или может сможете написать?
avatar
AlexGood, я ещё только Python изучаю, но мне кажется в lua создать окно с графиком дельты не получиться. Видел реализацию рендж баров, но там lua в связке с Си.
avatar
Алексей Манин, приветствую, а вы не могли бы подсказать где посмотреть как строить range бары в квике из таблицы обезличенных сделок?
avatar
Mars_Man, за появление нового бара отвечает вот эта часть кода:
if abs(self.df.iloc[len(self.df) - 1]['delta']) >= 500:<br />    self.df.loc[len(self.df)] = [0, 0, 0, 0, 0, 0, 0]  # Добавляем строку в DF
Попробуйте заменить её на:
if self.df.iloc[-1]['open'] + 100 <= parse[4] and self.df.iloc[-1]['open'] != 0:<br />    self.df.loc[len(self.df)] = [0, self.df.iloc[-1]['open'] + 100, 0, 0, 0, 0, 0]  # Добавляем строку в DF<br />if self.df.iloc[-1]['open'] - 100 >= parse[4]:<br />    self.df.loc[len(self.df)] = [0, self.df.iloc[-1]['open'] - 100, 0, 0, 0, 0, 0]  # Добавляем строку в DF

По идее должны получиться рендж бары размерностью 100
avatar
Алексей Манин, спасибо, а куда эти части прописывать, чтоб увидеть бары на графике? я просто вообще никогда не работал с lua
avatar
Mars_Man, наверное для вас это будет слишком сложно. Код приведенный мной написан на Python. А это нужно установить сам интерпретатор и дополнительные модули. Видео по серверу, возможно вам поможет понять принцип работы связки LUA -> Python &feature=youtu.be
avatar
Алексей Манин, спасибо за ответы
avatar
О, новая библиотечка. Надо глянуть.
avatar



Дальнейшее тестирование библиотеки finplot выявило появление багов. Что послужило причиной не понял (
avatar

Решил проблему с зависанием. Добавил маркер кластера с максимальным объемом в свече.
Ссылка на код https://pastebin.com/sGffxmHP


Читайте на SMART-LAB:
Фото
BRENT: Дипломатия Трампа против "бычьего десанта" — кто блефует?
После сенсационного заявления Трампа о достижении двухнедельного перемирия с Ираном нефть открыла торги в среду с мощным гэпом вниз. Цена...
Фото
🔴 Эфир начинается через 5 минут
Уже совсем скоро, в 11:00 начнём эфир, посвящённый финансовым результатам Группы МГКЛ по МСФО за 12 месяцев 2025 года. Разберём ключевые...
АПРИ продолжает строительство всесезонного мультикурорта «ФанПарк»
АПРИ продолжает строительство всесезонного мультикурорта «ФанПарк» «ФанПарк» – это мультифункциональный всесезонный курорт на...
Фото
Кто сейчас самый дешевый сбыт? Сводный пост по сбытовым компаниям по отчетам РСБУ за 2025г.
Волгоградэнергосбыт Ставропольэнергосбыт Самараэнерго Мордовэнергосбыт Пермэнергосбыт Новосибирскэнергосбыт...

теги блога Алексей Манин

....все тэги



UPDONW
Новый дизайн