nikolz (Автор тем)

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

Страницы: Пред. 1 2 3 След.
Для писателей роботов
 
Рекомендую ознакомиться :
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)
-------------------
Спасибо
Что не так?
 
Попытался установить новую версию для демо.
при распаковке получил это:
 
и такая дребедень Целый день
 
брокер Сбербанк.
Стыдоба - это ведущий банк РФ.   Внедряют ИИ.



и такая дребедень Целый день.
QUIK съедает более 2 ГБ памяти вне зависимости от брокера.
 
Добрый день,
Периодически на форуме появляются душераздирающие вопли о том,
что мол у брокера .... QUIK съедает .. ГБ.
Попытка объяснить ,
что и как надо сделать наталкивается либо на вопли "мы все это знаем",
либо на рассуждения о том, что это не у любого брокера, а лишь у избранного.
----------------------
Полагаю, что проблема не в зеркале,
то есть не в брокере,
а как обычно, в отсутствии знаний у пользователя.
-----------------
Доказательство:
-------------------
брокер СБЕРБАНК.
Чтобы доказать, что брокер не виноват,
специально настроил QUIK так, чтобы получить наибольшую загрузку памяти для этого брокера.
---------------------------
Желающие могут получить и большую загрузку.
Я к этому не стремился, но знаю как это сделать.
-----------------
итак вот картинка результата сегодня:


а это результат обычной настройки

-----------------------------------------------
Успехов в борьбе за знания, т.е. за память.
старт скрипта по расписанию
 
Добрый день,
Пример запуска скрипта по расписанию.
Если есть вопросы - пишите
Код
local isRun=0;  --флаг завершения функции main
local fstop=true;  -- флаг остановки скрипта при запуске по расписанию
local Ts={"12:53:00","12:54:00","12:55:00","12:56:00","12:57:00","12:58:00","12:59:00",}
for i=1,#Ts do local x=Ts[i] Ts[i]=60*(60*string.sub(x,1,2)+string.sub(x,4,5))+string.sub(x,7,8); end
------------
function main()
   local jT,x=0,0;
   while isRun do
      if #Ts>jT then  local dt=-1;
         if fstop then fstop=false;  -- в колбеках первой строкой поставить if fstop then return end
            x= getInfoParam("SERVERTIME"); --      local x=os.date("%X");
            local z=60*(60*string.sub(x,1,2)+string.sub(x,4,5))+string.sub(x,7,8);
            while #Ts>jT and 0>dt do jT=jT+1; dt=Ts[jT]-z; end
         end
         if dt>=0 then message(x.." до старта "..dt.."сек"); sleep(1000*dt); else sleep(1); end
      end
      if fstop==false then  x= getInfoParam("SERVERTIME");    message("старт "..x.." fstop="..tostring(fstop) ); end
  -- исполнение скрпита
      fstop=true;  --- остановить скрипт
      if fstop then    x= getInfoParam("SERVERTIME");  message("стоп  "..x.." fstop="..tostring(fstop) ); end
   end
end

Предлагаю углубить, Расширение функций библиотеки QLUA
 
Добрый день,
Предлагаю добавить в библиотеку QLUA функцию установки идентификатора для графика цена и индикатора .
---------------------
Объясняю зачем:
--------------------
1) Для установки идентификатора не надо будет лазить в меню окна.
Причем очень достает устанавливать этот идентификатор для индикатора при отладке индикатора.
----------------------------
2) идентификатор графика цены нужен для вывода меток на график.
Если это график с якорем, то отображаемый инструмент будет изменяться при изменении активной строки в таблице, а идентификатор при этом не меняется.
С помощью предлагаемой функции можно в скрипте динамически изменять идентификатор, например, указывая в нем имя инструмента.
В итоге можно метки на графике разделить по инструментам.
------------------------------
3) идентификатор индикатора нужен для чтения параметров индикатора в скрипте луа.
Сейчас для этого   надо лазить в меню окна и прописывать идентификатор в Settings.
В итоге идентификатор для индикатора можно будет динамически привязывать к инструменту, интервалу и алгоритму индикатора.
Lua советник
 
Добрый день,
---------------------------
Пример простого, универсального советника на луа на основе любых индикаторов.
------------------------------
Советник - это программа,
которая формирует сигналы "купить/продать" и показывает их, но не совершает сделки.
---------------------
Пример на основе  стратегии  пересечения двух скользящих средних.
Помещаем два индикатора на график цены инструмента
Присваиваем им идентификаторы MOV1 и MOV2  как на рисунке:

   

далее  пишем индикатор  "nk_bot"
Код
Settings={ i1="MOV2",i2="MOV1", Name = 'nk_bot', }
------------------
local function gI(s,j,i)
 local t=getCandlesByIndex(s,j,i-1,1); if t then return t[0].close; else return 0 end
