не все то золото, что блестит

Страницы: 1
RSS
не все то золото, что блестит
 
информация к размышлению.
Вопрос: Какую информацию мы получаем в реальности?.
Для этого написал тест, который измеряет время реакции колбека относительно времени сервера.
так как реальные торги сейчас не проводятся, то тестируем тестовый сервер.
В итоге получаем следующий результат:
Первое число -это время сервера, когда тот послал нам последнюю порцию данных.
Например 17:16:22.
Далее указано время , которое прошло с момента срабатывания  последнего колбека QLUA
например 723174.2 мкс, Т е прошло 0.7 секунды
далее указан номер колбека
например 15 - это колбек OnParam
Обратите внимание на то, что далее время сервера не изменяется еще 9 значений.
При этом время вызова колбека составляет не более 100 мкс, т е 0.0001 сек
----------------------------
что же это означает.
Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета,
Потом этот пакет пересылается нам в колбеки.
В итоге вам кажется, что вы получаете данные в реальном времени, а в действительности с задержкой на 0.7 секунды.
В реальных торгах задержка возможно и меньше, но передачу пакетом никто не отменял.

Скрытый текст
 
Продолжим тестировать скорость исполнения скриптов.
версия квика 9.4.
------------
Посмотрим,
как влияет на скорость выполнения колбека чтение каких либо параметров .
------------------  
Сначала колбеки запишем так:
function OnParam (clas, sec)-- изменение текущих параметров
ncb=14;
nkevent.Set(event);  -- событие
end
function OnQuote (clas, sec)-- изменение стакана котировок
ncb=15;
nkevent.Set(event);  -- событие
end
-------------------
т е в колбеках ничего не делаем.
получаем:
=============
111746 1124068.5;14;0
111746 1.8;14;0
111746 1.3;14;0
111746 21.7;14;0
111746 1.7;14;0
111746 20.9;14;0
111746 21.1;14;0
111746 21.2;14;0
111746 1.5;14;0
111746 1.2;14;0
111746 6688.0;15;0
===========  
Получаем пакета onParam  один раз в секунду и вывод его в колбек onParam  время примерно от 2 до 20 мкс.
А колбек OnQuote  исполняется аж 6688 мкс.
===============
Теперь добавим в колбеки что-нибудь:
Например так:
function OnParam (clas, sec)-- изменение текущих параметров
ncb=14; --local clas=class_code; local sec=sec_code;
LAST=getParamEx(clas, sec,"LAST").param_value;
nkevent.Set(event);
end
function OnQuote (clas, sec)-- изменение стакана котировок
ncb=15;  ql2 = getQuoteLevel2(clas, sec);
nkevent.Set(event);
end
----------------------
получаем:
============
111942 1077168.6;14;0
111942 23.5;14;0
111942 77.2;14;0
111942 23.4;14;0
111942 40.1;14;0
111942 23.3;14;0
111942 40.2;14;0
111942 13.4;14;0
111942 47.4;14;0
111942 54.4;14;0
111942 40.6;14;0
111942 7207.1;15;0
 ==================  
Как видим, теперь время колбека  onParam  составляет от 20 до 80 мкс
Время колбека OnQuote  стало 7200 мкс.
Т е , чтобы прочитать один стакан затратили 7200-6700=500 мкс.
----------------  
Очевидно, что колбек стакана очень тяжелый,
так как на него затрачено в 100 раз больше времени чем на onParam.
======================  
Обращаю Ваше внимание, что разбор пакета параметров происходит очень быстро
время от 2 до 80 мкс.
Поэтому если Вы поставите в main sleep ,  то main  будет обрабатывать каждый чих колбека через интервалы сна.
Вы не сможете установить слип меньше 3 мс т е 3000 мкс.
А интервал кобеков в 1000 раз меньше.
--------------------------
Поэтому sleep не применяю вообще, а использую системные EVENT.


 
 
nikolz, Все вроде с виду в шоколаде, но если внюхаться — то нет.©

Лапуль, информация ПОЛНОСТЬЮ определяется ПРИЁМНИКОМ. Или, если угодно, "информация есть результат интерпретации данных исполнительным механизмом". И если у "механизма" в одно ухо влетает, а из другого вылетает, никакой информации нет.

Лично мне АБСОЛЮТНО насрать на все эти дурацкие миллисекунды, время реакции колбека, время сервера и всю остальную дребедень. Всё это НИКАК не влияет на алгоритмы торговли. По крайней мере, на НОРМАЛЬНЫЕ алгоритмы - например, мои. А криворукие бездари продолжают заниматься своей клинической хернёй, то бишь ловлей микросекунд, при этом они, как правило, даже с паршивым десятком тикеров справиться не способны. O tempora, o mores! :cry:  
 
Зачем же измерять время реакции робота на приход информации и знать время запаздывания этой информации спросите Вы?
-----------------------
Поясняю,  для тех, кому интересно.

Торговый робот - это система реального времени. Что это означает?
Это означает то, что такая система должна успеть обработать пришедшие данные до момента прихода новых.
Если робот не успевает их обработать, то данные либо теряются, либо Вы должны их накапливать для отложенной обработки.
-----------------
Выше я показал время прихода информации Таблицы текущих параметров.
Чаще всего именно по этой информации определяется изменение цены инструмента.  
Из данных выше следует что для демо сервера, информация об этом изменении может запаздывать до 1 секунды,
а значения из пакета данных могут передаваться в колбек через 10 мкс.
---------------
Ну и что?
Это означает, что при задержке данных в 1 секунду не надо мечтать о создании HFT робота.
----------------
А получение данных из пакета с интервалом в 10 мкс может привести к тому, что Вы пропустите сильное изменение цены инструмента
и узнаете об это по сливу вашего депозита на данном инструменте или с большим опозданием войдете в тренд.
 
