nikolz (Автор тем)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 3 След.
AlgoPack Mocex, FinRL China
 

В 2023 году Мосбиржа запустила Algopack и выложила на Гитхаб библиотеку на python – moexAlgo,

которая должна упростить работу с AlgoPack API.

AlgoPack — это данные, сигналы и аналитика для алгоритмической торговли через API
  • Загружать большой набор исторических данных
  • Тестировать свои торговые гипотезы
  • Построить алгоритмическую торговлю

В рамках интерфейса доступны следующие типы информации: статические данные о рынках (режимы торгов и их группы, финансовые инструменты и их описание), данные для построения графиков ("свечей"), сделки (анонимно), котировки, исторические данные, различные метаданные.

Аналогично продукту MOEX Trade INFO, который также работает через ИСС,

данные могут предоставляться или по подписке в режиме реального времени или в свободном доступе (без авторизации, но с задержкой).

Взаимодействие с сервером осуществляется по протоколу http.

https://data.moex.com/directory

https://www.moex.com/a2193
https://github.com/moexalgo/moexalgo

На питоне работает.
свечи: period_map = {'1m': 60, '10m': 600, '1h': 3600, '1D': 86400, '1W': 604800, '1M': 2678400, '1Q': 8035200}
----------------------
Использую для создания истории для ИИ
на основе FinRL:
Библиотека глубокого обучения с подкреплением для автоматизированной торговли акциями
https://github.com/AI4Finance-Foundation/FinRL
на питоне работает.
версия питона не выше 3.10
выше тоже можно, но сложнее.  работаю на 3.12.


Звук из файла и из памяти на Lua
 
Ранее в теме
https://forum.quik.ru/messages/forum10/message74775/topic8544/#message74775

Показал как воспроизвести звуковой файл на Lua из командной строки.
----------------
Недостаток такого способа - затраты времени на загрузку приложения плеера.
Достоинство - ничего не надо писать на СИ.
===============
В данной теме, по просьбе трудящихся, показываю как воспроизводить звуковой файл  сохранить его в памяти для
многократного воспроизведения.
--------------
Решить эту проблему невозможно без написания функции на СИ.
===============
По данной ссылке
https://cloud.mail.ru/public/PYXu/YrjyXLvcP
можно загрузить zip файл  nks.dll  c такой функцией,
там же есть пример, который напишу ниже,
и библиотека Lua53.dll
--------------------------
Пример :
Код
--функция для Lua 5.3 выводит на динамики звуковой файл
--при первом вызове записывает файл в буфер
--при последующих  вызовах воспроизводит содержимое буфера
--автор nikolz 2024
--распакуйте файл на диск  желательно D
--пример вызова функции для вывода на динамики системного звука

path = "D:/nks/"  --путь где находится файл nks.dll
package.cpath =path.."?.dll;"..package.cpath
require"nks"

local x="C:/Windows/Media/Alarm10.wav" -- звуковой файл
nks.run(x);        -- первый вызов с указанием файла
for x=1,5 do
   nks.run();     -- вызов воспроизведение из буфера памяти
end
nks.stop();        -- завершение работы и удаление буфера памяти
способ звукового сигнала в луа
 
Добрый день,
Можно воспроизводить звуковые сигналы Windows в скриптах луа так:
звук  из каталога C:/Windows/Media/:
Код
os.execute("powershell -c (New-Object Media.SoundPlayer 'C:/Windows/Media/Alarm10.wav').PlaySync();");
Код
os.execute("powershell -c (New-Object Media.SoundPlayer 'C:/Windows/Media/Ring10.wav').PlaySync();");
Что за хрень версия 10...
 
Решил сдуру поменять нормально работающую версию 8.7 на новую у сбербанка 10....
в итоге получился вроде бы тормоз.
---------------
Стал из бекапа восстанавливать и нате вам :


Ну и что теперь делать?
Индикатор Delta
 
Добрый день,
Написал индикатор Delta.
Скрипт 60 строк.
Пока он работает только для текущего дня.
Сам я им не пользуюсь, поэтому особенно не придумывал.
Вот такая картинка получилась для Сбера (нижний график ).
Рисует объему купить продать для тайма графика и накопительную функцию.

Работает быстро, если запустить с начала дня.
Если не сначала, то задумывается при запуске, так как для Сбера например получилось 35 тысяч сделок сегодня.
---------------------
Если кому надо, то пишите могу выложить nkDelta.luac  на какой-нибудь файлообменник.
Предлагаю реализовать
 
Добрый день,
Ув. разработчики
Предлагаю  реализовать возможность:
---------------------------
1) изменять параметры встроенных индикаторов   из скрипта индикатора.
-------------------------
2) устанавливать идентификатор индикатора из скрипта индикатора.
таблица "depo_limits" . Что не так?
 
Добрый день,
-----------------------
Проблема с чтением позиции по инструментам
----------------
В терминале позиция SBER есть  со сроком расчета T0 позиция 120


---------------
При чтении таблицы в скрипте
Код
local s="depo_limits";
local N1=getNumberOf(s)-1
for j=0,N1 do local x=getItem(s,j);
 if x and x.sec_code==sec then Qp=x.currentbal; jdep=j;
   Log:write(value2text(x,"depo=").."\n");Log:flush(); -- вывод в лог файл
   end;
end
есть только с limit_kind <0, естественно позиция НОЛЬ
Код
depo={
["trdaccid"]=NL0011100043,
["currentlimit"]=0.0,
["locked_buy"]=0.0,
["currentbal"]=0.0,
["limit_kind"]=-2000001,
["locked_buy_value"]=0.0,
["openlimit"]=0.0,
["openbal"]=0.0,
["awg_position_price"]=0.0,
["sec_code"]=SBER,
["locked_sell"]=0.0,
["wa_position_price"]=0.0,
["client_code"]=10326,
["wa_price_currency"]=SUR,
["locked_sell_value"]=0.0,
["firmid"]=NC0011100000}

версия 11.1.0.45
демо сервер.
----------------------------
Что не так?
Робот в виде скрипта индикатора
 
Добрый  день,
Рассказываю, как просто сделать робота в виде скрипта индикатора.
Сначала картинка работы такого робота.


В чем достоинство такого робота по сравнению с роботом на основе колбеков.
Робот значительно проще написать
Он загружается на график торгуемого инструмента,
Если для реализации алгоритма торговли  достаточно встроенных в QUIK индикаторов,
то нет надобности их программировать.
----------------  
Пример варианта основного  фрагмента такого робота:
Код
name="nkbot24"
Settings={["Name"] =name,["line"] ={},["account"]="",["client"]="",["Q"]=1;["wt"]=1000,["short"]=0}
Settings.Nind=0;

paths = "D:/QUIK_SCRIPT/"
package.cpath =package.cpath ..";"..paths.."?.dll";
package.path =package.path..paths.."?.lua;"
fnlog=paths..name..".log"; Log=io.open(fnlog,"w")

loadfile(paths.."nkbot24_func.lua")

function nkbuy(i,f)
---алгоритм покупки
 -- f=cross(1,1,2,1,1);
return f;
end

function nksell(i,f)
--алгоритм продажи
-- f=cross(1,1,2,1,1);
return f;
end

function nobuy(i,f)
--фильтр покупки
return f;
end

function nosell(i,f)
--фильтр продажи
return f;
end

function OnCalculate(i)
   local i1=i-1;
   if i==1 then nkInit(); return end
   if i~=i_ then    getI()   end
   N,torder=order(N);    Q=depo();
   if #t==0 then
--      f,j=cross(1,1,2,1,5); --пересечение двух индикаторов
      if i~=i_ then torg(nkbuysel(i));end
      M=os.clock();
   else
      del_ord(M);
   end
   i_=i;
return M1,M2;
end
Продолжение вероятно следует...
Сдвиговые регистры, циклические массивы. Экономим память
 
