Добрый день. Прошу подсказать, что обрывает break в нижеприведённом случае: условие if или цикл for. Мне нужно, чтобы обрывался цикл for. Заранее спасибо за помощь.
Код
--Стандартное отклонение
func1 = SD()
gorlovina[sec]=nil
for ddd=num_candles,num_candles-gorlovina_bars,-1 do
local dev=func1(ddd, {Period=x[sec], VType="Typical"}, ds[sec])
dev_k[sec]=dev/line_10[sec]
if dev_k[sec]<gorlovina_thresh[sec] then
gorlovina[sec]=true
break
end
end
Господа, теор. цена обновляется в КВИКе раз в минуту, это очень долго. Есть ли в открытом доступе модуль на Луа или просто формула для её расчёта? Чтобы самому расчитывать теор. цену. Я не про формулу Б-Ш в гипотетическом виде, а именно реализация в КВИКе. Спасибо.
Господа, замучился уже с этой функцией. Есть ли в ней ошибка?
Код
function ms (value)
if type(value)~="table" then
message (""..(value or "nil"),1)
else
for k,v in pairs(value) do
message (k.." "..v,1)
end
end
end
Объясню. Она то работает,то не работает. Будучи внутри колбека OnParam она в начале выдаёт нужные значения. Потом, не меняя код, начинает глючить и выдавать сообщение, что ms - это нил. Ну например ms("бид="..bid) После начала работы кода она пишет бид=55.2 А потом начинает вылетать с описанной выше ошибкой. Подскажите пожалуйста что с ней может быть не так.
И ещё вопрос вдогонку. ОнОрдер принял заявку. order.order_num равен ну например 12345 я хочу создать таблицу с названием 12345. И в ней будут поля 12345.order_price 12345.trade_price Не могу сообразить как создать таблицу 12345. Спасибо.
Господа, хочу делать подсчёт следующего рода. Робот выставляет заявку на покупку по формуле Лучший бид + 10 шагов цены. Я хочу делать подсчёт, насколько цена сделки оказалась лучше, чем цена выставленной заявки. То есть: разница=цена заявки минус цена сделки. Как это лучше сделать? По идее мне нужно в двух колбеках ОнТрейд и ОнОрдер отлавливать эту заявку по номеру, а потом сравнивать цену? Или есть способы получше?
Господа, хорошо знаком с КВИКом, много лет торгую, но на валютном споте никогда операций не проводил. Вопросы по технической части КВИКа. 1. Где смотреть есть у меня открытые позиции по USDRUB_TOM или нету? 2. Верно ли, что на следующий день купленный USDRUB_TOM будет отображаться в КВИКе уже как TOD? 3. Какие функции Луа позволяют получать информацию о купленных-проданных рублях или долларах? 4. Где смотреть прибыль-убыток по открытой позиции? 5. Где смотреть точку входа (по какой цене вошёл)? 6. В таблице купить-продать есть ли полезные данные по открытым позициям? Важное уточнение. У меня единая позиция: фьючерсы, акции, валютный спот. То есть всё вместе. Брокер Открытие. Заранее спасибо.
Ещё вопрос. У меня выставлено 60 заявок. У брокера ограничение 50 заявок. Я использую для массового снятия заявок функцию на Луа
Код
function killAllOrders(table_mask)
-- данная функция отправит транзакции на отмену АКТИВНЫХ заявок соответствующим фильтру указанному как входящий параметр table_mask
-- список всех возможных параметров : ACCOUNT,CLASSCODE,SECCODE,OPERATION,CLIENT_CODE,COMMENT
-- если вызвать функцию с параметром nil - снимутся ВСЕ активные заявки
local i,key,val,result_num=0,0,0,0
local tokill=true
local row={}
local result_str=""
for i=0,getNumberOf("orders")-1,1 do
row=getItem("orders",i)
tokill=false
if orderflags2table(row.flags).active then
tokill=true
if table_mask~=nil then
for key,val in pairs(table_mask) do
if string_lower(key)=='comment' then
if string_find(string_lower(row.brokerref),string_lower(val))==nil then tokill=false break end
else
if row[string_lower(key)]~=val then tokill=false break end
end
end
end
end
if tokill then
res,ms=killOrder(tostring(row.order_num),row[securityfiledname],row.class_code)
result_num=result_num+1
if res then
result_str=result_str..row.order_num..","
else
result_str=result_str.."!"..row.order_num..","
end
end
end
return true,"QL.killAllOrders(): Sended "..result_num.." transactions. order_nums:"..result_str
end
Вопрос. Эта функция снимет 50 заявок? Или она не снимет ни одной заявки, ведь сервер увидит что его мучают и не снимет ничего?
Спасибо за ответ. Это стало появляться совсем недавно. Брокер может делать такое ограничение, а может не делать? Это настраивается для всех клиентов, или брокер может вводить персональные ограничения для отдельных клиентов если видит, что они флудят заявками?
Добрый день. При попытке "снять все заявки" (их у меня больше сотни) начало появляться сообщение: Количество транзакций превышает максимально разрешённое 50 в секунду. Кто автор этой ошибки 1. КВИК 2. Брокер 3. Биржа?
Почему оно возникает несколько раз при попытке "Снять все активные заявки" через контекстное меню (клик правой кнопкой по таблице заявок). На скриншоте видно, что команда сгенерировалась 6 раз.
Добрый день. При работе с библиотекой socket постоянно проблемы с нахождением этой папки.
приходится класть папки mime и socket в ту же директорию где лежит скрипт. как задать к этим файлам путь принудительно, чтобы require сразу их находил?
C:\Program Files\Lua\5.1\lua\socket.lua:13: module 'socket.core' not found: no field package.preload['socket.core'] no file '.\socket\core.lua' no file 'C:\Open_Broker_QUIK\lua\socket\core.lua' no file 'C:\Open_Broker_QUIK\lua\socket\core\init.lua' no file 'C:\Open_Broker_QUIK\socket\core.lua' no file 'C:\Open_Broker_QUIK\socket\core\init.lua' no file 'C:\Open_Broker_QUIK\Include\socket\core.lua' no file 'C:\Open_Broker_QUIK\Include\socket\core.luac' no file 'C:\Open_Broker_QUIK\LuaIndicators\socket\core.lua' no file 'C:\Open_Broker_QUIK\LuaIndicators\socket\core.luac' no file 'C:\Program Files\Lua\5.1\lua\socket\core.luac' no file 'C:\Program Files (x86)\Lua\5.1\lua\socket\core.lua' no file 'C:\Program Files\Lua\5.1\lua\socket\core.lua' no file '.\socket\core.dll' no file 'C:\Open_Broker_QUIK\socket\core.dll' no file 'C:\Open_Broker_QUIK\loadall.dll' no file 'C:\Open
Господа, подскажите пожалуйста как реализовать такую задачу на Луа. 1. Робот заходит на страничку с дивидендами: http://smart-lab.ru/dividends/ 2. Читает её 3. Формирует Луа-таблицу с полями Тикер - дата отсечки Т+2 Тикер - дата отсечки Т+2 4. В последний день перед дивидендым гэпом посылает сообщение в КВИК.
Мои роботы на Луа никогда не читали интернет-странички и не брали из них данных. Даже не знаю с чего начать. Спасибо за помощь.
Господа, я долго писал свои коды на луа в Notepad++. Две недели как тестирую крутую китайскую программу LuaStudio. Но минусы в ней есть. Кое-в-чём Notepad++ круче. Вопрос такой. Как в Notepad++ исполнить свой скрипт (клавиша F5)? я не понимаю, что делать в этом окошке: Пробовал писать путь к КВИКу, но это не дало какого-то результата.
Линии на графике являются индикаторами. Когда линия находится сильно высоко от графика, к примеру на 40% выше цены, я бы хотел её не рисовать. Должен быть пропуск, индикатор не рисуется. Но это будет не красиво, потому что КВИК попытается все же соединить последнее значение перед дыркой и первое значение после дырки. Можно ли этого избежать? Можно ли одну линию сделать разноцветной? один участок красный, другой, например, зелёный?
Господа, никогда не писал индикаторы на Луа. Прошу дать совет. Мне нужен график рубле-бочки. Формула: рубле-бочка=(фьючерс на доллар-рубль умножить фьючерс барреля в долларах)/1000 То есть индикатор простой, но строить его надо по данным двух графиков
Обычный индикатор, берущий данные с 1 графика я сделать могу, взяв за шаблон коды С.Горохова, а вот как брать данные с двух графиков, не знаю.
Спасибо, буду разбираться. Я не кодер, поэтому страдаю от непонимания простых вещей. Все же надеюсь, что в эту ветку заглянет Сергей Горохов и внесёт ясность.
Добрый день. прошу подсказать, как делать перевод каретки на Луа. чтобы новое значение дозаписывалось в файл с новой строки. Это требуется для этого кода
Код
path="C:\\sintetika.lua"
function write_end(file_path,value)
cf=io.open(file_path,"a+")
cf:write(value)
cf:flush()
cf:close()
end
function main ()
chart1="1"
price1 = getNumCandles (chart1)
chart2="2"
price2 = getNumCandles (chart2)
for i=100,1,-1 do
local price_tab1=getCandlesByIndex(chart1,0,price1-i,1)
local high1=price_tab1[0].high
local low1=price_tab1[0].low
local last1=price_tab1[0].close
local typical1=(high1+low1+last1)/3
local price_tab2=getCandlesByIndex(chart2,0,price2-i,1)
local high2=price_tab2[0].high
local low2=price_tab2[0].low
local last2=price_tab2[0].close
local typical2=(high2+low2+last2)/3
local typical_synt=typical1/typical2
message (typical_synt.."",1)
write_end (path, typical_synt.." ")
end
end
Владимир, спасибо за ответ. Но это старая ветка. Вопрос изложенный в начале давно решён. Сейчас на повестке дня две других проблемы: 1. После обновления функций из INDICATORS.ZIP перестали работать скрипты. 2. Так и не получается передавать в индикатор только последний элемент. В приведённом вами примере используется прежний (нерациональный) способ передачи, от которого я хочу отказаться. dev = sec1.SD(i, {Period=mov_period, VType="Typical"}, ds_mov) Вместо ds_mov надо передавать одно число типа такого варианта (но он не работает) Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i)})
Передавать последний элемент тоже не вариант. Результат такой же.
Код
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")
num_candles=ds_main[sec]:Size() --параметр получен, с ним всё ок.
func = MA()
for i=1,num_candles do
ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, {[i]=ds_main[sec]:C(i)})
message (i.."="..ma_out,1)
end
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")
num_candles=ds_main[sec]:Size()
func = MA()
for i=1,num_candles do
ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, ds_main[sec])
message (i.."="..ma_out,1)
end
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")
num_candles=ds[sec]:Size()
func = MA()
for i=1,num_candles do
ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, ds_main[sec])
message (i.."="..ma_out,1)
end
Обновил. Теперь ничего не работает, все роботы стали глючить. Например перестал рассчитываться RSI Вот вид, который был рабочим до обновления функций:
Код
func = RSI()
local rsi_count={}
num_candles=ds[sec]:Size()
for i=1,num_candles do
rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[sec])
end
переменная i - это перебор значений в цикле. В моём случае она не определена. Она нужна только для EMA,RSI и других подобных индикаторов. Для стандартного отклонения она не требуется. Поэтому ваш пример не рабочий в моём случае.
Здравствуйте, Сергей. Добрался до того, чтобы посидеть над этими записями с форума. Не получается запихивать в индикатор только последнее значение. Начал с простого - Стандартное отклонение. В таком виде работает:
Лонгить Сбер и шортить МТС надо на равные суммы. Они должны взаимно перекрыть друг друга. Грубо говоря, купить сбер на x рублей и продать мтс на x рублей. Вот эту цифру x и надо высчитать.
Например лонг по Сбер должен быть на 650 тыр и шорт по МТС на такую же сумму 650 тыр. И не должно остаться излишков денег.
Господа, прошу помочь решить пример скорее математический, чем программистский.
На счету 500 000 рублей. Я буду покупать Сбер и против него шортить МТС. (акции взяты с потолка для примера) Маржинальный коэффициент D_long у Сбера 0.3924 Маржинальный коэффициент D_short у МТС 0,44
Нужно, 1. Чтобы плечо использовалось максимально. Не должно оставаться неизрасходованных денег. 2. Чтобы лонг и шорт были на равную сумму денег. Равную - в разумных пределах, она будет кривоватая в любом случае. Как рассчитать сумму денег, на которую покупать Сбер и шортить МТС?
Мои мысли. Чтобы посчитать максимум денег, на который я могу покупать Сбер, надо 500 000 разделить на 0,3924. Получается 1 274 209 Максимум денег, на который я могу зашорить МТС равен 500 000/0,44=1 136 363 Но эти расчёты не годятся, потому что будет одновременно две позиции: лонг Сбер против шорта МТС. Прошу подсказать как посчитать сумму денег на покупку каждой акции с учётом двух вышеназванных требований (использовать всё плечо, суммы по каждой акции равные) Спасибо.
Сергей, спасибо за ответ. Помогите решить загадку. Вот блок расчёта RSI
Код
func = RSI()
local rsi_count={}
message (""..#sintez_table[sintez_name],1)
for yyy=1,#sintez_table[sintez_name] do
rsi_count[yyy]=func(yyy, {Period=15, VType="Any"}, sintez_table[sintez_name])
end
Вот таблица sintez_table[sintez_name], которая в неё заходит. Это цены закрытия газпрома на пятиминутках. Поле 1 - это крайняя правая свеча.
Код
{1=123;2=122.53;3=122.61;4=122.7;5=122.65;6=122.6;7=122.51;8=122.63;9=122.63;10=122.67;11=122.65;12=122.6;13=122.81;14=122.97;15=122.85;16=123.08;17=123.13; и так далее.
А вот итоговая таблица rsi_count со значениями RSI
Они словно прилетели с другой планеты. У крайней правой свечи значение RSI 54,07. Вот оно:
Подскажите пожалуйста как получить правильное значение RSI. Быть может, мне нужно таблицу переделать с конца на начало, чтобы крайнее правое поле было последним значением таблицы?
local t=container[sec]; --это таблица цен по данному инструменту local len=#t -- это текущее количество цен в контейнере
local n=len-N; if n<1 then n=1; end -- это номер первого из N значений цен т е Ваши цены в t[n] до t[len]
Большая буква N - это сколько последних свечек я хочу брать для анализа? То есть аналог моей переменной how_many_candles? сразу как вы выложили свой вариант функции
Код
function mycallbackforallstocks(class,sec,index)
if container==nil then container={} end
if container[sec]==nil then container[sec]={} end
-----------------------------
local close=ds[sec]:C(index)
local open=ds[sec]:O(index)
local high=ds[sec]:H(index)
local low=ds[sec]:L(index)
container[sec][index]=(close+open+high+low)/4
end
я её испробовал, но она не работает. Код вылетает с ошибкой нил на строчке sintez_table[x]=temp_t[x]/temp_tt[x]
function OnInit ()
class_code="TQBR"
interval=INTERVAL_M5 --интервал
how_many_candles=50
ticker_list="GAZP,SBER,VTBR"
ds={}
num_candles={}
line_count_table={}
container={}
is_run = true
dofile ("C:\\Program Files\\Lua\\5.1\\lua\\2.lua") --читаем индикатор RSI из INDICATORS.ZIP
end
function OnStop(s)
is_run = false
return 100
end
function mycallbackforallstocks(class,sec,index)
num_candles[sec]=ds[sec]:Size()
if index==num_candles[sec] then
for i=0, how_many_candles do
local close_price=ds[sec]:C(num_candles[sec]-i)
local open_price=ds[sec]:O(num_candles[sec]-i)
local high_price=ds[sec]:H(num_candles[sec]-i)
local low_price=ds[sec]:L(num_candles[sec]-i)
local typical_price=(close_price+open_price+high_price+low_price)/4
table.insert(container[sec],i,typical_price)
end
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class_code,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class_code,sec,...) end)
return ds[sec]
end
function main()
for sec in string.gmatch(ticker_list,"%a+") do
container[sec]={}
DataSource(class_code,sec,interval)
end
while is_run do
for sec in string.gmatch(ticker_list,"%a+") do
sleep (10000)
for second_sec in string.gmatch(ticker_list,"%a+") do
sintez_table={}
sintez_name=sec..second_sec..""
for x=0,how_many_candles do
if sec==second_sec then
local temp_t=container[sec]
sintez_table[x]=temp_t[x]
else
local temp_t=container[sec]
local temp_tt=container[second_sec]
sintez_table[x]=temp_t[x]/temp_tt[x]
end
end
func = RSI()
local rsi_count={}
for lll=1,#sintez_table do
rsi_count[lll]=func(lll, {Period=15, VType="Any"}, sintez_table)
end
end
end
end --is_run
end --main
Спасибо, Николай. Я хочу получить таблицу-контейнер, в которой будут храниться цены за последние how_many_candles свечей (how_many_candles-пользовательская переменная, например равная 50). В контейнер будет записываться типическая цена (Typical). Всё это нужно для создания синтетических инструментов и их анализа. Я хочу получить значение пары GAZP/SBER: сколько сберов надо отдать за 1 Газпром, получить по GAZP/SBER цены за how_many_candles свечей и эти данные загнать в индикаторы Сергея Горохова INDICATORS.ZIP. Например посчитать RSI по паре GAZP/SBER Вопрос о финальной стадии "запихивания" я задал в этой ветке. https://forum.quik.ru/forum10/topic2733/ Что то не клеится при расчёте RSI. Вот весь код, который на данный момент сырой и глючный.
Код
function OnInit ()
class_code="TQBR"
interval=INTERVAL_M5 --интервал
how_many_candles=50
ticker_list="GAZP,SBER,VTBR"
ds={}
num_candles={}
line_count_table={}
container={}
is_run = true
dofile ("C:\\Program Files\\Lua\\5.1\\lua\\2.lua") --читаем индикатор RSI
end
function OnStop(s)
is_run = false
return 100
end
function mycallbackforallstocks(class,sec,index)
num_candles[sec]=ds[sec]:Size()
if index==num_candles[sec] then
for i=0, how_many_candles do
local close_price=ds[sec]:C(num_candles[sec]-i)
local open_price=ds[sec]:O(num_candles[sec]-i)
local high_price=ds[sec]:H(num_candles[sec]-i)
local low_price=ds[sec]:L(num_candles[sec]-i)
local typical_price=(close_price+open_price+high_price+low_price)/4
table.insert(container[sec],i,typical_price)
end
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class_code,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class_code,sec,...) end)
return ds[sec]
end
function main()
for sec in string.gmatch(ticker_list,"%a+") do
container[sec]={}
DataSource(class_code,sec,interval)
end
while is_run do
for sec in string.gmatch(ticker_list,"%a+") do
sleep (10000)
for second_sec in string.gmatch(ticker_list,"%a+") do
sintez_table={}
sintez_name=sec..second_sec..""
for x=0,how_many_candles do
if sec==second_sec then
local temp_t=container[sec]
sintez_table[x]=temp_t[x]
else
local temp_t=container[sec]
local temp_tt=container[second_sec]
sintez_table[x]=temp_t[x]/temp_tt[x]
end
end
func = RSI()
local rsi_count={}
for lll=1,#sintez_table do
rsi_count[lll]=func(lll, {Period=15, VType="Any"}, sintez_table)
end
end
end
end
end
Вроде бы делаю всё по инструкции, но не получается. Пытаюсь рассчитать значение RSI на основе данных этой таблицы. Она считается сама по своим правилам 1=122.5475;2=122.63;3=122.6325;4=122.635;5=122.535;6=122.5375;7=122.6075;8=122.6575;9=122.63;10=122.61;11=122.71;12=122.9225;13=122.885;14=122.935;15=123.105;16=123.155;17=123.115;18=123.085;19=123.2;20=123.2725;21=123.3225;22=123.2825;23=123.2375;24=123.2275;25=123.19;26=123.26;27=123.27;28=123.305;29=123.2725;30=123.32;31=123.3575;32=123.3825;33=123.4625;34=123.46;35=123.475;36=123.3725;37=123.3125;38=123.2975;39=123.2575;40=123.2475;41=123.065;42=122.9225;43=122.91;44=122.96;45=122.9325;46=122.8125;47=122.79;48=122.84;49=123.0175;50=123.05;0=123 Её название sintez_table
Пишу так, почти копируя из инструкции к INDICATORS.ZIP
Код
func = RSI()
local rsi_count={}
for lll=1,#sintez_table do
rsi_count[lll]=func(lll, {Period=15, VType="Any"}, sintez_table)
end
с 1 по 14 итерацию rsi_count[lll]=nil и только с 15 раза начинает что то считать, и то не правильно. Это цены Газпрома, я отсчитал 15 свечек влево. Там RSI совсем другой. Как с этим бороться? Вот пример, который я брал за образец
Добрый день. Подскажите пожалуйста как записать этот код без создания лишней таблицы s
Цитата
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size() if index==num_candles then container[sec]={} s=container[sec] for i=0, how_many_candles do local close_price=ds[sec]:C(num_candles-i) local open_price=ds[sec]:O(num_candles-i) local high_price=ds[sec]:H(num_candles-i) local low_price=ds[sec]:L(num_candles-i) local typical_price=(close_price+open_price+high_price+low_price)/4 s[i]=typical_price end end end
Я пытался записать в таком виде, но код не работает.
Цитата
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size() if index==num_candles then container[sec]={} for i=0, how_many_candles do local close_price=ds[sec]:C(num_candles-i) local open_price=ds[sec]:O(num_candles-i) local high_price=ds[sec]:H(num_candles-i) local low_price=ds[sec]:L(num_candles-i) local typical_price=(close_price+open_price+high_price+low_price)/4 container[sec].[i]=typical_price end end end
Взгляните пожалуйста на такой вариант. Не происходит ли тут лишних действий, всё ли экономно в плане получения и подсчёта индикаторов?
Код
ds={}
ds_minutes={}
Код
function mycallbackforallstocks(class,sec,index)
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
function DataSource_minutes(class,sec,interval)
ds_minutes[sec] = CreateDataSource(class,sec,interval)
ds_minutes[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
Код
function main()
for key,sec in pairs(fut_list) do
DataSource(class,sec,rsi_tf)
DataSource_minutes(class,sec,mov_tf)
end
.............
while is_run do
for key,sec in pairs(fut_list) do
sleep (1000)
func = RSI()
local rsi_count={}
num_candles=ds[sec]:Size()
last_price[sec]=ds[sec]:C(num_candles)
for i=1,num_candles do
rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[sec])
end
.....................
--Стандартное отклонение
func = SD()
dev=func(ds_minutes[sec]:Size(), {Period=mov_period, VType="Typical"}, ds_minutes[sec])
.......................