nikolz,
Цитата
Торговый робот - это система реального времени. Что это означает?
Это означает, лапуль, что "реальное время" у такого робота измеряется В СЕКУНДАХ, а не в МИЛЛИсекундах и не в МИКРОсекундах. У меня в мейне в бесконечном цикле стоит sleep (500), т.е. полусекундная задержка, но она сделана даже не для торговли - там достаточно и в разы большей, а лишь для того, чтобы пользователю реакция на его события (нажатие клавиш или клики мышкой) казалось практически мгновенной. Только для этого, лапуль! Но и с полусекундной задержкой такая система прекрасно успевает "обработать пришедшие данные до момента прихода новых". И не на ваших идиотских тестах, а в реальной торговле с десятками, сотнями и даже тысячами тикеров. И только клинический дебил может "мечтать о создании HFT робота" на Квике. Просто программировать надо уметь, лапуль, а не корчить из себя вяликого списилиста.
 
Добрый день,Всем!
Предлагаю вашему вниманию сравнение быстродействия различных способов получения параметров свечи.
------------------------
фрагменты тестируемых скриптов:
--------------------по документации-----------
Код
local tx=candel[m]; if tx==nil then tx={} candel[m]=tx; i=1; else i=#tx; end --таблица сделок по инструменту
local m1=0;
if tsoc[m]=="SBER" then
nklib.startA();
while count>=i do
nklib.start();
Ti=ds:T(i) O=ds:O(i); H=ds:H(ind); L=ds:L(i); C=ds:C(i); V=ds:V(i)
x=nklib.stop();
tx[i]={O,H,L,C,V,Ti}; i=i+1; m1=m1+1;
end
x1=nklib.stopA();
----------------передача в пул потоков--------------------
Код
local ev=nkevent.wait(event_Sber,0);
if ev==0 then
nklib.start();
nkevent.Res(event_Sber);
z=nkini.VMLua(pVMSber,"main",t,count);
x2=nklib.stop();
end

--фрагмент из скрипта отдельного потока
Код
nklib.startB();
local m=#candel; if m==0 then m=1 end
local m1=0;
while count>=m do
if PData==nil then PData,j=nkini.IniPData("ds"); end
O,H,L,C,V,T,x=nkini.GetData(m,PData);
candel[m]={O,H,L,C,V,T};
m=m+1;
m1=m1+1
end
======результат расчета в main =====================
count=484,x1=1948.1,x2=70.1
count=1,x1=239.1,x2=7.3
count=1,x1=66.5,x2=7.5
count=1,x1=59.6,x2=4.0
=======результат расчета в main потока ================
Sber,count=484,x1=1931.1
Sber,count=1,x1=146.6
Sber,count=1,x1=119.5
Sber,count=1,x1=9.5,
===============================  
итоги:
в первой сточке указано время для получения 484 свечей
x1- время затраченное на 484 свечи (~2 ms)
x2 -время затраченное на передачу задачи в поток(0.07 ms)
------------
Далее обработка одной новой свечи
x1=0.2 ms, x2=0.007 ms
=======
Из результатов теста видно, что время передачи задачи в поток примерно в 20 раз меньше, чем время расчета в функции MAIN.
---------------------------
Это время не зависит от сложности задачи.
---------------------------
т е чтобы запустить алгоритм любой сложности в потоке для любого инструмента потребуется не более 0.0001 секунды.
------------------------
При этом колбеки не дублируются и выполняют минимум работы - устанавливают событие и передают свои данные в MAIN
MAIN определяет текущую задачу и передает ее в свободный в пуле поток.
-----------------------  
 
и еще...
любая задача в потоке имеет доступ ко всем глобальным параметрам  основного потока и основной функции MAIN.
Время обращения к этой информации такое же.  
 
nikolz, Лично я давно достиг АБСОЛЮТНОГО быстродействия получения параметров свечи: 0.000 мкс! Ещё до того, как написал свой первый скрипт на Lua, я прекрасно знал, что вся эта "японская" дребедень АБСОЛЮТНО не нужна торговому роботу - он прекрасно умеет считать свечи сам, причём НОРМАЛЬНЫЕ свечи, а не эту хрень. И свечи ему нужны не только минутные (насколько я помню, это минимальный интервал из того, что вообще можно "получать"), и уже по этой причине "сравнение быстродействия" на ТАКИХ свечах есть клинический идиотизм. У нормальных программистов нет никаких проблем с быстродействием и на более лёгких свечах, причём не с чтением готовенького, посчитанного дядей Васей, а с самостоятельным расчётом свечей всех мастей и размеров. С самого начала мои свечи начинались с 15-секундных, но под "тлетворным влиянием Бориса" были заменены сначала на 7.5-секундные, а затем на 10-секундные. А всё остальное - это для любителей заниматься онанизмом, щеголяя при этом вумными словечками вроде "пул потоков" или "мьютексы".
 