Добрый день,
В этой теме я расскажу кратко что такое сдвиговые регистры и циклические массивы.
И покажу как на Lua  экономить память при создании роботов.
----------------------
При торговле на бирже приходит много информации, такой , как новости, результаты сделок, значения индикаторов, например свечей.
эта информация записывается в массивы и в файлы и может составлять очень большой объем.
------------------
Однако, при реальной торговле, для принятия решения, нет надобности не только во всей накопленной информации в файлах, но и порою нужна лишь информация за последние например 60 минут, свечей с интервалом 1 минута.
=================
Чтобы массивы с данными не разбухали до безумных размеров я реализую временное окно,
в пределах которого  храню текущую информацию.
-------------------
Например, храним только 1024 последних отсчета.
Для этого необходимо выделить массив всего в 1024 элемента.
Для каждого нового отсчета необходимо сдвинуть содержимое массив влево на один отсчет,
а в освободившейся место записать принятое значение.
--------------------
Возникает вопрос как реализовать этот сдвиг элементов массива, чтобы было быстро.
---------------------
Один из приемов - циклические массивы.
-------------------
В таком массиве элементы не двигаются, а двигается указатель на место удаляемого первого элемента .
Это же место является местом размещения принятого элемента.
---------------
Еще одним способом является использование многобитовых регистров процессора, с помощью которых можно реализовать многобитовые сдвиги данных за одну операцию.
===================
В луа есть операции сдвига >>m (<<m).
Они позволяют сдвинуть целое число на m разрядов влево ( вправо), что соответствует делению(умножению) этого числа на 2 в степени m.
Такая операция сдвига числа выполняется в регистре сдвига  ( в процессоре это АЛУ+регистры)
------------------
В современных процессорах Intel есть регистры в 256 бит (в последних 512 бит)
------------------------------
Так как число double занимает 64 бита, а long(integer в lua) 32 бита,
то с помощью этих регистров можно сдвигать не одно число, а массив из 4,8,16 чисел одной командой.
Для простоты будем называть эти регистры 256(512) ,битовыми тоже сдвиговыми регистрами.
------------------
Очевидно, что с помощью этих регистров можно сдвигать массивы чисел.
=======================
Если не использовать С for lua,
то в скрипте на луа можно реализовать два способа работы с такими временными окнами.
------------------------------
Либо циклический массив,
либо сдвиг элементов массива.
--------------------------------------
Так как данный ликбез в основном для начинающих,
то покажу наиболее простой способ, но при этом достаточно быстродействующий.
-------------------------------
Вот скрипт функций, которые реализуют механизм такого временного окна данных,
где N - размер временного окна
Код
local function newCA(N) local t={}; for j=1,N do t[j]=0; end; return t; end --вставка нового элемента
local function setCA(t,X) table.remove(t,1); t[#t+1]=X;  end --вставка нового элемента

Посмотрим, что сохраняется в таком массиве
Организуем цикл записи номеров отсчетов которые изменяются от 1 до M
и какие из отсчетов будут сохраняться в массиве фиксированной длины 32 элемента
Код
local M=1000000
local t=newCA(32)
for j=1,M do setCA(t,j)
print("j="..j..",t="..table.concat(t,","));
end
это содержимое массива на каждом цикле
Код
>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "test_lines.lua" 
j=1,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
j=2,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2
j=3,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3
j=4,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4
j=5,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5
j=6,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6
j=7,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7
j=8,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8
j=9,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9
j=10,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10
j=11,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11
j=12,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12
j=13,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13
j=14,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
j=15,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
j=16,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
j=17,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
j=18,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
j=19,t=0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
j=20,t=0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
j=21,t=0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
j=22,t=0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
j=23,t=0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
j=24,t=0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
j=25,t=0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
j=26,t=0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
j=27,t=0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
j=28,t=0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
j=29,t=0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
j=30,t=0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
j=31,t=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
j=32,t=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
j=33,t=2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33
j=34,t=3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34
j=35,t=4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35
j=36,t=5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
j=37,t=6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37
j=38,t=7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38
j=39,t=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39
j=40,t=9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40
j=41,t=10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41
j=42,t=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42
j=43,t=12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43
j=44,t=13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44
j=45,t=14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45
j=46,t=15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46
j=47,t=16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
j=48,t=17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48
j=49,t=18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49
j=50,t=19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50
j=51,t=20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51
j=52,t=21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52
j=53,t=22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53
j=54,t=23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54
j=55,t=24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55
j=56,t=25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56
j=57,t=26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57
j=58,t=27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58
j=59,t=28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59
j=60,t=29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60
j=61,t=30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61
j=62,t=31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62
j=63,t=32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
j=64,t=33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
j=65,t=34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65
j=66,t=35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66
j=67,t=36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67
j=68,t=37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68
j=69,t=38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69
j=70,t=39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70
j=71,t=40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71
j=72,t=41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72
j=73,t=42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73
j=74,t=43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74
j=75,t=44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75
j=76,t=45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76
j=77,t=46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77
j=78,t=47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78
j=79,t=48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79
j=80,t=49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80
j=81,t=50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81
j=82,t=51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82
j=83,t=52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83
j=84,t=53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84
j=85,t=54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85
j=86,t=55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86
j=87,t=56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87
j=88,t=57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88
j=89,t=58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89
j=90,t=59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90
j=91,t=60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91
j=92,t=61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92
j=93,t=62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93
j=94,t=63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94
j=95,t=64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95
j=96,t=65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96
j=97,t=66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97
j=98,t=67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98
j=99,t=68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99
j=100,t=69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
j=101,t=70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101
j=102,t=71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102
j=103,t=72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103
j=104,t=73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104
j=105,t=74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105
j=106,t=75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106
j=107,t=76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107
j=108,t=77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108
j=109,t=78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109
j=110,t=79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110
j=111,t=80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111
j=112,t=81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112
j=113,t=82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113
j=114,t=83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114
j=115,t=84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115
j=116,t=85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116
j=117,t=86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117

Оценим быстродействие такого метода для массива в 1024 элемента
Код
local M=1000000
local t=newCA(1024)
--nklib.startA();
local tim=os.clock();
for j=1,M do setCA(t,j) end
--local tim=0.1*nklib.stopA()/M
tim=os.clock()-tim
print(1000000.*tim/M.." мкс" )
результат:
Код
>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "test_lines.lua" 
10.099 мкс
>Exit code: 0

Т .е. на сохранение одного нового элемента в таком массиве затрачивается примерно 10 мкс.
---------------------
Таким образом, с помощью приведенных выше двух простых функций,
Вы можете  управлять расходом оперативной памяти в своем роботе,
исходя из требуемого временного окна обработки поступающих данных.
CalcBuySell. Что не так?
 
Функция выдает нули.  Что не так?
-------------
Тест:
Код
function main()
   while fconnect do
      if getInfoParam("SERVERTIME") then fconnect=2;  end
      while fconnect==2 do
      c="QJSIM"; s="SBER"  client="10326"; acc="NL0011100043"; price=275.74;
      qty,com=CalcBuySell(c,s,client,acc,price,true,false);
      local s=c..","..s..","..tostring(client)..","..tostring(price)..","..tostring(acc)..", qty="..tostring(qty);
      message(s,1);
         sleep(10000); end
   end
end
function OnInit(pfile)    fconnect=isConnected(); end

Результат:

os.sysdate() . Что-то в ней не так..
 
Добрый день,
Вопрос к разработчикам
В документации на библиотеку QLua заявлено, что
os.sysdate() возвращает системное время с точность до микросекунды.
------------------------
Это означает, как я понимаю, что если я получу с помощью этой функции время в двух точках скрипта, то разница даст мне время исполнения этого участка с точностью до микросекунды.
------------------
Я написал такой тест:
Код
paths = "D:/nkarray/"
package.cpath =paths.."?.dll";
require "nkarray"
event=nkevent.Create("event");
---------------------
name="bot";  -- имя робота
path = "D:/QUIK_SCRIPT/nk_bot/"   --папка где разместим лог файл
Log=io.open(path..name..".log","w")   -- создаем лог файл для записи
------------
_N=0; _tN={};
----------------------
function main()
-----------------------
   while fconnect do
      if getInfoParam("SERVERTIME") then    fconnect=2;  end
------------------------------
      while fconnect==2 do
      w=nkevent.wait(event); --ждем события
         while _N>0 do
            t=_tN[_N]; _N=_N-1
   ----------------------
            tim2=0.1*nklib.stopA();
            T=os.sysdate();
            local _,_,_,t3=nkvm.D(); --HMS,YMD,dHMS,dt,ns
            t1=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs);
            local x1=1000000.*(t1-t[1])//1;
            local x2=1000000.*(t3-t[2])//1;
            Log:write("os.sysdate OnParam(сек)="..t[1]..", os.sysdate main(сек)="..t1..",разность 1(мкс)=="..(t1-t[1]).."\n");Log:flush();
            Log:write("nkvm.D OnParam(мкс)="..t[2]..", nkvm.D main(мкс)="..t3..", разность 2(мкс)="..(t3-t[2]).."\n");Log:flush();
            Log:write("разность 3 по высокоточному таймеру OC(мкс)="..tim2.."\n\n");Log:flush();
         end
      end

   end
end
----------------------------
function OnInit(pfile)    fconnect=isConnected(); end
----------------
function OnParam(c,s)
local T=os.sysdate(); local tim=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs)
nklib.startA();   local _,_,_,tim1=nkvm.D();    _N=_N+1; _tN[_N]={tim,tim1};
nkevent.Set(event);
end
В котором я замеряю системное время в колбеке on Param  в строке
Код
local T=os.sysdate(); local tim=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs)

и передаю его в функцию main
в функции main я снова получаю системное время в строках
Код
T=os.sysdate();

t1=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs);

вычисляю разность этих показаний в строке
Код
local x1=1000000.*(t1-t[1])//1;
и все три значения вывожу в лог файл, который покажу ниже.
----------------------
кроме того, для сравнения я делаю тоже самое на основе собственной функции времени а также своего таймера который реализован на высокоточном таймере процессора.  Но это так, чтобы показать, что действительность не такая, как показывает ваша функция.
и вот результат :
Код
os.sysdate OnParam(сек)=78115.93613, os.sysdate main(сек)=78115.93613,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78114968.3296, nkvm.D main(мкс)=78114968.3932, разность 2(мкс)=0.063599988818169
разность 3 по высокоточному таймеру OC(мкс)=59.8

os.sysdate OnParam(сек)=78115.998828, os.sysdate main(сек)=78115.998828,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78114999.9583, nkvm.D main(мкс)=78115000.0045, разность 2(мкс)=0.046200007200241
разность 3 по высокоточному таймеру OC(мкс)=30.3

os.sysdate OnParam(сек)=78115.870038, os.sysdate main(сек)=78115.870038,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78115435.1791, nkvm.D main(мкс)=78115435.2126, разность 2(мкс)=0.033499985933304
разность 3 по высокоточному таймеру OC(мкс)=24.3
На основе Вашей функции разность показаний равна НУЛЮ.
Мои функции показывают разность от 63 до 24 мкс, что более соответствует реальному процессу,
так как процессор у меня далеко не квантовый.
--------------------
Вопрос:
Что не так с вашей функцией os.sysdate() ?
Очередь -элементарно и полезно, Как сделать очередь в роботе и зачем.
 
Добрый день,
Хочу поделиться некоторыми приемами, которые я использую при построении своих роботов.
См. тему -мой робот.
-----------------
В структуре спинного мозга робота , реализуемого в QUIK, условно можно выделить колбеки,
в которые приходят сообщения о событиях и функцию main,
работающую в отдельном потоке, которая обрабатывает эти события.
-------------------
Как правило, в  main делается бесконечный цикл, в котором и осуществляется обработка.
------------------------
Если обрабатывать нечего, то рекомендуют ставить sleep(time) , где time - число миллисекундах,
на которое Вы заморозите работу main.
===============
Но проблема в том, что пока Main не работает, в колбеки поступают события ,
которые надо обрабатывать либо как-то сохранить иначе они потеряются.
------------------------------
Если обрабатывать события  в колбеках, то на время обработки будет остановлен терминал QUIK, так как колбеки работают в основном потоке термина.
------------------
Проблема решается путем сохранения сообщений из колбеков в массиве,
из которого потом main сможет обработать все сохраненные сообщения.
Такой список (массив,таблица и т д) сообщений называется очередью.
===================
Вопрос лишь в том, как организовать эту очередь , чтобы было просто и быстро.
---------------
Есть несколько вариантов,
------------
Вариант 1: классический - это сделать универсальные списки, очереди. Алгоритмов и их реализаций много можно найти в интернете.
Сложно, малопонятно не спецам . Большая нагрузка на сборщик мусора, что замедляет исполнение скрипта.
--------------------
Вариант 2: -рекомендуемый  в документации QLUA - использовать потоко безопасные функции записи и удаления из массива.
Просто, но относительно медленно.
-------------------
Вариант 3:   это мой, тот который я расскажу далее. просто и быстро.
Объяснять буду на рабочем примере.
-------------------
Продолжение следует...

 
Прикольно: Lua5.4 медленнее Lua5.3
 
