func = RSI() ;
local rsi_count={}
nk=ds[real]:Size()
for i=1,nk do rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[real]) end
if rsi_count[nk]~=nil then
rsi0=rsi_count[nk]
rsi1=rsi_count[nk-1]
rsi2=rsi_count[nk-2]
rsi3=rsi_count[nk-3]
rsi4=rsi_count[nk-4]
max_rsi=math.max(rsi0,rsi1,rsi2,rsi3,rsi4)
in_rsi=math.min(rsi0,rsi1,rsi2,rsi3,rsi4)
else
mm (real.." "..nk.." rsi_count[num_candles]=nil") ; sleep (100)
end
Квик стоит на виртуалке. Скрипт лежит на моём ноутбуке. Скрипт читает файлик с сигналами, который тоже лежит на ноутбуке. Вид файла с сигналами: 01.02.2021 at 11:00 open_long SBER
Эта строка парсится и записывается в Луа-таблицу. Я надеюсь, что она вечно хранится в памяти. Но выходит что нет? Каждое утро Квик по новой запускает main и обнуляет все переменные? Уточните пожалуйста что происходит утром в плане: -работы main -существования переменных и таблиц скрипта.
Начал запускать свой старый скрипт. Он был 100% рабочим. Теперь на версии КВИКа 8.8.4.3 вылазит ошибка: смысл понятен - мне надо 32 битную, а тут 62. Но как с этим бороться, - не понимаю. Скрипт пытается сделать
Добрый день. Подписан у брокера Открытие на трансляцию мировых рынков. График по иностранным инструментам выглядит так: Искусственно заполняются неторговые часы. Брокер говорит, что эта проблема есть только у меня. По просьбе брокера я удалил все .dat файлы отовсюду, даже на всякий случай удалил info.wnd. Проблема осталась. Более того, она также воспроизводится на других экземплярах КВИКА. А у брокера (со слов менеджера) её нет. Верится с трудом. Теперь брокер просит выслать им архив КВИКа. Я не против, но прошу всё же ответа от компетентного специалиста-разработчика. Для сравнения, то же самое на других акциях - NVIDIA (ранее я их НЕ скачивал, этот график прилетел ко мне в терминал впервые)
Я подписываюсь на новые сделки через INTERVAL_TICK и обрабатываю их в OnAllTrade Хочу анализировать только новые сделки. Старые сделки, уже прошедшие за сегодня, обрабатывать не хочу. Есть ли риски, что в OnAllTrade прилетит старая сделка из сегодняшних? Ну например при первом старте КВИКа в 13 часов в КВИК начнут сыпаться ранее прошедшие сделки. Они мне не нужны. И только потом начнут поступать новые.
В последующих версиях Lua есть функция continue, но КВИК работает на древней версии Луа, где такой опции нет. можно ли как то силами Lua написать свою функцию continue и легко вставлять её в нужные куски кода, например:
Код
function continue ()
--бла-бла-бла
end
for i=1, 10 do
if i==5 then continue() end
--бла-бла
end
Заметил, что отправка транзакций - выставление и снятие заявок - трудоёмкая операция. Торгую 50-ю акциями. Если у меня висит 50 заявок, то при их массовом одновременном снятии квик подвисает на несколько секунд. При быстром выставлении такого же числа заявок он тоже зависает. Поэтому вопросы. 1. Наблюдения верны? Отправка транзакций - ресурсоёмкая процедура? 2. Хочу отправлять транзакции из OnParam. Это плохая идея? С точки зрения логики работы программы это было бы очень удобно. Сейчас у меня отправка заявок идёт в функции main, там в бесконечном цикле перебираются одна за другой 50 акций на соблюдение условия выставления/снятия. Хочу перенести этот блок в OnParam. Заявок ставится много, они всё время перевыставляются. В день отправляется до 10 тысяч заявок, то есть с учётом снятия это 20 000 транзакций.
Как с помощью колбека OnTrade понять, что заявка с известным номером исполнилась полностью или частично? Как то же самое узнать с помощью колбека OnOrder?
Скрипт организован вот так: То есть он не видит файл в той же папке где лежит запускаемый скрипт. Но стоит запускамый скрипт Unitas 3.0.lua удалить а потом добавить, как всё начинает работать:
Запустил КВИК, нажал кнопку Запустить - не работает. Удалил скрипт из списка, добавил снова, запустил - работает.
биржа штрафует за ошибочные транзакции. хочу уточнить - если я вижу такое сообщение, значит моя транзакция не долетела до биржи и отбита сервером брокера?
Пытаюсь переписать на Питоне индикатор Фрактал (код ниже). Но не могу понять что в этом коде происходит. Помогите пожалуйста написать на питоне индикатор фрактал для самого простого случая - список цен: Например, как найти верхний фрактал (для пиков)? price=[186.99,190.99,191.24,197,196.75,196.8,196.8,198,201.26,203.32,208.44,207.17,207.95,210.4,212.2,212,209.7,213.61,213.14,217.9,216.29,215.5,217.85,216.59,211.01,210.43,214,219.1,213.9,204.43,208,204.19,202.08,206.89,203.41,205.25,205.86,205.8,205.4,207.8,206.54,205.5,202.92,205,203.95,205.25,205.1,206,203.66,203.55,205.9,207.7,209.8,210.61,207.7,214,218,214.1,215.07,214.42,217.7,218.23,219.05,221.8,227.5,232.3,238,243.68,238.86,239.5,237.8,233.24,234.3,232.79,232.6,235.41,235.67,236,227.8,223.18,228.8,225.17,229.1,232.52,232.8,231.49,230,227,224.22,227.88,228.69,228.19,226.94,226]
Код
Settings = {
Name = "*FRACTALS (Fractals)",
Period = 5,
line = {{
Name = "Horizontal line",
Type = TYPE_LINE,
Color = RGB(140, 140, 140)
},
{
Name = "FRACTALS - Up",
Type = TYPE_TRIANGLE_UP,
Color = RGB(0, 206, 0)
},
{
Name = "FRACTALS - Down",
Type = TYPE_TRIANGLE_DOWN,
Color = RGB(221, 44, 44)
}
},
Round = "off",
Multiply = 1,
Horizontal_line="off"
}
function Init()
func = FRACTALS()
return #Settings.line
end
function OnCalculate(Index)
local Out1,Out2 = func(Index, Settings)
SetValue(Out1, 2, ConvertValue(Settings,H(Out1)))
SetValue(Out2, 3, ConvertValue(Settings,L(Out2)))
return tonumber(Settings.Horizontal_line),nil,nil
end
function FRACTALS() --Fractals ("FRACTALS")
local H_tmp={}
local L_tmp={}
local it = {[1]=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
if (P>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {[1]=0, l=0}
end
if CandleExist(I,ds) then
if I~=it[Squeeze(it.l,P)] then
it.l = it.l + 1
it[Squeeze(it.l,P)] = I
end
local Ip,Ipppp = Squeeze(it.l,P),Squeeze(it.l,P-1)+1
local nP = math.floor(P/2)*2+1
H_tmp[Ipppp] = GetValue(it[Ip],HIGH,ds)
L_tmp[Ipppp] = GetValue(it[Ip],LOW,ds)
if it.l >= nP then
local S = it[Squeeze(it.l-nP+1+math.floor(nP/2),P)]
local val_h=math.max(unpack(H_tmp))
local val_l=math.min(unpack(L_tmp))
local L = GetValue(S,LOW,ds)
local H = GetValue(S,HIGH,ds)
if (val_h == H) and (val_h >0)
and (val_l == L) and (val_l > 0) then
return S,S
else
if (val_h == H) and (val_h > 0) then
return S,nil
end
if (val_l == L) and (val_l > 0) then
return nil,S
end
end
end
end
end
return nil,nil
end
end
SMA,MMA,EMA,WMA,SMMA,VMA = "SMA","MMA","EMA","WMA","SMMA","VMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"
function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
(type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end
function Squeeze(I,P)
return math.fmod(I-1,P+1)
end
function ConvertValue(T,...)
local function r(V, R)
if R and string.upper(R)== "ON" then R=0 end
if V and tonumber(R) then
if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
else return math.ceil(V * 10^R - 0.5) / 10^R end
else return V end
end
if arg.n > 0 then
for i = 1, arg.n do
arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
end
return unpack(arg)
else return nil end
end
function GetValue(I,VT,ds)
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
if VT == OPEN then --Open
return (O and O(I)) or (ds and ds:O(I))
elseif VT == HIGH then --High
return (H and H(I)) or (ds and ds:H(I))
elseif VT == LOW then --Low
return (L and L(I)) or (ds and ds:L(I))
elseif VT == CLOSE then --Close
return (C and C(I)) or (ds and ds:C(I))
elseif VT == VOLUME then --Volume
return (V and V(I)) or (ds and ds:V(I))
elseif VT == MEDIAN then --Median
return ((GetValue(I,HIGH,ds) + GetValue(I,LOW,ds)) / 2)
elseif VT == TYPICAL then --Typical
return ((GetValue(I,MEDIAN,ds) * 2 + GetValue(I,CLOSE,ds))/3)
elseif VT == WEIGHTED then --Weighted
return ((GetValue(I,TYPICAL,ds) * 3 + GetValue(I,OPEN,ds))/4)
elseif VT == DIFFERENCE then --Difference
return (GetValue(I,HIGH,ds) - GetValue(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Записываю лучшие биды и аски по акциям средней ликвидности, например Распадская RASP. Что лучше выбрать: OnParam или OnQuote? Сомнения связаны с тем, что текущая таблица транслируется срезами раз в 50 миллисекунда, то есть будут пропущенные данные. А стакан? Он транслируется срезами или безостановочно?
Есть цикл, внутри которого качаются котировки с финама по многим инструментам. for i=start_year,cur_year,1 do
end В начале почти по всем акциям прилетают пустые годы (котировок ещё нет) Первый НЕпустой год я брать не хочу, потому что котировки ещё не адекватные. Я хочу брать второй не пустой год. То есть цикл должен быть таким
Код
for i=start_year,cur_year,1 do
--если размер таблицы нулевой, шагаем на 2 шага
--после этого всегда шагаем 1 шагом
end
Есть две огромных таблицы, которые описывают одни и те же свечки
Код
t_big[candle] --хранит цены: {1=open,2=high,3=low,4=close}
sd[candle]--хранит стандартные отклонения для этих свечек: sd[candle]=4.6432234444
Брут форс многкратно обращается к этим полям в поисках наилучших параметров. Крутит цикл, внутри него ещё цикл, а потом ещё цикл. На просчёт пятиминуток за 12 лет по 21 акции у меня ушла неделя. Объединение этих таблиц в одну приведёт ли к ускорению доступа к их полям? Хотя бы небольшому. Или это нейтрально?
Когда всё работает нормально, в чёрном окошке пишется то, что задумано. Это пишет питоновская функция print: Lua-функция os.execute возвращает 0 (признак успеха). Но часто бывает такая ерунда. Чёрное окошко появляется, в нём ничего не пишется. До print в 14 строчке не доходит. И так навеки, пока это окошко не закрыть. После закрытия окошка функция os.execute раздупляется и возвращает огромное отрицательное число, например -1073741510 Данные не получены, надо запускать скрипт заново. Помогите побороть этот глюк. Самое обидное то, что функция os.execute на время пустого чёрного окошка оказывается в подвешенном состоянии. Пока висит чёрное окошко, она ничего не возвращает, а значит нельзя обработать ошибку.
Есть ряд чисел от 0 до 10 с шагом 0,1 0 - белый цвет (точнее розовый, доведённый до стадии белого) промежуточные цвета - розовые разной насыщенности 10 - красный цвет Чем ближе к 10, тем сильнее розовый превращается в красный. помогите пожалуйста задать это на Луа. Это будет работать в таблице КВИКа и задаваться через SetColor Если по простому, мне это надо, чтобы сильно упавшие акции были ярко-красными, а слабо упавшие были розовыми. Чем сильнее упала акция, тем интенсивнее красный цвет. Надеюсь, понятно выразил мысль.
Читаю книжку Иерусалимскиса про Луа. Вот код оттуда.
Код
function values (t)
local i = 0
return function () i = i + 1; return t[i] end
end
t = {10, 20, 30}
iter = values(t) -- создает итератор
while true do
local element = iter() -- вызывает итератор
if element == nil then break end
print(element)
end
Иду по книжке иерусалимскиса "Программирование на Луа" Поясните пожалуйста этот пример
Код
function derivative (f, delta)
delta = delta or 1e-4
return function (x) return (f(x + delta) - f(x))/delta end
end
c = derivative(math.sin)
print(math.cos(5.2), c(5.2))
Подскажите пожалуйста, что в этом коде делает _Window и чем она отличается от Window?
Код
function Window (options)
-- проверка обязательных опций
if type(options.title) ~= "string" then
error("no title")
elseif type(options.width) ~= "number" then
error("no width")
elseif type(options.height) ~= "number" then
error("no height")
end
-- everything else is optional
_Window(options.title,
options.x or 0, -- значение по умолчанию
options.y or 0, -- значение по умолчанию
options.width, options.height,
options.background or "white", -- по умолчанию
options.border -- по умолчанию false (nil)
)
end
Это код из Главы 5.3. книги Иерусалимскиса Программирование на Луа. Речь идёт про именованные аргументы. Перед приведённым кодом идёт текст:
Добрый день. Функция os.clock() почему то вернула неадекватное значение, хотя всегда работала нормально согласно ожиданиям. Терминал стоит на виртуалке, не выключался несколько недель. Произошёл "перешаг" в новый месяц с ноября на декабрь... Не знаю важно ли это для установления проблемы. Из за чего это может быть?
пишу dll на C++ для КВИКа (вызывается через Lua) Схема действий такая. Десятки файлов, каждый по 50-100 тысяч строк хранят биржевую информацию, которую я каждый день записываю. Тестер будет прочёсывать множество таких накопленных файлов. Поиск наилучшего параметра будет проходить обычным брутфорсом, например, параметр А прогнать на каждом из файлов, меняя значение параметра с 1 до 100, то есть сто итераций. Какой путь лучше избрать с точки зрения скорости исполнения? 1. Значения из файла (те самые 50 тысяч строк) считываются в оперативную память и хранятся в массиве map. Робот прогоняет 100 значений параметра на содержимом этого map. 2. На каждой итерации робот читает файл строчку за строчкой, то есть каждый раз обращается к тексту, не запоминая содержимое файла. Что будет быстрее? Попробовать оба варианта мне будет сложно из-за слабых программистских навыков, поэтому прошу опытных людей подсказать лучший путь.
Уже не первый год работаю с индикаторами INDICATORS.ZIP, написанными Сергеем Гороховым. https://arqatech.com/upload/iblock/2eb/INDICATORS.zip Как в этих индикаторах, на примере Moving Average отсекать свечки премаркета (те которые 9:59)? Где ставить проверку "Если время меньше 10 часов, то игнорировать свечу?" Спасибо.
Сижу туплю, не пойму как мне профилировать dll на Си++ с помощью Visual Studio 2017. dll вызывается из Луа Что писать в Command-line arguments и Working directory? При попытке запустить профилирование появляется ошибка: Это сопровождается текстом: Profiling started. Instrumenting D:\_c++\runfast\Release\runfast.dll in place Info VSP3049: Small functions will be excluded from instrumentation. Microsoft ® VSInstr Post-Link Instrumentation 15.8.18219.1 x86 Unable to obtain debug information. Link with the /PROFILE linker switch. PRF0002: Instrumentation failed with these options: /u "D:\_c++\runfast\Release\runfast.dll" /excludesmallfuncs. Please check the output window for additional details. Data written to D:\_c++\runfast\info181001(3).vsp. Profiling finished. Profiling complete.
Английские слова все понятны, но технический смысл я не улавливаю. Помогите пожалуйста
Но иногда в этом файле могут быть кривые данные. Если вызывать этот файл с помощью dofile (tbl.lua), могут быть ошибки и основной скрипт остановится с ошибкой. Как написать в духе:
dofile (tbl.lua), но если там нечитаемый бред, то идти дальше и не обновлять таблицу t (пользоваться старой).
Прошу подсказать какой аналог глобальной таблицы Луа для Си++ Совсем точноЙ формулировкой вопроса будет, как то же самое написать на Си++
Код
ticker_list="GAZP,SBER,GMKN"
period_muvinga={}
period_muvinga.GAZP=23
period_muvinga.SBER=19
period_muvinga.GMKN=20
for sec in string.gmatch(ticker_list,"%a+") do
local period=period_muvinga[sec]
end
и второй вопрос. Когда дойдёт дело до объявления чего-то глобального в Си++ (то что является ответом на первый вопрос), в какой части кода это объявлять? Я пока не могу придумать ничего лучше кроме как здесь. Речь идёт про dll, написанную на Си++:
А этот цикл обрывается на второй итерации:
for (int i = 1; i<=4; i++){
printf("%i", i);
printf("\n");
lua_rawgeti(L, -2, i);
lua_getfield(L, -1, "quantity");
auto q = lua_tonumber(L, -1);
}
Пишет 1 2
Путём опытов я понял, что проблема в функции lua_rawgeti(L, -2, i); Она обрывает цикл на второй итерации. Почему? П.С. Если это важно, то всё это происходит внутри обработки колбека OnQuote
Спасибо этому форуму за советы и подсказки. Как принять в dll таблицу с целочисленными ключами, разобрался. Прошу подсказать как внутри dll разобрать по полям более сложную таблицу.
Код
qt=getQuoteLevel2(class, sec)
Согласно документации она возвращает таблицу, в которой два стринга и две вложенных таблицы. Мне нужны для работы все четыре. Как мне, к примеру, получить объём из 3-й котировки на покупку?
Для разбора таблицы с целочисленными индексами мой код внутри dll выглядит так:
Код
static int forLua_SumArray(lua_State* L) {
// Get the length of the table (same as # operator in Lua)
int n = lua_objlen(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
Вот функция на Си++ внутри dll. Она принимает таблицу и выдаёт обратно в Луа сумму элементов этой таблицы.
Код
static int forLua_SumArray(lua_State* L) {
// Get the length of the table (same as # operator in Lua)
int n = lua_objlen(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
Я ожидаю, что чем больше элементов будет в таблице, тем сильнее dll должна опережать аналогичные подсчёты в Луа. Написал код для сравнения скорости.
Код
iterations=1000000
function main ()
t={}
for i=1,20 do--вставляем в таблицу 20 элементов
table.insert(t,i)
end
--гоняем цикл миллион раз
start=os.clock()
for i=1,iterations do
s=runfast.SumArray(t)
end
finish_dll=os.clock()-start
mm("dll:"..finish_dll)
--гоняем цикл миллион раз
start=os.clock()
for i=1,iterations do
s=sum(t)
end
finish_lua=os.clock()-start
mm("Lua:"..finish_lua)
mm("Lua slower:"..math_round((finish_lua/finish_dll),1))
end
Луа медленнее в 2,4 раза. Я мучаюсь с Си ради роста скорости в 100 раз, ну да ладно. В 2,5 раза тоже кое-что. Сказываются транспортные издержки при перекидывании данных между Си и Луа. ************************ А теперь удивительное для меня. Заполняю таблицу 40 элементами.
Код
t={}
for i=1,40 do
table.insert(t,i)
end
Значит внутри Си++ будет производиться в 2 раза больше операций и она сможет лучше проявить своё преимущество в скорости по сравнению с Луа. Но нет: при 40 элементах в таблице преимущество Си в скорости такое же.
Почему? Я думал, что чем больше таблица, тем быстрее будет работать вариант кода с dll. Объясните пожалуйста.
static int forLua_SumArray (lua_State* L) { // Get the length of the table (same as # operator in Lua)
int n = luaL_len(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
всё хорошо, но в Луа 5.1. нет функции luaL_len. Она появилась в более поздних версиях. Вот код этой функции в Луа 5.3.
Как мне это внедрить в свою dll? Как дописать строку в lauxlib.h - это понятно. А вот файла lauxlib.c в моей Луа 5.1.5 вообще нет.
У меня в dll две функции. Обе постоянно что то делают со стеком. Есть ли риски того, что они будут по ошибке брать элементы друг друга? Или для каждой из них свой стек и путаница не грозит?
Как делать простые вещи с dll вроде разобрался. Прошу проконсультировать, как поместить в dll колбек OnQuote Чтобы это выглядело как то так: package.cpath = "C:\\runfast.dll" require "runfast" runfast.OnQuote() ... и так далее. Ума не приложу где мне эту строчку runfast.OnQuote() размещать. За пределами main как и сейчас? подскажите пожалуйста
Я совершаю в Луа арифметические операции со временем. Например 124500+5=124505 (12:45:05). По какой формуле я могу избежать проблемы с 60 минутами/секундами? 124459+5=124504 (не 124464) Как этого добиться?