К вопросу о скорости передачи по DDE
----------------------
Переписал сервер DDE для LUA 5.4.
----------------------  
Время передачи обезличенных сделок 16385 сделок по 8 параметров составляет 750 мкс.
===============
Переписал программу обращения к источнику данных ds.   Работает на 30% быстрее, чем исходная QLUA, но не быстрее DDE.
------------------------------
Время передачи 6 параметров свечи составляет 3 мкс,
=====================
Время передачи по  DDE 6 сделок по 8 параметров  составляет 0.3 мкс.
 
Теперь напишите функцию CalcBuySell, чтобы время её выполнения составляло единицы (на худой конец - десятки) микросекунд, а то у Арки не получается.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Теперь напишите функцию CalcBuySell, чтобы время её выполнения составляло единицы (на худой конец - десятки) микросекунд, а то у Арки не получается.
сделал тест (фрагмент)
Код
local is_buy=true;
local is_market=true;
nklib.startA();
local qty,comis=CalcBuySell(clas, sec,"1737","NL0011100043", 0, is_buy, is_market);
x1=nklib.stopA();
Log:write(tostring(sec)..",qty="..tostring(qty)..",comis="..tostring(comis)..","..",time(мкс)"..tostring(0.1*x1).."\n");Log:flush()

на демо сервере получилось:  
время расчета не более 0.0005 сек.
т е не более 500 микросекунд при расчете по рынку.
-----------------------------------------
AFLT,qty=4309,comis=487.23,,time(мкс)412.3
MOEX,qty=277,comis=203.15,,time(мкс)259.2
SBER,qty=876,comis=490.81,,time(мкс)333.9
AFLT,qty=4309,comis=487.23,,time(мкс)542.0
ROSN,qty=786,comis=207.33,,time(мкс)468.0
AFLT,qty=4309,comis=487.23,,time(мкс)459.4
AFLT,qty=4309,comis=487.23,,time(мкс)418.2
ROSN,qty=786,comis=207.33,,time(мкс)321.3
AFLT,qty=4309,comis=487.23,,time(мкс)344.7
AFLT,qty=4309,comis=487.23,,time(мкс)314.1
NVTK,qty=206,comis=204.82,,time(мкс)206.1
TATN,qty=648,comis=208.2,,time(мкс)188.9
AFLT,qty=4309,comis=487.23,,time(мкс)240.8
AFLT,qty=4309,comis=487.23,,time(мкс)515.5
LKOH,qty=210,comis=483.08,,time(мкс)434.5
AFLT,qty=4309,comis=487.23,,time(мкс)435.4
VTBR,qty=1558,comis=207.15,,time(мкс)562.9
AFKS,qty=528,comis=394.79,,time(мкс)296.8
MGNT,qty=80,comis=203.1,,time(мкс)206.1
ROSN,qty=786,comis=207.33,,time(мкс)204.5
AFLT,qty=4309,comis=487.23,,time(мкс)237.7
AFKS,qty=528,comis=394.79,,time(мкс)364.7
LKOH,qty=210,comis=483.08,,time(мкс)290.4
ROSN,qty=786,comis=207.33,,time(мкс)264.4
AFLT,qty=4309,comis=487.23,,time(мкс)288.6
 
есть еще функция

TABLE getBuySellInfo (STRING firm_id, STRING client_code, STRING  class_code, STRING sec_code, NUMBER price)

она считает купить и продать

вот результат  теста:

AFLT,buy_q=69184,sel_g==68444,price=25.44,,time(мкс)837.9

NLMK,buy_q=1684,sel_g==0,price=178.0,,time(мкс)487.5

AFLT,buy_q=69184,sel_g==68444,price=25.44,,time(мкс)483.4

AFKS,buy_q=66537,sel_g==66537,price=12.86,,time(мкс)684.2

SBER,buy_q=13398,sel_g==13384,price=131.37,,time(мкс)511.0

AFKS,buy_q=66537,sel_g==66358,price=12.86,,time(мкс)596.0

PHOR,buy_q=43,sel_g==0,price=6895.0,,time(мкс)474.2

AFLT,buy_q=69184,sel_g==68444,price=25.44,,time(мкс)447.3

VTBR,buy_q=17060775,sel_g==0,price=0.01757,,time(мкс)482.7

AFLT,buy_q=69184,sel_g==68444,price=25.44,,time(мкс)657.4

VTBR,buy_q=17065631,sel_g==0,price=0.017565,,time(мкс)348.6

AFLT,buy_q=69184,sel_g==68444,price=25.44,,time(мкс)415.5

 
О, Господи! Опять это стадо микросекунды ловит...  :cry:  
 