end --значение индикатора
-------------------------
local function cross(s1,j1,s2,j2,i)
   local m=i; local x= gI(s1,j1,m) local x1=gI(s2,j2,m);
    while m>1 and x~=0 and x1~=0 and x>x1 do m=m-1; x=gI(s1,j1,m); x1=gI(s2,j2,m) end
    if m>1 and i>m then return m end
end  --пересечение
--------------------------
function OnCalculate(i)
   local Bu,Se; local i1=i-1;
   if i>1 then
      local jU_,jD_=jU,jD;
      jU=cross(Settings.i1,0,Settings.i2,0,i1); --MOV1 пересекает MOV2 снизу вверх
      jD=cross(Settings.i2,0,Settings.i1,0,i1); --MOV1 пересекает MOV2 сверху вниз
      if jU and jU_==nil then jBu=i; Bu=L(i)-0.1; end
      if jD and jD_==nil then jSe=i; Se=H(i)+0.1; end
      if i==Size() then  -- последняя свеча
      end
   end
return Se,Bu;
end
-----
function Init()
local t={};
   t[#t+1]={Name = "Se",Color = RGB(255,0,0),Type = 11,Width =3};   ---sell
   t[#t+1]={Name = "Bu",Color = RGB(0,255,0),Type = 10,Width =3};   ---buy
Settings.line=t;
return #t;
end

и помещаем его на график инструмента
В результате получим на истории торгов сигналы "купить/ продать" на графике инструмента

---------------------
На основе данного примера  Вы можете построить советник для  любых индикаторов,
которые встроены в терминал КВИК  или написаны кем-то.
Прикольно, но ошибка
 
Недавно сообщал на форуме о том,
что дата сервера в текущих торгах показывает вчерашнюю дату.
сегодня выявил как это можно повторить.
-------------------
проблему можно обнаружить, если загрузить квик и подключить его к серверу до начала торгов.
В этом случае, после начала торгов дата сервера не обновляется и остается равной дате предыдущих торгов.
если разорвать соединение и снова восстановить то дата сервера обновляется до текущей.
--------------------
От версии КВИКА этот прикол не зависит.
Ответ на вопрос: "Что быстрее , рассчитать индикатор или взять с графика?"
 
Добрый день,
---------------
сделал следующий тест.
На график вывел два варианта индикатора  стохастик.
-----------------------
1)  встроенный в терминал (третий график  на картинке )
2)  взятый из предложенных разработчиками вариантов на луа. (четвертый график )
-----------------------
Во втором варианте добавил чтение индикатора с графика первого варианта
и вывод этого значения для сравнения на график второго варианта.
-------------
На втором варианте это линия белого цвета.
------------------
Вот такая картинка в итоге:



Время чтения индикатора с графика 6.8 мкс ,
а время расчета индикатора  23.4 мкс.

--------------
Прикольно,но факт.
 
Сегодня в сбербанке на реальных торгах наблюдаем это:
посмотрите дату торгов и дату сервера.
Очевидно, все в отпуске и сервером управляет пьяный робот.
 
Индикатор для арбитража
 