Добрый день,
Тестил скорость питона, луа и jit и решил посмотреть, как ускорит Lua5.4 по сравнению 5.3.
--------------------
Раньше было быстрее, да и интернет говорит об этом же.
Выкладывал тест на форуме.
------------
Но получился прикол.
На этом тесте оказалось наоборот
Вот этот testSM.lua
Код
local V={}
local t=os.clock();
local N=256;
local y=0.;
local A=100.
local P=128
local W=2*3.14/N
for i=1,10000000 do
   y=A*math.sin(W*i);
end
local t1=os.clock()
print("time="..t1-t,"y="..y);

результат:
Код
>D:/lua54/lua54.exe -e "io.stdout:setvbuf 'no'" "testSM.lua" 
time=0.74   y=-94.501629942958
>Exit code: 0

>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "testSM.lua" 
time=0.597   y=-94.501629942958
>Exit code: 0
Кто сможет объяснить?
Cкорость обмена данными через файлы
 
Добрый день,
Эта тема в основном для начинающих строителей роботов.
--------------------------
На вопрос  как сохранить или как передать данные в другой скрипт и приложение,
я рекомендую начать с обмена через файлы.
--------------------
Как правило в ответ получаю - через файлы - это медленно.
На вопрос -откуда Вы это знаете -обычно ответа нет.
----------------
Аналогичный вопрос возникает при попытке передать данные из одного приложения в другое.
---------------
Тем кто,  знает С for Lua, рекомендую mapping files, как самый универсальный и быстрый способ обмена,
если Вас не устраивает обычный обмен через файлы.
---------------
В этой теме я покажу как "медленно" реализуется обмен через файлы.
===============
Тест обмена через файлы в одном приложении.
-------------------
Написал вот такой тест:
Код
pD ="D:/QUIK_SCRIPT/nk_bot/Data/"
fn=pD..name..".log";  Log=io.open(fn,"w");
pDA ="D:/QUIK_SCRIPT/nk_bot/DataA/"
fnA=pDA..name..".log"; LogA=io.open(fnA,"w");
--------------------
local nF=nkevent.ccf(fn);
local nFA=nkevent.ccf(fnA);
local _,_,dHMS1=nkvm.D();
for j=1,100 do
     local _,_,dHMS=nkvm.D(); d=(1000000.*(dHMS-dHMS1))//1;
    Log:write(j..","..dHMS..","..d.."\n");Log:flush();
    while true do
   if nkevent.wcf(nF) then  dHMS1=dHMS; local  C=Log; Log=LogA; LogA=C; local x=nF; nF=nFA; nFA=x  break; end
   end
end
Что он делает?
Создаем на диске два каталога Data и DataA до запуска скрипта.
Скрипт открывает  в каждом из каталогов файл test.log.
-------------------
Далее в цикле 100 раз производится
запись с нечетным j в файл в Каталоге Data.
При обнаружении записи в файл , производим запись в файл в каталоге DataA по четным значениям j.
------------------
Таким образом, в файл каталога Data записываются ответы на запись в файл каталога DataA и наоборот.
---------------------
Каждая запись содержит значения j, текущее время и  задержку обнаружения записи в очередной файл.

Результат  Data/test.log:
Код
1,151047.6863891,790.0
3,151047.6865335,61.0
5,151047.6865586,10.0
7,151047.6865764,8.0
9,151047.6865931,8.0
11,151047.6866097,8.0
13,151047.6866333,15.0
15,151047.6866505,8.0
17,151047.6866669,8.0
19,151047.686683,8.0
21,151047.6866992,8.0
23,151047.6867155,8.0
25,151047.6867317,8.0
27,151047.6867478,8.0
29,151047.6867637,7.0
31,151047.6867809,8.0
33,151047.6867971,8.0
35,151047.6868131,8.0
37,151047.6868292,8.0
39,151047.6868453,8.0
41,151047.6868614,8.0
43,151047.6868775,8.0
45,151047.6868937,8.0
47,151047.6869098,8.0
49,151047.686926,8.0
51,151047.6869421,8.0
53,151047.6869583,8.0
55,151047.6869748,8.0
57,151047.6869909,8.0
59,151047.6870071,8.0
61,151047.687025,8.0
63,151047.6870415,8.0
65,151047.687059,8.0
67,151047.6870752,8.0
69,151047.6870911,8.0
71,151047.6871073,8.0
73,151047.6871234,8.0
75,151047.6871394,8.0
77,151047.6871554,8.0
79,151047.6871715,8.0
81,151047.6871876,8.0
83,151047.6872036,8.0
85,151047.6872198,8.0
87,151047.687236,8.0
89,151047.6872521,8.0
91,151047.6872683,8.0
93,151047.6872844,8.0
95,151047.6873004,8.0
97,151047.6873165,8.0
99,151047.6873325,8.0
Результат  DataA/test.log:
Код
2,151047.6864724,83.0
4,151047.6865484,14.0
6,151047.6865676,9.0
8,151047.6865849,8.0
10,151047.6866013,8.0
12,151047.6866179,8.0
14,151047.686642,8.0
16,151047.6866586,8.0
18,151047.6866749,8.0
20,151047.6866911,8.0
22,151047.6867072,7.0
24,151047.6867237,8.0
26,151047.6867397,8.0
28,151047.6867558,8.0
30,151047.6867727,8.0
32,151047.686789,8.0
34,151047.686805,7.0
36,151047.6868212,8.0
38,151047.6868372,7.0
40,151047.6868533,8.0
42,151047.6868695,8.0
44,151047.6868856,8.0
46,151047.6869017,8.0
48,151047.6869179,8.0
50,151047.686934,8.0
52,151047.6869502,8.0
54,151047.6869665,8.0
56,151047.6869828,8.0
58,151047.686999,8.0
60,151047.6870167,9.0
62,151047.6870333,8.0
64,151047.6870509,9.0
66,151047.687067,8.0
68,151047.6870831,7.0
70,151047.6870991,8.0
72,151047.6871153,8.0
74,151047.6871314,7.0
76,151047.6871474,8.0
78,151047.6871635,8.0
80,151047.6871795,8.0
82,151047.6871956,8.0
84,151047.6872116,7.0
86,151047.6872278,8.0
88,151047.687244,8.0
90,151047.68726,7.0
92,151047.6872763,8.0
94,151047.6872924,8.0
96,151047.6873085,8.0
98,151047.6873245,8.0
100,151047.6873405,8.0
Самое смешное то ,
что задержка измеряется в мкс
и составляет в среднем не более  10 . т.е. 0.000001 сек.
-------------------------
Это медленно?  
Запаздывание тиков
 
Добрый день,
Вопрос к разработчикам.
Можете объяснить, почему на учебном сервере тики приходят с запаздыванием от 500 до 1700 ms.
При этом задержка обмена по интернет не более 30 ms.
Задержка обработка колбека не более 0.1 ms
Вот результаты теста
строки с первым числом 2 - это обработка колбека onAllTrade.
Последнее число в строке(zT) - это задержка в ms
Я понимаю, что это учебный сервер, но у всего есть причина.
Хотелось бы понять и простить.
Код
4; 0.2, 22.6,AMEZ, 108,Ntpm=0
2,1.4; 163; MTLR,zT=712.0
2,0.2; 37; SBER,zT=712.0
2,0.1; 56; NKNC,zT=712.0
2,0.1; 27; MTSS,zT=712.0
2,0.1; 42; MTSS,zT=712.0
2,0.1; 24; MTSS,zT=712.0
2,0.1; 42; KAZT,zT=712.0
2,0.1; 31; VSMO,zT=712.0
2,0.1; 22; VSMO,zT=712.0
2,0.2; 25; TCSG,zT=1712.0
2,0.1; 20; TCSG,zT=1712.0
2,0.1; 26; TCSG,zT=1712.0
2,0.1; 30; TCSG,zT=1712.0
2,0.2; 23; TCSG,zT=1712.0
2,0.1; 24; MTLR,zT=1712.0
2,0.1; 34; SPBE,zT=1712.0
2,0.2; 41; SPBE,zT=1711.0
2,0.1; 25; SPBE,zT=1711.0
2,0.2; 32; SPBE,zT=1711.0
2,0.1; 41; BSPB,zT=1711.0
2,0.1; 25; BSPB,zT=1711.0
14; 0.2, 260.5,VSMO, 108,Ntpm=12
14; 0.2, 24.0,VKCO, 108,Ntpm=11
14; 0.2, 18.4,TCSG, 108,Ntpm=10
14; 0.2, 27.1,SPBE, 108,Ntpm=9
14; 0.1, 22.7,SGZH, 108,Ntpm=8
14; 0.2, 15.5,SBER, 108,Ntpm=7
14; 0.2, 15.3,ROSN, 108,Ntpm=6
14; 0.2, 154658.2,NKNC, 109,Ntpm=5
14; 0.4, 23.9,MTSS, 109,Ntpm=4
14; 0.3, 110.0,MTLR, 109,Ntpm=3
14; 0.2, 21.5,KMAZ, 109,Ntpm=2
14; 0.1, 150429.8,KAZT, 110,Ntpm=1
14; 0.4, 29.6,BSPB, 110,Ntpm=0
2,1.2; 179; SBER,zT=777.0
2,0.2; 30; SBER,zT=777.0
2,0.2; 23; SBER,zT=777.0
2,0.2; 23; SBER,zT=777.0
2,0.1; 23; SBER,zT=777.0
2,0.1; 21; SBER,zT=777.0
2,0.1; 22; SBER,zT=777.0
2,0.1; 24; SBER,zT=777.0
2,0.1; 27; SBER,zT=777.0
2,0.2; 44; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.2; 21; SBER,zT=776.0
2,0.2; 22; SBER,zT=776.0
2,0.2; 22; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.1; 19; SBER,zT=776.0
2,0.2; 20; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.1; 21; SBER,zT=776.0
2,0.1; 38; SBER,zT=776.0
Тест времени подключения источников данных
 