Цитата
Старатель написал:
Теперь напишите функцию CalcBuySell, чтобы время её выполнения составляло единицы (на худой конец - десятки) микросекунд, а то у Арки не получается.
если  вместо CalcBuySell  считать по параметрам портфеля и инструмента, то получится примерно в 2 раза быстрее.
результат теста:
AFLT,money=299983,lot=10,qty=1138,price=26.28,comis=749,,time(мкс)213.1
GAZP,money=299983,lot=10,qty=124,price=240.2,comis=749,,time(мкс)174.3
MOEX,money=299983,lot=10,qty=309,price=96.68,comis=749,,time(мкс)124.6
SBER,money=299983,lot=10,qty=227,price=131.35,comis=749,,time(мкс)171.2
AFLT,money=299983,lot=10,qty=1138,price=26.28,comis=749,,time(мкс)384.6
GAZP,money=299983,lot=10,qty=124,price=240.08,comis=749,,time(мкс)144.3
NVTK,money=299983,lot=1,qty=221,price=1349.0,comis=749,,time(мкс)139.0
ROSN,money=299983,lot=1,qty=832,price=359.5,comis=749,,time(мкс)101.5
SBER,money=299983,lot=10,qty=227,price=131.35,comis=749,,time(мкс)136.4
AFLT,money=299983,lot=10,qty=1138,price=26.28,comis=749,,time(мкс)294.6
LKOH,money=299983,lot=1,qty=55,price=5370.0,comis=749,,time(мкс)195.8
MOEX,money=299983,lot=10,qty=309,price=96.68,comis=749,,time(мкс)198.0
SBER,money=299983,lot=10,qty=227,price=131.36,comis=749,,time(мкс)186.5
AFLT,money=299983,lot=10,qty=1138,price=26.28,comis=749,,time(мкс)239.0
IRAO,money=299983,lot=100,qty=1306,price=2.2895,comis=749,,time(мкс)116.6
MAGN,money=299983,lot=10,qty=650,price=46.0,comis=749,,time(мкс)150.9
SBER,money=299983,lot=10,qty=227,price=131.4,comis=749,,time(мкс)117.3
 
Цитата
Старатель написал:
Теперь напишите функцию CalcBuySell, чтобы время её выполнения составляло единицы (на худой конец - десятки) микросекунд, а то у Арки не получается.
вычисления без этой функции можно ускорить, если запомнить размер лота и не извлекать его из хранилища
а также не извлекать размер свободных денежных средств а рассчитывать их при совершении сделки и иногда сверять с портфелем.
-----------------  
результат теста  для этого варианта позволяет  укорить рассчеты примерно в 10..20  раз.
AFLT,money=299983,lot=10,qty=1136,price=26.32,comis=749,,time(мкс)39.7
DSKY,money=299983,lot=10,qty=399,price=74.88,comis=749,,time(мкс)38.8
PHOR,money=299983,lot=1,qty=43,price=6900.0,comis=749,,time(мкс)12.7
SBER,money=299983,lot=10,qty=227,price=131.43,comis=749,,time(мкс)38.7
AFLT,money=299983,lot=10,qty=1136,price=26.32,comis=749,,time(мкс)20.3
LKOH,money=299983,lot=1,qty=56,price=5332.5,comis=749,,time(мкс)17.3
RUAL,money=299983,lot=10,qty=449,price=66.5,comis=749,,time(мкс)17.5
TATN,money=299983,lot=1,qty=706,price=423.5,comis=749,,time(мкс)14.5
AFLT,money=299983,lot=10,qty=1136,price=26.32,comis=749,,time(мкс)14.8
LKOH,money=299983,lot=1,qty=56,price=5320.5,comis=749,,time(мкс)13.7
SBER,money=299983,lot=10,qty=227,price=131.43,comis=749,,time(мкс)20.9
AFLT,money=299983,lot=10,qty=1136,price=26.32,comis=749,,time(мкс)84.9
LKOH,money=299983,lot=1,qty=56,price=5320.5,comis=749,,time(мкс)81.3
ROSN,money=299983,lot=1,qty=831,price=360.0,comis=749,,time(мкс)22.5
SBER,money=299983,lot=10,qty=227,price=131.43,comis=749,,time(мкс)27.2
 
Цитата
nikolz написал:
вычисления без этой функции можно ускорить, если запомнить размер лота и не извлекать его из хранилища
а также не извлекать размер свободных денежных средств а рассчитывать их при совершении сделки и иногда сверять с портфелем.
Чтобы поделить количество свободных денежных средств на цену действительно не нужна никакая функция.
Но существует такая вещь, как маржинальная торговля. Есть бумаги разного типа: маржинальные/не маржинальные, принимаемые и не принимаемые в в обеспечение маржинального кредита и пр.
Почитайте, узнаете много интересного.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Но существует такая вещь, как маржинальная торговля. Есть бумаги разного типа: маржинальные/не маржинальные
А еще есть комиссия. Которая не всегда просто процент от суммы сделки.
 
Ещё один из редчайших случаев, когда я согласен с nikolz.  :smile: Не с его дурацкой ловлей микросекунд, разумеется, а с "запомнить размер лота" (у меня он-таки "извлекается из хранилища", но один раз на тикер при запуске скрипта), а также с "не извлекать размер свободных денежных средств а рассчитывать их при совершении сделки и иногда сверять с портфелем" - именно так происходит и у меня, хотя программная сверка давно уже перестала работать. Лично мне всегда было плевать на комиссию (хотя в последнее время "под влиянием Бориса" я стал её учитывать), равно как и на дивиденды (у одного из моих брокеров они капают прямо на брокерский счёт, у другого на карту), пару месяцев побаловался с маржинальной торговлей - чисто для эксперимента, пришёл к выводу, что мне она нафиг не нужна. Но во всех этих случаях именно сверка свободных средств автоматически учитывает все эти удержания и поступления, считает это дело сам брокер, а у моего скрипта и других задач выше крыши. Единственное, что учитывается алгоритмом - это минимальная прибыль при закрытии позиций, чтобы она гарантированно была в разы больше очень грубо, "с запасом" посчитанной комиссии за сделки.
 