Добрый день,
Специально для буратин и чайников выкладываю исходник индикатора арбитража.
-----------------
На графике отображается  
белый  - разность цен
красный - максимум за торговый день
синий -минимум за торговый день
зеленый - средний за торговый день
розовый - эксп.скользящая средняя
------------------
Инструкция для ощущения счастья:
1. Откройте график цены первого инструмента
2. Откройте в этом же окне график цены второго инструмента.
3. На вкладке Дополнительно второго графика запишите Идентификатор, который записан в  исходнике индикатора в поле sec    таблицы Settings
4. Откройте индикатор в новой области этого окна.
------------------
Код
--title="Arbitr <nikolz> "-- арбитраж
name='arb_nk'
Settings={
sec ="SB_arb",  --идентификатор 2-го инструмента (графика)
LEMA = 30,
Name = name,
}
-------
function OnCalculate(i)
   if i==1 then
      AL=1/Settings.LEMA; y,Ma,Mi,Me,x=nil;
   else
      local C1=C(i)
      if T(i-1).hour>T(i).hour then y,Ma,Mi,Me,x=nil  end
      local t=getCandlesByIndex(Settings.sec,0,i,1);  t=t[#t];
      if t  then
         local C2=t.close;
         if C2  and C1 then
            x1=C1-C2;
            if Ma==nil or x1>Ma then Ma=x1 end
            if Mi==nil or Mi>x1 then Mi=x1 end
            if Ma and Mi then
            Me=(Ma+Mi)/2; x=x1;
            if y==nil then y=x; end y=(1-AL)*y+AL*x;
            end
         end
      end
   end
   return Me,Ma,Mi,x,y
end
-----
function Init()
 Settings.line={};
   Settings.line[1] =    {Name = "Me",Color = RGB(0,255,0),      Type =1,Width = 2   };
   Settings.line[2] =    {Name = "Ma",Color = RGB(255,0,0),      Type =1,Width = 2   };
   Settings.line[3] =    {Name = "Mi",Color = RGB(0,0,255),      Type =1,Width = 2   };
   Settings.line[4] =    {Name = "x",Color = RGB(255,255,255),   Type =1,Width = 1   };
   Settings.line[5] =    {Name = "eMA",Color = RGB(255,32,255),   Type =1,Width = 2   };
   return #Settings.line;
end
 
Хотелось бы узнать, где про ЭТО прчитать.
 
Добрый день,
Вопрос к знатокам.
В документации QLua в разделе: "Функции для работы с таблицами Рабочего места QUIK"
-------------------
написано:
-----------------
В таблицах Рабочего места QUIK, созданных с помощью скриптов на языке Lua,
поддержаны следующие возможности :
  • ..
  • пользовательские фильтры,
  • ...
===========================  
прошу подсказать, где я могу прочитать про эти "секретные возможности" под названием " пользовательские фильтры"
------------------
Читать на расстоянии мысли разработчиков пока не научился,
а в документации ничего не нашел.
Недокументированный "Троянский конь" на Lua
 
Добрый день, всем,
Хотя о том, про что буду рассказывать знаю с момента появления LUA VM в КВИКЕ
и думал, что эту подлянку давно поборол, однако она снова дала о себе знать.
---------------------
В частности примерно это же недавно обнаружил посетитель по нику Старатель.
--------------------
Так как я давно казалось бы проблему решил, поэтому на его вопрос особо не обратил внимание.
===============
но вот недавно столкнулся с проблемой удваивания заявок-близнецов.
=================  
Хотя ничего хорошего мне на форуме как обычно не посоветовали, но вредные советы тоже пригодились.
===============
Например, представитель разработчиков гневно заявил, что мол надо все обнулять при index=1 в индикаторах.
Благодарю его за его вредный совет.
------------------
Действительно, верно говорят -выслушай совет на Красной площади и сделай наоборот.
----------------------------
Поэтому я обратил внимание, что именно по index=1 я обнулил лог файл.
-------------
продолжение следует..
робот в индикаторе
 
Добрый день, Всем
В качестве ликбеза для буратин и чайников,
привожу результаты тестирования скорости исполнения выставления и снятия заявки в роботе,
который реализован в индикаторе.
-------------
кратко в чем преимущество такой реализации относительно реализации в виде скриптов.
================
1) нет надобности писать колбеки и разбираться в них.
----------------
2) робот можно сделать одинаковым для любых инструментов
Например робот автомат управления стопом.
---------------------
3) проще реализовать, так как нет надобности заморачиваться с фильтрацией инструментов.
На какой график кинете этого робота, на том инструменте он и будет работать.
=================
А теперь о скорости его работы.
Тест, в котором выставляется заявка, когда она выставится, робот ее снимает.
при этом он проверяет таблицу стоп-заявок, заявок и депо.
=================
На выставление заявки уходит примерно 0.006 сек
На проверку активной заявки и выставление заявки на снятие уходит примерно выставление заявки на снятие уходит примерно 0.004 сек
--------------------------
время в мкс:
Код
depo t1=47.8, таб.стоп_ордер t2=1.8, таб.ордер t3=272.4, ордер t4=30.7
m=1,flag=2.0,nu=6947069167,idt=421
depo t1=40.2, таб.стоп_ордер t2=1.6, таб.ордер t3=67.6, ордер t4=304.5
m=1,flag=1.0,nu=6947069357,idt=423
depo t1=48.1, таб.стоп_ордер t2=1.6, таб.ордер t3=257.6, ордер t4=29.6
m=1,flag=2.0,nu=6947069357,idt=423
depo t1=38.5, таб.стоп_ордер t2=1.9, таб.ордер t3=75.6, ордер t4=309.8
m=1,flag=1.0,nu=6947069489,idt=425
depo t1=52.4, таб.стоп_ордер t2=2.1, таб.ордер t3=339.3, ордер t4=38.9
m=1,flag=2.0,nu=6947069489,idt=425
depo t1=72.4, таб.стоп_ордер t2=3.1, таб.ордер t3=124.2, ордер t4=584.2
m=1,flag=1.0,nu=6947069557,idt=427
depo t1=47.9, таб.стоп_ордер t2=1.7, таб.ордер t3=240.8, ордер t4=27.6
m=1,flag=2.0,nu=6947069557,idt=427
depo t1=64.9, таб.стоп_ордер t2=2.5, таб.ордер t3=123.0, ордер t4=580.2
m=1,flag=1.0,nu=6947069616,idt=429
depo t1=59.9, таб.стоп_ордер t2=2.3, таб.ордер t3=334.9, ордер t4=39.1
m=1,flag=2.0,nu=6947069616,idt=429
depo t1=70.8, таб.стоп_ордер t2=2.5, таб.ордер t3=123.9, ордер t4=518.8
m=1,flag=1.0,nu=6947069717,idt=431
depo t1=62.7, таб.стоп_ордер t2=2.6, таб.ордер t3=397.2, ордер t4=52.4
m=1,flag=2.0,nu=6947069717,idt=431
depo t1=70.3, таб.стоп_ордер t2=3.0, таб.ордер t3=124.9, ордер t4=523.5
Удваиваются заявки. Версия 9.7.1.10., Вопрос разработчикам QUIK
 
