Проблема такая: при первой покупке бумаг происходит задержка между отправкой транзакции на покупку и фактическим зачислением в портфель. Эта задержка составляет примерно 5 секунд. При последующих покупках этой же бумаги такой большой задержки нет. Но стоит переключиться на покупку другой бумаги - все повторяется: при первой покупке снова задержка >5 сек, при последующих покупках задержка стандартная. Как измерял задержку: Старт: os.clock() перед sendTransaction() Окончание: изменение os.clock() после tonumber(getDepoEx(<Firm_ID>, <Client_code>, <ticker_buy>, <Account>, 2).currentbal) > 1
Сергей С., Квику по барабану - это разве что брокер может что-то там запретить. Да и вообще: лично я покупаю бумаги для того, чтобы они приносили прибыль, а не для того, чтобы её через секунду продать. Многие бумаги могут лежать в портфеле днями, неделями, месяцами - уж как-нить успеют их зачислить.
Владимир написал: Сергей С., Квику по барабану - это разве что брокер может что-то там запретить. Да и вообще: лично я покупаю бумаги для того, чтобы они приносили прибыль, а не для того, чтобы её через секунду продать. Многие бумаги могут лежать в портфеле днями, неделями, месяцами - уж как-нить успеют их зачислить.
Спасибо за ваше мнение, но мне непонятно, почему в Quik первая транзакция всегда с задержкой зачисления, а все последующие по этой бумаге - нет. И можно ли с этим что-то сделать? Или это принципиальная "фича" Quik?
Это Вы про реальный торговый счет спрашиваете? На демо счете ARQA это такая особенность. На реальных счетах разных брокеров особой задержки не наблюдал. Впрочем, от брокера зависит, конечно.
Nikolay написал: Это Вы про реальный торговый счет спрашиваете? На демо счете ARQA это такая особенность. На реальных счетах разных брокеров особой задержки не наблюдал. Впрочем, от брокера зависит, конечно.
Да, это реальный торговый счет. Сначала этот вопрос я адресовал брокеру. На что он сказал, что это проблемы на стороне клиента Квик. Брокер ФИНАМ. У других брокеров есть такая особенность первой сделки?
Сергей С., Ну хотя бы потому, что под новый тикер, видимо, заводится какая-то структура, а под уже имеющийся она уже заведена. Может, проверить надо, можно ли Вам вообще этим тикером торговать. В любом случае, это РАЗНЫЕ ситуации. Лично у меня добавлене тикера в портфель или удаление из него довольно редкая операция, но алгоритмы работы заметно отличаются от обычных сделок, когда тикер был и остаётся в портфеле.
Сергей С. написал: Да, это реальный торговый счет. Сначала этот вопрос я адресовал брокеру. На что он сказал, что это проблемы на стороне клиента Квик. Брокер ФИНАМ. У других брокеров есть такая особенность первой сделки?
Клиент Квик не может приводить к задержкам, т.к. он клиент. Его задача просто получать данные с сервера брокера. Правда проверьте, что у Вас просто не установлен период получения данных. Иногда ставят период 10 секунд который задан по умолчанию, что и приведет к таким задержкам.
Проверить же можете просто. Пишите скрипт, фиксирующий в логе, сообщениях (не важно) время отправки транзакции, время прихода колбека о ордере, сделках и, главное, время прихода колбеков OnDepoLimit или OnFuturesClientHolding. Сразу будет видно как сколько времени тратится на полный цикл.
Владимир написал: Сергей С., Ну хотя бы потому, что под новый тикер, видимо, заводится какая-то структура, а под уже имеющийся она уже заведена. Может, проверить надо, можно ли Вам вообще этим тикером торговать. В любом случае, это РАЗНЫЕ ситуации. Лично у меня добавлене тикера в портфель или удаление из него довольно редкая операция, но алгоритмы работы заметно отличаются от обычных сделок, когда тикер был и остаётся в портфеле.
Да, скорее всего задержка связана именно с создание новой структуры в клиенте QUIK. Попробовал этот же самый скрипт у другого брокера - результата такой же - задержка 5 сек при покупке актива в первый раз. Тогда, наверное, это вопрос к разработчикам - можно ли с этим что-то сделать?
А бел Lua скрипта, если руками выставить заявку - изменение в таблице лимитов по бумагам происходит тоже только через 5 секунд? Или эта проблема только в скрипте?
swerg написал: А без Lua скрипта, если руками выставить заявку - изменение в таблице лимитов по бумагам происходит тоже только через 5 секунд? Или эта проблема только в скрипте?
Да, руками тоже задержка при первой покупке бумаги.
Владимир написал: Сергей С., Дались Вам эти несчастные 5 секунд. У меня тикеры держатся в портфеле месяцами и годами, а тут секунды. ЗАЧЕМ с этим что-то делать?
Была идея немного поарбитражить в квике... но, видимо, для этой цели квик не подходит.
Владимир написал: Сергей С. , Дались Вам эти несчастные 5 секунд. У меня тикеры держатся в портфеле месяцами и годами, а тут секунды. ЗАЧЕМ с этим что-то делать?
Была идея немного поарбитражить в квике... но, видимо, для этой цели квик не подходит.
QUIK Подходит для арбитража. На форуме выкладывал пример скрипта для арбитража.
Сергей С. написал: Да, руками тоже задержка при первой покупке бумаги.
Подумал еще вот что уточнить: скрипт ваш в это время работает или нет? при ручном выставлении заявки Если работает - то отключить и проверить выставление руками
А может кто-то пробовал, что быстрее будет работать для получения информации о зачислении бумаг в портфель: getDepoEx().currentbal, или цикл по getNumberOf("depo_limits") с перебором getItem("depo_limits", i).currentbal ?
Сергей С. написал: А может кто-то пробовал, что быстрее будет работать для получения информации о зачислении бумаг в портфель: getDepoEx().currentbal, или цикл по getNumberOf("depo_limits") с перебором getItem("depo_limits", i).currentbal ?
Работать будет одинаково, так как обращение к архиву. Быстрее будет работать колбек. Но разница будет не в секундах, а в ms. ------------- Цикл при этом лишний, так как эти таблицы не увеличиваются в размере. --------------- Если у Вас изменение портфеля всегда так долго, то что-то не так в настройках или в канале связи. Ищите, где не так.
Сергей С. написал: А может кто-то пробовал, что быстрее будет работать для получения информации о зачислении бумаг в портфель: getDepoEx().currentbal, или цикл по getNumberOf("depo_limits") с перебором getItem("depo_limits", i).currentbal ?
Работать будет одинаково, так как обращение к архиву. Быстрее будет работать колбек. Но разница будет не в секундах, а в ms. ------------- Цикл при этом лишний, так как эти таблицы не увеличиваются в размере. --------------- Если у Вас изменение портфеля всегда так долго, то что-то не так в настройках или в канале связи. Ищите, где не так.
Нет, зачисление не всегда так долго. А только самая первая сделка по бумаге. Потом все изменения портфеля по этой бумаге проходят быстро - 100-200 мс. Заявки рыночные. На сервере брокера все происходит быстро, т.к. в Таблице заявок и в Таблице сделок время одинаковое. Но по факту, quik на моей стороне говорит, что бумага зачислена, с опозданием в 5 сек. Только для первого раза. По всей видимости, задержка связана с проверкой getDepoEx(<Firm_ID>, <Client_code>, <ticker>, <Account>, 2) ~= nil. Пять (!!!) секунд создается структура в клиентском quik. Вот можно ли это это как-то ускорить?
Сергей С. написал: А может кто-то пробовал, что быстрее будет работать для получения информации о зачислении бумаг в портфель: getDepoEx().currentbal, или цикл по getNumberOf("depo_limits") с перебором getItem("depo_limits", i).currentbal ?
Работать будет одинаково, так как обращение к архиву. Быстрее будет работать колбек. Но разница будет не в секундах, а в ms. ------------- Цикл при этом лишний, так как эти таблицы не увеличиваются в размере. --------------- Если у Вас изменение портфеля всегда так долго, то что-то не так в настройках или в канале связи. Ищите, где не так.
Нет, зачисление не всегда так долго. А только самая первая сделка по бумаге. Потом все изменения портфеля по этой бумаге проходят быстро - 100-200 мс. Заявки рыночные. На сервере брокера все происходит быстро, т.к. в Таблице заявок и в Таблице сделок время одинаковое. Но по факту, quik на моей стороне говорит, что бумага зачислена, с опозданием в 5 сек. Только для первого раза. По всей видимости, задержка связана с проверкой getDepoEx(<Firm_ID>, <Client_code>, <ticker>, <Account>, 2) ~= nil. Пять (!!!) секунд создается структура в клиентском quik. Вот можно ли это это как-то ускорить?
Как Вы определяете, "quik на моей стороне говорит, что бумага зачислена, с опозданием в 5 сек" В настройках есть параметр установки времени пересчета клиентского портфеля. Уменьшите это время. или поставьте флаг пересчитывать при изменении позиции, если смотрите в портфеле.
nikolz написал: Как Вы определяете, "quik на моей стороне говорит, что бумага зачислена, с опозданием в 5 сек"В настройках есть параметр установки времени пересчета клиентского портфеля. Уменьшите это время. или поставьте флаг пересчитывать при изменении позиции, если смотрите в портфеле.
Определяю по разнице времени между появлением сделки в Таблице сделок и getDepoEx(<Firm_ID>, <Client_code>, <ticker>, <Account>, 2).currentbal) > 0. Эта разница больше 5 сек. В настройках Квика стоят обе галочки - пересчитывать при изменении позиции и пересчитывать раз в 10 сек.
nikolz написал: Как Вы определяете, "quik на моей стороне говорит, что бумага зачислена, с опозданием в 5 сек"В настройках есть параметр установки времени пересчета клиентского портфеля. Уменьшите это время. или поставьте флаг пересчитывать при изменении позиции, если смотрите в портфеле.
Определяю по разнице времени между появлением сделки в Таблице сделок и getDepoEx(<Firm_ID>, <Client_code>, <ticker>, <Account>, 2).currentbal) > 0. Эта разница больше 5 сек. В настройках Квика стоят обе галочки - пересчитывать при изменении позиции и пересчитывать раз в 10 сек.
Что-то у Вас не так, возможно в Вашем скрипте Функция getDepoEx лишь берет данные из архива терминала , откуда Вы и видите в таблице их.
nikolz написал: Что-то у Вас не так, возможно в Вашем скрипте Функция getDepoEx лишь берет данные из архива терминала , откуда Вы и видите в таблице их.
Я бы согласился с тем, что проблемы в моем скрипте, если бы не было разницы между первой и последующими сделками. Ведь скрипт не видит разницу между ними, для него все сделки одинаковы.
nikolz написал: Что-то у Вас не так, возможно в Вашем скрипте Функция getDepoEx лишь берет данные из архива терминала , откуда Вы и видите в таблице их.
Я бы согласился с тем, что проблемы в моем скрипте, если бы не было разницы между первой и последующими сделками. Ведь скрипт не видит разницу между ними, для него все сделки одинаковы.
Вы тоже не видите ошибку, пока ее не найдете. Если хотите помощь, выложите пример с результатом.
_res = sendTransaction(Transaction_buy) if _res ~= "" then message("Ошибка транзакции покупки:".._res) end end
попробуйте для начала заменить это:
Код
while getDepoEx(Firm_ID, Client_code, _ticker_buy, Account, 2) == nil
do
sleep(100)
end
while tonumber(getDepoEx(Firm_ID, Client_code, _ticker_buy, Account, 2).currentbal) < 1
do
sleep(100)
end
на это:
Код
local z; while (z==nil) or (z.currentbal<1) do z=getDepoEx(Firm_ID, Client_code, _ticker_buy, Account, 2) end
Tue Aug 29 11:21:47 2023,getDepoEx currentbal=0.0
Tue Aug 29 11:21:47 2023,выставляем заявку
Tue Aug 29 11:21:48 2023,getDepoEx currentbal=10.0
Tue Aug 29 11:21:48 2023,OnDepolimit currentbal=10.0
1 строка - до выставления заявки 2 строка выставили заявку по рынку и купили 3 строка getDepoEx ответ в колбеке 4 строка - колбек OnDepoLimit -------------------- Резюме: Задержка менее 1 секунды. .
paths = "D:/nkarray/"
package.cpath =paths.."?.dll";
require"nkarray"
require"nkthread"
path = "D:/QUIK_SCRIPT/nk_bot/"
event=nkevent.Create("event");
local acc="NL0011100043"
local firmid="NC0011100000"
local firmid_f="SPBFUT000000"
local Client_code="10590"
local acc_f="SPBFUT000ie"
local sec_code="SBER"
local class_code="QJSIM"
Order_buy = {
["ACTION"]="NEW_ORDER",
["ACCOUNT"] = tostring(acc),
["CLIENT_CODE"] = Client_code,
["TYPE"] = "M",
["TRANS_ID"] = 0,
["CLASSCODE"] = class_code,
["SECCODE"] = sec_code,
["OPERATION"] = "B",
["PRICE"] = "0",
["QUANTITY"] = "1",
["EXPIRY_DATE"]="TODAY",
}
function main()
local f=0;
local trans_id=1;
while true do
nkevent.wait(event); --ждем события
local z=getDepoEx(firmid, Client_code,sec_code,acc,0); --или 2
if z then z=z.currentbal;
Log:write(os.date()..",getDepoEx currentbal="..tostring(z).."\n"); Log:flush();
end
if f==0 then
Log:write(os.date()..",выставляем заявку\n"); Log:flush();
Order_buy.TRANS_ID=tostring(trans_id);
local res = sendTransaction(Order_buy);
if res ~="" then message("Ошибка транзакции:"..res) else trans_id=trans_id+1; end
f=1;
local z=getDepoEx(firmid, Client_code,sec_code,acc,0).currentbal;
Log:write(os.date()..",getDepoEx currentbal="..tostring(z).."\n"); Log:flush();
-- f=0;
end
end
end
function OnDepoLimit(t)
sec=t.sec_code -- STRING Код инструмента
acc=t.trdaccid --STRING Счет депо
firm=t.firmid --STRING Идентификатор фирмы
client=t.client_code-- STRING Код клиента
cur=t.currentbal -- NUMBER Текущий остаток
Log:write(os.date()..",OnDepolimit currentbal="..tostring(cur).."\n"); Log:flush();
nkevent.Set(event);
end
function OnInit(pfile)
path = getScriptPath();
Log=io.open(path.."/forum_test.log","w") --лог файл
fconnect=isConnected();
end
function OnParam(c,s)
nkevent.Set(event);
end
Tue Aug 29 11 : 21 : 47 2023 , getDepo Ex currentbal = 0.0
Tue Aug 29 11 : 21 : 47 2023 ,выставляем заявку
Tue Aug 29 11 : 21 : 48 2023 , getDepo Ex currentbal = 10.0
Tue Aug 29 11 : 21 : 48 2023 ,OnDepolimit currentbal = 10.0
1 строка - до выставления заявки 2 строка выставили заявку по рынку и купили 3 строка getDepoEx ответ в колбеке 4 строка - колбек OnDepoLimit -------------------- Резюме: Задержка менее 1 секунды. .
И вот результат: 1 29.08.2023 13:16:35 OnInit - инициализация функции main 15702.911 2 29.08.2023 13:19:40 (162) Заявка на покупку N 38404828165 зарегистрирована (1 удовлетворено). 3 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.112 ... 8 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.145 9 29.08.2023 13:19:40 OnOrder - новая заявка или изменение параметров существующей заявки 15888.149 10 29.08.2023 13:19:40 OnOrder - новая заявка или изменение параметров существующей заявки 15888.151 11 29.08.2023 13:19:40 OnTrade - новая сделка 15888.152 12 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.155 ... 17 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.185 18 29.08.2023 13:19:45 OnDepoLimit - изменение бумажного лимита 15893.151 ... 23 29.08.2023 13:19:45 OnDepoLimit - изменение бумажного лимита 15893.168 24 29.08.2023 13:20:08 (163) Заявка на продажу N 38404864243 зарегистрирована (1 удовлетворено). 25 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.868 ... 36 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.934 37 29.08.2023 13:20:08 OnOrder - новая заявка или изменение параметров существующей заявки 15915.958 38 29.08.2023 13:20:08 OnOrder - новая заявка или изменение параметров существующей заявки 15915.961 39 29.08.2023 13:20:08 OnTrade - новая сделка 15915.962 40 29.08.2023 13:20:08 OnMoneyLimit - изменение денежного лимита 15915.964 ... 45 29.08.2023 13:20:08 OnMoneyLimit - изменение денежного лимита 15915.994 46 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.995 ... 57 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15916.039
Строки 17 и 18 - это покупка бумаги. Как раз та самая 5-секундная пауза, которую я и наблюдаю. Обратите внимание, строки 45, 46 - это продажа бумаги. Паузы уже нет. Это реальный счет, не демо. Пример для покупки SBER.
Tue Aug 29 11 : 21 : 47 2023 , getDepo Ex currentbal = 0.0
Tue Aug 29 11 : 21 : 47 2023 ,выставляем заявку
Tue Aug 29 11 : 21 : 48 2023 , getDepo Ex currentbal = 10.0
Tue Aug 29 11 : 21 : 48 2023 ,OnDepolimit currentbal = 10.0
1 строка - до выставления заявки 2 строка выставили заявку по рынку и купили 3 строка getDepoEx ответ в колбеке 4 строка - колбек OnDepoLimit -------------------- Резюме: Задержка менее 1 секунды. .
И вот результат: 1 29.08.2023 13:16:35 OnInit - инициализация функции main 15702.911 2 29.08.2023 13:19:40 (162) Заявка на покупку N 38404828165 зарегистрирована (1 удовлетворено). 3 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.112 ... 8 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.145 9 29.08.2023 13:19:40 OnOrder - новая заявка или изменение параметров существующей заявки 15888.149 10 29.08.2023 13:19:40 OnOrder - новая заявка или изменение параметров существующей заявки 15888.151 11 29.08.2023 13:19:40 OnTrade - новая сделка 15888.152 12 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.155 ... 17 29.08.2023 13:19:40 OnMoneyLimit - изменение денежного лимита 15888.185 18 29.08.2023 13:19:45 OnDepoLimit - изменение бумажного лимита 15893.151 ... 23 29.08.2023 13:19:45 OnDepoLimit - изменение бумажного лимита 15893.168 24 29.08.2023 13:20:08 (163) Заявка на продажу N 38404864243 зарегистрирована (1 удовлетворено). 25 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.868 ... 36 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.934 37 29.08.2023 13:20:08 OnOrder - новая заявка или изменение параметров существующей заявки 15915.958 38 29.08.2023 13:20:08 OnOrder - новая заявка или изменение параметров существующей заявки 15915.961 39 29.08.2023 13:20:08 OnTrade - новая сделка 15915.962 40 29.08.2023 13:20:08 OnMoneyLimit - изменение денежного лимита 15915.964 ... 45 29.08.2023 13:20:08 OnMoneyLimit - изменение денежного лимита 15915.994 46 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15915.995 ... 57 29.08.2023 13:20:08 OnDepoLimit - изменение бумажного лимита 15916.039
Строки 17 и 18 - это покупка бумаги. Как раз та самая 5-секундная пауза, которую я и наблюдаю. Обратите внимание, строки 45, 46 - это продажа бумаги. Паузы уже нет. Это реальный счет, не демо. Пример для покупки SBER.
Серегей, Я вам выложил скрипт и результат. У меня никаких запаздываний нет. ------------------------ Как я понял теперь у Вас другая проблема. Раньше вы писали о задержке между таблицей и функцией getDepoEx ------------ Теперь Вы лукавите, это у вас другая задержка ------------------------------- Если хотите, то выложите свой скрипт я его проверю.
nikolz написал: Серегей, Я вам выложил скрипт и результат. У меня никаких запаздываний нет.------------------------Как я понял теперь у Вас другая проблема.Раньше вы писали о задержке между таблицей и функцией getDepoEx ------------Теперь Вы лукавите, это у вас другая задержка -------------------------------Если хотите, то выложите свой скрипт я его проверю.
У меня тоже никаких запаздываний не будет, если в этот торговый день я уже делал операции с этой бумагой. Проблема только в самой первой покупке. Не понимаю, в чем тут лукавство с моей стороны. С помощью getDepoEx я ловил момент зачисления бумаг в портфель. Вы предложили другой способ - по колбеку. Я его проверил - проблема осталась. Мне кажется причина кроется не в скрипте или методе проверки факта зачисления, а в самом клиентском квике, может быть какая-то настройка, галочка и т.п. Запустите тестовый скрипт из ссылки выше и проверьте. Только обращаю еще раз ваше внимание, бумага для теста должна быть выбрана такая, торговли которой в этот день еще не было.
По вашей ссылки какой-то форум и там много чего написано.
Поместите сюда тот скрипт, результаты которого выложили. .
-- Флаг поддержания работы скриптаIsRun = true;
function main() -- Цикл будет выполнятся, пока IsRun == true while IsRun do sleep(1000); end; end;
function OnAccountBalance() message("OnAccountBalance - изменение позиции по счету "..tostring(os.clock())); end; function OnAccountPosition() message("OnAccountPosition - изменение позиции по счету "..tostring(os.clock())); end; function OnAllTrade() --message("OnAllTrade - новая обезличенная сделка "..tostring(os.clock())); end; function OnCleanUp() message("OnCleanUp - смена торговой сессии и при выгрузке файла qlua.dll "..tostring(os.clock())); end; function OnClose() message("OnClose - закрытие терминала QUIK "..tostring(os.clock())); end; function OnConnected() message("OnConnected - установление связи с сервером QUIK "..tostring(os.clock())); end; function OnDepoLimit() message("OnDepoLimit - изменение бумажного лимита "..tostring(os.clock())); end; function OnDepoLimitDelete() message("OnDepoLimitDelete - удаление бумажного лимита "..tostring(os.clock())); end; function OnDisconnected() message("OnDisconnected - отключение от сервера QUIK "..tostring(os.clock())); end; function OnFirm() message("OnFirm - описание новой фирмы "..tostring(os.clock())); end; function OnFuturesClientHolding() message("OnFuturesClientHolding - изменение позиции по срочному рынку "..tostring(os.clock())); end; function OnFuturesLimitChange() message("OnFuturesLimitChange - изменение ограничений по срочному рынку "..tostring(os.clock())); end; function OnFuturesLimitDelete() message("OnFuturesLimitDelete - удаление лимита по срочному рынку "..tostring(os.clock())); end; function OnInit() message("OnInit - инициализация функции main "..tostring(os.clock())); end; function OnMoneyLimit() message("OnMoneyLimit - изменение денежного лимита "..tostring(os.clock())); end; function OnMoneyLimitDelete() message("OnMoneyLimitDelete - удаление денежного лимита "..tostring(os.clock())); end; function OnNegDeal() message("OnNegDeal - новая заявка на внебиржевую сделку "..tostring(os.clock())); end; function OnNegTrade() message("OnNegTrade - новая сделка для исполнения "..tostring(os.clock())); end; function OnOrder() message("OnOrder - новая заявка или изменение параметров существующей заявки "..tostring(os.clock())); end; function OnParam() --message("OnParam - изменение текущих параметров "..tostring(os.clock())); end; function OnQuote() --message("OnQuote - изменение стакана котировок "..tostring(os.clock())); end; function OnStop() message("OnStop - остановка скрипта из диалога управления "..tostring(os.clock())); -- Останавливает цикл в функции main IsRun = false; end; function OnStopOrder() message("OnStopOrder - новая стоп-заявка или изменение параметров существующей стоп-заявки "..tostring(os.clock())); end; function OnTrade() message("OnTrade - новая сделка "..tostring(os.clock())); end; function OnTransReply() message("OnTransReply - ответ на транзакцию "..tostring(os.clock())); end;