Enfernuz/quik-lua-rpc

Пример клиента на python для quik-lua-rpc v2.0-alpha.0 JSON?

Opened this issue · 17 comments

Пример клиента на python?

Пока только на Java. Не знаю, буду ли я в этом году писать для Python... Можете выложить свои наработки, если таковые имеются, -- наверняка народ подхватит.

Механизм аутентификации ZeroMQ:"NULL" (нет аутентификации)

-- coding: utf-8 --

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.

Почему альфа?

  • нет покрытия авто-тестами
  • вручную тоже не всё тестировал
  • не обновлял структуры данных коллбэков (OnFirm и прочие) в соответствии с последним руководством к терминалу (у меня структуры от руководства ~июля 2018) -- каких-то полей, добавленных позднее, может не хватать
  • нет документации
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 Вы имеете в виду прямой доступ к бирже, минуя всякие терминалы? Если так, то такая штука давно существует и её предоставляют почти все брокеры.

Получение маркет-даты через следующие протоколы:

  • Plaza2 (самописный протокол от Московской Биржи);
  • FAST

Отправка транзакций:

  • Plaza2;
  • TWIME (самописный бинарный протокол от Московской Биржи)
  • FIX

Но, уверяю, работа с этими протоколами на порядок сложнее, чем с 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()))