Тестирую в демо версии выставление заявок
фрагмент кода такой:
Код
t1.PRICE=tostring(price);
t1.QUANTITY=tostring(Q);
t1.TRANS_ID=tostring(id+1);    -- Уникальный идентификационный номер заявки,  от «1» до «2 147 483 647»
local str=sendTransaction(t1); --отправить транзакцию
Log:write("сообщение"..str.."\n");   Log:flush()  -- вывод сообщения в файл
if str=="" then  id=id+1; ji=ji+1; ti[ji]={id,0}; ti[0]=ji;
   Log:write("заявка id"..tostring(id)..",ji="..tostring(ji).."\n");   Log:flush()
end ---если  сообщение пустое то в файл выводится id транзакции
Поясняю.
Разработчикам просьба внимательно читать пояснения.
Все тщательно разжую.
================
Выполняется:
str=sendTransaction(t1)  
строка str выводится в файл
если сообщения  нет , то  id  увеличивается на 1 и становится равным id транзакции
и выводится в файл
=====================
ВНИМАНИЕ!!!
Таким образом, исключается передача транзакции с одинаковым id
и контролируется количество переданных транзакций.
===================
В лог файле при выполнении транзакции получаем:
Код
сообщение
заявка id31,ji=1
Т. е. ожидаем одну заявку с id=31
----------------
ВНИМАНИЕ!!!
смотрим в таблицу заявок:

 
Однако,
наблюдаем по две заявки с одинаковыми id
одинаковыми параметрами
и в одно и тоже время.
------------------------
Что не так?
Уничтожаем фейки
 
Добрый день, Всем.
----------------------
На форуме очень много  буратин и чайников,
жизнь которых на рынке только начинается.
Поэтому попробую, по мере сил и желания,  снять с их ушей лапшу,
которую им упорно развешивают некоторые словообильные посетители.
--------------------
Начнем с определений:
чайник - чел,начинающий программировать робота в QUIK.
буратино - чел,начинающий гений торговли и уверенный в быстром обогащении на бирже, мечтающий о халяве.
Тики - данные отображающиеся на графике с интервалом -"тиковый"
================
Фейк №1
===============
Есть тики , а есть обезличенные сделки и это разные данные, тики -няка, а обезличенные сделки -бяка.
Тики обрабатываются быстрее, чем обезличенные сделки.
--------------  
Такая тема неоднократно появлялась на форуме.
Как правило это связано с самопальными свечами с интервалом меньше 1 минуты.
================
Так вот , противопоставление тиков и обезличенных сделок - это ложь.
Тики и обезличенные сделки - это одни и те же данные.
===========  
Получить эти данные можно тремя способами:
1) подписаться на обезличенные сделки на LUA;
2) заказать обезличенные сделки через меню терминала
3) открыть график с интервалом "тиковые"
-----------------------
Во всех трех случаях данные будут поступать в таблицу обезличенных сделок,в колбек скрипта и на график.
==============
Доказательство :
1) см документацию:
функция CreateDataSource
param – Если параметр не задан, то заказываются данные
на основании таблицы обезличенных сделок.
--------------
2) без заказа через терминал, откройте тиковый график. А потом откройте таблицу обезличенных сделок.
Вы увидите в таблице инструмент с тикового графика.
------------------
3) сделаем следующий тест.
На тиковый график разместим индикатор, который пишет текущую цену инструмента (ТИК) в лог файл.
В этот же лог файл пишем параметры обезличенных сделок данного инструмента, полученные скриптом onAllTrade.
И дополнительно проверим, что же мы получим по данному инструменту через колбек onParam, т е из ТТП.
-----------
Вот результат данного теста:
Код
onAllTrade QJSIM;SMLT;2738.000000,1,0,20220626,131036,0,101420,36
interval=0,QJSIM,SMLT;2738.000000
onAllTrade QJSIM;SMLT;2738.000000,1,0,20220626,131037,0,221,17
interval=0,QJSIM,SMLT;2738.000000
onParam QJSIM;SMLT;2738.000000
onParam QJSIM;SMLT;2737.400000
onAllTrade QJSIM;SMLT;2737.400000,1,0,20220626,131047,0,79827,33
interval=0,QJSIM,SMLT;2737.400000
onParam QJSIM;SMLT;2737.400000
onParam QJSIM;SMLT;2739.000000
onAllTrade QJSIM;SMLT;2737.400000,9,0,20220626,131057,0,98496,32
interval=0,QJSIM,SMLT;2737.400000
onAllTrade QJSIM;SMLT;2737.400000,1,0,20220626,131057,0,202,15
interval=0,QJSIM,SMLT;2737.400000
onAllTrade QJSIM;SMLT;2737.500000,40,0,20220626,131057,0,142,14
interval=0,QJSIM,SMLT;2737.500000
onAllTrade QJSIM;SMLT;2737.500000,1,0,20220626,131057,0,209,16
interval=0,QJSIM,SMLT;2737.500000
onAllTrade QJSIM;SMLT;2738.000000,10,0,20220626,131057,0,165,20
interval=0,QJSIM,SMLT;2738.000000
onAllTrade QJSIM;SMLT;2738.000000,1,0,20220626,131057,0,160,16
interval=0,QJSIM,SMLT;2738.000000
onAllTrade QJSIM;SMLT;2738.000000,2,0,20220626,131057,0,158,12
interval=0,QJSIM,SMLT;2738.000000
onAllTrade QJSIM;SMLT;2738.000000,1,0,20220626,131057,0,149,11
interval=0,QJSIM,SMLT;2738.000000
onAllTrade QJSIM;SMLT;2738.500000,22,0,20220626,131057,0,129,11
interval=0,QJSIM,SMLT;2738.500000
onAllTrade QJSIM;SMLT;2738.500000,1,0,20220626,131057,0,126,11
interval=0,QJSIM,SMLT;2738.500000
onAllTrade QJSIM;SMLT;2738.500000,48,0,20220626,131057,0,122,11
interval=0,QJSIM,SMLT;2738.500000
onAllTrade QJSIM;SMLT;2739.000000,8,0,20220626,131057,0,131,11
interval=0,QJSIM,SMLT;2739.000000
onAllTrade QJSIM;SMLT;2739.000000,1,0,20220626,131057,0,134,19
interval=0,QJSIM,SMLT;2739.000000
onAllTrade QJSIM;SMLT;2739.000000,44,0,20220626,131057,0,125,12
interval=0,QJSIM,SMLT;2739.000000
onParam QJSIM;SMLT;2739.500000
Резюме:
Первым ВСЕГДА отрабатывает колбек onAllTrade, после него данные приходят в индикатор графика.
---------------
Колбек onParam , как и ожидалось принимает лишь некоторые тики,
которые попадают в текущий срез данных, передаваемых в таблицу текущих параметров.
------------------------
Установка Quik 8.5...9.5 в Ubuntu 20.04,..21.10
 
