Open euvgub opened 5 years ago
Пока только на Java. Не знаю, буду ли я в этом году писать для Python... Можете выложить свои наработки, если таковые имеются, -- наверняка народ подхватит.
Механизм аутентификации ZeroMQ:"NULL" (нет аутентификации)
import zmq context = zmq.Context() print("Connecting to test server") socket = context.socket(zmq.REQ) socket.connect("tcp://localhost:5560") print("Sending request") socket.send_string('GET_SCRIPT_PATH') message = socket.recv() print("Received reply [ %s ]" % (message))
Connecting to test server Sending request Received reply [ b"\x10\x01\x1a\xe6\x01\xd0\xa0\xd1\x9b\xd0\xa1\xe2\x82\xac\xd0\xa0\xd1\x91\xd0\xa0\xc2\xb1\xd0\xa0\xd1\x94\xd0\xa0\xc2\xb0 \xd0\xa0\xd1\x97\xd0\xa1\xd0\x82\xd0\xa0\xd1\x91 \xd0\xa0\xd1\x95\xd0\xa0\xc2\xb1\xd0\xa1\xd0\x82\xd0\xa0\xc2\xb0\xd0\xa0\xc2\xb1\xd0\xa0\xd1\x95\xd0\xa1\xe2\x80\x9a\xd0\xa0\xd1\x94\xd0\xa0\xc2\xb5 \xd0\xa0\xd0\x86\xd0\xa1\xe2\x80\xa6\xd0\xa0\xd1\x95\xd0\xa0\xd2\x91\xd0\xa1\xd0\x8f\xd0\xa1\xe2\x80\xb0\xd0\xa0\xc2\xb5\xd0\xa0\xd1\x96\xd0\xa0\xd1\x95 \xd0\xa0\xc2\xb7\xd0\xa0\xc2\xb0\xd0\xa0\xd1\x97\xd0\xa1\xd0\x82\xd0\xa0\xd1\x95\xd0\xa1\xd0\x83\xd0\xa0\xc2\xb0: 'C:\Test_QUIK\lua\protobuf\decoder.lua:311: Tag had invalid wire type.'." ]
Эмм, нет, это не так работает. В той версии, что лежит сейчас в ветке master, сообщения от/к серверу сериализуются/десериализуются с помощью Protobuf (гайд для Python). Сами схемы сообщений (файлы .proto) можно найти в директории qlua/rpc RPC-сервиса. То есть, фактически, сервис с Вами общается посредством бинарных сообщений, которые закодированы Protobuf'ом.
Есть наработки для общения посредством JSON, но там ещё не доделано. Думаю, в течение следующей недели дозалью коммиты к альфа-версии.
Если нужна помощью по Protobuf -- пишите.
В ветке master теперь лежит альфа-версия с поддержкой JSON.
Почему альфа?
import zmq
context = zmq.Context()
print("Connecting to test server")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5560")
print("\nSending request")
socket.send_string("{\"method\":\"message\", \"args\":{\"message\":\"Hello!\",\"icon_type\":\"WARNING\"}}")
message = socket.recv()
print("Received reply [ %s ]\n" % (message))
print("Sending request")
socket.send_string("{\"method\":\"getScriptPath\"}")
message = socket.recv()
print("Received reply [ %s ]\n" % (message))
print("Sending request")
socket.send_string("{\"method\":\"getClassesList\"}")
message = socket.recv()
print("Received reply [ %s ]" % (message))
Connecting to test server
Sending request Received reply [ b'{"result":{"result":1}}' ]
Sending request Received reply [ b'{"result":{"script_path":"D:\\programs\\Quik_KF\\lua\\quik-lua-rpc"}}' ]
Sending request Received reply [ b'{"result":{"classes_list":"CROSSRATE,PSAU,AUCT,INDX,TQTC,EQOB,EQEO,EQDB,EQRP_INFO,TQBR,TQDE,TQOB,EQTC,TQIF,TQTF,SPEQ,TQTD,TQOD,EQTD,CETS,INDXC,CETS_MTL,REPORT,REPORTFORTS,SPBXM,RTSIDX,SPBFUT,SPBOPT,USDRUB,OPTW,"}}' ]
Документацию по API пока не написал, но вскоре займусь ей. В общих чертах, формат сообщений такой:
Запрос:
{
"method":"НАЗВАНИЕ_QLUA-ФУНКЦИИ",
"args": {
// АРГУМЕНТЫ QLUA-ФУНКЦИИ
}
}
Ответ:
{
"method": "НАЗВАНИЕ_QLUA-ФУНКЦИИ",
"result": // РЕЗУЛЬТАТ QLUA-ФУНКЦИИ (число, объект, строка -- в зависимости от вызываемой функции)
}
Ответ в случае ошибки сервиса:
{
"method":"НАЗВАНИЕ_QLUA-ФУНКЦИИ",
"error": {
"code": // ЧИСЛОВОЙ КОД ОШИБКИ,
"message": "ИНФОРМАЦИЯ ОБ ОШИБКЕ"
}
}
!!! Все дробные числа передаются как строки (что в аргументах, что в ответе от сервиса).
Чудесно! В отдельный бы репозиторий quik-lua-rpc-python-client - Пример Python-клиента к сервису 'quik-lua-rpc'.
Ну, по сути, кроме этих сниппетов кода на Python как такового и нет... Клиент, в моём понимании, -- это всё же некая библиотека, позволяющая скрыть от пользователя низкоуровневую работу с сообщениями и ZeroMQ. Если вдруг раньше меня напишете такую на Python -- дайте знать.
Может кто в курсе. А нет просто нормального РФ брокера с апи? Чтобы не мучаться с этим адом квиком
Какие-то брокеры предоставляют доступ на MOEX через MetaTrader. QUIK, имхо, -- он больше для профессиональных трейдеров в фирмах (в том числе брокерских), поэтому может показаться, что в нём много всякой "ненужной фигни".
Квик для компа бесспорно норм. Но вот именно прямого апи у брокера жалко нету. Те недобиржи по крипте это все сделали давно...( Но они меня не интересуют.
Ладно хоть Квик под wine пашет. Хоть что-то немного радует.)
Вот уже есть пример Python-клиента к сервису quik-lua-rpc https://github.com/yofi2tofi/mmvddss
sholoma, под прямым API Вы имеете в виду прямой доступ к бирже, минуя всякие терминалы? Если так, то такая штука давно существует и её предоставляют почти все брокеры.
Получение маркет-даты через следующие протоколы:
Отправка транзакций:
Но, уверяю, работа с этими протоколами на порядок сложнее, чем с QUIK (особенно по части обработки транзакций -- говорю из собственного опыта), даже при использовании каких-то готовых библиотек. Проще всех из них, наверное, Plaza2. И по латенси не сказать что бы андердог.
Вот уже есть пример Python-клиента к сервису quik-lua-rpc https://github.com/yofi2tofi/mmvddss
Да, в качестве клиента к первой версии, где только protobuf, очень даже сойдёт. Добавлю ссылку в доку. Да и для второй версии сгодится, если в нём перегенерировать .py-обвязки над .proto-файлами (я поменял везде название message Request на message Args -- так лучше вписывается в модель).
Может кто в курсе. А нет просто нормального РФ брокера с апи? Чтобы не мучаться с этим адом квиком
Это прямо готовая идея подпольного стартапа moex data sharing по аналогии со спутниковым шарингом
Актуальное руководство по Qlua QUIK Lua. Версия 7.24 от 21.01.2019 Интерпретатор языка Lua. Руководство пользователя. Версия 7.24 https://euvgub.github.io/
В ветке master теперь лежит альфа-версия с поддержкой JSON.
- не обновлял структуры данных коллбэков (OnFirm и прочие) в соответствии с последним руководством к терминалу (у меня структуры от руководства ~июля 2018) -- каких-то полей, добавленных позднее, может не хватать
Python клиент для второй версии quik-lua-rpc v2.0-alpha.0 JSON
import zmq
context = zmq.Context()
socket = self.context.socket(zmq.REQ)
socket.connect('tcp://127.0.0.1:5560')
socket.send_string('{"method":"datasource.CreateDataSource","args":{"class_code":"SPBFUT", "sec_code":"SiU9", "interval":"INTERVAL_M1", "param":""}}')
datasource_uuid = json.loads(socket.recv_string())['result']['datasource_uuid']
socket.send_string('{"method":"datasource.Size","args":{"datasource_uuid":"%s"}}' % (datasource_uuid))
num_candles = json.loads(socket.recv_string())['result']['value']
for i in range(0,num_candles):
socket.send_string('{"method":"datasource.C","args":{"datasource_uuid":"%s","candle_index":%d}}' % (datasource_uuid, i))
candle_close = json.loads(socket.recv_string())['result']['value']
socket.send_string('{"method":"datasource.O","args":{"datasource_uuid":"%s","candle_index":%d}}' % (datasource_uuid, i))
candle_open = json.loads(socket.recv_string())['result']['value']
socket.send_string('{"method":"datasource.T","args":{"datasource_uuid":"%s","candle_index":%d}}' % (datasource_uuid, i))
candle_time = json.loads(socket.recv_string())['result']['value']
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://127.0.0.1:5561")
socket.setsockopt(zmq.SUBSCRIBE, b"OnAllTrade")
while True:
print(json.loads(socket.recv_unicode()))
Пример клиента на python?