Цитата
Старатель написал:
Цитата
nikolz написал:
вычисления без этой функции можно ускорить, если запомнить размер лота и не извлекать его из хранилища
а также не извлекать размер свободных денежных средств а рассчитывать их при совершении сделки и иногда сверять с портфелем.
Чтобы поделить количество свободных денежных средств на цену действительно не нужна никакая функция.
Но существует такая вещь, как маржинальная торговля. Есть бумаги разного типа: маржинальные/не маржинальные, принимаемые и не принимаемые в в обеспечение маржинального кредита и пр.
Почитайте, узнаете много интересного.
Я это знаю, но торгую лишь ликвидом, которые принимают. Поэтому такой проблемы нет.  
При расчете количества учитываю плечо.
--------------------
Обратил внимание, что эта функция в некоторых случаях дает завышенные результаты.
Как это объяснить не знаю.
 
Цитата
nikolz написал:
Обратите внимание на то, что далее время сервера не изменяется еще 9 значений.
При этом время вызова колбека составляет не более 100 мкс, т е 0.0001 сек
----------------------------
что же это означает.
Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета

Это означает, что время сервера меняется с дискретностью 1 секунда. Т.о., с какой бы частотой мы не получили пакеты в течение 1 секунды, для них всех время сервера будет одинаковым.
Делать какие-либо измерения в микросекундах на основе величины, шаг цены которой 1 секунда, - величайшая глупость.
 
Цитата
nikolz написал:
Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета,
Потом этот пакет пересылается нам в колбеки.
В итоге вам кажется, что вы получаете данные в реальном времени, а в действительности с задержкой на 0.7 секунды.
В реальных торгах задержка возможно и меньше, но передачу пакетом никто не отменял.

По моему опыту мне кажется, что данные я получаю чаще, чем один раз в 0.7 секунды.
Но, как говорится, частота получения данных и задержка - это две большие разницы.
В реальных торгах задержка может достигать нескольких секунд или более. Хоть получать вы можете данные с высокой частотой, но это будут "старые" данные с большой задержкой.
 
Цитата
r написал:
Цитата
nikolz написал:
Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета,
Потом этот пакет пересылается нам в колбеки.
В итоге вам кажется, что вы получаете данные в реальном времени, а в действительности с задержкой на 0.7 секунды.
В реальных торгах задержка возможно и меньше, но передачу пакетом никто не отменял.

По моему опыту мне кажется, что данные я получаю чаще, чем один раз в 0.7 секунды.
Но, как говорится, частота получения данных и задержка - это две большие разницы.
В реальных торгах задержка может достигать нескольких секунд или более. Хоть получать вы можете данные с высокой частотой, но это будут "старые" данные с большой задержкой.
У меня данные с сервера приходят с задержкой 0.03 сек - это задержка канала связи (смотрим  в информационном окне терминала QUIK в расширенном режиме) .
-----------------------------------
Но как быстро обновляются данные в пакетах среза - это вопрос открытый.
----------------------------------
Ранее встречал информацию, что биржа рассылает широковещательно информацию с интервалом 0.5 сек.
=================  
При большой очереди к серверу брокера задержка реакции на транзакцию может составить и секунды.
------------------------
Сами разработчики QUIK сообщали ранее, что скорость обслуживания транзакции сервером QUIK составляет 0.001 сек.
==============  
Пример задержки реакции сервера брокера на транзакцию клиента.
-----------------------
У известного брокера число клиентов 800 тысяч.
Предположим, у него 100 серверов.
Предположим, что все клиенты выставляют заявки.
В среднем на каждом сервере будет очередь 8000.  
-----------------------------------------
Последний в очереди будет стоять в очереди 8 секунд.
 
nikolz, Чушь полная.

1. Вероятность того, что все клиенты одновременно выставляют заявки РАВНА нулю.

2. Даже в этом случае данные от клиентов обрабатываются последовательно, и очередь (системная) одна: даже просто для того, чтобы раскидать пакеты по серверам, нужно принимать какие-то решения на уровне диспетчера, даже если эти решения принимаются на аппаратном уровне.

3. Заявка клиента будет стоять в очереди до тех пор, пока не будет исполнена или снята, а никакие не "8 секунд". Если же под "заявкой" подразумевается любая транзакция, то время её обработки наверняка будет зависеть от её вида.

4. Брокер, у которого столько клиентов, не может быть стеснён в деньгах по определению, и с радостью расширит свою пропускную способность до любых требуемых величин. Возможно даже, он часть заявок своих клиентов замкнёт друг на друга у себя, связываясь с биржей лишь в остальных случаях.

5. В любом случае "реальное время" у робота на клиенте нужно измерять В СЕКУНДАХ, а не в МИЛЛИсекундах и не в МИКРОсекундах. Dixi.
 
Цитата
Владимир написал:
nikolz, Чушь полная.

1. Вероятность того, что все клиенты одновременно выставляют заявки РАВНА нулю.

2. Даже в этом случае данные от клиентов обрабатываются последовательно, и очередь (системная) одна: даже просто для того, чтобы раскидать пакеты по серверам, нужно принимать какие-то решения на уровне диспетчера, даже если эти решения принимаются на аппаратном уровне.

3. Заявка клиента будет стоять в очереди до тех пор, пока не будет исполнена или снята, а никакие не "8 секунд". Если же под "заявкой" подразумевается любая транзакция, то время её обработки наверняка будет зависеть от её вида.

4. Брокер, у которого столько клиентов, не может быть стеснён в деньгах по определению, и с радостью расширит свою пропускную способность до любых требуемых величин. Возможно даже, он часть заявок своих клиентов замкнёт друг на друга у себя, связываясь с биржей лишь в остальных случаях.