источник: https://athunder.livejournal.com/763507.html
============================================================­=========
  1. Устанавливаем Wine и Winetricks, выполнив в терминале
    sudo dpkg --add-architecture i386
    wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add -

    Добавляем репозиторий для Ubuntu 20.04
    sudo apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main'

    Для Ubuntu 20.10 менем focal на groovy:
    sudo apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ groovy main'

    И завершаем установку следующими строчками:
    sudo apt update
    sudo apt install --install-recommends winehq-stable winetricks

    Добавлять поддержку архитектуры win32 (первая команда выше) нужно только если ваша система 64-разрядная.

    Проблему рано или поздно исправят, так что можно будет пользоваться WINE и без дополнительного репозитория:
    sudo dpkg --add-architecture i386
    sudo apt install wine winetricks
  2. Устанавливаем VC6RedistSetup. Можно его скачать с сайта Майкрософт и запустить при помощи Wine. А можно просто выполнить в терминале
    winetricks vcrun6

    Гораздо проще воспользоваться winetricks, т.к. перед установкой VC6RedistSetup он предложит установить необходимые нам "Wine Mono Installer" и "Wine Gecko Installer". На предложения скачать и установить нужно соглашаться и нажимать на кнопку Install.
  3. Скачиваем Quik с сайта брокера. Если приложение находится в архиве (zip, rar), то его нужно предаварительно распаковать. WINE будем запускать с .exe файлом.
  4. Для установки Quik используйте команду в терминале:
    LC_ALL=ru_RU.UTF-8 wine64 quik_inst.exe

    Где вместо quik_inst.exe нужно подставить имя вашего установщика quik (например, это может быть "quik_8.7.exe"). Обратите внимание, что запускать эту команду нужно из папки, в которой находится этот установщик (installer). Если вы скачали его в папку пользователя Downloads, распаковали ZIP архив именно в эту папку, то переходите в неё при помощи команды cd в терминале:
    cd ~/Downloads
  5. Копируем ключи secring.txk и pubring.txk в папку /home/USER/.wine/dosdevices/c:/Program Files/BROKER/Keys, где USER - ваше имя пользователя, а BROKER - подпапка в "Program Files (x86)", в которую установлен торговый терминал Quik (Возможно, вы захотите установить Quik не в Program Files, а в корень, например, в C:\SBERBANK. Тогда и ключи копируем в соответствующую папку). Ключи конечно же можно хранить и в другой папке, при этом в "Система" -> "Настройки" -> "Основные настройки" -> "Программа" -> "Шифрование" -> "Шифровать с помощью СКЗИ" -> Qrypto32 -> "Настроить" нужно указать путь к ключам.
  6. Создаем ярлык для запуска. В моем случае это shell скрипт (текстовый файл с расширением sh) на рабочем столе.
    cd "~/.wine/dosdevices/c:/Program Files/BROKER/"
    LC_ALL=ru_RU.UTF-8 wine64 "c:/Program Files/BROKER/info.exe"
    Если опустить параметр "LC_ALL=ru_RU.UTF-8", то часть текста может отображаться некорректно (вместо текста появляются вопросы или кракозябры).
    Если не перейти в папку с установленной программой перед запуском, то возникают проблемы с настройками.
    Вместе же две команды решают проблемы с запуском Quik в Ubuntu (Linux).
  7. После создания shell скрипта quik.sh можно открыть свойства этого текстового файла и на вкладке Permissions разрешить выполнение в качестве программы. Но можно переходить в папку с этим скриптом в терминале и запускать его, добавляя "./" перед именем файла:
    cd ~/Desktop
    ./quik.sh
  8. После запуска Quik нужно изменить в настройках шрифты. Если этого не сделать, то в некоторых диалогах будут появляться кракозябры, хотя большая часть информации всё же отображается корректно. Для этого в меню выбираем "Система" -> "Настройки" -> "Основные настройки...(F9)" -> "Программа" -> "Шрифты", после чего изменяем шрифты, например, на Arial (или любой другой шрифт, который вам нравится, но который будет корректно отображать русские буквы в Quik).


  9. Если нужно сгенерировать ключи для Quik, то запускаем keygen.exe из под WINE:
    cd ~/.wine/dosdevices/c:/Program Files (x86)/BROKER/KeyGen
    LC_ALL=ru_RU.UTF-8 wine64 keygen.exe
  10. Профит!
