Дело бы вечером, делать было нечего. --------------- Предположим, что у Вас есть большая таблица в терминале QUIK. ------------------------ Например, у меня получилась такая таблица "orders" В ней 227 тысяч строк. ------------------------- И Вы хотите пробежать по строкам и найти строку с нужными вам параметрами для этого Вы пишите такой цикл: -----------------------
Код
local N= getNumberOf("orders");
local j=1; while N>=j do
local z=getItem("orders",jz-1)
jz=jz+1;
end
для контроля добавим два оператора первый для замера расхода памяти и второй для вывода результата в лог файл получится так
Код
local N= getNumberOf("orders");
local j=1; while N>=j do
local mem=math.floor(collectgarbage ("count"))
local z=getItem("orders",jz-1)
Log:write(tostring(jz)..","..tostring(mem).."\n");
jz=jz+1;
end
А теперь вопрос знатокам, в ответ не подглядывать. Сколько памяти займет данный цикл пробега по строкам таблицы заявок, в которой 227 строк. ----------------------------- Уверен, что Вы даже не представляете себе это . ================== Ответ на поставленный вопрос в лог файле посмотрели 1-ю строку, заняли память 121 КБ
Код
1,121
посмотрели 100-ю строку, заняли память 654 КБ
Код
100,654
посмотрели 1000-ю строку, заняли память 5395 КБ т е округленно 5 МБ
Код
1000,5395
ну и когда посмотрели последнюю 227851 строку, заняли память 1205 952 КБ т е округленно 1.2 ГБ
Код
227851,1205952
Вот так Lua в QUIK кушает память. И в этом случае мы просто нашли нужную нам заявку в таблице заявок. ------------------------------------------------------- Угадайте, как с этим бороться?
qtyB,comission=CalcBuySell(clas,sec,client,acc,price,true,false); --расчитать доступное количество к покупке
qtyS,comission=CalcBuySell(clas,sec,client,acc,price,false,false); --расчитать доступное количество к продаже
local tp=getBuySellInfo (firm,client,clas,sec,price);
Qcur=tp.balance --STRING Текущая позиция по инструменту, в лотах
NQb=tp.can_buy --STRING Оценка количества лотов, доступных на покупку по указанной цене *
NQs=tp.can_sell-- STRING Оценка количества лотов, доступных на продажу по указанной цене *
Dp=tp.share --STRING Процентное отношение стоимости позиции по данному инструменту к стоимости всех активов клиента, рассчитанное по текущим ценам
QmaxBuy=tp.can_buy_own --STRING Максимально возможное количество инструментов в заявке на покупку этого инструмента на этом классе на собственные средства клиента, исходя из цены лучшего предложения
QmaxSel=tp.can_sell_own --STRING Максимально возможное количество инструментов в заявке на продажу этого инструмента на этом классе из собственных активов клиента, исходя из цены лучшего спроса
Добрый день, ---------------------- Написал скрипт краш-теста. В целом результатами доволен. Рассказываю подробности. ----------------------------, Условия теста: демо-сервер версия терминала 9.7 ( тормозная) -------------------- Робот на каждую принятую сделку по колбеку OnParam рассчитывает цену на 20 шагов ниже цены последней сделки определяет максимальное число контрактов для текущего инструмента функцией CalcBuySell и выставляет заявку на покупку одного контракта по расчетной цене. При очередном вызове колбека , робот снимает все выставленные ранее заявки , проверяет отсутствие неисполненной транзакции и открытой заявки по текущему инструменту и при положительном решении, выставляет новую заявку. -------------------- Результаты теста(фрагмент):
Время работы теста составило примерно 12000 секунд( примерно 1.5 часа) За это время колбеки вызывались 2 млн 670 тысяч раз, выставлено и снято заявок 278 тысяч инструментов 908 (акции валюта фьючерсы) среднее время на одну заявку составляет примерно 2.5 ms, максимальное 8 ms, минимальное 0.25 ms. из 2.5 ms одного цикла выставления заявки, 2.2 ms уходит на функцию CalcBuySell. уж не знаю, что туда напичкали, если на все остальное у робота уходит в 10 раз меньше,чем на эту функцию. На обработку колбеков заявок и транзакций уходит 0.05 до 0.1 ms. ------------------------------------------- Размер скрипта 600 строк LUA+ DLL для обработки событий и расчета времени с квантом 0.1 мкс.
Добрый день, Посвятил целую неделю, чтобы выполнить работу разработчиков и найти критическую ошибку версий 9 10, по которой терминал может минутами не отвечать. -------------------------- Если У Вас нет желание это наблюдать, то рекомендую не ставить эти версии, а также другие выше 8 , пока разработчики официально не укажут на исправление этой ошибки. -------------------------- В настоящее время последней нормальной версией является 8.7.1.3, которую и рекомендую.
Добрый день, Просьба пояснить при каких условиях выдаются следующие сообщения: В документации не нашел, если есть, дайте ссылку. 1. Превышена позиция по инструменту 2. Превышен лимит отправки транзакций для данного логина.
Добрый день, второй день на демо счете все чудеснее и чудеснее. В настоящее время при загрузке демо квика версии 10.01 терминал QUIK-JUNIOR подключается к демо счету после этого не отвечает по несколько минут на каждое нажатие мышки на экране. А в диспетчере задач видим следующее. 2-я строка это демо сервер версия 10 загрузка процессора около 30% 1-я строка рабочий терминал версия 8.7 загрузка процессора около 3%
для сравнения загрузил версию 9.7 и наблюдаем чудеса:
----------- На рабоем терминале работают индикаторы и скрипты На демо терминалах ничего своего не ставил. Просто скачал развернул и подключил. И ловлю кайф. Такого прикола еще не видел.
Полагаю, что отсутствие класса фьючерсов на демо связано с тем, что Вы забыли установить входящий остаток по средствам на демо счете фьючерсов. --------------------- Потому и класс нет. ====================== Может в консерватории надо что-то исправить.
Добрый день, тестирую функции на демо сервере. Сделал лишь старт квика. т е ничего не покупал и не продавал. ----------------- поясняю: колбек OnParam принимает сделки:function OnParam(c,s)
Код
for i=1,#tparam do local t=tparam[i]; if t=="table" then if t[1]==14 and t[3]==s then return end end end
local t={14,c,s}; if #tparam==0 then tparam[1]=t; ESet(event); else table.sinsert(tparam,t); end
end
и загружает clas и sec в таблицу tparam
фунция main в цикле принимает значения из tparam и вызывает функцию getDemo
Код
Log:write("clas="..clas..",sec="..sec..",firm="..firm..",account="..account..",client="..client.."\n");Log:flush();
local t1=getDepo(client,firm,sec,account);
Log:write("type="..type(t1).."\n");Log:flush();
1 строка выводит в лог файл все параметры функции getDemo, которая вызывается во 2-ой строке 3 строка - выводим в лог файл тип возвращенного значения t1 ------------------ В результате получаем следующий кирдык: --------------------- Таблица позиций по инструментам имеет вид: т е в таблице есть лишь SBER c нулевыми значениями ================ А теперь смотрим лог файл
Сегодня в Сбербанке повторилось. Дата торгов была вчера. И естественно вчерашний день пропал. -------------- Проблема решилась лишь после разрыва связи , длительного ожидания и установки связи заново. ---------------- Так как такую и подобные проблемы наблюдал неоднократно, то хочу высказать свое предположение о ее источнике. =================== проблема возникает, если установить соединение до начала торгов, либо в момент начала. Предположу, что при этом происходит не полная загрузка с сервера начальных данных, но после начала торгов сервер не проверяет некорректность данных у клиентов а продолжает работу с неполными либо с неверными данными. ============ Полагаю, это недоработка разработчиков QUIK. Но это лишь мои предположения. =============== Проблема решается иногда лишь перезагрузкой но после начала торгов и длительного ожидания.
Добрый день, решил написать робота, который работает со всеми доступными в терминале кодами клиентов и вдруг откуда не возьмись появился ... затык. ----------------------- Вопрос: ---------------- Каким образом ,т е на основе каких таблиц или функций, можно установить соответствие кода клиента (таблица client_codes) торговому счету (таблица trade_accounts) ------------------- Спасибо
Добрый день, Периодически на форуме появляются душераздирающие вопли о том, что мол у брокера .... QUIK съедает .. ГБ. Попытка объяснить , что и как надо сделать наталкивается либо на вопли "мы все это знаем", либо на рассуждения о том, что это не у любого брокера, а лишь у избранного. ---------------------- Полагаю, что проблема не в зеркале, то есть не в брокере, а как обычно, в отсутствии знаний у пользователя. ----------------- Доказательство: ------------------- брокер СБЕРБАНК. Чтобы доказать, что брокер не виноват, специально настроил QUIK так, чтобы получить наибольшую загрузку памяти для этого брокера. --------------------------- Желающие могут получить и большую загрузку. Я к этому не стремился, но знаю как это сделать. ----------------- итак вот картинка результата сегодня:
а это результат обычной настройки ----------------------------------------------- Успехов в борьбе за знания, т.е. за память.
Добрый день, Пример запуска скрипта по расписанию. Если есть вопросы - пишите
Код
local isRun=0; --флаг завершения функции main
local fstop=true; -- флаг остановки скрипта при запуске по расписанию
local Ts={"12:53:00","12:54:00","12:55:00","12:56:00","12:57:00","12:58:00","12:59:00",}
for i=1,#Ts do local x=Ts[i] Ts[i]=60*(60*string.sub(x,1,2)+string.sub(x,4,5))+string.sub(x,7,8); end
------------
function main()
local jT,x=0,0;
while isRun do
if #Ts>jT then local dt=-1;
if fstop then fstop=false; -- в колбеках первой строкой поставить if fstop then return end
x= getInfoParam("SERVERTIME"); -- local x=os.date("%X");
local z=60*(60*string.sub(x,1,2)+string.sub(x,4,5))+string.sub(x,7,8);
while #Ts>jT and 0>dt do jT=jT+1; dt=Ts[jT]-z; end
end
if dt>=0 then message(x.." до старта "..dt.."сек"); sleep(1000*dt); else sleep(1); end
end
if fstop==false then x= getInfoParam("SERVERTIME"); message("старт "..x.." fstop="..tostring(fstop) ); end
-- исполнение скрпита
fstop=true; --- остановить скрипт
if fstop then x= getInfoParam("SERVERTIME"); message("стоп "..x.." fstop="..tostring(fstop) ); end
end
end
Добрый день, Предлагаю добавить в библиотеку QLUA функцию установки идентификатора для графика цена и индикатора . --------------------- Объясняю зачем: -------------------- 1) Для установки идентификатора не надо будет лазить в меню окна. Причем очень достает устанавливать этот идентификатор для индикатора при отладке индикатора. ---------------------------- 2) идентификатор графика цены нужен для вывода меток на график. Если это график с якорем, то отображаемый инструмент будет изменяться при изменении активной строки в таблице, а идентификатор при этом не меняется. С помощью предлагаемой функции можно в скрипте динамически изменять идентификатор, например, указывая в нем имя инструмента. В итоге можно метки на графике разделить по инструментам. ------------------------------ 3) идентификатор индикатора нужен для чтения параметров индикатора в скрипте луа. Сейчас для этого надо лазить в меню окна и прописывать идентификатор в Settings. В итоге идентификатор для индикатора можно будет динамически привязывать к инструменту, интервалу и алгоритму индикатора.
Добрый день, --------------------------- Пример простого, универсального советника на луа на основе любых индикаторов. ------------------------------ Советник - это программа, которая формирует сигналы "купить/продать" и показывает их, но не совершает сделки. --------------------- Пример на основе стратегии пересечения двух скользящих средних. Помещаем два индикатора на график цены инструмента Присваиваем им идентификаторы MOV1 и MOV2 как на рисунке:
далее пишем индикатор "nk_bot"
Код
Settings={ i1="MOV2",i2="MOV1", Name = 'nk_bot', }
------------------
local function gI(s,j,i)
local t=getCandlesByIndex(s,j,i-1,1); if t then return t[0].close; else return 0 end
end --значение индикатора
-------------------------
local function cross(s1,j1,s2,j2,i)
local m=i; local x= gI(s1,j1,m) local x1=gI(s2,j2,m);
while m>1 and x~=0 and x1~=0 and x>x1 do m=m-1; x=gI(s1,j1,m); x1=gI(s2,j2,m) end
if m>1 and i>m then return m end
end --пересечение
--------------------------
function OnCalculate(i)
local Bu,Se; local i1=i-1;
if i>1 then
local jU_,jD_=jU,jD;
jU=cross(Settings.i1,0,Settings.i2,0,i1); --MOV1 пересекает MOV2 снизу вверх
jD=cross(Settings.i2,0,Settings.i1,0,i1); --MOV1 пересекает MOV2 сверху вниз
if jU and jU_==nil then jBu=i; Bu=L(i)-0.1; end
if jD and jD_==nil then jSe=i; Se=H(i)+0.1; end
if i==Size() then -- последняя свеча
end
end
return Se,Bu;
end
-----
function Init()
local t={};
t[#t+1]={Name = "Se",Color = RGB(255,0,0),Type = 11,Width =3}; ---sell
t[#t+1]={Name = "Bu",Color = RGB(0,255,0),Type = 10,Width =3}; ---buy
Settings.line=t;
return #t;
end
и помещаем его на график инструмента В результате получим на истории торгов сигналы "купить/ продать" на графике инструмента --------------------- На основе данного примера Вы можете построить советник для любых индикаторов, которые встроены в терминал КВИК или написаны кем-то.
Недавно сообщал на форуме о том, что дата сервера в текущих торгах показывает вчерашнюю дату. сегодня выявил как это можно повторить. ------------------- проблему можно обнаружить, если загрузить квик и подключить его к серверу до начала торгов. В этом случае, после начала торгов дата сервера не обновляется и остается равной дате предыдущих торгов. если разорвать соединение и снова восстановить то дата сервера обновляется до текущей. -------------------- От версии КВИКА этот прикол не зависит.
Добрый день, --------------- сделал следующий тест. На график вывел два варианта индикатора стохастик. ----------------------- 1) встроенный в терминал (третий график на картинке ) 2) взятый из предложенных разработчиками вариантов на луа. (четвертый график ) ----------------------- Во втором варианте добавил чтение индикатора с графика первого варианта и вывод этого значения для сравнения на график второго варианта. ------------- На втором варианте это линия белого цвета. ------------------ Вот такая картинка в итоге:
Время чтения индикатора с графика 6.8 мкс , а время расчета индикатора 23.4 мкс.
Сегодня в сбербанке на реальных торгах наблюдаем это: посмотрите дату торгов и дату сервера. Очевидно, все в отпуске и сервером управляет пьяный робот.
Добрый день, Специально для буратин и чайников выкладываю исходник индикатора арбитража. ----------------- На графике отображается белый - разность цен красный - максимум за торговый день синий -минимум за торговый день зеленый - средний за торговый день розовый - эксп.скользящая средняя ------------------ Инструкция для ощущения счастья: 1. Откройте график цены первого инструмента 2. Откройте в этом же окне график цены второго инструмента. 3. На вкладке Дополнительно второго графика запишите Идентификатор, который записан в исходнике индикатора в поле sec таблицы Settings 4. Откройте индикатор в новой области этого окна. ------------------
Код
--title="Arbitr <nikolz> "-- арбитраж
name='arb_nk'
Settings={
sec ="SB_arb", --идентификатор 2-го инструмента (графика)
LEMA = 30,
Name = name,
}
-------
function OnCalculate(i)
if i==1 then
AL=1/Settings.LEMA; y,Ma,Mi,Me,x=nil;
else
local C1=C(i)
if T(i-1).hour>T(i).hour then y,Ma,Mi,Me,x=nil end
local t=getCandlesByIndex(Settings.sec,0,i,1); t=t[#t];
if t then
local C2=t.close;
if C2 and C1 then
x1=C1-C2;
if Ma==nil or x1>Ma then Ma=x1 end
if Mi==nil or Mi>x1 then Mi=x1 end
if Ma and Mi then
Me=(Ma+Mi)/2; x=x1;
if y==nil then y=x; end y=(1-AL)*y+AL*x;
end
end
end
end
return Me,Ma,Mi,x,y
end
-----
function Init()
Settings.line={};
Settings.line[1] = {Name = "Me",Color = RGB(0,255,0), Type =1,Width = 2 };
Settings.line[2] = {Name = "Ma",Color = RGB(255,0,0), Type =1,Width = 2 };
Settings.line[3] = {Name = "Mi",Color = RGB(0,0,255), Type =1,Width = 2 };
Settings.line[4] = {Name = "x",Color = RGB(255,255,255), Type =1,Width = 1 };
Settings.line[5] = {Name = "eMA",Color = RGB(255,32,255), Type =1,Width = 2 };
return #Settings.line;
end
Добрый день, Вопрос к знатокам. В документации QLua в разделе: "Функции для работы с таблицами Рабочего места QUIK" ------------------- написано: ----------------- В таблицах Рабочего места QUIK, созданных с помощью скриптов на языке Lua, поддержаны следующие возможности :
..
пользовательские фильтры,
...
=========================== прошу подсказать, где я могу прочитать про эти "секретные возможности" под названием " пользовательские фильтры" ------------------ Читать на расстоянии мысли разработчиков пока не научился, а в документации ничего не нашел.
Добрый день, всем, Хотя о том, про что буду рассказывать знаю с момента появления LUA VM в КВИКЕ и думал, что эту подлянку давно поборол, однако она снова дала о себе знать. --------------------- В частности примерно это же недавно обнаружил посетитель по нику Старатель. -------------------- Так как я давно казалось бы проблему решил, поэтому на его вопрос особо не обратил внимание. =============== но вот недавно столкнулся с проблемой удваивания заявок-близнецов. ================= Хотя ничего хорошего мне на форуме как обычно не посоветовали, но вредные советы тоже пригодились. =============== Например, представитель разработчиков гневно заявил, что мол надо все обнулять при index=1 в индикаторах. Благодарю его за его вредный совет. ------------------ Действительно, верно говорят -выслушай совет на Красной площади и сделай наоборот. ---------------------------- Поэтому я обратил внимание, что именно по index=1 я обнулил лог файл. ------------- продолжение следует..
Добрый день, Всем В качестве ликбеза для буратин и чайников, привожу результаты тестирования скорости исполнения выставления и снятия заявки в роботе, который реализован в индикаторе. ------------- кратко в чем преимущество такой реализации относительно реализации в виде скриптов. ================ 1) нет надобности писать колбеки и разбираться в них. ---------------- 2) робот можно сделать одинаковым для любых инструментов Например робот автомат управления стопом. --------------------- 3) проще реализовать, так как нет надобности заморачиваться с фильтрацией инструментов. На какой график кинете этого робота, на том инструменте он и будет работать. ================= А теперь о скорости его работы. Тест, в котором выставляется заявка, когда она выставится, робот ее снимает. при этом он проверяет таблицу стоп-заявок, заявок и депо. ================= На выставление заявки уходит примерно 0.006 сек На проверку активной заявки и выставление заявки на снятие уходит примерно выставление заявки на снятие уходит примерно 0.004 сек -------------------------- время в мкс:
Тестирую в демо версии выставление заявок фрагмент кода такой:
Код
t1.PRICE=tostring(price);
t1.QUANTITY=tostring(Q);
t1.TRANS_ID=tostring(id+1); -- Уникальный идентификационный номер заявки, от «1» до «2 147 483 647»
local str=sendTransaction(t1); --отправить транзакцию
Log:write("сообщение"..str.."\n"); Log:flush() -- вывод сообщения в файл
if str=="" then id=id+1; ji=ji+1; ti[ji]={id,0}; ti[0]=ji;
Log:write("заявка id"..tostring(id)..",ji="..tostring(ji).."\n"); Log:flush()
end ---если сообщение пустое то в файл выводится id транзакции
Поясняю. Разработчикам просьба внимательно читать пояснения. Все тщательно разжую. ================ Выполняется: str=sendTransaction(t1) строка str выводится в файл если сообщения нет , то id увеличивается на 1 и становится равным id транзакции и выводится в файл ===================== ВНИМАНИЕ!!! Таким образом, исключается передача транзакции с одинаковым id и контролируется количество переданных транзакций. =================== В лог файле при выполнении транзакции получаем:
Код
сообщение
заявка id31,ji=1
Т. е. ожидаем одну заявку с id=31 ---------------- ВНИМАНИЕ!!! смотрим в таблицу заявок:
Однако, наблюдаем по две заявки с одинаковыми id одинаковыми параметрами и в одно и тоже время. ------------------------ Что не так?
Добрый день, Всем. ---------------------- На форуме очень много буратин и чайников, жизнь которых на рынке только начинается. Поэтому попробую, по мере сил и желания, снять с их ушей лапшу, которую им упорно развешивают некоторые словообильные посетители. -------------------- Начнем с определений: чайник - чел,начинающий программировать робота в QUIK. буратино - чел,начинающий гений торговли и уверенный в быстром обогащении на бирже, мечтающий о халяве. Тики - данные отображающиеся на графике с интервалом -"тиковый" ================ Фейк №1 =============== Есть тики , а есть обезличенные сделки и это разные данные, тики -няка, а обезличенные сделки -бяка. Тики обрабатываются быстрее, чем обезличенные сделки. -------------- Такая тема неоднократно появлялась на форуме. Как правило это связано с самопальными свечами с интервалом меньше 1 минуты. ================ Так вот , противопоставление тиков и обезличенных сделок - это ложь. Тики и обезличенные сделки - это одни и те же данные. =========== Получить эти данные можно тремя способами: 1) подписаться на обезличенные сделки на LUA; 2) заказать обезличенные сделки через меню терминала 3) открыть график с интервалом "тиковые" ----------------------- Во всех трех случаях данные будут поступать в таблицу обезличенных сделок,в колбек скрипта и на график. ============== Доказательство : 1) см документацию: функция CreateDataSource param – Если параметр не задан, то заказываются данные на основании таблицы обезличенных сделок. -------------- 2) без заказа через терминал, откройте тиковый график. А потом откройте таблицу обезличенных сделок. Вы увидите в таблице инструмент с тикового графика. ------------------ 3) сделаем следующий тест. На тиковый график разместим индикатор, который пишет текущую цену инструмента (ТИК) в лог файл. В этот же лог файл пишем параметры обезличенных сделок данного инструмента, полученные скриптом onAllTrade. И дополнительно проверим, что же мы получим по данному инструменту через колбек onParam, т е из ТТП. ----------- Вот результат данного теста:
Резюме: Первым ВСЕГДА отрабатывает колбек onAllTrade, после него данные приходят в индикатор графика. --------------- Колбек onParam , как и ожидалось принимает лишь некоторые тики, которые попадают в текущий срез данных, передаваемых в таблицу текущих параметров. ------------------------
Добавлять поддержку архитектуры win32 (первая команда выше) нужно только если ваша система 64-разрядная.
Проблему рано или поздно исправят, так что можно будет пользоваться WINE и без дополнительного репозитория: sudo dpkg --add-architecture i386 sudo apt install wine winetricks
Устанавливаем VC6RedistSetup. Можно его скачать с сайта Майкрософт и запустить при помощи Wine. А можно просто выполнить в терминале winetricks vcrun6
Гораздо проще воспользоваться winetricks, т.к. перед установкой VC6RedistSetup он предложит установить необходимые нам "Wine Mono Installer" и "Wine Gecko Installer". На предложения скачать и установить нужно соглашаться и нажимать на кнопку Install.
Скачиваем Quik с сайта брокера. Если приложение находится в архиве (zip, rar), то его нужно предаварительно распаковать. WINE будем запускать с .exe файлом.
Для установки Quik используйте команду в терминале: LC_ALL=ru_RU.UTF-8 wine64 quik_inst.exe
Где вместо quik_inst.exe нужно подставить имя вашего установщика quik (например, это может быть "quik_8.7.exe"). Обратите внимание, что запускать эту команду нужно из папки, в которой находится этот установщик (installer). Если вы скачали его в папку пользователя Downloads, распаковали ZIP архив именно в эту папку, то переходите в неё при помощи команды cd в терминале: cd ~/Downloads
Копируем ключи secring.txk и pubring.txk в папку /home/USER/.wine/dosdevices/c:/Program Files/BROKER/Keys, где USER - ваше имя пользователя, а BROKER - подпапка в "Program Files (x86)", в которую установлен торговый терминал Quik (Возможно, вы захотите установить Quik не в Program Files, а в корень, например, в C:\SBERBANK. Тогда и ключи копируем в соответствующую папку). Ключи конечно же можно хранить и в другой папке, при этом в "Система" -> "Настройки" -> "Основные настройки" -> "Программа" -> "Шифрование" -> "Шифровать с помощью СКЗИ" -> Qrypto32 -> "Настроить" нужно указать путь к ключам.
Создаем ярлык для запуска. В моем случае это shell скрипт (текстовый файл с расширением sh) на рабочем столе. cd "~/.wine/dosdevices/c:/Program Files/BROKER/" LC_ALL=ru_RU.UTF-8 wine64 "c:/Program Files/BROKER/info.exe" Если опустить параметр "LC_ALL=ru_RU.UTF-8", то часть текста может отображаться некорректно (вместо текста появляются вопросы или кракозябры). Если не перейти в папку с установленной программой перед запуском, то возникают проблемы с настройками. Вместе же две команды решают проблемы с запуском Quik в Ubuntu (Linux).
После создания shell скрипта quik.sh можно открыть свойства этого текстового файла и на вкладке Permissions разрешить выполнение в качестве программы. Но можно переходить в папку с этим скриптом в терминале и запускать его, добавляя "./" перед именем файла: cd ~/Desktop ./quik.sh
После запуска Quik нужно изменить в настройках шрифты. Если этого не сделать, то в некоторых диалогах будут появляться кракозябры, хотя большая часть информации всё же отображается корректно. Для этого в меню выбираем "Система" -> "Настройки" -> "Основные настройки...(F9)" -> "Программа" -> "Шрифты", после чего изменяем шрифты, например, на Arial (или любой другой шрифт, который вам нравится, но который будет корректно отображать русские буквы в Quik).
Если нужно сгенерировать ключи для Quik, то запускаем keygen.exe из под WINE: cd ~/.wine/dosdevices/c:/Program Files (x86)/BROKER/KeyGen LC_ALL=ru_RU.UTF-8 wine64 keygen.exe
Профит!
Данный способ запуска Quik в Linux прекрасно работает для брокеров ВТБ, Открытие, БКС, Финам, Сбербанк, Промсвязьбанк и прочих. В том числе не возникает и проблем, если для входа требуется SMS подтверждение.
Если при запуске через некоторое время возникает ошибка "Не хватило памяти под объекты, без которых приложение работать не может", то первым делом нужно проверить наличие свободной памяти. .
Предлагаю принять участие в тестировании моей библиотеки обмена сообщениями между процессами, потоками , приложениями, скриптами на любом языке программирования. ------------------------------- Как это работает Приложению или скрипту присваиваем номер NUM от 1 до 30000. ---------------- 1) Послать сообщение S: res=nkLp.send(NUM,S) , если успешно , то res=1. Num - номер получателя. 2) Принять сообщение S: на Lua S=nklP.get(NUM), на других языках nkLP(Num,S). Если нет, то пусто. Num-номер получателя. ================= Возможности 1) В скриптах для QUIK, колбеки можно размещать лишь в одном. Этот скрипт может рассылать информацию всем желающим. ----------------------------- 2) Индикаторы и скрипты могут обмениваться информацией. ------------------------------ 3) Любое внешнее приложение , например на питоне, может обмениваться информацией с QUIK или любым другим приложением, например, на луа. ================= Чем это решение лучше других 1) Другие таких решений нет . Если знаете, дайте ссылку. 2) Не блокирует потоки, не использует файлы, не обращается к ядру ОС. 3) Самый быстрый способ обмена. ================== Ограничения тестовой версии: В данном решении длина сообщения 64 символа. Используется лишь один ящик сообщений. Т е новое сообщение будет передано лишь после того, как прочитают предыдущее. В сообщении нет обратного адреса. Тестировал на Win10 64bit, Lua 5.4 =================== Как принять участие в тесте: Написать свою почту в личку.
Добрый день, Ищу решение следующей проблемы. ---------------- Сейчас у меня реализовано так: -------------------- В функции main для каждого инструмента запускается свой поток. Потоки берутся из пула. Если свободного нет, то создается новый. ------------------ Данные передаются в поток через параметры скрипта и мапинг-файлы. ------------------ Прием данных от источника и стаканов реализуется в main. ----------------- Все работает замечательно. Но узким местом является прием данных всех инструментов в одном потоке main. ----------------------- Хочу принимать данные и стаканы в отдельном потоке каждого инструментов. ------------------ Применение общего глобального стека не дает результата. ---------------------- Если кто-то решил данную проблему, просьба сказать каким методом. ------------ Спасибо ================= Отдельная пожелание разработчикам. Реализовать указанные функции для приема данных и стаканов для произвольного потока.
Что считает терминал QUIK в таблице купить/продать и что же считает функция getBuySellInfo . ------------------- Казалось бы должны считать одно и тоже. ====================== Если -нет, то дайте ссылку на документацию. =============== Проверяем: Берем данные из таблицы терминала купить продать и по этим данным считаем функцией getBuySellInfo =========== результат ниже: Сумма - это произведение цены на количество. --------------------------------- Отличия: 1) Все суммы различные , даже там , где цена и количество одинаковые Например ===========================================
28
MGNT
4201
71
298 271
71
298 662
=============================================
2) QUIK для всех акций считает как не маржинальные, а формула очевидно учитывает маржинальные Но учитывает как то странно Например:
Риск 5.9, но для физ лиц не может быть более 5, а для юр. лиц может быть аж 8. Откуда 5.9 ? ------------------------ Там, где риск=1, количество не совпадает в большинстве случаях.
Читаем таблицу, которую получает колбек OnDepoLimit ---------------- currentbal=0.0 locked_sell=0.0 locked_buy=0.0 wa_position_price=0.0 sec_code=CNTL firmid=NC0011100000 client_code=1737 limit_kind=-3 locked_buy_value=9.96 awg_position_price=0.0 wa_price_currency=SUR openbal=0.0 trdaccid=NL0011100043 locked_sell_value=-1e+48 -- Стоимость инструментов , заблокированных на продажу currentlimit=0.0 openlimit=0.0 ----------------------- Вопрос к знатокам: сколько стоят инструменты, заблокированные на продажу?
Добрый день, Предлагаю зарегистрировать следующее пожелание. Добавить в таблицу "Позиции по инструментам" class_code. -------------------- Объясняю в чем проблема. ================= При написании скриптов возникает необходимость получить параметры по инструментам, чтобы выставлять какие-либо заявки. ------------- Для формирования заявки по позиции инструмента нужен класс этого инструмента, а его в таблице позиций нет. ---------------- В результате, чтобы найти класс надо делать "танцы с бубном" извлекать клиента по нему находить торговый счет по счету находить фирму и получать список торгуемых классов потом в классах искать тот, в каком есть данный инструмент. ----------------- Напоминает наблюдение гланд через зад. Занятие занятное , но бесполезное. ================= Спасибо
Добрый день, -------------- Вопрос к знатокам: ----------------------------- Вычисляю функцией CalcBuySell сколько акций можно купить.
фрагмент кода: local qty1,comis1=CalcBuySell(clas, sec,"1737","NL0011100043",price, true,false); ------------------------- Поясняю, что ожидаю: ------------------ На учебном сервере денежных средств 300 тысяч рублей. ---------------- Данная функция должна считать комиссию и число лотов для покупки по указанной цене. Полагаю, что коммиссия должна быть примерно одинаковой (сумма денег одна) А число акций умноженное на цену одной и на количество их в лоте должна составлять примерно 300 тыс рублей ------------------- Для проверки, считаю количество и комиссию по формуле. -------------------------- В результате обозначено: ------------------- qt1,comis1 - расчет функции qt,comis - расчет формулы m - сумма денег исходная m1- расчет суммы денег по результатам функции ----------------------- результат вычисления: ============= акции, для которых результат функции и по формуле примерно одинаковый: ------------------ TATNP,m=299983, lotsize=1., qty1=937, m1=299881, qty=935, comis1=229.26, comis=749, price=319.8 ROSN,m=299983, lotsize=1., qty1=844, m1=299887, qty=842, comis1=225.54, comis=749, price=355.05 ------------- "чудеса в решете": -------------------- CHMF,m=299983, lotsize=1., qty1=1530, m1=1759940, qty=260, comis1=746.54, comis=749, price=1149.8 ---------- при цене 1150 рублей по формуле можно купить 260 акций, что вполне похоже на правду. ----------------------------- функция считает, что можно купить 1530 акций, при этом комиссия примерно одинаковая, что указывает что затрачено примено 300 тыс рубг ---------------------- следующее чудо: SBER,m=299983, lotsize=10., qty1=1349, m1=1759982, qty=229, comis1=751.81, comis=749, price=130.41 ----------- Сбербанк акция 130 рублей по формуле можно купить 229 лотов или 2290 акций, что правда. функция считает, что можно купить 1349 лотов, на сумму 1млн759 тыс 982 рублей Величина комиссии указывает что ее считали с суммы 300 тысяч. --------------------- еще один прикол: AFLT,m=299983, lotsize=10., qty1=6567, m1=1760716, qty=1116, comis1=760.2, comis=749, price=26.8 ================== Кто сие может объяснить? Спасибо
Добрый день На учебном сервере версия 9.4 l------------------- читаем код клиента
Код
message("всего=.. getNumberOf("client_codes") );
for i=0,getNumberOf("client_codes")-1 do
local x=getItem("client_codes",i);
message("i="..i..",cod="..tostring(x) );
end
получаем результат: всего=2 i=0,cod=1737 i=1,cod= -------------------- если я правильно понял, то должен быть всего один код клиента. и действительно код i=0,cod= 1737 но почему-то их два, i=1, cod=пусто. ------------------------ Что не так я делаю? Какой в этом пустом коде тайный смысл? ======================================= Огласите весь список, п..жалуста, в каких еще таблицах так сделано. Спасибо.
Известно, что колбеки в QLUA блокируют основной поток терминала QUIK. Решение изначально было спорное, но в ту пору попытка переубедить разработчиков в их ошибке была безрезультатна. ----------------------- Как мера, якобы устраняющая данную проблему, по задумке разработчика QLUA был введен еще один поток для функции main. ----------------------- Поэтому Всем известна рекомендация разработчиков делать минимальные вычисления в колбеках и выполнять основные расчеты в функции main. ================== Однако, это кажущееся ускорение вычислений легко можно свести к нулю, что уверен и делается большинством программистов роботов на QLUA. =================== Рассказываю в чем фишка. ================ Экспериментируя с реализацией пула потоков, обнаружил, что потоки, использующие область глобальных переменных, а также функция main на самом деле не работают независимо от колбеков, а тоже останавливаются на время их работы. Очевидно, это связано с блокировкой области глобальных переменных при работе колбеков. ==================== В итоге, если у Вас в функции main используются глобальные переменные, а это, в том числе , источники данных, то параллельная работа функции main не получится. ------------------ В итоге поток Main будет останавливаться вместе с основным потоком терминала и Ваш робот на QLUA будет фактически работать в одном потоке с остановками на каждом колбеке. ========================== Прикольно, но есть решение, которое позволяет: во-первых, полностью убрать из QLUA эти монстры-колбеки, останавливающие основной поток и функцию main в указанных выше случаях. во-вторых, не останавливать основной поток вообще для передачи данных в другие потоки, которых может быть любое число. ========================= я сомневаюсь, что разработчики когда-нибудь решат это сделать, так как им платят брокеры, а брокерам это до лампочки. ---------------------------- Поэтому могу лишь рекомендовать писателям роботов свести к минимуму использование глобальных переменных в функции main.
Добрый день, ------------- Вопрос к разработчикам QUIK или к тем, кто это решил. ------------- версия QUIK 9.4. -------------------- Возникла следующая проблема. =========== Написал библиотеку запуска произвольных скриптов Луа по событиям в отдельных потоках из пула потоков. ============ Все работает замечательно. ============= Решил в скрипте, запущенном в моем потоке, обратиться к функциям из библиотеки QLUA. ============ Например, подключиться к источнику данных: ----------------------- if ds==nil then ds=CreateDataSource("QJSIM","SBER",INTERVAL_M1) end -------------------- Мой скрипт имеет функцию main и запускается из функции main Вашего скрипта. ---------------- В вашей main все работает, а в моей - пишет ds=nil.
Попытка подключить через require "qlua" дает ошибку: ---------------- D:/lua-5.4.2/lua54.exe: error loading module 'qlua' from file 'D:/QUIK_SCRIPT/qlua.dll': Не найдена указанная процедура. ---------------------- Проверяю зависимости - Все находит. ------------------------- Что делаю не так? Спасибо.
информация к размышлению. Вопрос: Какую информацию мы получаем в реальности?. Для этого написал тест, который измеряет время реакции колбека относительно времени сервера. так как реальные торги сейчас не проводятся, то тестируем тестовый сервер. В итоге получаем следующий результат: Первое число -это время сервера, когда тот послал нам последнюю порцию данных. Например 17:16:22. Далее указано время , которое прошло с момента срабатывания последнего колбека QLUA например 723174.2 мкс, Т е прошло 0.7 секунды далее указан номер колбека например 15 - это колбек OnParam Обратите внимание на то, что далее время сервера не изменяется еще 9 значений. При этом время вызова колбека составляет не более 100 мкс, т е 0.0001 сек ---------------------------- что же это означает. Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета, Потом этот пакет пересылается нам в колбеки. В итоге вам кажется, что вы получаете данные в реальном времени, а в действительности с задержкой на 0.7 секунды. В реальных торгах задержка возможно и меньше, но передачу пакетом никто не отменял.
Добрый день, В данной теме предлагаю Вашему вниманию информацию о том, что у VM LUA (виртуальная машина луа) внутри. ------------------------------- Полагаю, что данный материал будет особенно полезным тем начинающим, которые буратино на фондовом рынке и чайники в программировании. ---------------------------- Основа VMLua - это таблицы. ------------------------------ Полагаю, что многие просто не представляют сложность реализации таблиц в VM Lua. ---------------------- Даю ссылку на статью. В ней речь идет о LuaJit - это более быстрый вариант VMLua, чем просто Lua 5.3 или 5.4. Но принцип организации работы с таблицами тот же. ------------------- Прошу: https://habr.com/ru/company/vk/blog/493642/
Привет, разработчики КВИК. Возникла проблема. Квик работал, работал и настал кирдык. ----------------------------------- Брокер сбарбанк ----------------- версия квик 8.7.1.3 ------------------- Соединение с сервером двухфакторное. -------------------------- При запуске КВИК получаю сообщение в окне сообщений:
Connection was closed by peer: Can’t get messege size from net. И все. Соединения нет. Что делать? Спасибо
Предлагаю для скриптов LUA реализовать: 1) колбеки QLUA в виде asynchronous procedure call (APC)для потока main; 2) в одном скрипте создавать несколько потоков и с помощью APC распределять по ним обработку данных из терминала КВИК.
Полагаю , что останов функции main c помощью sleep неудачное решение разработчиков. -------------------------------- Сам использую останов потока системным событием Event. Неоднократно предлагал разработчикам реализовать останов потока системным событием Event. Но воз и ныне там. ------------------------------ Чтобы показать наглядно эффективность предлагаемого способа реализовал следующий тест. ----------------------- Во всех колбеках поставил счетчик вызова и старт таймера. В функции main поставил останов таймера и запись в лог счетчиков событий всех колбеков и прошедшее время с момента вызова очередного колбека. ---------------------- Вот фрагмент лог файла: ... 93>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15784,95846,0 83>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15784,95847,0 90>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15784,95848,0 129>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15785,95848,0 110>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15786,95848,0 261>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15786,95850,0 431>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15786,95850,0 88>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15786,95851,0 85>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15786,95852,0 131>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15787,95852,0 113>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15788,95852,0 162>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15788,95853,0 91>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15788,95854,0 93>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15789,95854,0 294>0,0,0,0,11,11,0,0,0,0,0,0,0,0,15789,95855,0 .... На первой позиции время в микросекундах, прошедшее с момента вызова терминалом колбека до момента активации потока main скрипта. далее через запятую счетчики вызова колбеков. -------------------------------------------- Как видно из лог файла это время составляет примерно 100 мкс (компьютер слабый, WIN XP). -------------------------- Получается, что использование функции sleep либо приведет к постоянной активации потока и бесполезной загрузки ядра, либо к пропуску завершения работы колбеков. Обе ситуации плохо.
Добрый день, проблема следующая. ------------------ Использую в торговых роботах нейронные сети. ----------------------- Если нейронные сети встраивать на основе QLUA , то все работает медленно и кушает много памяти. Поэтому полноценный процесс обучения практически не реализуем. ------------------------------------- Реализовал векторную алгебру в виде библиотеки на CИ для QLUA. Скорость вычислений возрастает в 7-20 раз, а затраты памяти сокращаются во столько же. Процесс обучения реализуем. ------------------------------------------------ Но очень раздражает необходимость делать бессмысленную работу перегоняя данные туда и обратно а потом обратно и туда. Сначала функциями QLUA приходится вытаскивать из архива квика данные , преобразовывая их в формат луа, а потом функциями из своей библиотеки обратно их преобразовывать из формата луа в формат CИ --------------------------------- Просьба к разработчикам выложить API С для обращения к хранилищу данных терминала QUIK. ----------------- Спасибо
Вопрос к разработчикам. что делать? -------------------------------------- брокер Сбербанк QUIK версия 8.7.1.3 (для предыдущей было тоже самое) Сейчас - утренняя сессия изменяются данные лишь в стакане Графики и таблица позиций не обновляется. Не отображаются новые сделки. На графиках лишь вчерашний день. Так часто бывает и в начала вечерней сессии.
Для тестирования торговых роботов не хватает истории торгов. Просьба сделать возможность конвертации данных из текстового формата в формат файлов с данными типа .dat , либо выложить формат этих файлов.
Добрый день, Прошу разработчиков рассмотреть следующее предложение по развитию QLUA. ---------------- Суть проблемы. При создании нескольких скриптов приходится дублировать внешнюю среду функции main в каждом скрипте Т е все колбеки и все глобальные переменные Но так как все это исполняется в одном потоке создается существенное торможение работы терминала при большом числе скриптов. -------------------- Решение - предложение. Решить проблему можно двумя путями. Вариант1 Реализовать возможность создание в одном скрипте множество функций main Т е реализовать механизм запуска нескольких потоков в одном скрипте Ввариант2 Реализовать возможность работы множеству скриптов с одной глобальной областью Этот вариант реализуется, например, путем подмены указателя глобальной таблицы скрипта на указатель общей глобальной области Этот вариант я реализовал лет восемь назад для win32 и LUA 5.1, Теперь надо все переделывать на 64 и 5.3 ------------------- Поэтому предлагаю это сделать для всех буратин.
Добрый день, вопрос к разработчикам. ---------------------- Рассмотрим такую ситуацию. На сервере есть очередь заявок длинною 100 первой стоит заявка клиента1 в текущий момент этот клиент подает точно такую же заявку, но с другим количеством ----------------------- Внимание вопросы: 1) как данную ситуацию обработает сервер квика 2) как данную ситуацию обработает сервер биржи --------------------- Варианты ответов 1) поместит заявку в очередь с номером 101 2) добавит заявку в очередь с номером 1 ------------ Спасибо
Добрый день, Просьба пояснить почему в качестве новой версии в QUIK выбрана lua5.3 мое тестирование показывает, что версия 5.3 работает так же медленно как и 5.1 ------------------ а вот luajit, которая основана на Lua5.1 работает в 2 раза быстрее при исполнении скриптов и позволяет исполнять очень быстро и просто вставки на СИ увеличивая скорость исполнения до 50 раз. ---------------------------- кроме того версия LuaVela на основе luajit решает проблему ограничения памяти 2Гб. -------------------- Так в чем же тайный смысл замены 5.1 на 5.3? Спасибо