5. В любом случае "реальное время" у робота на клиенте нужно измерять В СЕКУНДАХ, а не в МИЛЛИсекундах и не в МИКРОсекундах. Dixi.
Владимир,
----------------  
Я хотя бы привожу свое со ссылкой на числовые данные доступные на отчетах конференций разработчиков QUIK.
Вы же голословно рассуждаете.
-----------------------
Все Ваши домыслы полная хрень.
-------------------------
Вот лишь доказательство  этого  п.4:
----------------
По существу замечу следующее (читайте ФЗ "о рынке ЦБ" и ГК РФ)
----------------  
Брокер не имеет право замыкать сделки между клиентами, если они не дали согласие на внебиржевые сделки.
Но и в этом случае  клиенты должны подать соответствующие поручения.
-----------------
Остальные пункты даже критиковать не буду. Мало ли что на заборе пишут.
 
Цитата
nikolz написал:
[QUOTE]nikolz написал:
У меня данные с сервера приходят с задержкой 0.03 сек - это задержка канала связи (смотрим  в информационном окне терминала QUIK в расширенном режиме) .

Учитывать надо общую задержку с момента отправки данных с биржи до момента получения их клиентом. И тут могут быть секунды и десятки секунд.
Это как радоваться, что почтальон вам доставил посылку из регионального отделения почты за один день, в то время как в самом отделении до этого её месяц не могли найти ))
 
nikolz, АХХХРЕНИТЕЛЬНЫЕ "числовые данные", лапуль! Предположим, что 800 000 клиентов, предположим, что 100 серверов, предположим, что все одновременно заявки послали. Что ни предположение, то БСК.

Вот именно: мало ли что на заборе пишут. В смысле, в ФЗ. :smile:

В любом случае "реальное время" у робота на клиенте нужно измерять В СЕКУНДАХ, а не в МИЛЛИсекундах и не в МИКРОсекундах.  Шурупен зи?
 
Расскажу Вам об одном заблуждении,
которое бытует не столько у чайников, как  у  профи, ваяющих роботов на луа.
--------------  
Постановка задачи :
---------------------
Есть инструмент X и его параметр  P.
Надо сделать таблицу инструментов и их параметров.
Периодически надо искать параметры конкретного инструмента  X в этой таблице.
------------------
Вопрос:
Как  быстрее сделать поиск нужного элемента таблицы.
-----------------------
есть как минимум два способа организации таблицы
-------------
Вариант 1 использовании хэш индексов.
В этом случае для записи параметра P  инструмента X  таблицу  T,  пишем  T[X]=P , чтобы прочитать параметр P надо записать P=T[X]
----------------------------------
Вариант 2  -любимый тех писателей роботов, которые плохо  знают  луа, но писали на других языках программирования.
В этом случае используем два индексных массива  T1 и T2, в которых под одинаковыми номерами j пишем T1[j]=X; T2[j]=P
=============
Теперь для поиска параметра P элемента X во втором варианте надо перебрать в цикле по индексу массив T1 и найти X
потом по этому индексу прочитать параметр из массива T2
===========
Какой вариант быстрее?
Давайте сравним на следующем тесте:
------------
заполняем три массива
Код
local t,t1,t2={},{},{}
local N=1000
for i=1,N do local x="a"..i; local x1="b"..i; t[i]=x; t1[i]=x1;   t2[x]=x1 end
считаем время по первому варианту:
Код
 local Tm1=0;
for i=1,N do local x="a"..i;
nklib.startA();
local s=t2[x];
 Tm1=Tm1+nklib.stopA();
 end
 print(0.1*Tm1);
считаем время по второму варианту :
Код
local Tm2=0;
for i=1,N do local j; local x="a"..i;
nklib.startA();
 for n=1,N do if t[n]==x then j=i; break end end
 local s=t1[j];
 Tm2=Tm2+nklib.stopA();
 end
  print(0.1*Tm2);
print(Tm2/Tm1)
Результат:

Вариант 1:  58 мкс
Вариант 2: 8027 мкс
------------------  
Резюме:    Вариант 2 в 138 раз медленнее, чем Вариант 1.
 
В качестве информации и для сравнения,
выкладываю время работы колбеков и main скрипта на тестовом сервере QUIK.
---------------------
В данном тесте  роботу задана работа по 36 инструментам.
----------------------------------
При получении колбека onParam по инструменту,
робот вычисляет свечи 4 таймов,
снимает ранее выставленную заявку
и выставляет новую.
и так далее
----------------------------
В приведенной ниже таблице результата обозначено:
_tk -время main ;
если указан инструмент,
то это время получения свечей 1 минута и формирование на их основе свечей 5 мин 30 мин и 1 день.
Время колбеков содержит их имя.

--------------------------------
Скрытый текст
 