Данный способ запуска Quik в Linux прекрасно работает для брокеров ВТБ, Открытие, БКС, Финам, Сбербанк, Промсвязьбанк и прочих. В том числе не возникает и проблем, если для входа требуется SMS подтверждение.

Если при запуске через некоторое время возникает ошибка "Не хватило памяти под объекты, без которых приложение работать не может", то первым делом нужно проверить наличие свободной памяти. .
добавить параметры графика в settings
 
Предлагаю добавить в settings
параметр для управления флагами графика
"Учитывать при автомаштабировании"
"привязка к левой(правой) оси
и.т.д.
 
Обмен сообщениями приложений , скриптов на Lua, Python ,С
 
Предлагаю принять участие
в тестировании моей библиотеки обмена сообщениями
между  процессами, потоками , приложениями, скриптами на любом языке программирования.
-------------------------------
Как это работает
Приложению или скрипту присваиваем номер NUM от 1 до  30000.
----------------
1) Послать сообщение S:  res=nkLp.send(NUM,S) , если успешно , то res=1. Num - номер получателя.
2) Принять сообщение S: на Lua S=nklP.get(NUM), на других языках nkLP(Num,S).  Если нет, то  пусто. Num-номер получателя.
=================
Возможности
1) В скриптах для QUIK,  колбеки можно размещать лишь в одном.
Этот скрипт может рассылать информацию всем желающим.
-----------------------------
2) Индикаторы и скрипты могут обмениваться информацией.
------------------------------
3) Любое внешнее приложение ,
например на питоне,
может обмениваться информацией с QUIK
или любым другим приложением,
например, на луа.
=================
Чем это решение лучше других
1) Другие таких решений нет . Если знаете,  дайте ссылку.
2) Не блокирует потоки, не использует файлы, не обращается к ядру ОС.
3) Самый быстрый способ обмена.
==================
Ограничения  тестовой версии:
В данном решении длина сообщения 64 символа.
Используется лишь один ящик сообщений.
Т е новое сообщение будет передано лишь после того, как прочитают предыдущее.
В сообщении нет обратного адреса.
Тестировал на Win10 64bit, Lua 5.4
===================
Как принять участие в тесте:
Написать  свою почту в личку.
 
Прием данных и стаканов в различных потоках
 
Добрый день,
Ищу решение следующей проблемы.
----------------  
Сейчас у меня реализовано так:
--------------------
В функции main для каждого инструмента запускается свой поток.  Потоки берутся из пула.  Если свободного нет, то создается новый.
------------------
Данные передаются в поток через параметры скрипта и мапинг-файлы.
------------------
Прием данных от источника и стаканов реализуется  в main.
-----------------
Все работает замечательно.   Но узким местом  является прием данных всех инструментов в одном потоке main.
-----------------------
Хочу принимать данные и стаканы в  отдельном потоке   каждого  инструментов.
------------------
Применение общего глобального стека не дает результата.
----------------------  
Если кто-то решил данную проблему, просьба сказать каким методом.
------------
Спасибо
=================  
Отдельная пожелание разработчикам.
Реализовать указанные функции для приема данных и стаканов для произвольного потока.
Найдите, где правильно?, Вопрос к разработчикам QUIK
 
