diff --git a/.idea/QuikPy.iml b/.idea/QuikPy.iml new file mode 100644 index 0000000..b53adb4 --- /dev/null +++ b/.idea/QuikPy.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2fe431f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Examples/05 - Stream.py b/Examples/05 - Stream.py index 38fba04..7475bce 100644 --- a/Examples/05 - Stream.py +++ b/Examples/05 - Stream.py @@ -1,7 +1,15 @@ from datetime import datetime +import os import time # Подписка на события по времени from QuikPy import QuikPy # Работа с QUIK из Python через LUA скрипты QuikSharp +from pydub import AudioSegment +from pydub.playback import play + +sound_audio = None + +play_audio_alert = False + def PrintCallback(data): """Пользовательский обработчик событий: @@ -9,6 +17,8 @@ def PrintCallback(data): - Получение обезличенной сделки - Получение новой свечки """ + if play_audio_alert: + play(sound_audio) # звуковое оповещение о новых данных print(f'{datetime.now().strftime("%d.%m.%Y %H:%M:%S")} - {data["data"]}') # Печатаем полученные данные def ChangedConnection(data): @@ -19,14 +29,21 @@ def ChangedConnection(data): print(f'{datetime.now().strftime("%d.%m.%Y %H:%M:%S")} - {data}') # Печатаем полученные данные if __name__ == '__main__': # Точка входа при запуске этого скрипта - qpProvider = QuikPy() # Вызываем конструктор QuikPy с подключением к локальному компьютеру с QUIK + # qpProvider = QuikPy() # Вызываем конструктор QuikPy с подключением к локальному компьютеру с QUIK # qpProvider = QuikPy(Host='<Ваш IP адрес>') # Вызываем конструктор QuikPy с подключением к удаленному компьютеру с QUIK + host = os.getenv("QUIK_HOST_0") + qpProvider = QuikPy(Host=host) # Вызываем конструктор QuikPy с подключением к удаленному компьютеру с QUIK - # classCode = 'TQBR' # Класс тикера - # secCode = 'GAZP' # Тикер + play_audio_alert = True - classCode = 'SPBFUT' # Класс тикера - secCode = 'SiH2' # Для фьючерсов: <Код тикера><Месяц экспирации: 3-H, 6-M, 9-U, 12-Z><Последняя цифра года> + if play_audio_alert: + sound_audio = AudioSegment.from_file('../Sounds/alert_sound.wav') + + classCode = 'TQBR' # Класс тикера + secCode = 'GAZP' # Тикер + + # classCode = 'SPBFUT' # Класс тикера + # secCode = 'SiH2' # Для фьючерсов: <Код тикера><Месяц экспирации: 3-H, 6-M, 9-U, 12-Z><Последняя цифра года> # Запрос текущего стакана. Чтобы получать, в QUIK открыть Таблицу Котировки, указать тикер # print(f'Текущий стакан {classCode}.{secCode}:', qpProvider.GetQuoteLevel2(classCode, secCode)['data']) @@ -42,32 +59,32 @@ if __name__ == '__main__': # Точка входа при запуске это # print('Статус подписки:', qpProvider.IsSubscribedLevel2Quotes(classCode, secCode)['data']) # qpProvider.OnQuote = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию - # Обезличенные сделки. Чтобы получать, в QUIK открыть Таблицу обезличенных сделок, указать тикер - # qpProvider.OnAllTrade = PrintCallback # Обработчик получения обезличенной сделки - # sleepSec = 1 # Кол-во секунд получения обезличенных сделок - # print('Секунд обезличенных сделок:', sleepSec) - # time.sleep(sleepSec) # Ждем кол-во секунд получения обезличенных сделок - # qpProvider.OnAllTrade = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию + """ Обезличенные сделки. Чтобы получать, в QUIK открыть Таблицу обезличенных сделок, указать тикер """ + qpProvider.OnAllTrade = PrintCallback # Обработчик получения обезличенной сделки + sleepSec = 180 # Кол-во секунд получения обезличенных сделок + print('Секунд обезличенных сделок:', sleepSec) + time.sleep(sleepSec) # Ждем кол-во секунд получения обезличенных сделок + qpProvider.OnAllTrade = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию # Просмотр изменений состояния соединения терминала QUIK с сервером брокера qpProvider.OnConnected = ChangedConnection # Нажимаем кнопку "Установить соединение" в QUIK qpProvider.OnDisconnected = ChangedConnection # Нажимаем кнопку "Разорвать соединение" в QUIK - # Подписка на новые свечки. При первой подписке получим все свечки с начала прошлой сессии - # TODO В QUIK 9.2.13.15 перестала работать повторная подписка на минутные бары. Остальные работают + """ Подписка на новые свечки. При первой подписке получим все свечки с начала прошлой сессии """ + # TODO В QUIK 9.2.13.15 перестала работать повторная подписка на минутные бары. Остальные работают # # Перед повторной подпиской нужно перезапустить скрипт QuikSharp.lua Подписка станет первой, все заработает - qpProvider.OnNewCandle = PrintCallback # Обработчик получения новой свечки - for interval in (60,): # (1, 60, 1440) = Минутки, часовки, дневки - print(f'Подписка на интервал {interval}:', qpProvider.SubscribeToCandles(classCode, secCode, interval)['data']) - print(f'Статус подписки на интервал {interval}:', qpProvider.IsSubscribed(classCode, secCode, interval)['data']) - input('Enter - отмена\n') - for interval in (60,): # (1, 60, 1440) = Минутки, часовки, дневки - print(f'Отмена подписки на интервал {interval}', qpProvider.UnsubscribeFromCandles(classCode, secCode, interval)['data']) - print(f'Статус подписки на интервал {interval}:', qpProvider.IsSubscribed(classCode, secCode, interval)['data']) - qpProvider.OnNewCandle = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию + # qpProvider.OnNewCandle = PrintCallback # Обработчик получения новой свечки + # for interval in (60,): # (1, 60, 1440) = Минутки, часовки, дневки + # print(f'Подписка на интервал {interval}:', qpProvider.SubscribeToCandles(classCode, secCode, interval)['data']) + # print(f'Статус подписки на интервал {interval}:', qpProvider.IsSubscribed(classCode, secCode, interval)['data']) + # input('Enter - отмена\n') + # for interval in (60,): # (1, 60, 1440) = Минутки, часовки, дневки + # print(f'Отмена подписки на интервал {interval}', qpProvider.UnsubscribeFromCandles(classCode, secCode, interval)['data']) + # print(f'Статус подписки на интервал {interval}:', qpProvider.IsSubscribed(classCode, secCode, interval)['data']) + # qpProvider.OnNewCandle = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию - qpProvider.OnConnected = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию - qpProvider.OnDisconnected = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию + # qpProvider.OnConnected = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию + # qpProvider.OnDisconnected = qpProvider.DefaultHandler # Возвращаем обработчик по умолчанию # Выход qpProvider.CloseConnectionAndThread() # Перед выходом закрываем соединение и поток QuikPy из любого экземпляра diff --git a/Sounds/alert_sound.wav b/Sounds/alert_sound.wav new file mode 100644 index 0000000..0384695 Binary files /dev/null and b/Sounds/alert_sound.wav differ diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..b0674dc --- /dev/null +++ b/poetry.lock @@ -0,0 +1,18 @@ +# This file is automatically @generated by Poetry and should not be changed by hand. + +[[package]] +name = "pydub" +version = "0.25.1" +description = "Manipulate audio with an simple and easy high level interface" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"}, + {file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "2f03b13bb7a06894989a6922ca38de51da6367ba86937fefd0da29970805d73d" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..244b5af --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "quikpy" +version = "0.1.0" +description = "" +authors = ["Your Name "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.10" +pydub = "^0.25.1" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"