Добрый день,
По просьбе разработчиков
https://forum.quik.ru/messages/forum10/message73569/topic8440/#message73569
выкладываю для общего пользования
свой тест измерения времени подключения источников данных.
Так как ранее использовался очень большой скрипт,
то пришлось написать специально тест для общего пользования.
-------------------
В тесте используется два таймера.
Один - мой на основе высокоточного счетчика OC на СИ. Выкладывал его на форуме.  Его квант 0.1мкс.
Второй - на основе socket. Для исключения сомнения в измерениях. Его квант 1 мс.
-------------------
Начинающие писатели роботов, можете позаимствовать мое решение организации очереди.
Код
--тест скорости подключения источников данных -автор nikolz
name="testnk"
paths = "D:/nkarray/"
package.cpath =paths.."?.dll";
require "nkarray"
p2 = "D:/luasocket/"
package.cpath =package.cpath ..";"..p2.."?.dll";
package.path =package.path..p2.."?.lua;"
socket = require("socket")
path = "D:\\QUIK_SCRIPT\\nk_bot\\"
Log=io.open(path..name..".log","w")
Ntp=0;    tp={}
local ds_int={INTERVAL_M1,INTERVAL_M5,INTERVAL_M30,INTERVAL_TICK};
function main()
   local t,int,tms,t1;
     while true do
      while Ntp>0 do
         t=tp[Ntp]; Ntp=Ntp-1 clas=t[1] sec=t[2]
         for i=1,#ds_int do ds={}
            t2=socket.gettime()*1000.
            nklib.startB();
            int=ds_int[i];
            local d,err; while d==nil do d,err=CreateDataSource(clas,sec,int); end
            d:SetEmptyCallback();
            t1=0.01*nklib.stopB();
            tms=(socket.gettime()*1000.-t2)//1
            Log:write("interval="..int..",sec="..tostring(sec)..",tnk="..t1.."мкс, tsocet="..(tms).."мc\n");Log:flush();
         end
      end
      sleep(1);
   end
end

function OnInit(pfile)  fconnect=isConnected(); end
function OnParam(c,s) Ntp=Ntp+1;    tp[Ntp]={c,s}; end
Это результаты работы теста на моем компе:
Код
interval=1,sec=VTBR,tnk=39.41мкс, tsocet=0.0мc
interval=5,sec=VTBR,tnk=20.17мкс, tsocet=0.0мc
interval=30,sec=VTBR,tnk=17.82мкс, tsocet=0.0мc
interval=0,sec=VTBR,tnk=13072.46мкс, tsocet=130.0мc

interval=1,sec=VSMO,tnk=57.81мкс, tsocet=0.0мc
interval=5,sec=VSMO,tnk=21.82мкс, tsocet=0.0мc
interval=30,sec=VSMO,tnk=21.73мкс, tsocet=0.0мc
interval=0,sec=VSMO,tnk=13581.32мкс, tsocet=135.0мc

interval=1,sec=UGLD,tnk=57.16мкс, tsocet=0.0мc
interval=5,sec=UGLD,tnk=25.99мкс, tsocet=0.0мc
interval=30,sec=UGLD,tnk=26.66мкс, tsocet=1.0мc
interval=0,sec=UGLD,tnk=12974.53мкс, tsocet=128.0мc

interval=1,sec=NMTP,tnk=57.63мкс, tsocet=0.0мc
interval=5,sec=NMTP,tnk=19.32мкс, tsocet=0.0мc
interval=30,sec=NMTP,tnk=17.54мкс, tsocet=0.0мc
interval=0,sec=NMTP,tnk=12912.37мкс, tsocet=129.0мc

interval=1,sec=VRSB,tnk=35.37мкс, tsocet=0.0мc
interval=5,sec=VRSB,tnk=27.25мкс, tsocet=0.0мc
interval=30,sec=VRSB,tnk=21.7мкс, tsocet=0.0мc
interval=0,sec=VRSB,tnk=12604.62мкс, tsocet=125.0мc

interval=1,sec=SIBN,tnk=34.2мкс, tsocet=0.0мc
interval=5,sec=SIBN,tnk=43.41мкс, tsocet=0.0мc
interval=30,sec=SIBN,tnk=18.91мкс, tsocet=0.0мc
interval=0,sec=SIBN,tnk=12793.29мкс, tsocet=127.0мc

Время подключения источников с интервалом 1,5,30 минут  составляет 30 мкс.
Время подключения тиков 12900 мкс. замедление в 400 раз.
==================
Демо сервер КВИК.
версия КВИК 11.1.0.45
Lua таблицу в файл и обратно
 
Преобразование таблицы Lua в строку, запись в файл и загрузка таблицы из файла в скрипт.
Код
function value2text(t,s)  --преобразование таблицы в скрипт
   local s1=""; --новое значение
   local n=string.len(s); local z=string.sub(s,n);
   local m= type(t);
   if m=="string" then
      s1='"'..tostring(t)..'"';  elseif m=="number" then s1=tonumber(t);  elseif t==nil then s1="nil";
   elseif m=="table" then local f;
      for j,v in pairs(t) do
         local x=v;
         if f then s1=s1.."," end  f=1;
         if  type(j)~="number" then    s1=s1..'\n["'..tostring(j)..'"]='; end
         s1=value2text(x,s1);
      end
      if z=='}' then s1='\n{'..s1..'}'; else s1='{'..s1..'}' end
   end
return s..s1;
end

--------------------  это пример вывода и загрузки с распечаткой значений из таблиц
local t2={6,7,8,9}
local t={1,2,3,4,5,"asd",t2}  -- это таблица которую выводим в файл
----------вывод в файл
local fn=p3.."test999.lua"
fLog=io.open(fn,"w"); fLog:write("t1="..value2text(t,"").."\n");fLog:flush()
fLog:close();
-----------ввод из файла
dofile(fn);
----------------прочитали таблицу из файла в таблицу t1
--теперь печатаем из введенной таблицы значения и сравниваем их со значениями в t2 и t
local t3=t1[7]
local s1=t1[6];
print(t1[1],s1,t3[3])

результат:
это содержимое файла test999.lua:
Код
t1={1,2,3,4,5,"asd",{6,7,8,9}}
это печать значений
Код
1   asd   8
Тормоз подключения тиков
 
Добрый день,
Вопрос к разработчикам.
Можете объяснить, почему выполнение функции  
CreateDataSource для тиков выполняется в 700 раз медленнее (у меня за 189000 мкс)
чем для других интервалов (у меня за 270 мкс)
Мой робот
 
Добрый день,
Решил замутить тему о том, как я строю робота.
-------------------
В данной теме, если не лень, буду описывать  основные блоки нового робота,
которого сейчас пишу.
--------------  
Данный робот обрабатывает информацию по всем инструментам, на которые мы подписываемся в терминале QUIK.
---------------------
В этом роботе, назовем его для определенности Петя (Вася у меня был 10 лет назад),
выделяю два основных блока(мозга)- спинной и головной.
-----------------
Спинной блок отвечает за обработку , которую необходимо выполнять для получения и отправки информации на биржу или брокеру. К этому блоку относится обработка информации о сделках и заявках.
Спинной блок занимается рутинной работой, без которой невозможно торговать.
---------------
Головной блок занимается управлением торговлей.
Он осуществляет прогноз движения рынка и формирование сигналов покупки/продажи.
Головной блок - это творческая часть робота, которая собственно либо сливает депозит, либо его увеличивает.  
==========
Спинной блок.
Здесь реализуется следующие блоки обработки:
1. OnTransReply  -  транзакций
2. OnStopOrder  -  информации о выставленных  стоп-заявках
3. OnOrder  -  информации о  выставленных заявок
4. OnTrade - информации о совершенных своих сделках
5. OnParam -информации об изменении состояния подписанных в терминале QUIK инструментов
--------------
OnParam
Пример реализации  функции:
Код
function OnParam(c,s)
if TLL and c~="SPBFUT" and c~="CETS"  then
     local Lev=tonumber(getParamEx(c,s,"LISTLEVEL").param_value); 
     if Lev>0 then
   local i=1; while #TLL>=i do if Lev==TLL[i] then break; end i=i+1 end
   if i>#TLL then  return; end
     end
end
   local t={14,c,s}; tprm[#tprm+1]=t;--if 2>#tprm then nkevent.Set(event);
end
Это основная функция, которая создает события event  при изменении параметров любого из инструментов.
Эти события обрабатываются в функции main, которая выполняется в отдельном потоке.
--------------------------
В данной реализации OnParam добавлено условие (оператор if) фильтрации инструментов по листингу.
--------------------
Можно добавить и другие фильтры. Например, можно задать список торгуемых инструментов из числа всех подписанных. В этом случае робот будет торговать и отслеживать лишь списочные инструменты.
-----------------
В роботе реализованы три механизма событий, которые вызывают функцию main.
событие №1  OnParam.
По этому событию выполняется регистрация параметров инструмента и подписка на свечи или тики для данного инструмента. Кроме того, по этому сигналу обрабатываются стоп-заявки и заявки.  
-----------------------------------
событие №2  таймер интервала свечей. Например, если головной блок использует свечи с интервалом 1 минута, то таймер выдает сигнал каждую минуту и по этому сигналу запускается для каждого торгуемого инструмента отдельный поток из пула потоков, в котором работает головной блок.  
----------------------------------
событие №3 . Так называемый Watchdog -"сторожевой пес".  Таймер, который выдает сигнал, если нет события №1 например в течении 30 секунд.   Это событие означает, что что-то не так и надо предпринимать соответствующие меры.
==================
Продолжение следует...
Ошибка:Не хватило памяти под объекты...
 
Добрый день,
Вопрос к разработчикам
версия 11.0.1.3
После экспериментов с открытием множества потоков
На демо сервере при очередном запуске QUIK получаем это:

и после этого QUIK выгружается.
Есть ли способ исправить и запустить QUIK  без установки заново?
Сравнение языков программирования
 
Вдруг откуда ни возьмись, появилась ...Проблема с индикатором
 
Добрый день
Вопрос разработчикам.
---------------
Версия 8.7 Рабочая
-----------------
При очередном запуске  QUIK на графике исчезли все данные индикатора( отображалось 38 параметров), который установлен в квике  почти год  назад и работал до сегодня.
--------------------
При открытии редактирования, индикатор в окне редактирования есть .
------------------------------
В таблице  "Добавить индикатор"  - индикатора нет.
-------------------------------
При запуске QUIK никаких сообщений об ошибке в индикаторе нет.
--------------------
Каким образом обнаружить причину отсутствия индикатора на графике и в таблице "Добавить индикатор"  
Программирование скриптов
 
Добрый день,
Реализовал для себя,
предлагаю реализовать в QUIK для все пользователей.
-----------------
1) Запуск  произвольного количества скриптов, каждый  в отдельном потоке.  
--------------------------
2)  Реализацию скриптов вне зависимости от версии Lua,
а также  на языках LuaJit,Terra, Julia.
-----------------------
3) Очереди к  потокам
-------------------------
4) Передача данных между скриптами.
 