Добрый день,

Вопрос к разработчикам:

Что считает терминал QUIK в таблице купить/продать  и что же считает функция getBuySellInfo .
-------------------  
Казалось бы должны считать одно и тоже.  
======================
Если -нет, то дайте ссылку на документацию.
===============  
Проверяем:
Берем данные из таблицы терминала купить продать
и по этим данным считаем функцией getBuySellInfo
===========
результат ниже:
Сумма - это произведение цены на количество.
---------------------------------
Отличия:
1) Все суммы различные  , даже там , где цена и количество одинаковые
Например
===========================================
28MGNT420171298 27171298 662
=============================================


2)  QUIK для всех акций считает как не маржинальные,
а формула очевидно  учитывает маржинальные
Но учитывает как то странно
Например:

==================================================
3AFLT38.147867300 047465761 760 5735.9
============================================

Риск 5.9, но для физ лиц не может быть более 5, а для юр. лиц может быть аж 8.
Откуда 5.9 ?
------------------------
Там, где риск=1, количество не совпадает в большинстве случаях.


Например:

================================================
20ISKJ85.23512299 2223518299 8041.0
================================================
QUIK    ПозицииgetBuySellInfo плечо
Код инструментаЦенаКупитьСуммаКупитьСуммаРиск
2AFKS13.82121709300 04062013855 2832.9
3AFLT38.147867300 047465761 760 5735.9
4AGRO1041288299 808288299 5201.0
5ALRS933226300 018189211 759 6535.9
6BANEP671445298 5951250843 7502.8
7BSPB63.124753300 0094753299 7721.0
8CHMF1077.4278299 51716271 753 9065.8
9CNTL10.228685292 58729394299 8191.0
10DSKY85.313515299 8653527299 7951.0
11ENRU0.5283567206299 655564219299 8261.0
12ETLN71.584177298 9904166299 7851.0
13FIVE1360220299 200223299 3781.0
14FLOT53.275632300 0175634299 7851.0
15GAZP242.81234299 61571101 728 8685.8
16GCHE3197.593297 36893297 1821.0
17GLTR384781299 904781299 8261.0
18HYDR0.7816381357298 06922032751 727 3685.8
19IRAO2.678112043300 051112206299 8261.0
20ISKJ85.23512299 2223518299 8041.0
21KAZT474.8631299 599639299 6911.0
22KMAZ101.32947298 5312959299 7471.0
23KZOSP21.5113801296 86013906299 8131.0
24LKOH5306.556297 1643261 733 9945.8
25LSRG540555299 700555299 7001.0
26MAGN43.346919299 8696893299 8111.0
27MDMG597500298 500500299 2501.0
28MGNT420171298 27171298 6621.0
29MOEX104.22872299 2622869299 8111.0
30MRKC0.26221131419296 6581135705299 8261.0
31MRKP0.17181731404297 4551744205299 8291.0
32MSNG1.78168568300 051168633299 8291.0
33MTLR102.22935299 9572956299 7681.0
34MTLRP195.81525298 5951524299 6951.0
35MTSS217.81376299 6931375299 7501.0
36MVID248.81205299 8041200299 6401.0
37NKNCP81.183696300 0413699299 7671.0
38NLMK161.91852299 8391852299 7281.0
39NMTP4.9460191297 34460510299 8271.0
40NVTK1288232298 816232299 4661.0
41OGKB0.4179718000300 052720558299 8241.0
42OKEY27.9310735299 82910738299 8051.0
43OZON1302.5230299 575232299 2801.0
44PIKK589.9508299 669510299 6251.0
45PLZL13479.522296 54922296 4721.0
46POGR12.6923644300 04223608299 8221.0
47POLY942.3318299 651318299 8101.0
48POSI1051.8285299 763285299 8201.0
49QIWI443.5675299 363674299 7281.0
50RASP389771299 919771299 8031.0
51RENI46.986386300 0146382299 8261.0
52RNFT103.42901299 9632910299 7301.0
53ROSN407737299 959736299 5521.0
54RSTI0.7177417842299 885417528299 8271.0
55RTKM62.354793298 8444833299 7911.0
56RTKMP62.654785299 78013640854 5462.8
57RUAL70.744238299 7964243299 7681.0
58RUGR25.211906300 03112260299 8061.0
59SBER145.862055299 742120761 760 5605.9
60SBERP153.341956299 9331949299 7371.0
61SELG46.866403300 0456434299 8241.0
62SFTL2891038299 9821037299 5891.0
63SGZH9.29832267300 01932347299 8241.0
64SIBN434.95689299 681692299 7051.0
65SMLT2709110297 990110299 2331.0
66SNGS26.1311483300 05111395299 8251.0
67SNGSP35.158535300 0058528299 8021.0
68TATN395.5758299 789758299 7891.0
69TATNP348861299 628861299 6281.0
70TCSG354284297 52884298 7461.0
71UPRO1.647181410298 782181935299 8291.0
72VKCO511.4586299 680581299 6801.0
73VTBR0.02283513140021300 05213225443299 8211.0
74YNDX2108.4142299 393142298 6541.0
чтобы это значило?
 
