Как отследить в Lua ситуацию, что торговля по определённым (или всем) инструментам запрещена?
В терминале кнопки для выставления транзакций заблокированы, т. е. терминал знает, что торговля по этому инструменту запрещена. Как определить это в Lua?
sendTransaction возвращает ошибку 'Указанная транзакция по указанному классу не найдена: "CETS".' тестирую на транзакции:
Скрытый текст
TYPE = L OPERATION = S ACTION = NEW_ORDER CLASSCODE = CETS TRANS_ID = 739621792 SECCODE = USD000000TOD QUANTITY = 1 CLIENT_CODE = //R4319 PRICE = 69.9150 ACCOUNT = ACCOUNT
Сейчас я работаю с данными при помощи Subscribe_Level_II_Quotes и Unsubscribe_Level_II_Quotes. При этом подписка на данные переносится на следующий день. (т.е. я не отписаваюсь в обработчике OnDisconnected)
В какой момент нужно проверять, что таблица всех инструментов обновилась (добавились новые, удалились старые)? В момент начала выполнения обработчика OnConnected таблица инструментов уже обновлена?
Что делать с подписками по Subscribe_Level_II_Quotes на удаленные инструменты?
Робот у меня может непрерывно работать в нескольких месяцев.
getSecurityInfo возрващает поле min_price_step с типом number. Некоторые инструменты имеют min_price_step 0.05. Число 0.05 не имеет точного представления в типе number (double).
Код
local info = getSecurityInfo("SPBFUT", "MMM6");
message(string.format("%.20f", info.min_price_step), 1); -- см. 3 последние цифры
Отсюда возникают вопросы: 1. Планируется ли менять тип min_price_step с number на string. 2. Регламентировано ли (и где) максимальное число значащих цифр после запятой для min_price_step. 3. Те же вопросы для любой переменной типа number c вещественной частью, возвращаемой через QLua API (пока столкнулся только с min_price_step).
Почему это важно: Например, проверка на кратность цены вида ↓ работать не будет
Есть код, который выполняется в main и в callback'ах Lua. Задача - обеспечить доступ к разделяемому ресурсу. Допустим, доступ к разделяемому ресурсу осуществляется с помощью C++ std::recursive_mutex или критических секций (WinAPI).
Например, пусть один поток добавляет элемент в таблицу, а другой читает её. Сам вопрос в коде.
Код
-- положим, есть внешняя библиотека, которая создаёт userdata для std::recursive_mutex в lua
-- mtx:lock() вызывает std::recursive_mutex::lock() (или EnterCriticalSection, если используются критические секции вместо recursive_mutex)
-- mtx:unlock() вызывает std::recursive_mutex::unlock() (или LeaveCriticalSection, если --//--)
mtx = recursive_mutex.create();
tbl = {};
function OnParam(class_code, sec_code)
local idx = class_code .. "|" .. sec_code;
mtx:lock();
tbl[idx] = (tbl[idx] or 0) + 1;
mtx:unlock();
end
running = true;
function OnStop()
running = false;
end
function main()
while (running) do
sleep(50);
mtx:lock();
local str = {};
-- ВОПРОС: Будет ли в этом месте таблица tbl содержать актуальные значение?
-- Допустим, только что выполнился вызов mtx:unlock() в OnQuote в callback'е и мы попали сюда в потоке main.
-- Отразится ли изменение выполненное в потоке callback'а строкой кода "tbl[idx] = (tbl[idx] or 0) + 1"
-- на таблице tbl в потоке main?
-- Как добиться здесь актуального значения полей таблицы tbl в этом месте?
for k,v in pairs(tbl) do
str[#str+1] = k .. "=" .. v;
end
message(table.concat(str, "\n"));
mtx:unlock();
end
end
Пример общий. Планируется не только добавлять строки в таблицу, но и удалять, и изменять. И не только в одну таблицу. Прошу дать ответ для последней версии Quik и для версии Quik 6.17.3.6.
Каким образом настроить Quik так, чтобы в случае разрыве связи он автоматически переподключался к серверу? Есть ли возможность инициировать подключение из Lua? Версия Quik 6.17.3.6.
Пожалуйста, помогите удостоверится в правильности отслеживания выполнения транзакций в QUIK. Вопросов у меня много по процессу. Хотелось бы получить ответы на все из них.
Ниже код с вопросами:
Код
-- Utility. Not optimized. Just an example.
function bittest(number, shift)
local v = 1;
for i=1,shift do
v = v * 2;
end
return (number - v) ~= number;
end
running = true;
transaction = {}
transaction_stage = "not send";
transaction_details = {};
function set_stage(new_stage)
transaction_stage = new_stage;
message(transaction_stage, 1);
end
function OnStop()
running = false;
end
function main()
transaction = {
ACCOUNT = "L01-00000***", -- (*** - для приватности)
CLIENT_CODE = "51***//COMMENT", -- лимит 20 символов для этого поля, это верно для транзаций по всем инструментам?
ACTION = "NEW_ORDER",
CLASSCODE = "TQBR", SECCODE = "MTSS",
OPERATION = "B",
TYPE = "M", PRICE = "0", QUANTITY = "1",
TRANS_ID = "1000001", -- какие есть ограничения на значения этого поля? (самые жёсткие, для всех классов инструментов сразу)
};
local result = sendTransaction(transaction);
if (result ~= '') then
message("Ошибка отправки транзакции: "..result, 1);
else
transaction_stage = "send";
end
while running do sleep(50); end
end
function OnTransReply(trans_reply)
if (tostring(trans_reply.trans_id) == transaction.TRANS_ID) then
if (trans_reply.brokerref ~= transaction.CLIENT_CODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится транзация?
set_stage("???"); -- прошу уточнить, что должно быть вместо ??? (в каком состоянии транзакция)
return;
end
if (trans_reply.class_code ~= transaction.CLASSCODE or trans_reply.sec_code ~= transaction.SECCODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится транзация?
set_stage("???");
return;
end
if (trans_reply.quantity ~= tonumber(transaction.QUANTITY)) then
-- Возможна ли такая ситуация, и в каком состоянии находится транзация?
-- Может ли транзакция выполниться частично? При каких условиях?
set_stage("???");
return;
end
-- какие коды (ret_code) могут быть в result_msg? где можно посмотреть весь список?
local ret_code = string.match(trans_reply.result_msg, "^%((%d+)%)");
-- в чём измеряется time? как привести время к текущему?
local time = trans_reply.time;
if (trans_reply.status == 3) then
transaction_details.order_num = trans_reply.order_num;
set_stage("Транзакция успешно отправлена на сервер в "..time.." с кодом сообщения "..ret_code);
else
set_stage("Ошибка отправки транзакции на сервер (время "..time..", код "..ret_code..")");
end
end
end
function OnTrade(order)
if (transaction_details.order_num == order.order_num) then
-- пожалуйста, прокомментируйте возможные значащие значения order.flags в этом месте
if (order.account ~= transaction.ACCOUNT) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.brokerref ~= transaction.CLIENT_CODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.class_code ~= transaction.CLASSCODE or order.sec_code ~= transaction.SECCODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.qty ~= tonumber(transaction.QUANTITY)) then
-- Возможна ли такая ситуация, и как будет выглядеть частичное выполнение транзакции на максимально доступный объём?
set_stage("???");
return;
end
transaction_details.price = order.price;
-- где ещё может использоваться trade_num в дальнейшем? при каких условиях? (пока не встречал этот id вне метода OnTrade)
transaction_details.trade_num = order.trade_num;
-- правильный ли тут статус?
set_stage(string.format("Совершается сделка %d на %s лотов %d по цене %s",
order.trade_num, bittest(order.flags, 2) and "продажу" or "покупку", order.qty, order.price))
end
end
function OnOrder(order)
if (transaction_details.order_num == order.order_num) then
-- те же проверки, что и в OnTrade
if (order.account ~= transaction.ACCOUNT) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.brokerref ~= transaction.CLIENT_CODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.class_code ~= transaction.CLASSCODE or order.sec_code ~= transaction.SECCODE) then
-- Возможна ли такая ситуация, и в каком состоянии находится сделка?
set_stage("???");
return;
end
if (order.qty ~= tonumber(transaction.QUANTITY)) then
-- Возможна ли такая ситуация, и как будет выглядеть частичное выполнение транзакции на максимально доступный объём?
set_stage("???");
return;
end
-- какие биты в order.flags в этом месте являются значащими?
-- что значит в этом месте установленный бит 4 в order.flags? (бит 4 (0x10) Разрешить / запретить сделки по разным ценам)
-- правильный ли тут статус?
set_stage(string.format("Заявка %d на %s лотов %d выполнена",
order.order_num, bittest(order.flags, 2) and "продажу" or "покупку", order.qty))
end
end