таблица не очень
поэтому повторю ее еще раз:
Код
_tk(us)=1.2
SBER(us)=3089.9
__tk(us)=3124.1
TransReply t(us)=2.3
Order t(us)=6.3
TransReply t(us)=0.9
Order t(us)=5.0
SBER(us)=165.5
__tk(us)=199.4
Order t(us)=3.3
Order t(us)=2.6
__tk(us)=1.4
__tk(us)=1.3
__tk(us)=11.1
SBER(us)=182.7
__tk(us)=221.2
FLOT(us)=3879.5
__tk(us)=3916.3
TransReply t(us)=7.2
__tk(us)=119.8
FLOT(us)=547.5
__tk(us)=587.2
Order t(us)=11.5
Order t(us)=9.0
LKOH(us)=4958.5
__tk(us)=3586.8
__tk(us)=2.1
__tk(us)=0.9
TransReply t(us)=7.2
TransReply t(us)=1.1
Order t(us)=3.4
FLOT(us)=224.7
__tk(us)=397.8
LKOH(us)=540.6
__tk(us)=687.2
Order t(us)=6.2
Order t(us)=2.7
Order t(us)=2.4
__tk(us)=1.6
__tk(us)=1.4
SBER(us)=190.5
__tk(us)=223.0
__tk(us)=0.9
SBER(us)=199.9
__tk(us)=344.4
__tk(us)=0.9
SBER(us)=224.4
__tk(us)=268.7
SBER(us)=217.0
__tk(us)=255.2
SBER(us)=223.6
__tk(us)=263.0
__tk(us)=1.1
LKOH(us)=362.7
__tk(us)=406.7
SBER(us)=216.2
__tk(us)=236.4
__tk(us)=1.0
CHMF(us)=4883.2
__tk(us)=4917.7
TransReply t(us)=7.9
__tk(us)=2.1
__tk(us)=1.6
CHMF(us)=733.1
__tk(us)=774.4
SBER(us)=169.0
__tk(us)=185.8
Order t(us)=3.3
Order t(us)=2.4
TransReply t(us)=2.7
Order t(us)=3.8
CHMF(us)=614.0
__tk(us)=834.3
RNFT(us)=3410.1
__tk(us)=3447.4
Order t(us)=8.0
__tk(us)=1.8
__tk(us)=11.0
TransReply t(us)=10.4
TransReply t(us)=2.3
__tk(us)=2.3
__tk(us)=1.6
__tk(us)=1.4
__tk(us)=1.4
CHMF(us)=482.3
__tk(us)=660.0
RNFT(us)=441.2
__tk(us)=459.7
__tk(us)=0.9
Order t(us)=3.6
Order t(us)=2.9
Order t(us)=2.8
Order t(us)=2.8
TransReply t(us)=2.9
__tk(us)=1.8
TransReply t(us)=1.6
Order t(us)=3.3
CHMF(us)=620.0
__tk(us)=797.2
SBER(us)=187.0
__tk(us)=208.0
__tk(us)=1.0
Order t(us)=3.8
Order t(us)=3.1
Order t(us)=2.9
__tk(us)=1.9
__tk(us)=1.6
TransReply t(us)=6.9
__tk(us)=2.4
__tk(us)=1.8
AFKS(us)=3926.4
__tk(us)=3960.6
Order t(us)=5.9
Order t(us)=2.4
TransReply t(us)=8.5
__tk(us)=1.8
AFKS(us)=501.9
__tk(us)=538.4
LKOH(us)=163.5
__tk(us)=183.6
SBER(us)=159.5
__tk(us)=180.2
__tk(us)=1.1
Order t(us)=4.2
Order t(us)=3.2
TransReply t(us)=3.7
Order t(us)=4.2
AFKS(us)=348.4
__tk(us)=524.3
Order t(us)=5.0
SGZH(us)=4205.9
__tk(us)=3090.5
__tk(us)=1.9
__tk(us)=0.7
TransReply t(us)=5.9
TransReply t(us)=2.2
Order t(us)=4.3
AFKS(us)=503.0
__tk(us)=605.1
MRKV(us)=1123.5
__tk(us)=1239.7
__tk(us)=1.0
Order t(us)=3.7
Order t(us)=3.1
Order t(us)=2.7
__tk(us)=1.9
__tk(us)=1.6
__tk(us)=1.8
TransReply t(us)=11.4
TransReply t(us)=1.7
__tk(us)=2.3
__tk(us)=1.4
AFKS(us)=440.4
__tk(us)=600.9
SBER(us)=138.8
__tk(us)=158.4
__tk(us)=0.9
Order t(us)=6.9
Order t(us)=3.1
Order t(us)=2.8
Order t(us)=2.7
__tk(us)=2.2
TransReply t(us)=11.2
AFKS(us)=629.5
__tk(us)=663.4
SBER(us)=131.6
__tk(us)=214.6
Order t(us)=3.3
Order t(us)=2.5
TransReply t(us)=3.8
Order t(us)=3.6
AFKS(us)=498.4
__tk(us)=624.5
SBER(us)=99.7
__tk(us)=111.3
Order t(us)=8.7
SNGS(us)=3741.5
__tk(us)=2769.7
TransReply t(us)=8.1
TransReply t(us)=1.1
__tk(us)=1.8
__tk(us)=1.3
__tk(us)=1.3
AFKS(us)=582.5
__tk(us)=733.9
Order t(us)=4.7
Order t(us)=5.1
Order t(us)=4.0
SNGS(us)=2139.4
Order t(us)=3.8
__tk(us)=19.6
TransReply t(us)=3.8
__tk(us)=2.4
TransReply t(us)=1.9
Order t(us)=6.5
AFKS(us)=458.8
__tk(us)=650.8
ROSN(us)=4161.7
__tk(us)=4191.7
Order t(us)=8.0
Order t(us)=4.3
Order t(us)=3.2
__tk(us)=2.2
TransReply t(us)=2.5
__tk(us)=2.5
TransReply t(us)=2.0
Order t(us)=4.2
AFKS(us)=642.0
__tk(us)=825.9
__tk(us)=1.3
Order t(us)=3.3
Order t(us)=3.0
Order t(us)=2.6
__tk(us)=1.7
__tk(us)=1.3
TransReply t(us)=11.8
__tk(us)=2.9
AFKS(us)=584.2
__tk(us)=623.6
SBER(us)=140.5
__tk(us)=154.1
Order t(us)=4.2
Order t(us)=3.0
TransReply t(us)=4.7
Order t(us)=6.7
 