Читаем таблицу, которую получает колбек OnDepoLimit
----------------
currentbal=0.0
locked_sell=0.0
locked_buy=0.0
wa_position_price=0.0
sec_code=CNTL
firmid=NC0011100000
client_code=1737
limit_kind=-3
locked_buy_value=9.96
awg_position_price=0.0
wa_price_currency=SUR
openbal=0.0
trdaccid=NL0011100043
locked_sell_value=-1e+48  -- Стоимость инструментов , заблокированных на продажу
currentlimit=0.0
openlimit=0.0
-----------------------
Вопрос к знатокам:
сколько стоят инструменты, заблокированные  на продажу?
доработка таблицы Позиции по инструментам
 
Добрый день,
Предлагаю зарегистрировать следующее пожелание.
Добавить в таблицу "Позиции по инструментам"   class_code.
--------------------
Объясняю в чем проблема.
=================  
При написании скриптов
возникает необходимость получить параметры по инструментам, чтобы выставлять какие-либо заявки.
-------------
Для формирования заявки по позиции инструмента нужен класс этого инструмента,
а его в таблице позиций нет.
----------------
В результате, чтобы найти класс надо делать "танцы с бубном"
извлекать клиента
по нему находить торговый счет
по счету находить фирму и получать список торгуемых классов
потом в классах  искать тот, в каком есть данный инструмент.
-----------------
Напоминает наблюдение гланд через зад.
Занятие занятное , но бесполезное.
=================
Спасибо
Чудно считает CalcBuySell
 
Добрый день,
--------------
Вопрос к знатокам:
-----------------------------
Вычисляю функцией CalcBuySell сколько акций можно купить.

фрагмент кода:
local qty1,comis1=CalcBuySell(clas, sec,"1737","NL0011100043",price, true,false);
-------------------------
Поясняю, что ожидаю:
------------------
На учебном сервере денежных средств 300 тысяч рублей.
----------------
Данная функция должна считать комиссию и число лотов для покупки по указанной цене.
Полагаю, что коммиссия должна быть примерно одинаковой (сумма денег одна)
А число акций умноженное на цену одной и на количество их в лоте должна составлять примерно 300 тыс рублей
-------------------
Для проверки, считаю количество и комиссию по формуле.
--------------------------
В результате обозначено:
-------------------
qt1,comis1 - расчет функции
qt,comis -  расчет формулы
m - сумма денег исходная
m1- расчет суммы денег по результатам функции
-----------------------
результат вычисления:
=============
акции, для которых результат функции и по формуле примерно одинаковый:
------------------
TATNP,m=299983, lotsize=1., qty1=937, m1=299881, qty=935, comis1=229.26, comis=749, price=319.8
ROSN,m=299983, lotsize=1., qty1=844, m1=299887, qty=842, comis1=225.54, comis=749, price=355.05
-------------
"чудеса в решете":
--------------------
CHMF,m=299983, lotsize=1., qty1=1530, m1=1759940, qty=260, comis1=746.54, comis=749, price=1149.8
----------
при цене 1150 рублей
по формуле можно купить 260 акций, что вполне похоже на правду.
-----------------------------
функция считает, что можно купить 1530 акций,
при этом комиссия примерно одинаковая, что указывает что затрачено примено 300 тыс рубг
----------------------
следующее чудо:
SBER,m=299983, lotsize=10., qty1=1349, m1=1759982, qty=229, comis1=751.81, comis=749, price=130.41
-----------
Сбербанк  акция 130 рублей по формуле можно купить 229 лотов или 2290 акций, что правда.
функция считает, что можно купить 1349 лотов, на сумму 1млн759 тыс 982 рублей
Величина комиссии указывает что ее считали с  суммы 300 тысяч.
---------------------
еще один прикол:
AFLT,m=299983, lotsize=10., qty1=6567, m1=1760716, qty=1116, comis1=760.2, comis=749, price=26.8
==================  
Кто сие может объяснить?
Спасибо
лишний элемент или так задумано?
 
Добрый день
На учебном сервере
версия 9.4
l-------------------
читаем код клиента
Код
message("всего=.. getNumberOf("client_codes") );
for i=0,getNumberOf("client_codes")-1 do
local x=getItem("client_codes",i);
message("i="..i..",cod="..tostring(x) );
end
получаем результат:
всего=2
i=0,cod=1737
i=1,cod=  
--------------------
если я правильно понял, то должен быть всего один код клиента.
и  действительно  код i=0,cod= 1737
но почему-то их два, i=1, cod=пусто.
------------------------
Что не так я делаю?
Какой в этом пустом коде тайный смысл?
=======================================
Огласите весь список, п..жалуста, в каких еще таблицах так сделано.
Спасибо.
Страницы: Пред. 1 2 3 След.
Наверх