ПростоПример
 
Робот в октябре.
----------------------
Последний график - это прибыль и убытки.
белая линия - итого.
зеленая -лонг
синяя -шорт
штриховая - текущая, не зафиксированная
---------------
На первом графике
профит нарастающий за месяц
на втором профит за каждый день


Для писателей роботов
 
Рекомендую ознакомиться :
https://habr.com/ru/articles/680872/
примеры колбеков
 
Написал  изучающим Lua примеры вариантов колбеков сделок, заявок и стоп-заявок.
----------------------
Примеры написаны специально для форума и не тестировались, а лишь проверены на синтаксис.
---------------------------
Поэтому, если есть желающие тестить и найдете ошибки, то пишите, исправим вместе.
--------------
В этих колбеках сделки, активные заявки и активные стоп заявки размещаются в соответствующие инструментам рабочие таблицы.
--------------------------------
Код
--таблицы
TRADE={}; -- индексы сделок по инструментам
ORDER={}; -- индексы активных заявок по инструментам
STOP={}; -- индексы активных стоп-заявок по инструментам

function OnTrade(tr)
  local n,m;local sec=tr.sec_code;
  local t=TRADE[sec]; --таблица номеров строк сделок в таблице QUIK инструмента sec
  if t then
   m=TRADE[0]; n=t[0];
 else                --создание таблицы инструмента
   m=getNumberOf("trades"); n=0;
   t=SearchItems("trades",n,m-1, function(p1) if p1==sec then return true;end return false; end,"sec_code")
   TRADE[sec]=t;
end
 if m>t[n] then n=n+1; t[n]=m;  t[0]=n; TRADE[0]=m+1; end
end

local function fOrder(tr,T,s)  --функция обработки для колбеков orders и stop_orders
  local n,m,x;local sec=tr.sec_code; local t=T[sec];  --таблица номеров строк в таблице QUIK активных ордеров или стоп_ордеров инструмента sec
  local flag=tr.flags&1; local num=tr.order_num;
  if t then
    m=T[0]; n=t[0];
   for i=1,n do x=getItem(s,i-1);
      if x.num_order==num then
         if flag==0 then n=n-1;if n>0 then t[i]=t[n]; end break; else return; end
      end
   end
 else                --создание таблицы инструмента
   m=getNumberOf(s); n=0;
   t=SearchItems(s,n,m-1, function(p1,p2) if p1==sec and p2&1==1 then return true;end return false; end,"sec_code,flags")
   T[sec]=t;
end
   if flags==1 then n=n+1; t[0]=n; t[n]=m; T[0]=m+1; end
end

function OnOrder(t)   fOrder(t,ORDER,"orders");  end
function OnStopOrder(t) fOrder(t,ORDER,"stop_orders"); end
 
Равнение на "Яндекс"!!!
 
«Яндекс» увеличил фонд своей программы багбаунти «Охота за ошибками» в 2023 году в 2 раза до 100 млн рублей. В 2022 году компания выплатила белым хакерам 39,7 млн рублей за нахождение уязвимостей и багов в своих сервисах и службах.
Синхронизация QUIK с NTP
 
Добрый день,
Для контроля  реального времени прихода сделок с биржи синхронизирую компьютер с сервером точного времени.
Не удается получить погрешность менее 20 ms.



Майкрософт декларирует возможность 1 ms.
----------------
Если кому-то это удалось, подскажите как Вы это достигли.
Тест. Данные в другое приложение.
 
Добрый день,
Неоднократно на форуме интересовались передачей данных из  QUIK  в другое приложение(процесс).
Есть много способов.
Наиболее универсальным является file mapping
Этот метод позволяет обмениваться данными практически любого объема.
Использую этот метод не только для QUIK
------------------
В названии метода есть слово файл.
Уверен, что многие скривятся и скажут, что метод медленно работает.
А вот и нет. .
---------------------------------
Что нам рассказывает об этом методе Майкрософт:
--------------------------
Это объединение содержимого файла с частью виртуального адресного пространства процесса.
Система создает объект сопоставления файлов (также известный как объект раздела) для поддержания этой связи.
Просмотр файла - это часть виртуального адресного пространства, которую процесс использует для доступа к содержимому файла.
Сопоставление файлов позволяет процессу использовать как случайный ввод-вывод (I / O), так и последовательный ввод-вывод.
Это также позволяет процессу эффективно работать с большим файлом данных, таким как база данных,
без необходимости отображать весь файл в памяти.
Несколько процессов также могут использовать файлы, сопоставленные с памятью, для обмена данными.

Процессы считывают данные и записывают в файловое представление, используя указатели, точно так же, как они делали бы с динамически выделяемой памятью.

Использование данного метода повышает эффективность, поскольку файл находится на диске, а представление файла - в памяти.

===========================

Тест для измерения задержки передачи данных из скрипта QUIK  в приложение.

скрипт Теста в SciTe:

Код
paths = "D:/nkarray/"
package.cpath =paths.."?.dll;"
require"nkthread"
----------------------
local T=0; while true do local T1,dt,hms,s,num,HMS,ss=nkmx.gsm(0,T); if T1 then T=T1; print(0.1*dt,hms,s,num,HMS,ss); end  end

фрагмент скрипта в QUIK:
Код
function OnAllTrade(t)
   local c,s=t.class_code,t.sec_code;  local z=ds[c..s]; local num=t.trade_num;
   if z then   local d=z[1]; local n=z[2]; local f=z[3];
      local Ti=t.datetime; local HMS=(60*(60*Ti.hour+Ti.min)+Ti.sec)+0.001*Ti.ms;
      local D=os.date("*t"); local hms=60*(60*(D.hour-shH)+D.min)+D.sec-shS;
      local dt= hms-HMS+n;
      local size=d:Size();
      local T1=d:T(size);   local HMS1=(60*(60*T1.hour+T1.min)+T1.sec)+0.001*T1.ms;
      if HMS==HMS1 and z[4]~=num then
         local dt1=0.01*math.floor(100*dt);   if 0>dt then dt=0 end   count=count+1;   count1=count1+1;
         local m=math.floor(dt)+1;
         local ss=tostring(hms)..","..tostring(s)..",num="..tostring(num)..",size="..tostring(size)..",HMS="..tostring(HMS)..",dt="..tostring(dt1)..",n="..tostring(n)..",m="..tostring(m)..",clock="..(os.clock()-clockOS);
         nkmx.ssm(0,hms,s,num,HMS,ss); -- Log:write(ss.."\n"); Log:flush();
         if sts[m] then sts[m]=sts[m]+1; else sts[m]=1    end
      end
      z[4]=num;
   end
end

результат вывода параметров в SciTe:
Код
0.0   46972   MTSS   4794253307   44952.0   46972,MTSS,num=4794253307,size=2390,HMS=44952.0,dt=2020.0,n=0,m=2021,clock=8.4760000000024
0.1   46972   MTSS   4794253308   44952.0   46972,MTSS,num=4794253308,size=2391,HMS=44952.0,dt=2020.0,n=0,m=2021,clock=8.4760000000024
0.1   46972   FIVE   4794253618   44971.0   46972,FIVE,num=4794253618,size=2756,HMS=44971.0,dt=2001.0,n=0,m=2002,clock=8.4760000000024
0.1   46972   FIVE   4794253619   44971.0   46972,FIVE,num=4794253619,size=2757,HMS=44971.0,dt=2001.0,n=0,m=2002,clock=8.4760000000024
0.1   46972   FIVE   4794253620   44971.0   46972,FIVE,num=4794253620,size=2758,HMS=44971.0,dt=2001.0,n=0,m=2002,clock=8.4760000000024
0.1   46972   FIVE   4794253621   44971.0   46972,FIVE,num=4794253621,size=2759,HMS=44971.0,dt=2001.0,n=0,m=2002,clock=8.4760000000024
0.1   46972   MTSS   4794253982   44990.0   46972,MTSS,num=4794253982,size=2394,HMS=44990.0,dt=1982.0,n=0,m=1983,clock=8.4760000000024
0.1   46972   MTSS   4794255354   45061.0   46972,MTSS,num=4794255354,size=2396,HMS=45061.0,dt=1911.0,n=0,m=1912,clock=8.4760000000024
0.1   46972   MTSS   4794255355   45061.0   46972,MTSS,num=4794255355,size=2397,HMS=45061.0,dt=1911.0,n=0,m=1912,clock=8.4760000000024
0.1   46972   MTSS   4794255356   45061.0   46972,MTSS,num=4794255356,size=2398,HMS=45061.0,dt=1911.0,n=0,m=1912,clock=8.4760000000024
0.1   46972   MTSS   4794255903   45095.0   46972,MTSS,num=4794255903,size=2402,HMS=45095.0,dt=1877.0,n=0,m=1878,clock=8.4770000000026
0.1   46972   MTSS   4794255904   45095.0   46972,MTSS,num=4794255904,size=2403,HMS=45095.0,dt=1877.0,n=0,m=1878,clock=8.4770000000026
0.1   46972   FIVE   4794256157   45107.0   46972,FIVE,num=4794256158,size=2763,HMS=45107.0,dt=1865.0,n=0,m=1866,clock=8.4770000000026
0.1   46972   FIVE   4794256158   45107.0   46972,MTSS,num=4794256215,size=2405,HMS=45110.0,dt=1862.0,n=0,m=1863,clock=8.4770000000026
0.1   46972   MTSS   4794256215   45110.0   46972,MTSS,num=4794256215,size=2405,HMS=45110.0,dt=1862.0,n=0,m=1863,clock=8.4770000000026
0.1   46972   MTSS   4794256220   45111.0   46972,MTSS,num=4794256220,size=2407,HMS=45111.0,dt=1861.0,n=0,m=1862,clock=8.4770000000026
0.1   46972   VSMO   4794213402   42862.0   46972,VSMO,num=4794213402,size=2696,HMS=42862.0,dt=4110.0,n=0,m=4111,clock=8.4770000000026
0.1   46972   VSMO   4794213403   42862.0   46972,VSMO,num=4794213403,size=2697,HMS=42862.0,dt=4110.0,n=0,m=4111,clock=8.4770000000026
0.1   46972   VSMO   4794213404   42862.0   46972,VSMO,num=4794213404,size=2698,HMS=42862.0,dt=4110.0,n=0,m=4111,clock=8.4770000000026
0.1   46972   VSMO   4794213405   42862.0   46972,VSMO,num=4794213405,size=2699,HMS=42862.0,dt=4110.0,n=0,m=4111,clock=8.4770000000026
0.1   46972   VSMO   4794213406   42862.0   46972,VSMO,num=4794213406,size=2700,HMS=42862.0,dt=4110.0,n=0,m=4111,clock=8.4770000000026
0.1   46972   VSMO   4794213881   42889.0   46972,VSMO,num=4794213881,size=2702,HMS=42889.0,dt=4083.0,n=0,m=4084,clock=8.4770000000026
0.1   46972   VSMO   4794214435   42919.0   46972,VSMO,num=4794214435,size=2704,HMS=42919.0,dt=4053.0,n=0,m=4054,clock=8.482
0.0   46972   VSMO   4794214436   42919.0   46972,VSMO,num=4794214436,size=2705,HMS=42919.0,dt=4053.0,n=0,m=4054,clock=8.482
0.1   46972   VSMO   4794214729   42935.0   46972,VSMO,num=4794214729,size=2707,HMS=42935.0,dt=4037.0,n=0,m=4038,clock=8.482
0.1   46972   VSMO   4794214730   42935.0   46972,VSMO,num=4794214730,size=2708,HMS=42935.0,dt=4037.0,n=0,m=4038,clock=8.482
0.1   46972   VSMO   4794214732   42936.0   46972,VSMO,num=4794214732,size=2710,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.1   46972   VSMO   4794214733   42936.0   46972,VSMO,num=4794214733,size=2711,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.1   46972   VSMO   4794214734   42936.0   46972,VSMO,num=4794214734,size=2712,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.1   46972   VSMO   4794214735   42936.0   46972,VSMO,num=4794214735,size=2713,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.0   46972   VSMO   4794214736   42936.0   46972,VSMO,num=4794214736,size=2714,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.1   46972   VSMO   4794214737   42936.0   46972,VSMO,num=4794214737,size=2715,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
0.1   46972   VSMO   4794214738   42936.0   46972,VSMO,num=4794214738,size=2716,HMS=42936.0,dt=4036.0,n=0,m=4037,clock=8.482
первое число в стоке - задержка передачи параметров из QUIK в приложение в мкс.
--------------------
Резюме:  задержка передачи методом file mapping параметров из QUIK в другое приложение составляет 0.0000001 сек.

