В этом примере куча алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main
Konstantin написал: Вот этот пример из PDF "Использование Lua в Рабочем месте Quik" (пункт 2 "Взаимодействие потоков Lua скрипта") вешает терминал. Что я делаю не так
поясню в чем проблема. В данном примере все колбеки записывают свою информацию в таблицу. Функция main обрабатывает первую запись этой таблицы в функции ProcessingCallbakc потом удаляет эту запись и обрабатывает следующую При этом в функции ProcessingCallbakc есть sleep(3000) т е после обработки каждой записи спим 3 секунды Выше я привел данные по скорости работы колшбеков примерно 3 мкс за время сна 3 секунды в таблицу которую орабатывает main успеет записаться 1000 строк из колбеков Поэтому и зависает ------------------- Это очень плохой пример. в нем не только плохо сделана работа с колбеками но и используется удаление строк ирз таблицы что вызывает сдвиг всех строк - это очень медленно так как у Вас в этой таблице уже строк 1000 -------------------- Короче это пример как нельзя писать скрипт. Какой-то дебил написал этот примаер.
Владимир написал: nikolz, Использование sleep - ЛУЧШЕЕ решение! Простое, отлаженное, работающее, эффективное. Не sleep (1), конечно, а sleep (500). Использовать меньшие задержки в скриптах для торговли не вижу ни малейшего смысла. А если нет диалога, то и вообще sleep (1000).
Владимир, Сможете как-то обосновать Ваше решение лучшего выбора sleep и и величины 500 ms? ------------------------ Раньше Вы писали, что торгуете по 1000 инструментам. Тогда поясните сколько времени уйдет на обработку изменений цены инструмента, если на один инструмент Вы тратите не менее 0.5 секунды сна + время обработки? ------------------------
относительно sleep. ------------------------------------- например вот время реакции колбеков и main. колбеки вызываются каждые 2- 5 мкс. Sleep (1) даст задержку на 1000 и более мкс. Вот и посчитайте сколько сигналов изменения цены инструмента Вы пропустите с таким сном.
Kalmar написал: Я спросил что значит "мониторы не связаны в единое пространство"?
чтобы второй монитор не был продолжением рабочего стола (пространства) первого монитора , то есть, чтобы на 2-й не могли попадать окна от программ, за исключением терминала Quik..Пусть Quik выводит излбражение только на 2-й монитор, а остальные программы только на 1-й
возможно так в Windows?.
А для манипулятора мышь, желательна возможность работы с мониторами 1 и 2.
У меня так и работает уже лет ...дцать. Поместите окно квика на второй монитор и щелкните в правом углу окна терминала - во весь экран Будет ровно на весь второй монитор. На первом также делайте для программ на тервом.
Anton Belonogov написал: Konstantin, добрый день. Такое поведение связано с особенностями работы Lua-машины: при использовании бесконечных циклов в скрипте необходимо вносить небольшую задержку, иначе возникают зависания. Таким образом, для корректной работы данного скрипта в цикл while в теле функции main нужно добавить функцию sleep :
Код
function main ()
while is_run do
if # MAIN_QUEUE > 0 then
ProcessingCallbakc(MAIN_QUEUE[ 1 ])
table.sremove (MAIN_QUEUE, 1 )
message ( "Размер очереди " .. tostring( # MAIN_QUEUE))
end
sleep ( 1 )
end
end
В примере уже есть sleep на 3 секунды куда еще и зачем?
если комп с несколькими ядрами, то ничего не вешает. --------------------- Я использую системные события для синхронизации потоков. ------------------------- Без синхронизации загрузка процессора 33% с синхронизацией 1-5%. --------------------- Использование sleep не лучшее решение. -------------------------- Проще и лучше, если не используете системное событие , использовать флаги.
В качестве информации и для сравнения, выкладываю время работы колбеков и main скрипта на тестовом сервере QUIK. --------------------- В данном тесте роботу задана работа по 36 инструментам. ---------------------------------- При получении колбека onParam по инструменту, робот вычисляет свечи 4 таймов, снимает ранее выставленную заявку и выставляет новую. и так далее ---------------------------- В приведенной ниже таблице результата обозначено: _tk -время main ; если указан инструмент, то это время получения свечей 1 минута и формирование на их основе свечей 5 мин 30 мин и 1 день. Время колбеков содержит их имя.
Nikolay написал: Прямо сейчас наблюдаю такую картину. Время сервера отстает на минуту от текущего времени (оно синхронизировано и корректно). При этом время последней сделки на минуту впереди времени сервера и близко к правильному текущему времени, т.е. тоже опережает время сервера.
Я могу понять, что это проблема брокера (Сбербанк), но с какой стати время сделки в будущем относительно времени сервера брокера и времени пакета? Т.е. я понимаю, что время сделки просто транслирует биржа, но серверная часть должна же не просто транслировать, но и как-то контролировать, что она транслирует.
сервер брокера никак не контролирует то, что транслирует с биржи. его задача работать со заявками клиентов, проверять достаточность средств и формат заявок и отправлять их на сервер биржи. время сервера иногда гуляет относительно времени биржи.
Расскажу Вам об одном заблуждении, которое бытует не столько у чайников, как у профи, ваяющих роботов на луа. -------------- Постановка задачи : --------------------- Есть инструмент 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.
1. Вероятность того, что все клиенты одновременно выставляют заявки РАВНА нулю.
2. Даже в этом случае данные от клиентов обрабатываются последовательно, и очередь (системная) одна: даже просто для того, чтобы раскидать пакеты по серверам, нужно принимать какие-то решения на уровне диспетчера, даже если эти решения принимаются на аппаратном уровне.
3. Заявка клиента будет стоять в очереди до тех пор, пока не будет исполнена или снята, а никакие не "8 секунд". Если же под "заявкой" подразумевается любая транзакция, то время её обработки наверняка будет зависеть от её вида.
4. Брокер, у которого столько клиентов, не может быть стеснён в деньгах по определению, и с радостью расширит свою пропускную способность до любых требуемых величин. Возможно даже, он часть заявок своих клиентов замкнёт друг на друга у себя, связываясь с биржей лишь в остальных случаях.
5. В любом случае "реальное время" у робота на клиенте нужно измерять В СЕКУНДАХ, а не в МИЛЛИсекундах и не в МИКРОсекундах. Dixi.
Владимир, ---------------- Я хотя бы привожу свое со ссылкой на числовые данные доступные на отчетах конференций разработчиков QUIK. Вы же голословно рассуждаете. ----------------------- Все Ваши домыслы полная хрень. ------------------------- Вот лишь доказательство этого п.4: ---------------- По существу замечу следующее (читайте ФЗ "о рынке ЦБ" и ГК РФ) ---------------- Брокер не имеет право замыкать сделки между клиентами, если они не дали согласие на внебиржевые сделки. Но и в этом случае клиенты должны подать соответствующие поручения. ----------------- Остальные пункты даже критиковать не буду. Мало ли что на заборе пишут.
пишите значения индикатора в массив и читайте со смещением ------------------ Пример: local t={ } ----- local x=indicator(i) ---------------------- if x then t[i]=x else if #t>0 then t[i]=t[i-1] end end -- если значения нет, то пишем предыдущее значение ------------------- local M=#t; local x1; if M>0 then x1=t[M-1] end --читаем предыдущее значение ------------------- local x2; if M>01 then x1=tM-2] end --читаем предпредыдущее значение
nikolz написал: Это означает, что данные мы получаем не чаще чем один раз в 0.7 секунды в виде пакета, Потом этот пакет пересылается нам в колбеки. В итоге вам кажется, что вы получаете данные в реальном времени, а в действительности с задержкой на 0.7 секунды. В реальных торгах задержка возможно и меньше, но передачу пакетом никто не отменял.
По моему опыту мне кажется, что данные я получаю чаще, чем один раз в 0.7 секунды. Но, как говорится, частота получения данных и задержка - это две большие разницы. В реальных торгах задержка может достигать нескольких секунд или более. Хоть получать вы можете данные с высокой частотой, но это будут "старые" данные с большой задержкой.
У меня данные с сервера приходят с задержкой 0.03 сек - это задержка канала связи (смотрим в информационном окне терминала QUIK в расширенном режиме) . ----------------------------------- Но как быстро обновляются данные в пакетах среза - это вопрос открытый. ---------------------------------- Ранее встречал информацию, что биржа рассылает широковещательно информацию с интервалом 0.5 сек. ================= При большой очереди к серверу брокера задержка реакции на транзакцию может составить и секунды. ------------------------ Сами разработчики QUIK сообщали ранее, что скорость обслуживания транзакции сервером QUIK составляет 0.001 сек. ============== Пример задержки реакции сервера брокера на транзакцию клиента. ----------------------- У известного брокера число клиентов 800 тысяч. Предположим, у него 100 серверов. Предположим, что все клиенты выставляют заявки. В среднем на каждом сервере будет очередь 8000. ----------------------------------------- Последний в очереди будет стоять в очереди 8 секунд.
TWS - это терминал как и QUIK Терминал к терминалу подключать смысла нет. ---------------------------- Вам надо терминал QUIK подключать к серверу TWS. Но это вам не дадут сделать разработчики QUIK ------------------------ Если Вы хотите сделать робота для TWS то для этого их API - аналог QLUA в терминале QUIK ---------------------
Алексей написал: Здравствуйте, почитал пост но все равно не разобрался. Помогите пожалуйста. Оставлял тейк профит заявку на покупку одного лота AGRO по цене 865 отступ и спред стояли 0,стояла галочка "купить по рыночной цене" в итоге цена пришла на 864 заявка висит как исполнена но лот не купился. Указано "Не прошла контроль лимитов" Если не сложно покажите на примере какие параметры заявки тейк профит на покупку должны стоять если я хочу взять 1 лот по цене 865. Заранее спасибо
У Вас пробема в том, что Вы указали -купить по рынку. Поставьте конкретную цену и все будет OK
Старатель написал: QUIK 9.3.1.11, Lua 5.4 Ещё парочка "неуловимых" косяков. Обе ошибки были в main. Никаких сторонних библиотек не подключено, только QLua-код.
1.
Код
local Time = tonumber(( os.date ( '%H%M' )))
if Time > = 2300 then
Вопрос к любителям ловли ошибок в QLUA ----------------- Представим , что в момент вывода функцией main параметров некоторой таблицы QUIK происходит вызов терминалом колбека QLUA и изменение этой таблицы., ------------ Вопросы: 1) что будет выводить функция main в этом случае, то что было до вызова колбека или то, что осталось после вызова. ------------------------------- 2) если будут в параметрах nil, то это ошибка QLUA, или ошибка писателя main, который использует потоко не безопасные функции в ней? Например, использовал функцию getParamEx.
Если его запустить, то length = 5. Если закомментировать a[4] length = 3. Если закомментировать a[2] или a[3], то сразу или с какого то раза length = 5.
Все работает правильно. Чтобы проверить это набираем Ваш пример в Scite -редакторе текста со встроенным отладчиком версия вот ваш скрипт:
Если его запустить, то length = 5. ----------------- a[1]=1 a[2]=3 a[3]=5 a[4]=7 a[5]=9 a[6]=nil length=5 >Exit code: 0 >D:/lua54/lua54.exe -e "io.stdout:setvbuf 'no'" "test_.lua" ===================== Если закомментировать a[4] length = 3. a[1]=1 a[2]=3 a[3]=5 a[4]=nil a[5]=9 a[6]=nil length=3 >Exit code: 0 ========================== Т е QLUA не виновата __________________ В документации на Lua Вы можете прочитать, что длина массив #a - не является действительной длиной, если в массиве есть дырки - nil --------------------------
s_mike@rambler.ru написал: Вы должны сами решить, в каком классе из возможных продавать ваши бумаги. Кроме вас, никто об этом не знает.
вы сами писали в первом сообщении, что можете перебрать доступные торговому счету классы и найти там тот в котором можно продать ваши бумаги. Ну и делайте так, если все равно, как превратить бумаги в деньги.
ваш ответ, еще больше усилил проблему. то, что можно найти класс не решает проблемы совершения сделки по рынку. Например, как Вы пишите, докупили в классе не полных лотов. И при поиске класса нашли именно его В нем Вы и выставите стоп по рыночной цене. А когда стоп сработает, то там либо будет мало ликвидности либо ее вообще нет. И Ваш робот огребет по полной. как Вам такой расклад?
Что считает терминал QUIK в таблице купить/продать и что же считает функция getBuySellInfo . ------------------- Казалось бы должны считать одно и тоже. ====================== Если -нет, то дайте ссылку на документацию. =============== Проверяем: Берем данные из таблицы терминала купить продать и по этим данным считаем функцией getBuySellInfo =========== результат ниже: Сумма - это произведение цены на количество. --------------------------------- Отличия: 1) Все суммы различные , даже там , где цена и количество одинаковые Например ===========================================
28
MGNT
4201
71
298 271
71
298 662
=============================================
2) QUIK для всех акций считает как не маржинальные, а формула очевидно учитывает маржинальные Но учитывает как то странно Например:
Риск 5.9, но для физ лиц не может быть более 5, а для юр. лиц может быть аж 8. Откуда 5.9 ? ------------------------ Там, где риск=1, количество не совпадает в большинстве случаях.
s_mike@rambler.ru написал: Вы должны сами решить, в каком классе из возможных продавать ваши бумаги. Кроме вас, никто об этом не знает.
вы сами писали в первом сообщении, что можете перебрать доступные торговому счету классы и найти там тот в котором можно продать ваши бумаги. Ну и делайте так, если все равно, как превратить бумаги в деньги.
я и решаю сам. Но предложение мое направлено на то, чтобы не заниматься этим . Никто не мешает поставить туда класс по которому куплена первое количество, либо последнее количество, А если кому-то хочется поплясать с бубном, так никто не запрещает.
Сергей написал: Добрый день! Вчера, начиная с 18:20 не выставлялись заявки на срочном рынке, при этом терминал никаких ошибок не выдавал(но заявки в таблице заявок не появлялись), свечи обновлялись. sendTransaction ошибок не выдавал. OnTransReply - тоже ничего не зафиксировал, как будто заявок и не было. В 18:44 попытался выйти в деньги и выставить заявку вручную - тоже не получилось. В 19:00 посыпались ошибки "невозможно выставить заявку т.к. сессия неактивна". Брокер(Альфа-директ) сообщил, что у них всё работало штатно, проблема, вероятно, с моей стороны. Что это могло быть, и как избежать подобных ситуаций.
выводите сообщения транзакций и колбеков в лог-файл. сможете разобраться что и как было и почему.
nikolz написал: Для тех,кто не понял либо не знает
Дисконты применяются только при маржинальной торговле.
nikolz, как обычно, сел в лужу
как обычно, это вы из нее вылезли ,чтобы прокукарекать чушь. ------------------ Вы прочитайте внимательно. речь идет о функции, которая при расчетах дает не то, что дает терминал КВИК. А он считает без учета плечей, ---------------------- Про заемные средства Вы тоже не в теме. ---------------------- Если У вас нет никаких бумаг то нахрен Вам дисконты. ---------------------- Заемные средства считаются лишь с учетом плеча. --------------------------- Торгую с маржинальными сделками давно. ================= но в данной теме никакие плечи не учитываются, а дисконты вообще применять можно лишь к тупой голове, так как акций для залога в данном расчете нет. --------------------------- Тему уже засрали все, кому не лень, аА объяснить на числах, почему формула и КВИК дает разные результаты никто не может. =================== Хотелось бы услышать автора этой формулы. Просьба разработчиков рассказать , что эта формула считает и почему такое расхождение в результатах расчета КВИКа и этой формулы.
Читаем таблицу, которую получает колбек 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 ----------------------- Вопрос к знатокам: сколько стоят инструменты, заблокированные на продажу?
s_mike@rambler.ru написал: Акции в вашем портфеле не привязаны к классам. Это кажется необычным, но это так. Акци. Лукойла теоретически вы можете купить в разных классах, при этом они будут учтены вместе одним количеством.
стандартный случай, когда вы купили тот же Лукойл в классе tqbr и потом догнались тем же лукойлом в классе неполных лотов
Вот именно. Но Вы не поняли проблемы. Вопрос в том, как выставить заявку на число акций в позиции, если класс вам не известен? или вы можете выставить заявку без указания класса?
Добрый день, Предлагаю зарегистрировать следующее пожелание. Добавить в таблицу "Позиции по инструментам" class_code. -------------------- Объясняю в чем проблема. ================= При написании скриптов возникает необходимость получить параметры по инструментам, чтобы выставлять какие-либо заявки. ------------- Для формирования заявки по позиции инструмента нужен класс этого инструмента, а его в таблице позиций нет. ---------------- В результате, чтобы найти класс надо делать "танцы с бубном" извлекать клиента по нему находить торговый счет по счету находить фирму и получать список торгуемых классов потом в классах искать тот, в каком есть данный инструмент. ----------------- Напоминает наблюдение гланд через зад. Занятие занятное , но бесполезное. ================= Спасибо
Для тех,кто не понял либо не знает, но что-то советует. -------------------- Показываю, что считает QUIK ---------------- Квик считает именно так, как посчитал Я. --------------------------- Сумма 300 тысяч.
Дисконты вообще не из той оперы. ---------------------------------- Удивляюсь, как Вы вообще торгуете, если ничего не понимаете, но даете советы.
Александр П написал: добрый день. подскажите, а возможно ли установить один квик и в нём уже переключаться между двумя-тремя брокерами?
PS: не нашел подходящей темы, поэтому пишу тут)
Интересно, как терминал будет создавать архивы под разных брокеров и защищенные каналы связи. сейчас все брокеры используют двухфакторное соединение, Тоже прикольно посмотреть как QUIK с этим справится. --------------- Проще откройте кучу квиков, но в одном окна и все индикаторы, а в других лишь стаканы торгуемых интсрументов. и будет Вам счастье.
Вячеслав написал: При запуске приложения ошибка , пишет не хватает памяти под объекты, без которых приложение не может работать. Памяти на компьютере свободной дост аточно, программ запущенных больше нет. Как это все можно исправить ?
Вася написал: function Subscribe(list) for i = 1, #list do local classCode = list[1] local secCode = list[2] local x = Subscribe_Level_II_Quotes(class_code, sec_code) while not x do sleep(10) end Calculate(classCode, secCode) endendВ ней я по очереди подписываюсь на котировки по каждому инструменту функцией Subscribe_Level_II_Quotes(). Дальше цикл (на всякий случай), чтобы убедиться, что функция вернула true. И дальше какое-то вычисление.Здесь у меня все работает нормально.Дальше я прохожусь циклом по этому же списку, чтобы отписаться от каждой котировки.function Unsubscribe(list) for i = 1, 100 do local classCode = list[1] local secCode = list[2] local x =Unsubscribe_Level_II_Quotes(class_code, sec_code) while not x do sleep(10) end endendЗдесь на первом же элементе из списка я застреваю в цикле while. Если цикл убрать, то функция отрабатывает, а отписка не происходит.Подскажите как справиться с этой проблемой. Нужно сначала подписаться на инструменты, потом отписаться от них.Версия квика 9.2.3.15. Может дело не в моих кривых руках, а в версии?
если актуально, то ловите решение: -------------------------- фрагмент скрипта
Код
while Subscribe_Level_II_Quotes(cl,se)==false do sleep(5) end --подписываемся на стакан
local z=IsSubscribed_Level_II_Quotes (cl,se); --проверяем подписку
Log:write(tostring(cl)..","..tostring(se)..",z="..tostring(z).."\n"); --выводим в файл результат
while Unsubscribe_Level_II_Quotes(cl,se)==false do sleep(5) end -- отписываемся от стакана
z=IsSubscribed_Level_II_Quotes (cl,se); --проверяем отписку
Log:write(tostring(cl)..","..tostring(se)..",z="..tostring(z).."\n"); --выводим в лог файл результат
Дмитрий написал: nikolz,а что не так? Бумаги маржинальные, соответственно, и покупка больше, чем на 300 тыс. Откройте таблицу Купить/Продать и сравните
На учебном сервере плечо 2. Т е максимум 600 тысяч, но не 1 млн.759тыс982. Даже, если предположить, что плечо максимальное (для квалифицированных инвесторов, которым я являюсь, плечо 5 ) , то все равно не выходит каменная чаша.
Добрый день, -------------- Вопрос к знатокам: ----------------------------- Вычисляю функцией 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 ================== Кто сие может объяснить? Спасибо
nikolz написал: вычисления без этой функции можно ускорить, если запомнить размер лота и не извлекать его из хранилища а также не извлекать размер свободных денежных средств а рассчитывать их при совершении сделки и иногда сверять с портфелем.
Чтобы поделить количество свободных денежных средств на цену действительно не нужна никакая функция. Но существует такая вещь, как маржинальная торговля. Есть бумаги разного типа: маржинальные/не маржинальные, принимаемые и не принимаемые в в обеспечение маржинального кредита и пр. Почитайте, узнаете много интересного.
Я это знаю, но торгую лишь ликвидом, которые принимают. Поэтому такой проблемы нет. При расчете количества учитываю плечо. -------------------- Обратил внимание, что эта функция в некоторых случаях дает завышенные результаты. Как это объяснить не знаю.
Старатель написал: Теперь напишите функцию 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
Старатель написал: Теперь напишите функцию 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, чтобы время её выполнения составляло единицы (на худой конец - десятки) микросекунд, а то у Арки не получается.
сделал тест (фрагмент)
Код
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
Старатель написал: sleep с отрицательным числом, видимо длится бесконечно долго. Скрытый текст То, что в sleep попало отрицательное число - моя ошибка. Но реализация слипа - ошибка ваша.
Читаем документацию у майкрософт на функцию sleep Значение INFINITE указывает, что время ожидания приостановки не должно истекать. INFINITE =-1 предположу, что любое отрицательное число даст тоже самое т е время ожидания - вечность.
name="main";
paths = "D:/QUIK_SCRIPT/"
function cb(i)
O=ds:O(i); H=ds:H(i); L=ds:L(i); C=ds:C(i); V=ds:V(i) Ti=ds:T(i)
Log:write("ds "..tostring(O)..","..tostring(H)..","..tostring(L)..","..tostring(C).."\n");Log:flush()
end
function cb1(i)
O=ds1:O(i); H=ds1:H(i); L=ds1:L(i); C=ds1:C(i); V=ds1:V(i) Ti=ds1:T(i)
Log:write("ds1 "..tostring(O)..","..tostring(H)..","..tostring(L)..","..tostring(C).."\n");Log:flush()
end
function main()
while true do
sleep(10);
if ds==nil then ds=CreateDataSource("QJSIM","SBER",INTERVAL_M1)
Log:write("ds="..tostring(ds).."\n");Log:flush()
ds: SetUpdateCallback (cb)
end
if ds1==nil then ds1=CreateDataSource("QJSIM","SBER",INTERVAL_M1,"Last")
Log:write("ds1="..tostring(ds1).."\n");Log:flush()
ds1: SetUpdateCallback (cb1)
end
if ds~=nil then local count=ds:Size();
local i=count; O=ds:O(i); H=ds:H(i); L=ds:L(i); C=ds:C(i); V=ds:V(i) Ti=ds:T(i)
Log:write("ds:count="..count..","..tostring(O)..","..tostring(H)..","..tostring(L)..","..tostring(C).."/"..tostring(i).."\n");Log:flush()
end
if ds1~=nil then local count=ds1:Size();
local i=count O=ds1:O(i); H=ds1:H(i); L=ds1:L(i); C=ds1:C(i); V=ds1:V(i) Ti=ds1:T(i) i=i+1;
Log:write("ds1:coint="..count..","..O..","..H..","..L..","..C.."/"..i.."\n");Log:flush()
end
end
end
--------------
function OnInit(pfile)
Log=io.open(paths..name..".log","w")
end
В тесте открываются два источника: ds - это свечи обычные d1- это свечи "Last" тест пускаем на демо сервере. ----------------- Результаты ниже. Поясню что там. сначала смотрим ds и ds1 - они есть значит подписались ------------------ потом смотрим результат обычные свечи - есть а свечи last - нет ---------------------------- ds=table: 00000119201F8290 ds1=table: 00000119201F8BD0 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ds1:coint=0,0.0,0.0,0.0,0.0/1 ds:count=823,132.0,132.0,132.0,132.0/823 ------------------------