nikolz, Лапуль, сколько раз можно повторять, что Вы и есть самый натуральный, без подмесу, чайник? И что профессионалу почти всё равно, на каком языке писать - была бы обеспечена требуемая функциональность.

Как всегда, уже постановка задачи бездарная до невозможности:

Есть ГРУППА инструментов X и их параметров P, причём набор параметров для разных инструментов и/или их классов может различаться и в таблицу не влезать - только в ГРУППУ таблиц. А "искать параметры конкретного инструмента X в этой таблице" нужно только В ИСКЛЮЧИТЕЛЬНЫХ случаях - при нормальной организации должно быть и так известно, где они лежат.
Цитата
Вопрос:
Как  быстрее сделать поиск нужного элемента таблицы.
Ответ: обратиться к нему по имени (лучше по индексу). А всю остальную бредятину выбросить на помойку. И тогда значение любого параметра просто достаётся из этой таблицы: V=T[X][P][a][b][c]

Да, бывает и так, что используется НЕСКОЛЬКО индексных массивов, в которых под одинаковыми номерами j пишем некие данные. Например, у меня аж ВОСЕМЬ таких массивов по ДЕВЯТИ таймфреймам для каждого из пары-тройки сотен или тысяч обслуживаемых инструментов. Это свечи (накапливаемые, последние и предпоследние), ранги скоростей движения курса, количество сделанных ставок на каждом таймфрейме и ещё кое-что. И обращение к ним одинаковое, лапуль, тупее не придумаешь. Например, в ячейке a[i][1][4][j] лежит размер массива сделанных ставок по i-му тикеру на j-м таймфрейме. И искать ничего не надо, подходи и бери. А криворукие бездари пущай перебирают в цикле свои "вариант 1" и "вариант 2" - что с них взять, кроме анализа?
 
Информация к размышлению.
Всем известна  рекомендация не делать ничего в колбеках, а переносить все в main.
--------------------------
Но не все то золото, что рекомендуют.
===============
проведем эксперимент.
Колбек AllTrade
обработка данных выполняется так:
Код
local clas=t.class_code;
local sec=t.sec_code;
local t1=Data[clas]; if t1==nil  then t1={}; Data=t1 end
local t2=t1[sec] if t2==nil then t2={} t1[sec]=t2 end
t2[#t2+1]={t.trade_num,t.flags,t.price,t.qty,t.value};
Рассмотрим два варианта
-----------------
В первом случае все делаем в колбеке.
-------------------
В результате получаем  время исполнения (мкс)
Код
AllTrade(us)=2.6,SiM2
AllTrade(us)=1.7,BRM2
AllTrade(us)=2.6,SiM2
AllTrade(us)=2.6,RIM2
AllTrade(us)=1.9,SiM2
AllTrade(us)=3.0,BRM2
Во втором случае те же действия делаем в main.
------------------
В результате получаем:
Код
AllTrade(us)=319.2,SBER
AllTrade(us)=318.0,SBER
AllTrade(us)=335.8,SBER
AllTrade(us)=319.8,ALRS
AllTrade(us)=280.9,SBER
AllTrade(us)=395.5,SiM2
AllTrade(us)=428.8,SiM2
Таким образом,
-------------------
в колбеке  3,
в main   430.

.
 
nikolz, Не просто "всем известна  рекомендация не делать ничего в колбеках, а переносить все в main", а известна она, как минимум, полвека. И не надо проводить никаких экспериментов - абсолютно очевидно, что прерывания происходят в случайные, непредсказуемые моменты времени, а потому следует оттуда уматывать как можно быстрее - хотя бы для того, чтобы одно прерывание не столкнулось с другим. Я не знаю, что такое "колбек AllTrade" - может, OnAllTrade? Так он нафиг не нужен. А если OnTrade - так это единственный коллбек, который я использую. И вот как раз для него я и завёл третий стек, и как раз с целью разгрузить обработчик и вынести всё в main. Потому как обработка там не чета Вашему убогому
"эксперименту" - там требуется: а) проверить, не дубль ли это (прерывания от Квика приходят целой колодой, причём вразнобой), а это уже сама по себе операция нетривиальная и довольно дорогая - прерывания могут приходить вперемешку по разным тикерам, разным заявкам одного тикера, разным сделкам по одной заявке. И всё это "в трёх экземплярах". А ещё неплохо бы определить, наша это заявка или левая (может, юзер руками что-то купил/продал, может, другой скрипт). А потом не хило бы узнать, что это такое: покупка или продажа, открывающая сделка или закрывающая, лонговая или шортовая, на рубли или на доллары, прибыльная или убыточная (для закрывающих), какая взята комиссия брокера и биржи. А затем неплохо бы откорректировать данные портфеля и кошелька, разобраться с зарезервированной наличностью (если деньги резервировались) и, возможно, что-то сообщить пользователю. Это отнюдь не код Вашего сраного "эксперимента" - это НАМНОГО более трудоёмкие операции!
Страницы: 1
Читают тему
Наверх