Пример
 
Добрый день,
по просьбе трудящихся выкладываю пример на QPILE
Код
PORTFOLIO_EX TEST;
DESCRIPTION TEST;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST FIRM_ID;
USE_CASE_SENSITIVE_CONSTANTS;

PROGRAM

NEW_GLOBAL("count",0)
NEW_GLOBAL("CLAS","CETS")
NEW_GLOBAL("List","USD000000TOD,EURUSD000TOD,EUR_RUB__TOD")
NEW_GLOBAL("com",0.000445)

i=1
dif=0
e=1-3*com
f=create_map()
z=create_map()
FOR SEC IN List
  s=get_param_ex(CLAS,SEC,"SHORTNAME")
  n=get_value(s,"PARAM_IMAGE")
  s=get_param_ex(CLAS,SEC,"LAST")
  p=get_value(s,"PARAM_IMAGE")+0
  s=get_param_ex(CLAS,SEC,"OFFER")
  po=get_value(s,"PARAM_IMAGE")+0
  s=get_param_ex(CLAS,SEC,"BID")
  pb=get_value(s,"PARAM_IMAGE")+0
  s=get_param_ex(CLAS,SEC,"LOTSIZE")
  q=get_value(s,"PARAM_IMAGE")+0
  z=set_value(z,"Name",n)
  z=set_value(z,"last",p)
  z=set_value(z,"bid",pb)
  z=set_value(z,"offer",po)
  z=set_value(z,"lotsize",q)
  IF count=0
   add_item(i,z)
  ELSE
   MODIFY_ITEM(i,z)
  END IF
  IF i==3
    IF pb>0
      dif=e/pb-1
      f=set_value(f,"lotsize",dif)
   END IF
  ELSE
    e=e*po
  END IF
  i=i+1
END FOR

IF count=0
  add_item(4,f)
ELSE
   MODIFY_ITEM(4,f)
END IF
 count=1
END_PROGRAM

PARAMETER Name;
PARAMETER_TITLE Name;
PARAMETER_DESCRIPTION here is Name;
PARAMETER_TYPE STRING(15);
END

PARAMETER last;
PARAMETER_TITLE last;
PARAMETER_DESCRIPTION good;
PARAMETER_TYPE STRING(10);
END

PARAMETER bid;
PARAMETER_TITLE bid;
PARAMETER_DESCRIPTION good;
PARAMETER_TYPE STRING(10);
END

PARAMETER offer;
PARAMETER_TITLE offer;
PARAMETER_DESCRIPTION good;
PARAMETER_TYPE STRING(10);
END

PARAMETER LOTSIZE;
PARAMETER_TITLE lotsize;
PARAMETER_DESCRIPTION good;
PARAMETER_TYPE STRING(10);
END

END_PORTFOLIO_EX


 
Кто сможет объяснить необъяснимое?
 
Ув, разработчики
Просьба объяснить следующий феномен работы системы QUIK
-----------------------
На реальном рынке вычисляю функцию распределения запаздывания времени прихода обезличенных сделок  в терминал QUIK на моем компе с сервера брокера сбербанк.
----------------------
Алгоритм расчета следующий
Вычисляем разницу текущего времени компа и времени обезличенной сделки и в добавляем 1 в ячейку массива с индексом равным разности.
В результата по  24 000 обезличенных сделок
получаем следующий график распределения запаздывания


Что получилось:
80% пришло с задержкой не более 1 секунды  это при пинге до сервера 0.03 сек.
12% с задержкой от 1 до 2 секунд
8% с задержкой более 2 секунд
1% с задержкой 17 секунд
0.5% с задержкой 30 секунд
---------------------
Что не так c сервером QUIK у брокера Сбербанк.
Запаздывание свечей. Что не так.?
 
Добрый день,
Сделал тест получения свечей с интервалом 1 5 и 30 мин для всех инструментов, которые определены у меня в ТТП
В лог файл выводим время открытия новой свечи и время свечей
------------------
Тест исполняем на реальных торгах Брокер Сбербанк.
=================
вот результаты в лог файле время местное на 1 час сдвинуто относительно биржевого
Код
Fri Apr 14 12:36:01 2023,sec=MAGN ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:02 2023,sec=SBER ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:02 2023,sec=VTBR ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:03 2023,sec=NVTK ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:03 2023,sec=YNDX ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:03 2023,sec=LKOH ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:03 2023,sec=GAZP ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:04 2023,sec=GMKN ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:04 2023,sec=CHMF ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:04 2023,sec=POLY ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:04 2023,sec=MGNT ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:05 2023,sec=ROSN ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:05 2023,sec=SBERP ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:05 2023,sec=IRAO ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:06 2023,sec=TATN ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:06 2023,sec=ALRS ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:07 2023,sec=MTLR ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:07 2023,sec=NLMK ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:08 2023,sec=PLZL ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:09 2023,sec=AFKS ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:10 2023,sec=AFLT ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:17 2023,sec=AMEZ ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:27 2023,sec=SNGSP ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:27 2023,sec=OGKB ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:28 2023,sec=ZILL ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:29 2023,sec=HYDR ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:31 2023,sec=TATNP ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:32 2023,sec=LSRG ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:38 2023,sec=AKRN ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:46 2023,sec=PIKK ,T30=123000.0,T5=123500.0,T1=123600.0
Fri Apr 14 12:36:55 2023,sec=SNGS ,T30=123000.0,T5=123500.0,T1=123600.0
Обращаю внимание на следующее:
----------------------
Для инструмента в 1 ой строке минутная свеча сформирована  01 секунду
----------------------------------
Fri Apr 14 12:36:01 2023,sec=MAGN ,T30=123000.0,T5=123500.0,T1=123600.0
-------------------------
а для инструмента в последней строке через 55 секунд после первой.
Fri Apr 14 12:36:55 2023,sec=SNGS ,T30=123000.0,T5=123500.0,T1=123600.0
-----------------------------
Чем дальше в таблице инструмент от первой строки тем больше запаздывание.
--------------------------------
Что не так?
Вам такое не снилось!!!, LUA5.3 LUAJIT MQL5
 
   
Сравни LUA5.3 и LUAJIT в QUIK
 
Добрый день,
Ранее сообщал, что сделал возможность запуска скриптов QUIL  в отдельных потоках в LUAJIT.
----------------
кратко это работает так.
В колбек OnParam приходят сделки инструментов, которые передаются в функцию main()
-----------------------
В main - это LUA 5.3  по каждому инструменту запускается скрипт алгоритма робота в отдельном потоке из пула потоков  под LUAJIT.
======================
На просторах интернета нашел тесты по которым разработчики сравнивали MT5  сравнивали  MQL5 и LUA в QUIK.
---------------------
вот сами тесты:
Код
-- TestQuickSort
local array={}
local function QuickSort(arr,left,right)
  local  i=left
  local  j=right
  local  center=arr[math.floor((i+j)/2)]
    while i<=j do
        while(arr[i]<center and i<right) do   i=i+1  end
        while(arr[j]>center and j>left) do  j=j-1   end
        if i<=j then  local   x=arr[i]   arr[i]=arr[j]    arr[j]=x     i=i+1    j=j-1  end
    end
    if left<j then  QuickSort(arr,left,j)  end
    if right>i then  QuickSort(arr,i,right)  end
end

local function Start1()
    for i=0,MAX_SIZE-1 do  array[i]=i%100 end
    start=os.clock()
    QuickSort(array,0,MAX_SIZE-1)
    res=(os.clock()-start)*1000
    print("TestQuickSort SIZE="..MAX_SIZE..", time=" .. res .. " ms")
    for i=1,MAX_SIZE-1 do
        if array[i]<array[i-1] then  print("Array not sorted"); break;
        end
    end
