Написал dll, в которой одна функция: сложение двух чисел. Вот она внутри проекта C++ (пример взят с сайта quik2dde.ru)
Код
static int forLua_AddTwoNumbers(lua_State *L) {
// получаем первый и второй параметры вызова функции из стека с проверкой каждого на число
double d1 = luaL_checknumber(L, 1);
double d2 = luaL_checknumber(L, 2);
// помещаем в стек результат сложения
lua_pushnumber(L, d1 + d2);
return(1); // эта функция возвращает одно значение
}
Теперь тестирую эту функцию в Луа. Сравниваю скорость: 1) как быстро складывает dll 2) как быстро складывает Lua
Код
package.cpath = "C:\\runfast.dll"
require("runfast")
iterations=10000000
function main()
start=os.clock()
for i=1,iterations do
r = runfast.AddTwoNumbers(i, i)
end
finish=os.clock()-start
message ("C dll:"..tostring(finish), 1)
start=os.clock()
for i=1,iterations do
r = i+i
end
finish=os.clock()-start
message ("Lua:"..tostring(finish), 1)
end
результат: Луа быстрее в 3,6 раза. Почему? Из-за всех этих телодвижений со стеком? Но как тогда извлекать преимущество от скорости Си++? Мне надо переместить в dll из Луа кучу трудоёмких функций, чтобы быстро считалось.
if string.find(reply.result_msg, "Снят") or string.find(reply.result_msg, "снят") then
end
Для этого использую string.lower(reply.result_msg) Но он не понимает русские буквы. Текст всё равно остаётся "Заявка 89900000 снята" или "Снято заявок". Большие буквы не становятся маленькими. Дело в русских буквах? Как с этим справиться?
Возможна ли такая ситуация: в стакане произошли два изменения одновременно, и колбек OnQuote сработал только один раз? Или раз заявки идут одна за другой очередью, то будет гарантированно два срабатывания колбека?
На просторах интернета есть скрипт на основе debug-библиотеки, встроенной в Луа. https://stackoverflow.com/questions/15725744/easy-lua-profiling Я - увы - ничего не понимаю в этом коде, но моих слабых способностей хватило, чтобы начать его использовать. До начала отслеживаемого куска ставится код:
Код
local calls, total, this = {}, {}, {}debug.sethook(function(event)
local i = debug.getinfo(2, "Sln")
if i.what ~= 'Lua' then return end
local func = i.name or (i.source..':'..i.linedefined)
if event == 'call' then
this[func] = os.clock()
else
local time = os.clock() - this[func]
total[func] = (total[func] or 0) + time
calls[func] = (calls[func] or 0) + 1
end
end, "cr")
--изучаемый код
Концовка:
Код
debug.sethook()
-- print the results
for f,time in pairs(total) do
print(("Function %s took %.3f seconds after %d calls"):format(f, time, calls[f]))
end
вместо print я вывожу эту строку в файл.
Скрипт работает и внутри колбека OnQuote показывает мои "личные" функции:
Но самое ценное - функцию получения стакана getQuoteLevel2 не показывает. Видимо, он понимает только пользовательские функции. Прошу подсказать, как в этот дебаггер добавить другую полезную информацию: --функции QLUA --пробегание циклов --переменные Спасибо за советы.
Здравствуйте. Последние дни на рынке паника. Активность резко возросла. Я в КВИКе подписываюсь на стаканы 5 фьючерсов и 50 акций. Обрабатываю их в OnQuote. В июне-июле не было никаких проблем из за вялого рынка. Но в среду-четверг-пятницу пошла жесть. КВИК подвисает намертво. Пришлось отказаться от акций, оставил два фьючерса Si и RTS, но даже их пришлось разнести по разным КВИКам. Два фьючерса в одном скрипте в одном КВИке всё равно вешали КВИК. Сейчас на 1 квик у меня по 1 скрипту, в котором 1 инструмент. Благодаря этому удалось вернуться к работе. --- Прошу дать совет, как решить эту проблему. 1. Я уже перенёс из OnQuote много функций, которые теперь обрабатываются в main, но там по прежнему остаётся обработка таблиц, несколько циклов и немного математики. Время, за которое проходит одна итерация внутри OnQuote около 20 миллисекунд. 2. На виртуалке поставил более быстрые ядра. Сейчас конфигурация такая: Обидно, что даже в моменты пиковой нагрузки загрузка процессора даже близко не подходила к 100%, то есть были свободные ядра. При этом более быстрые ядра не решили проблему, квик всё равно подвисал. 3. Работает сборщик мусора луа, проблем с памятью не наблюдалось. --- Можно ли OnQuote направлять на разные ядра процессора? например с помощью модуля многопоточности луа LuaLanes? --- Можно ли запустить в одном скипте несколько OnQuote? В один принимать фьючерсы, в другой акции например? --- Буду благодарен за любые советы и подсказки.
Здравствуйте. Это позиции по фьючерсам. Вопрос про поле этой таблицы session_status=6 На одном из серверов моего брокера транслируется не только текущая сессия (№6 - это вечорка), но и предыдущая с номером 4 Поэтому когда робот бегает по этой таблице, он может взять значение другой сессии и будет ошибка. Как можно получить этот параметр? И какие номера каким сессиям соответствуют? Спасибо.
Добрый день. Пытаюсь победить странную проблему с роботом. После того как робот поработает час, заявки на биржу улетают очень долго: между отправкой и получением реплая до 5 секунд. Стоит выключить робота и включить по новой, как проблема решается, заявки улетают быстро. --- В функции main стоит collectgarbage Она чистит мусор везде? Может быть нужно поставить её в другие колбеки, которые открывают новый поток? У меня из трудоёмких колбеков работают OnQuote (60 инструментов) и OnAllTrade.
Я заказываю ленту всех сделок через CreateDataSource вот так:
Код
ds_tick[sec] = CreateDataSource(class_code[sec],sec,INTERVAL_TICK)
ds_tick[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class_code[sec],sec,...) end)
ds[sec] = CreateDataSource(class_code[sec],sec,INTERVAL_M1)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class_code[sec],sec,...) end)
while ds[sec]:Size()==nil or ds[sec]:C(ds[sec]:Size())==nil or ds[sec]:Size()==0 or ds[sec]:C(ds[sec]:Size())==0 do
sleep (1)
end
Этот кусок кода находится в начале функции main и выполняется единожды при запуске скрипта. Всё работает, жалоб не было до сегодняшнего дня. Утром я запустил робота примерно в 9:57. Робот начал работать, но сделки не приходили. Робот не получал ни одной сделки, в том числе по супер-ликвидам, которые точно торговались. Остановил скрипт, запустил по новой. Всё стало работать штатно, сделки начали приходить. Подскажите пожалуйста что это могло быть и как с этим бороться в будущем?
Добрый день. При торговле я использую огромную библиотеку функций на луа. Там около 3000 строчек, десятки функций. Далеко не все они нужны. Я эту библиотеку подключаю с помощью
Код
require "TradeLib"
Можно ли импортировать не все функции, а только часть? Наподобие того как в питоне делается:
Цитата
fr om TradeLib import (SendLim it, GetPrice)
И второй вопрос. Если я загружаю всю эту библиотеку в 3000 строчек, то происходит ли чрезмерная загрузка памяти, замедление работы или ещё что-нибудь плохое? Может быть не стоит и волноваться? Спасибо.
Добрый день. Осваиваю работу с сайтом финама. https://www.finam.ru/profile/moex-akcii/sberbank/export/ Беру оттуда архив котировок, к примеру в таком виде: теперь я хочу воспользоваться замечательной библиотекой INDICATORS.ZIP (спасибо огромное её автору, эти функции верно служат мне несколько лет). В описании библиотеки такое предусмотрено:
Код
--Пример расчета индикатора Moving Average по произвольному набору чисел:
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")
tbl = {[1]=2587.5, [2]=2588.5, [3]=2585.1, [4]=2583.7, [5]=2582.6, [6]=2581.2, [7]=2579.2, [8]=2574.7,
[9]=2571.5, [10]=2570.8, [11]=2569.9, [12]=2569.7, [13]=2567.2, [14]=2569.3, [15]=2566.1, [16]=2567,
[17]=2563.3, [18]=2565.2, [19]=2564.3, [20]=2565.9, [21]=2568.5, [22]=2572.2, [23]=2572, [24]=2572, [25]=2571.3}
function main()
func = MA()
t_id = AllocTable()
AddColumn(t_id,1,"Price",true,QTABLE_INT_TYPE,10)
AddColumn(t_id,2,"MA",true,QTABLE_INT_TYPE,10)
CreateWindow(t_id)
SetWindowCaption(t_id,"MA")
for i=1,#tbl do
ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, {[i]=tbl[i]})
tmp=InsertRow(t_id,-1)
SetCell(t_id,tmp,1,tostring(tbl[i]),tbl[i])
SetCell(t_id,tmp,2,tostring(ma_out),ma_out)
end
end
Строить буду по ценам закрытия Close. Вопрос касается таблицы tbl, которая передаётся в функцию. Она будет иметь вид: дата, время, open,high,low,close.
Господа, прошу помочь. Уже долгие часы сжёг на эту проблему. Пытаюсь установить модуль Lunatic Python. Он позволят из скрипта луа вызывать питоновские функции. Вот он https://pypi.org/project/lunatic-python-universal/ --- У меня установлен питон 3.7.0 Установщик pip обновлён до текущей версии. Он благополучно устанавливает пакеты питона, например математическую библиотеку matplotlib --- Установлена Луа 5.1.5 --- Коды на питоне пишу в PyCharm от JetBrains --- Пытаюсь установить lunatic python, но безуспешно Текст ошибки Command "python setup.py egg_info" failed with error code 1 in C:\Users\A\AppData\Lo cal\Temp\pip-install-ley5xara\lunatic-python-universal\ --- попытка установить пакет прямо из папки куда он распакован, тоже неудачная: --- easy_install тоже не даёт результата... Спасибо за любые подсказки
Прошу дать совет. У меня работает скрипт, обрабатывающий большой объём данных. На расчёт уходит много времени. Прошу подсказать, можно ли в луа реализовать многопоточность, чтобы эффективно задействовать все ядра виртуальной машины. В нынешнем виде скрипт работает так:
Код
f_ticker_list="GAZR,SBRF,MIX,Si,RTS"
for instrument in string.gmatch(f_ticker_list,"%w+") do
--утомительные расчёты на основе анализа множества файлов с рыночной информацией
end
Он задействует только 1 ядро виртуальной машины. Как разбросать этот процесс на другие свободные ядра виртуалки? Спасибо
Господа, вопрос не совсем по Луа. Но может быть кто то поможет. У меня две виртуалка, на них установлена Windows Server 2003 На одной виртуалке стоят расчётные роботы, которые "готовят" файлики с параметрами. На второй виртуалке стоит робот, который торгует. Он должен прочитать файлик с параметрами, лежащий на первой виртуалке, например с помощью функции dofile. Как это сделать? Папку с файлом на первой виртуалке нужно сделать общей. Я не умею соединять две виртуалки между собой. Спасибо заранее, если кто то знает.
Господа, прошу подсказать. Мои скрипты работают на луа. Я объединяю данные в огромную таблицу. Вот образец данных: Таких файлов десятки. Я их склеиваю в одну большую таблицу с помощью функции:
Код
function tableMerge(table1, table2)
for k,v in pairs(table2) do
--deceleration()
table.insert(table1,v)
--проверим качество данных в таблице. Нет ли разрывов в записях.
-- if v.stime-(remember_prev_time or v.stime)>100 then
-- mm("в таблице дырка "..v.stime.." "..v.bid)
-- end
remember_prev_time=v.stime
end
remember_prev_time=nil
return table1
end
В итоге получается огромная таблица, которая сильно забивает память. --- Вот как это выглядит на виртуалке. А теперь мой вопрос. в конце работы скрипта я УБИВАЮ эту гигантскую таблицу с помощью строчки t_big=nil Надеюсь, что при этом будет освобождена память. Но этого не происходит. Более того. Остановка скрипта не освобождает память. Она освобождается только с выключением КВИКа подскажите как освобождать память силами самого скрипта. Спасибо. --- П.С. Я знаю, что мой подход сам по себе не совершенен. Иду по пути переноса громоздких функций в dll. Но в силу слабеньких мозгов мне ещё далеко до этого. Так что пока работаю в рамках Луа.
Добрый день. Не могу сообразить как мне получать обезличенные сделки без открытия таблицы обезличенных сделок. Здесь где-то писали, что это можно делать через заказ тикового графика INTERVAL_TICK Но мне нужны параметры обезличенных сделок, такие как Купля-Продажа. Как это реализовать через заказ тикового графика?
Господа, я с горем пополам выучил Луа. Но его возможностей мне уже не хватает, так как накапливаю большие объёмы данных и обрабатываю их. Теперь начал с горем пополам учить С++. Не могу понять как написать простейший dll-файл под КВИК. Например, файл принимает данные текущей таблицы по инструменту SBER (колбек OnParam). Подскажите пожалуйста. Премного благодарен. Прошу простить за тупенькие вопросы.
Друг посоветовал учить язык Golang. Мой тестер стратегии на Луа просчитывает массив данных за 7 часов. Golang это сделает за час. Посоветуйте пожалуйста как из скрипта Луа запускать файл с кодом .go Можно ли это делать через dofile? Или сделать третий файл с флагом вкл/выкл, который будет читаться скриптом на go?
Добрый день. У меня при сохранении настроек выставлена опция В этом состоянии КВИК работал много месяцев. В КВИКе запущены роботы. Включена лента обезличенных сделок по 1 инструменту Си. Сегодня заметил, что КВИК тормозит. Начал думать из-за чего. Увидел, что файл info.log достиг 80 мегабайт. Файл curr_data.log около 10 мегабайт. Удалил все .dat файлы, удалил info.log и curr_data.log Запустил чистенький КВИК. Быстро файл info.log набрал опять под 100 мегабайт. Торможение никуда не делось. Переключение между вкладками происходит с подвисанием на 3-10 секунд. То есть каждая манипуляция в КВИКе сопровождается дикими торможениями.
Господа, прошу подсказать. Этой функцией я записываю текущую маркет дату
Код
function rec_big_data(file_path,value)
if rn==nil then rn={} end
if file_open==nil then file_open={} end
if file_open[file_path]==nil then
rn[file_path]=io.open(file_path,"a+")
file_open[file_path]=true
mm("QL:open file "..file_path)
end
rn[file_path]:write(value.."\n")
rn[file_path]:flush()
end
file_path меняется три раза в день (в его название включён тикер, текущая дата и номер триместра: утренняя сессия 1, дневная сессия 2, вечерняя сессия 3). вот пример historyGDM8 20180511-2.lua В функции нет закрытия файла, потому что файл становится огромным, и скрипту тяжело его постоянно открывать-закрывать. Робот пишет большое количество инструментов много дней подряд. Файлы остаются открытыми. Я замечаю, что виртуалка начинает тормозить. Думаю, что это из-за незакрытых файлов. Подскажите пожалуйста как грамотно закрывать файл в конце триместра (при переходе на новый файл) с помощью close()? Не могу сообразить, что в неё писать. Спасибо.
Господа, помогите пожалуйста советом. Хочу написать гибкий цикл, в котором можно возвращаться на шаг назад, и перебирать данные с разным шагом. Постарался описать это здесь:
Код
iterations=20
start=0
finish=100
step=(finish-start)/iterations
for i=start,finish,step do
--делаем расчёт.
if profit>0 then
--возвращаемся на step назад
--iterations=100 (шаг становится более мелким)
end
end
то есть если я при переборе большого массива данных (слепки стакана) наткнулся на прибыльный участок, то я хочу проанализировать его тщательно, с более мелким шагом. А потом, когда снова пошли убыточные участки, хочу вернуться на прежний шаг - обычный.
Робот работает на виртуалке Windows Server 2003 Я обрабатываю луа-скриптом таблицу с гигантским количеством полей (запись слепков стакана за 10 дней и более). Робот при добавлении очередного дня-таблицы со слепками в общую огромную таблицу вылетает с ошибкой not enough memory, хотя оперативной памяти хватает. Я добавлял на виртуалку ещё 1 ГБ опер.памяти, чтобы наверняка хватало, но всё равно скрипт вылетает с этой ошибкой. Гуглил эту ошибку в интернете, нашёл такую ветку с обсуждением этой темы: https://github.com/minetest/minetest/issues/2988 Нашёл там такую фразу Lua has no problem consuming 2GiB, but LuaJIT bails at 1GiB. Вот: Я, увы, не сильно понял в чём дело и что такое LuaJIT. Но у меня вылетает скрипт как раз на 1 гигабайте оперативки. Прошу подсказать решение проблемы. Также я не понял что это за код, который советует использовать комментатор. Он превращает числа в строки? Но как я это могу применить у себя? Заранее спасибо.
Добрый день. У меня в файл записываются мелкие числа в таком виде: EuM8=7.5599999999996e-005. Это одно из полей таблицы. В дальнейшем робот обращается к этой таблице и не может прочитать это значение.
Вопрос 1. Как записывать мелкие числа в обычном виде?
Вопрос 2. Если пробовать работать с этим числом (кривым), то как его читать?
Добрый день. Пользуюсь колбеком OnTransReply При снятии заявки приходит такая строчка: 04/12/18 13:07:20,267 price=0;client_code=.....;balance=4;time=130720;status=3;qty=0;trans_id=930631256;account=;exchange_code=;quantity=0;firm_id=.........;flags=262145;result_msg=(210) Снято заявок: 1. Снято количество: 4. Нельзя снимать: 0.;brokerref=;order_num=0;R=930631256;server_trans_id=359;uid=.........;ordernum=0;
Как эту запись не перепутать с отчётом о зарегистрированной заявке? В вышеназванной строчке какой признак говорит о том, что пришло снятие? price=0, qty=0 или другие? Или достоверным является только result_msg=(210) Снято заявок: 1. Снято количество: 4. Нельзя снимать: 0
прошу подсказать. Я считаю сумму проторгованных контрактов из таблицы всех сделок. Мне интересны только сделки за последние 60 секунд. В только что написанном коде следующий алгоритм. Он внутри колбека OnAllTrade
Код
sum_vol=0
for n,w in pairs (simple_volume) do
vremya_diff=stime-simple_volume[n].time_time
if vremya_diff>60 then
simple_volume[n]=nil
else
sum_vol=(sum_vol or 0)+simple_volume[n].deal
end
end
simple_volume-это глобальная таблица. В ней есть микро-таблицы, посвящённые каждой сделке. В каждой из микро-таблиц есть поля time_time(время) и deal (объём)
Моё сомнение связано со строкой simple_volume[n]=nil
Я делаю перебор таблицы, и в ходе этого перебора удаляю элемент. Можно ли так делать, и не собьётся ли итоговый подсчёт суммы контрактов?
Добрый день. Есть ли в КВИКе такое явление: инвесторские ключи или инвесторский пароль? Я хочу дать КВИК человеку, чтобы он смотрел счёт, видел рынок, но не мог совершать сделки/отправлять заявки. То есть просмотровый режим
Подскажите пожалуйста. Немного запутался. Нужно ли мне держать открытой таблицу обезличенных сделок при работе с коллбеком OnAllTrade()? Или достаточно выставить птички в заказываемых инструментах? Спасибо.
Прошу подсказать, как вылечить эту проблему. График Открытого интереса выглядит так (количество открытых позиций): Пропуски свечей за сегодня за то время, пока КВИК был выключен. Брокер Открытие. --- Получение пропущенных данных включено: --- Кнопка Обновить нажималась, даже пришло сообщение что "Получены пропущенные данные". Но это не так. Дырки на графике остались.
Добрый день. Уже много лет я пользуюсь кодом для расчёта среднего спреда по акции:
Код
--Внутри колбека OnParam
--Считаем средний спред
local tablebid = getParamEx(class_code, fff, "bid") --получаем таблицу "bid"
local bid=tablebid.param_value --из таблицы берём значение
local tableoffer = getParamEx(class_code, fff, "offer") --получаем таблицу "offer"
local offer=tableoffer.param_value --из таблицы берём значение
local p_spread = (offer - bid) / bid * 100 --считаем текущий спред по бумаге
local elem = average_spreads[fff] --создаём таблицу для хранения расчётных данных
if elem == nil then
average_spreads[fff] = { Count = 1, Spread = p_spread, Avr = p_spread}
elem = average_spreads[fff]
else
elem.Spread = p_spread
elem.Avr = (elem.Avr * elem.Count + p_spread) / (elem.Count + 1)
elem.Count = elem.Count + 1
spread[fff]=elem.Avr
end
Его написал один добрый человек на каком-то трейдерском форуме по Луа. Уже не помню где и кто. Этот код считает средний спред безостановочно по всем значениям, даже если их будет миллион. Подскажите пожалуйста как видоизменить код, чтобы он считал спред за последние 1000 значений? Мне приходит на ум только создание таблицы с 1000 полями, которые будут обновляться, а старые (ненужные) удаляться. Может быть есть более красивый вариант? Благодарю за советы
Добрый день. Прошу дать совет. У меня два робота. У каждого своя стратегия, но каждому из них нужен минутный график фьючерса РТС. Оба робота подписываются на него с помощью колбека.
Код
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
Индикаторы у них разные, поэтому расчёт индикаторов не дублируется. Тем не менее вопрос: не происходит ли двойной работы по получению графика? Если да, то как этого избежать? И стоит ли этого избегать (может быть это маленькая нагрузка, которую можно игнорировать). Спасибо
dofile ("C:\\Program Files\\Lua\\5.1\\lua\\ATR.lua")--ATR
ds_v = CreateDataSource(instr[k].v_class,instr[k].v_sec,INTERVAL_D1)
ds_v:SetEmptyCallback()
sleep(1000)
func2 = ATR()
candles=ds_v:Size() --до этого места доходит и выдаёт количество свечей
long_v={}
short_v={}
for i=1,candles do
long_v[i]=func2(candles, {Period=252}, ds_v)
short_v[i]=func2(candles, {Period=5}, ds_v)
end
Добрый день. Для расчёта одного параметра мне нужно раз в сутки заказать дневной график и посчитать по нему новое значение индикатора. В дальнейшем в течение дня график уже не нужен. Раз в день и всё. Два вопроса. 1. Как это сделать с помощью OnCleanUp()? Этот колбек для меня самый подходящий в данной ситуации. Но в момент его срабатывания графики ещё не транслируются, слишком рано. Может быть есть другой кол-бек, который сработает 1 раз в день? Мне не важно когда получать, утром, днём или вечером. Это погоды не делает. 2. Какие функции работы с графиками следует использовать, чтобы не подписываться на обновления, а 1 раз в день получить новые данные? Достаточно ли будет одного CreateDataSource(class,sec,interval)? Или всё же нужно использовать что-то ещё: SetEmptyCallback например? Я (увы) не сильно понимаю механику этих функций. Дайте пожалуйста подсказки. Заранее спасибо.
Прошу подсказать. У меня с программированием дела плохи. Еле-еле освоил Луа. Учить другие языки нет сил. Скорости КВИКа для отправки заявок мне уже не хватает. Нужен полноценный HFT. Возможно ли реализовать прямой доступ на биржу так чтобы у меня визуально всё осталось по старому: КВИК и Луа? Спасибо за ответ.
Добрый день. Из-за чего может быть такая ошибка? Unknown error. Possible unhandles exeption.
Даже не знаю какие сообщить подробности. Роботы уже давно работают и проверены на баги. Ничего необычного не происходило. Чик - и выбило скрипт с этим мессиджем.
Господа, прошу подсказать какой вариант экономнее 1 вариант
Код
func = RSI()
local rsi_count={}
for i=1,ds[бумага]:Size() do
rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[бумага])
end
rsi0=rsi_count[ds[бумага]:Size()]
rsi1=rsi_count[ds[бумага]:Size()-1]
rsi2=rsi_count[ds[бумага]:Size()-2]
или тоже самое, но с переменной num_candles
Код
func = RSI()
local rsi_count={}
num_candles=ds[бумага]:Size()
for i=1,num_candles do
rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[бумага])
end
rsi0=rsi_count[num_candles]
rsi1=rsi_count[num_candles-1]
rsi2=rsi_count[num_candles-2]
по сути, вопрос такой: тяжело ли компьютеру несколько раз получать значение ds[бумага]:Size()? введение переменной ускорит ли процесс?
В начале я инициализирую переменные. Это не быстрый процесс, потому что некоторые из них рассчитываются. В колбеке ОнПарам используется часть этих переменных. Если на момент срабатывания ОнПарам какая-то из переменных ещё равна нил, то скрипт выдаст ошибку. Скрипт от этого не выбивается. В дальнейшем, когда переменные досчитаются, эта ошибка появляться уже не будет. Как запустить ОнПарам не сразу, а (допустим) через секунду после запуска скрипта? Или запустить его после того как будут заданы все переменные? Спасибо.
Господа, мне нужно удалить элементы таблицы. Дайте пожалуйста совет как это лучше сделать. Вот код:
Код
s={}
for i=1,10 do
table.insert(s,random_max()) --в будущем вместо рандомных чисел будут номера активных заявок.
end
toLog(log, s)
for i=1,#s do
if i>0 then -- Сейчас я написал условие наугад. В будущем будет условие "удалить номер заявки из таблицы s если эта заявка снята или исполнена"
table.remove(s,i)
end
end
toLog(log, s)
фунция random_max() выдаёт случайные числа. Данные лога: таблица s ДО цикла с удалением: 1=941155680;2=1786453605;3=956870528;4=1765415360;5=1701888568;6=1306467983;7=1934583353;8=1639998291;9=498667592;10=1625028150;
таблица s ПОСЛЕ цикла с удалением: 1=1786453605;2=1765415360;3=1306467983;4=1639998291;5=1625028150;
Кхе-кхе. Я ждал, что она полностью удалится, но этого не произошло. Более того, элементы сдвинулись. Объясните пожалуйста почему так происходит и как мне удалять из таблицы нужные мне элементы.
Господа, прошу рассказать про функцию PrintDbgStr Вот я установил программу DebugView. Смотрю на экран. Если взять пример из мануала, то всё работает как задумано:
Код
PrintDbgStr("dbg from " ..getScriptPath())
Но теперь я осознанно допущу ошибку:
Код
a=step*1
PrintDbgStr("dbg from " ..a)
step=getParamEx("SPBFUT","MXZ7","SEC_PRICE_STEP").param_value
пользуюсь переменной step до того как ей присвоено значение (частая ошибка у кодеров-самоучек, а я самоучка) Жду от этой функции что она мне что то покажет, но она молчит. Прошу помощи и реальных примеров того как эта функция может быть полезной
Добрый день. Снятая заявка имеет параметр flags=30 Исполненная заявка имеет параметр flags=28
Как узнать флаги других состояний заявки? Например частично снятая? Из мануала ничего не понятно.
Второй вопрос. У снятой заявки запись такая withdraw_datetime={week_day=4;hour=11;ms=507;mcs=507000;day=2;month=11;sec=8;year=2017;min=58;} У заявки, которая не снималась, эта запись такая: withdraw_datetime={week_day=1;hour=0;ms=0;mcs=0;day=1;month=1;sec=0;year=1601;min=0;}
является ли это исчерпывающей характеристикой снятости-неснятости? ну например если hour==0, то заявка НЕ снятая, а если hour>0, то она снята? Спасибо.
Господа, прошу прощения за тупенький вопрос. Я не силён в математике, функциях и других простых вещах школьной программы. Я хочу задать такую зависимость: чем выше стандартное отклонение, тем шире будут полосы Боллинджера. Сейчас у меня запрограммировано так:
if sd[sec]>200 then otklonenie=5 end if sd[sec]>50 then otklonenie=4 end if sd[sec]>0 then otklonenie=3 end
То есть если рынок волатильный, то в Боллинджер будет заряжено больше стандартных отклонение (его ширина будет выше), а если рынок дохлый, то полосы будут более узкими. Я хочу, чтобы у меня были промежуточные значения. Ну например при sd[sec]==70 у меня ширина полос боллинджера будет 4,35 стандартных отклонений. Помогите это выразить через функцию. otklonenie= .......sd[sec]......... Я понимаю, что ответ может быть разным. Линия может иметь разную кривизну, но мне нужна хоть какая то стартовая подсказка, чтобы понять как это выразить математически. Спасибо заранее за помощь.
function QTable:SetValue(row, col_name, data, formatted)
-- Установить значение в ячейке
local col_ind = self.columns[col_name].id or nil
if col_ind == nil then
return false
end
local col_type = self.columns[col_name].c_type
if row==nil or col_name==nil or data==nil or col_ind==nil then
message ((row or "nil").." | "..(col_name or "nil").." | "..(data or "nil").." | "..(col_ind or "nil")),1)
end
if self.data[row][col_ind]==data then return true end
self.data[row][col_ind]=data
local col_type = self.columns[col_name].c_type
-- если для числового столбца дано НЕчисловое значение, то применяем к нему tonumber
if type(data) ~= "number" and (col_type==QTABLE_INT_TYPE or col_type==QTABLE_DOUBLE_TYPE or col_type==QTABLE_INT64_TYPE) then
data = tonumber(data) or 0
end
-- если для НЕстрокового значения уже дан отформатированный вариант, то сначала используется он
if formatted and col_type~=QTABLE_STRING_TYPE and col_type~=QTABLE_CACHED_STRING_TYPE then
return SetCell(self.t_id, row, col_ind, formatted, data)
end
-- если для столбца задана функция форматирования, то она используется
local ff = self.columns[col_name].format_function
if type(ff) == "function" then
-- в качестве строкового представления используется
-- результат выполнения функции форматирования
if col_type==QTABLE_STRING_TYPE or col_type==QTABLE_CACHED_STRING_TYPE then
return SetCell(self.t_id, row, col_ind, ff(data))
else
return SetCell(self.t_id, row, col_ind, ff(data), data)
end
else
if col_type==QTABLE_STRING_TYPE or col_type==QTABLE_CACHED_STRING_TYPE then
return SetCell(self.t_id, row, col_ind, tostring(data))
else
return SetCell(self.t_id, row, col_ind, tostring(data), data)
end
end
end
Она служит мне верой и правдой. Но иногда она выдает такую ошибку: Это он ругается на строчку if self.data[row][col_ind]==data then return true end Внутри колбека это не приводит к выбиванию скрипта, поэтому я продолжаю работать с ней. Важно: эта ошибка приходит в первую секунду после запуска, когда какое то значение ещё не определено. Потом всё работает хорошо. Вы можете видеть, что я пытаюсь отловить эту ошибку через message, но он спокойно проходит эту проверку. Подскажите где искать иэтот "нил"
Верхний график делится математически на средний график. В итоге получается красный индикатор (внизу). Теперь я хочу работать с нижним красным графиком и наложить на него другой индикатор, ну (для примера) Боллинджер. 1. Можно ли это сделать средствами КВИКа. Взять и "бросить" на этот график стандартный индикатор из списка? 2. Если нет, то как на этот график наложить индикаторы Сергея Горохова из файла INDICATORS.zip? Спасибо за подсказки.
Господа, добрый день. Я запустил робота с большим количеством транзакций на срочном рынке. Я думал, что верно интерпретировал формулу подсчёта сбора за транзакции. Полагал, что у меня достаточное количество сделок, чтобы не попадать на этот штраф. Но всё же биржа мне начислила этот штраф: 2300 рублей. Прошу подсказать где ошибка в моём коде. По сути формула изложена в самом конце кода: sbor=0.1*(orders*2*1-(trades*comiss*40)) Вот так она выглядит на сайте биржи http://www.moex.com/a3825 Спасибо за помощь.
Код
function Sbor()
local order_line
count=0
for t=getNumberOf("orders"),1,-1 do
order_line=getItem("orders",t-1)
if order_line.class_code=="SPBFUT" then
count=count+1
end
end
orders=count
local deal_line
count=0
comiss=0
for t=getNumberOf("trades"),1,-1 do
trade_line=getItem("trades",t-1)
if trade_line.class_code=="SPBFUT" then
comiss=comiss+trade_line.exchange_comission
count=count+1
end
end
trades=count
sbor=0.1*(orders*2*1-(trades*comiss*40))
tbl:SetValue(1,'sbor', orders.." | "..trades.." | "..comiss.." | "..sbor)
return orders,trades,comiss
end