cia76 / quikpy Goto Github PK
View Code? Open in Web Editor NEWБиблиотека-обертка, которая позволяет получить доступ к функционалу Quik из Python
Home Page: https://finlab.vip/quikpy
Библиотека-обертка, которая позволяет получить доступ к функционалу Quik из Python
Home Page: https://finlab.vip/quikpy
При выполнении метода "SendTransaction" в ответе Питону выдается json, где обращаясь к ключу "data", в ответ отдается булонская переменная, не подскажете, как можно получать ответ сервера (json с различными полями/текстом ошибки от сервера) на вызов этого метода?
Приветствую!
Обнаружил, что в питоновской локали utf-8 проблемы с выводом в QUIK сообщений на русском.
Да и не только наверное локаль виновата. Lua в принципе будет дробить уникод-символы на два символа.
Внес небольшое исправление для формирования правильного для QUIK json-а
def ProcessRequest(self, Request):
# ориг.версия
#rawData = dumps(Request) # Переводим запрос в формат JSON
#self.socketRequests.sendall(f'{rawData}\r\n'.encode()) # Отправляем запрос в QUIK`
# новый вариант делать json-совместимый запрос к неумеющим-правильно-unicode-lua
bstring = (f"{Request}\r\n").replace("'", '"').encode("cp1251")
self.socketRequests.sendall(bstring) # Отправляем запрос в QUIK
fragments = [] # Гораздо быстрее получать ответ в виде списка фрагментов
Теперь текст сообщений в QUIK на русском.
Например:
str_rus = "Ёжик в тумане окейно. Eng OK too."
print(f'Отправка сообщения в QUIK: {str_rus} {qpProvider.MessageInfo(str_rus)["data"]}') # Проверка работы QUIK.
Транзакции с автопереносом (которые надо делать на русском) тоже выставляются:
Например:
transaction = {
'TRANS_ID': "20",
'CLASSCODE': 'FUTSPREAD',
'ACTION': 'Ввод заявки на спрэд фьючерсов',
'Инструмент': 'EuM3EuU3',
'Торговый счет': TradeAccountId,
'Тип': 'Лимитированная',
'К/П': 'Покупка',
'Своп-Цена': str(price),
'Количество': str(quantity),
'Условие исполнения': "Поставить в очередь",
'Комментарий': '',
'Переносить заявку': 'Да',
'Дата экспирации': '20230531',
}
print(f'Новая лимитная заявка отправлена на рынок: {qpProvider.SendTransaction(transaction)["data"]}')
Игорь, добрый вечер!
Большое спасибо за вашу работу!
При попытке запустить скрипт 01-Connect.py выдаёт такую ошибку: ConnectionRefusedError: [WinError 10061] Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение - если запускаю через Jupyter
Если запускаю через консоль, выдаёт ошибку 10060 . Запускаю всё на локальном компьютере, отрубил брандмаузер. Возможно, имеет смысл какие-то другие порты указывать? Если да, то где их прописывать?
Прошу прощения, если это глупый вопрос.
С уважением, Александр
Здравствуйте! Просмотрел Ваш пример по получению информации по счетам, но не смог использовать его для получения Суммарной оценки стоимости позиций по ликвидационной цене
. Это итоговый параметр таблицы Состояние счета
(Отображение позиций клиента по инструментам). Данный параметр отображает реальную сумму средств, которыми распологает клиент в валюте и инструментах без учета займов.
Отображается внизу таблицы (Ликв. ст-ть: 461 765.10
)
Возможно ли эту цифру получить при помощи вашей библиотеки?
Hi!
I want to call GetAllDepoLimits method inside init(self) of strategy class:
_def __init__(self):
qp_provider = QuikPy() # Подключение к локальному запущенному терминалу QUIK
depo_Limits = qp_provider.GetAllDepoLimits()['data'] # Все лимиты по бумагам (позиции по инструментам)
qp_provider.CloseConnectionAndThread()
. . .
bla-bla-bla_
and got error inside GetAllDepoLimits:
_Process finished with exit code -1073741819 (0xC0000005)_
There are no issues if I call GetAllDepoLimits method from main body :
if __name__ == '__main__':
qp_provider = QuikPy() # Подключение к локальному запущенному терминалу QUIK
depo_Limits = qp_provider.GetAllDepoLimits()['data'] # Все лимиты по бумагам (позиции по инструментам)
qp_provider.CloseConnectionAndThread()_
Читал Ваш пост в телеграмме про намерение написать библиотеку по улучшению backtrader. Не нашел иного источника связи с Вами, поэтому напишу сюда свои мысли по этой теме. Сам занят чем-то похожим.
Можно еще глянуть на что-то типа того https://github.com/modin-project/modin
Я довольно долго обдумывал способы как построить свой торговый движок вокруг numpy-pandas и пришел к тому, что ни то не другое не предназначены для этого. Но и то и другое вполне приемлемо, если использовать их в отдельных сценариях, нежели чем в монолитной системе, что я у себя и делаю.
Для универсального же движка типа backtrader стоит присмотреться к cython. Возможно, c помощью cython даже есть смысл сам backtrader переделать. Хотя лично мне его архитектура не дает той свободы, которой хотелось бы, и там слишком много "метамагии" в коде движка. Но тем не менее, backtrader это самый продуманный из всех имеющихся движков на python, который "оброс" неплохими плагинами. Cython мог бы его очень хорошо ускорить, но объем работы мне сложно оценить.
Здравствуйте,
возможно ли получить цену последней сделки (для расчета текущих результатов по позициям) без того, чтобы подписываться на свечки или стакан, подобно тому, как это делается в LUA?
LUA:
x = getParamEx(CLASSCODE, SECCODE, "last").param_value
Здравствуйте! Благодарю за большой вклад в создание и развитие коннектора, а так же за шикарные примеры! Вопрос по Stream.py - можете показать пример, каким образом полученные значения по подписке можно сохранять в переменной, вместо того чтобы печатать в консоле? Правильно будет просто поместить глобальную переменную в PrintCallback, которая будет собирать данные?
Здравствуйте,
Большое Вам спасибо за этот проект. При использовании данной связки стало намного проще реализовывать торговые стратегии, нежели это было на чистом Lua.
Однако, столкнулся со следующей проблемой. Использую такую функцию (выделена в отдельный файл functions.py
):
def getCandles(classCode, secCode, timeFrameName, timeFrameVal, period):
from QuikPy import QuikPy
if timeFrameName == 'H':
timeFrame = 60*timeFrameVal
elif timeFrameName == 'D':
timeFrame = 1440
elif timeFrameName == 'W':
timeFrame = 10080
elif timeFrameName == 'MN':
timeFrame = 23200
else:
timeFrame = timeFrameVal
qpProvider = QuikPy()
newBars = qpProvider.GetCandlesFromDataSource(classCode, secCode, timeFrame, period)["data"].copy()
pdBars = pd.DataFrame.from_dict(pd.json_normalize(newBars), orient='columns')
pdBars.rename(columns={'datetime.year': 'year', 'datetime.month': 'month', 'datetime.day': 'day',
'datetime.hour': 'hour', 'datetime.min': 'minute', 'datetime.sec': 'second'},
inplace=True)
pdBars.index = pd.to_datetime(pdBars[['year', 'month', 'day', 'hour', 'minute', 'second']])
pdBars = pdBars[['open', 'high', 'low', 'close', 'volume']]
pdBars.index.name = 'datetime'
pdBars.volume = pd.to_numeric(pdBars.volume, downcast='integer')
#qpProvider.CloseConnectionAndThread()
return pdBars
Далее, в другом скрипте делаю from functions import *
. Соединение из этого скрипта проходит нормально и данные поступают. Однако, если в это время попытаться подключиться к Quik серверу из другого скрипта, то второй скрипт ждёт завершения первого.
Придумал закрывать соединение каждый раз, после обращения скриптов к этой функции (для этого добавляю .copy()
в получение переменной newBars
и раскомментирую последнюю строчку перед return
), но тогда при обращении выдается ошибка:
OSError: [WinError 10038] An operation was attempted on something that is not a socket
Возможно ли создание более одного соединения одновременно?
Есть ли способ получать значения open interest в quikpy?
Здравствуйте!
Запускаю свой скрипт подключения к QUIK из Jupyter Notebook. Скрипт работает и получает данные из QUIK должным образом. Однако, если в процессе работы разорвать подключение QUIK с сервером и затем установить связь снова, то QUIK зависает до тех пор пока вручную не отключить скрипт. Это особенно актуально когда ночью брокер перегружает сервера, соединение рвется и, соответственно, с утра после автоматического реконнекта настроенного в Quik он виснет, пока свой скрипт не перезапустишь.
Вот мой скрипт:
qp = QuikPy()
qp.OnNewCandle = handler
print(f'Подключено к терминалу QUIK по адресу: {qp.Host}:{qp.RequestsPort},{qp.CallbacksPort}')
print(f'Подписка на интервал 1:', qp.SubscribeToCandles('TQBR', 'SBER', 1)['data'])
while True:
pass
Здравствуйте. Спасибо за данную библиотеку. Хотел бы узнать больше о теме потоках при работе с Quik. Можно ли использовать здесь библиотеку threading? Будет ли у нас работать многопоточность? Ведь как я понимаю в Quik есть только один поток.
Сейчас пишу сеточного робота с использование Tkinter и выделил основную работу робота в отдельный поток для того, чтобы обновлять информацию в интерфейсе не закрывая к нему доступ. Думал выделить еще один поток для обработок заявок. Хорошая ли это практика или это может привезти к различным проблемам?
Могу ли я самостоятельно получить из lua в QuikPy такие функции как getBuySellInfo и getBuySellInfoEx, которые позволяют смотреть доступна ли акция для продажи, а так же ставка риска для лонга и шорта?
Добрый вечер!
в "02 - Accounts.py" [Examples]
функция qpProvider.GetFuturesHoldings() выдает ошибку:
{'lua_error': "Lua error: D:\QUIK\SBERBANK\lua\qsfunctions.lua:642: attempt to perform arithmetic on a nil value (local 'posType')", 'data': '', 'id': 0, 'cmd': 'lua_error', 't': ''}
Подскажите пожалуйста, где можно посмотреть. В Quik:
OnFuturesClientHolding() отрабатывает нормально, все показывает
в Исходнике подчеркнутое исправил на "getFuturesClientHoldings" - заработало. Ошибка ?
в теле не хватает буквы "s" при вызове метода
return self.ProcessRequest({'data': '', 'id': TransId, 'cmd': 'getClientCodeS', 't': ''})
Достаточно ли будет просто подсоединить Lua.dll версии 5.4.1? Или там необходимо сделать более масштабные изменения?
В 5.4 лучше реализована сборка мусора https://www.lua.org/manual/5.4/manual.html#2.5.2 Например, в 5.3.5 этот код потребляет неограниченное количество памяти:
function main()
while true do
sleep(100)
end
end
function OnQuote(class, sec)
local ql2 = getQuoteLevel2(class, sec)
end
Здравствуйте!
Спасибо за прекрасную библиотеку!!!
У меня не все запросы обрабатываются по опционам
ba = qpProvider.GetParamEx(classCode, secCode, 'OPTIONBASE')['data']['param_value'] # Базовый актив option_type = qpProvider.GetParamEx(classCode, secCode, 'OPTIONTYPE')['data']['param_value'] long_name = qpProvider.GetParamEx(classCode, secCode, 'LONGNAME')['data']['param_value'] # Длинное имя print(f'{ba=}, {option_type=}, {long_name=}') # Не работает, выводит '0.000000'
Полный код https://pastebin.com/bXa9aVqh
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.