end

local str=""
local a={}
local function PiCalculate(digits)
local   d = 0
local   c = (math.floor(digits/4)+1)*14
local   f = 10000
   for i=0,c do a[i]=20000000   end
   c=c-14
   b=c
   while b>0 do
      e=d%f
      d=e
      while b-1>0 do
         b=b-1
         d = d * b + a[b]
         g = (b * 2) - 1
         a[b]=(d%g)*f
            d=math.floor(d/g)
        end
        r=e+math.floor(d/f)
      if r<1000 then
         if(r>99) then
            str=str .. "0"
         else
            if(r > 9) then
               str=str .. "00"
            else
               str=str .. "000"
            end
         end
      end
      str=str .. string.format("%d",r)
      c=c-14
      b=c
   end
end

function Start2()
   start=os.clock()
   PiCalculate(MAX_SIZE)
   res=(os.clock()-start)*1000
   print("TestPiCalculated SIZE="..MAX_SIZE..", time=" .. res .." ms  Pi="..string.sub(str,1,16))
end

-- TestFibo

local fib={}
local function TestFibo(n)
   if n<2 then return 1 else return TestFibo(n-2)+TestFibo(n-1) end
end

local function Start3()
   start=os.clock()
   for i=0,MAX_SIZE-1 do    fib[i]=TestFibo(i) end
   res=(os.clock()-start)*1000
   print("TestFibo SIZE="..MAX_SIZE..", time="..res.." ms Fibo[39]="..fib[39])
end

-- TestArrays
local function Start4()
   local  x={}    local y={}
    local start=os.clock()
    for i=1,MAX_SIZE,1 do   x[i]=i  y[i]=0   end
    y[MAX_SIZE]=0
    for k=1,MAX_SIZE,1 do
        for i=MAX_SIZE, 1,-1 do  y[i]=y[i]+x[i] end
    end
    local res=(os.clock()-start)*1000
    local check=0
    for k=1,MAX_SIZE,1 do check=check+y[k]  end
    print("Test Arrays SIZE="..MAX_SIZE..", Time = "..res.." ms check=".. check)
end

local function Ackermann(m,n)
        if(m==0) then return(n+1) end
        if(n==0) then return(Ackermann(m-1,1)) end
        return(Ackermann(m-1,Ackermann(m,(n-1))))
end

-- TestAckermann
local function Start5()
    local check=0
    local start=os.clock()
        for i=1,MAX_SIZE do  check=check+Ackermann(1+i%3,1+i%5); end
    local finish=os.clock()
    local res=(finish-start)*1000
    print("TestAckermann SIZE="..MAX_SIZE..",time=".. string.format("%.0f",res).." ms check="..check)
end


-- TestFloat
local f0=0.0
local f1=123.456789
local f2=98765.12345678998765432
local f3=12345678943.98

function TestFloat(MAX_SIZE)
   MAX_SIZE=MAX_SIZE-1
   for i=0, MAX_SIZE do
        for j=0, MAX_SIZE do
            f0=f0+(f1/(i+1))-f2+(f3*i);
        end
    end
end

function Start6()
   local t=os.clock()
   TestFloat(MAX_SIZE)
   local res=(os.clock()-t)*1000
 local  check=f0
   print("TestFloat SIZE="..MAX_SIZE..", time=" ..res.." ms  check="..tostring(check));
end


MAX_SIZE=35000; Start6()
MAX_SIZE=120000; Start5()
MAX_SIZE=32000; Start4()
MAX_SIZE=40; Start3()
MAX_SIZE=22000; Start2()
MAX_SIZE=16000000; Start1()
===================
На этих тестах я провел тест LUA 5.3 и LUAJIT.
==================
Результаты  говорят сами за себя:

Когда подключу MT5 к QUIK, то сделаю тест и для него.
-----------------------
Следите за новостями.
Вызов функций С из DLL в скрипте Lua QUIK, информация к размышлению
 
Добрый день,
Всем известно, что есть  библиотека ffi
https://luajit.org/ext_ffi.html
Библиотека FFI позволяет вызывать внешние функции C и использовать структуры данных C из чистого кода Lua.
Библиотека FFI в значительной степени устраняет необходимость написания утомительных ручных привязок Lua / C на C.
Нет необходимости изучать отдельный язык привязки — он анализирует простые объявления C!
Они могут быть вырезаны и вставлены из заголовочных файлов C или справочных руководств.
Это задача связывания больших библиотек без необходимости иметь дело с хрупкими генераторами привязки.
---------------------
Все казалось прекрасно, но...
Библиотека FFI тесно интегрирована в LuaJIT (она недоступна как отдельный модуль).
конечно, не так уж страшно, но...
LuaJIT сделан на ядре Lua5.1 и следовательно для квика не подходит.
------------------------
Написал  собственную библиотеку  для любого ядра Lua, которая делает тоже самое, что и FFI, но быстрее.
В итоге можно загрузить на исполнение любую функцию написанную на С/С++ из любой библиотеки DLL.
И следовательно получить максимальную скорость вычисления любых алгоритмов, не программируя на СИ и не изучая API C for Lua.
----------------------------
Накладные расходы на преобразование параметров в пределах кванта высокоточного таймера (см далее).
---------------------------
Вот пример вызова трех функций из WIN32
------------------------------
QueryPerformanceCounter  - высокоточный таймер квант 0.1 мкс.
SleepEx - функция паузы
MessageBoxA - вывод окна сообщения
пример вызова в луа:
В программе два варианта измерение интервала Sleep в 1 секунду
и вывод результата в окно
Код
-------------sleep и высокоточный таймер вариант 1 -------------------
local x1=rfs("i","QueryPerformanceCounter","Kernel32.dll");
rfs(0,"SleepEx","Kernel32.dll",1000,0);
local x2=rfs("i","QueryPerformanceCounter","Kernel32.dll");


-------------sleep и высокоточный таймер вариант 2 -------------------
local pL,pF=nkcf.gf2L("Kernel32.dll","QueryPerformanceCounter")

local x3=rfs("i",pF);
rfs(0,"SleepEx","Kernel32.dll",1000,0);
local x4=rfs("i",pF);
s="t1="..0.1*(x2-x1).." мкс".." t2="..0.1*(x4-x3).." мкс";
print("            "..s);
rfs(0,"MessageBoxA","User32.dll",0, s, "sleep, timer",1);

а вот картинка результата

 
MT5+QUIK
 
Добрый день,
Реализовал механизм  запуска  в скрипте на луа  как отдельный поток или процесс
приложений на любом языке.
Теперь хочу подключить торговые платформы.
------------------
Из бесплатных есть лишь MT5.
Давно работал с MT4, с MT5 лишь  знакомился.
=====================
На вскидку подключить сравнительно просто, как и приложения на питоне,
но пока не знаю что это даст.
============================  
Если у кого есть опыт работы с MT5 на фондовом рынке
или работы на TM5+QUIK, то поделитесь опытом и проблемами,
а также хотелками.
Спасибо.
Что не так?
 
Выставляю и снимаю заявки на демо сервере.   КВИК 9.7  Луа 5.3.5
Иногда систематически прилетает ответ  в onOrders    с trans_id=0 , а в таблице orders не ноль
-------------------
вот пример
это в колбеке:
["trans_id"]=0, ["ordernum"]=21555625,
Код
5>пров.архив nun=21555625,t11=1087597,N=84,i=85,No=1086615,n.id=0,n.num=21555625,id=0,i_or=1086614
t={
["start_date"]=0,
["yield"]=0.0,
["settle_date2"]=0,
["withdraw_datetime"]={
["day"]=1,
["week_day"]=1,
["month"]=1,
["hour"]=0,
["min"]=0,
["sec"]=0,
["ms"]=0,
["year"]=1601,
["mcs"]=0},
["qty"]=1.0,
["value"]=80400.0,
["acnt_type"]=0,
["filled_value"]=0.0,
["activation_time"]=0,
["expiry_time"]=-1,
["sec_code"]=EUR_RUB__TOM,
["accepted_uid"]=0,
["price_currency"]=RUB,
["awg_price"]=0.0,
["userid"]=MD1000100002,
["seccode"]=EUR_RUB__TOM,
["uid"]=0,
["bank_acc_id"]=MB1000100002,
["ext_order_flags"]=0,
["expiry"]=-1,
["repovalue"]=0.0,
["on_behalf_of_uid"]=0,
["price"]=80.4,
["price2"]=0.0,
["executing_trader_short_code"]=0,
["accruedint"]=0.0,
["extref"]=,
["capacity"]=0,
["linkedorder"]=0,
["exchange_code"]=20833806,
["balance"]=1.0,
["executing_trader_qualifier"]=0,
["client_qualifier"]=0,
["value_entry_type"]=0,
["flags"]=25,
["repo_value_balance"]=0.0,
["value2"]=0.0,
["class_code"]=CETS,
["passive_only_order"]=0,
["canceled_uid"]=0,
["investment_decision_maker_short_code"]=0,
["repoterm"]=0,
["order_num"]=21555625,
["lseccode"]=,
["ext_order_status"]=0,
["qty2"]=0.0,
["price_entry_type"]=1,
["trading_session"]=0,
["operation_type"]=-1,
["visible_repo_value"]=0.0,
["visibility_factor"]=0.0,
["visible"]=0.0,
["side_qualifier"]=0,
["exec_type"]=0,
["repo2value"]=0.0,
["datetime"]={
["day"]=13,
["week_day"]=1,
["month"]=3,
["hour"]=19,
["min"]=31,
["sec"]=3,
["ms"]=873,
["year"]=2023,
["mcs"]=873468},
["settle_date"]=20230314,
["min_qty"]=0.0,
["trans_id"]=0,
["client_code"]=10546,
["settlecode"]=,
["investment_decision_maker_qualifier"]=0,
["ordernum"]=21555625,
["brokerref"]=10546,
["client_short_code"]=0,
["account"]=MB1000100002,
["start_discount"]=0,
["revision_number"]=0,
["settle_currency"]=RUB,
["reject_reason"]=,
["firmid"]=MB1000100000}

а это в таблице сделок


EUR_RUB__TOM 21 555 625 1 087 594 19:31:03 873468 19:31:04 106675 CETS Купля MB1000100002 80.4000 1 1 0 80 400.00 RUB 208 543 208 543 10546 10546 ЛРО Снята MB1000100002 EUR 1 000 80 400.00
Мало кто об этом знает.
 
Дело бы вечером, делать было нечего.
---------------
Предположим, что у Вас есть большая таблица в терминале 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 кушает память.
И  в этом случае мы просто нашли нужную нам заявку в таблице заявок.
-------------------------------------------------------
Угадайте, как с этим бороться?
Проблема с функцией getBuySellInfo
 
Пишем вот такой фрагмент:
Код
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   Максимально возможное количество инструментов в заявке на продажу этого инструмента на этом классе из собственных активов клиента, исходя из цены лучшего спроса
и затем выводим на печать исходные данные
Код
firm=SPBFUT000000, acc=SPBFUT00049, client=SPBFUT00049, clas=SPBFUT, sec=GDH3
и результаты работы
функции  CalcBuySell  (для сравнения)
Код
price=1161.5,qtyB=12,qtyS=10
и функции getBuySellInfo (проверяем)
Код
tp={}
Qbuy=nil,Qsel=nilNQb=nil,NQs=nil
CalcBuySell  выдает какие-то значения,
getBuySellInfo выдает пустую таблицу tp  
================
Что не так c getBuySellInfo?
КРАШ -ТЕСТ терминала
 
Добрый день,
----------------------
Написал скрипт краш-теста.
В целом результатами доволен.
Рассказываю подробности.
----------------------------,
Условия теста:
демо-сервер
версия терминала 9.7 ( тормозная)
--------------------
Робот на каждую принятую сделку по колбеку OnParam рассчитывает  цену на 20 шагов ниже цены последней сделки
определяет максимальное число контрактов для текущего инструмента функцией CalcBuySell
и выставляет заявку на покупку одного контракта по расчетной цене.
При очередном вызове колбека , робот  снимает все выставленные ранее заявки ,
проверяет отсутствие неисполненной транзакции и открытой заявки по текущему инструменту
и  при положительном решении, выставляет новую заявку.
--------------------
Результаты теста(фрагмент):
Код
31381.046s,240us, 28, 117, 30, 46.us, SFH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673016,#tparam=1,NNsec=908
31381.172s,613us, 55, 417, 47, 75.us, SiH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673018,#tparam=3,NNsec=908
31381.173s,284us, 30, 139, 24, 60.us, MXH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673019,#tparam=2,NNsec=908
31381.173s,214us, 19, 119, 24, 34.us, MMH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673020,#tparam=1,NNsec=908
31381.177s,361us, 37, 206, 33, 54.us, RMH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673022,#tparam=2,NNsec=908
31381.177s,210us, 22, 105, 28, 38.us, RIH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673023,#tparam=1,NNsec=908
31381.244s,385us, 53, 155, 83, 81.us, CRH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673026,#tparam=2,NNsec=908
31381.244s,195us, 21, 81, 28, 39.us, MXH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673027,#tparam=1,NNsec=908
31381.247s,312us, 36, 156, 38, 55.us, SVH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673029,#tparam=1,NNsec=908
31381.249s,231us, 25, 106, 32, 43.us, SiH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673031,#tparam=1,NNsec=908
31381.254s,3448us, 3115, 216, 41, 3131.us, USD000UTSTOM,ns_CETS=15,sumT=8188,Norder=277953,jc=2673033,#tparam=4,NNsec=908
31381.257s,2656us, 2414, 159, 24, 2429.us, CNYRUB_TOM,ns_CETS=15,sumT=8188,Norder=277953,jc=2673034,#tparam=3,NNsec=908
31381.26s,3379us, 3135, 159, 24, 3150.us, EUR_RUB__TOM,ns_CETS=15,sumT=8188,Norder=277953,jc=2673035,#tparam=2,NNsec=908
31381.263s,2509us, 2292, 137, 23, 2307.us, USDCNY_TOM,ns_CETS=15,sumT=8188,Norder=277953,jc=2673036,#tparam=1,NNsec=908
31381.37s,465us, 60, 223, 90, 83.us, USDRUBF,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673037,#tparam=3,NNsec=908
31381.37s,181us, 22, 75, 27, 39.us, TTH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673038,#tparam=2,NNsec=908
31381.37s,184us, 22, 85, 24, 38.us, SiH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673039,#tparam=1,NNsec=908
31381.373s,496us, 37, 140, 34, 54.us, GKH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673041,#tparam=1,NNsec=908
31381.374s,389us, 34, 192, 70, 64.us, GKH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673043,#tparam=2,NNsec=908
31381.375s,186us, 25, 77, 25, 42.us, SPH3,ns_SPBFUT=35,sumT=8188,Norder=277953,jc=2673044,#tparam=1,NNsec=908
Время работы теста составило примерно 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.
 
Добрый день,
Посвятил целую неделю, чтобы выполнить работу разработчиков и найти критическую ошибку версий 9 10, по которой терминал может минутами не отвечать.
--------------------------
Если У Вас нет желание это наблюдать,
то рекомендую не ставить эти версии,
а также другие выше 8 , пока разработчики официально не укажут на исправление этой ошибки.
--------------------------
В настоящее время последней нормальной версией является 8.7.1.3, которую и рекомендую.
 
не работают "горячие клавиши"
 
В таблице позиций по фьючерсам не работает  "Закрыть все" и соответствующая горячая клавиша.
Если так задумано, то сделать их невидимыми
нет в документации
 
Добрый день,
Просьба пояснить при каких условиях выдаются следующие сообщения:
В документации не нашел, если есть, дайте ссылку.
1. Превышена позиция по инструменту
2. Превышен лимит отправки транзакций для данного логина.
ДемоСчет. Что не так?
 
Добрый день,
второй день на демо счете все чудеснее и чудеснее.
В настоящее время при загрузке демо квика версии 10.01  
терминал QUIK-JUNIOR подключается к демо счету
после этого не отвечает по несколько минут на каждое нажатие мышки на экране.
А в диспетчере задач видим следующее.

2-я строка это демо сервер версия 10 загрузка процессора около 30%
1-я строка рабочий терминал версия 8.7 загрузка процессора около 3%

для сравнения загрузил версию 9.7  и наблюдаем чудеса:


-----------
На рабоем терминале работают индикаторы и скрипты
На демо терминалах ничего своего не ставил.
Просто скачал развернул и подключил.
И ловлю кайф.  
Такого прикола еще не видел.  
Демо счет 2, Ау, разработчики.
 
Полагаю, что отсутствие класса фьючерсов  на демо
связано с тем,
что Вы забыли установить входящий остаток по средствам на демо счете фьючерсов.
---------------------
Потому и класс нет.
======================
Может в консерватории надо что-то исправить.
 
проблема с функцией getDepo
 
Добрый день,
тестирую функции на демо сервере.
Сделал лишь старт квика. т е ничего не покупал и не продавал.
-----------------
поясняю:
колбек 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 нулевыми значениями
================
А теперь смотрим лог файл
Код
 clas=CETS,sec=EURUSD000TOM
clas=CETS,sec=EURUSD000TOM,firm=MB1000100000,account=MB1000100002,client=10323
type=table
tim=29.6543,tim1=0.061899999999998

 clas=CETS,sec=USD000UTSTOM
clas=CETS,sec=USD000UTSTOM,firm=MB1000100000,account=MB1000100002,client=10323
type=table
tim=28.3573,tim1=0.041400000000007

 clas=CETS,sec=CNYRUB_TOM
clas=CETS,sec=CNYRUB_TOM,firm=MB1000100000,account=MB1000100002,client=10323
type=table
tim=26.3304,tim1=0.044000000000008

 clas=CETS,sec=USD000000TOD
clas=CETS,sec=USD000000TOD,firm=MB1000100000,account=MB1000100002,client=10323
type=table
tim=26.163,tim1=0.048399999999997

 clas=CETS,sec=EUR_RUB__TOM
clas=CETS,sec=EUR_RUB__TOM,firm=MB1000100000,account=MB1000100002,client=10323
type=table
tim=26.6879,tim1=0.0442

 clas=QJSIM,sec=ALRS
clas=QJSIM,sec=ALRS,firm=NC0011100000,account=NL0011100043,client=10323
type=table
tim=27.8828,tim1=0.052700000000005

 clas=QJSIM,sec=MSTT
clas=QJSIM,sec=MSTT,firm=NC0011100000,account=NL0011100043,client=10323
type=table
tim=27.8581,tim1=0.125

 clas=QJSIM,sec=PLZL
clas=QJSIM,sec=PLZL,firm=NC0011100000,account=NL0011100043,client=10323
type=table
tim=27.1135,tim1=0.051300000000001

 clas=QJSIM,sec=SBER
clas=QJSIM,sec=SBER,firm=NC0011100000,account=NL0011100043,client=10323
до последней строки инструменты в таблице позиций отсутствуют
в последней строке SBER и QUIK висит.
--------------------
Что не так?
Проблема Сервера QUIK?, Вопрос риторический
 
Сегодня в Сбербанке повторилось.
Дата торгов была вчера. И естественно вчерашний день пропал.
--------------
Проблема решилась лишь после разрыва связи , длительного ожидания и установки связи заново.
----------------
Так как такую и подобные проблемы наблюдал неоднократно, то хочу высказать свое предположение о ее источнике.
===================
проблема возникает, если установить соединение до начала торгов, либо в момент начала.
Предположу, что при этом происходит не полная загрузка с сервера начальных данных, но после начала торгов сервер не проверяет некорректность данных у клиентов
а продолжает работу с неполными либо с неверными данными.
============
Полагаю, это недоработка разработчиков QUIK.
Но это лишь мои предположения.
===============
Проблема решается иногда лишь перезагрузкой но после начала торгов и длительного ожидания.
лыко да мочало начинай сначала
 
В сбербанк брокер теперь новая х...я
---------------
 
новая хрень у Сбербанка
 
 
вопрос к разработчикам QLUA
 
Добрый день,
решил написать робота,
который работает со всеми доступными в терминале кодами клиентов
и вдруг откуда не возьмись появился ...  затык.
-----------------------
Вопрос:
----------------
Каким образом ,т е на основе каких таблиц или функций,
можно установить соответствие  кода клиента (таблица client_codes)
торговому счету (таблица trade_accounts)
-------------------
Спасибо
Страницы: 1 2 3 След.
Наверх