Sergey Gorokhov написал: Ничего не мешает сделать несколько ds, для каждой бумаги свой. Например если вместо переменной использовать таблицу ds[sec] = CreateDataSource("TQBR", sec, INTERVAL_M1)
я пробовал, но тогда данные не заходят в функцию с вашего сайта:
Ок, переформулирую вопрос. 1. Этот код работает, но он работает медленнее чем брать данные с графика через идентификатор. Почему? Где самый тяжёлый участок кода? 2. Мне надо запустить ds = CreateDataSource("TQBR", sec, INTERVAL_M1) единожды, верно? 3. Мне надо запустить ds:SetUpdateCallback() тоже единожды, верно? 4. Мне надо перебрать много бумаг. Если я сделаю так,
Код
for sec in string.gmatch(ticker_list,"%a+") do
ds = CreateDataSource("TQBR", sec, INTERVAL_M1)
ds:SetUpdateCallback()
end
а потом основной цикл программы внутри while is run
for sec in string.gmatch(ticker_list,"%a+") do
запускаются функции, проверяются условия срабатывания, идёт торговля
end
это правильно? Ведь ds будет всё время принимать значение новой бумаги и будет каша. Спасибо за ответы
Михаил, я пытался применить ваш код для работы со многими бумагами, но не вышло. close_price=ds:C(index) - не расчитывается. Подскажите пожалуйста где ошибка.
Код
log="TESTS_ARROW_NEW.log"
f_ticker_list="BRZ6,EDZ6,SiZ6"
is_run=true
ds={}
function mycallbackforallstocks(class,security,index)
-- Теперь в колбеке нам доступны код и класс инструмента
close_price=ds:C(index)
message(close_price ,1)
-- Также доступны все параметры, которые приходят с колбеком из терминала
xxx = index
end
function DataSource(class,security,interval)
local ds = CreateDataSource(class,security,interval)
ds:SetUpdateCallback(function(...) mycallbackforallstocks(class,security,...) end)
return ds
end
function main()
for sec in string.gmatch(f_ticker_list,"%w+") do
ds[sec]=DataSource("SPBFUT", tostring(sec),INTERVAL_M1)
end
while is_run do
sleep (10)
end
end
Вопросы по ds:Size() 1. Почему у акций на минутном графике разный ds:Size() ? 2. От чего это зависит? 3. Он у каждой акции всегда одинаковый или менятся? Если меняется, то когда и почему?
Большое спасибо за ответы! Разрешите задать ещё вопрос. У меня робот перебирает много акций, и рассчитывать индикаторы надо для каждого из них. Вот как это выглядит сейчас. У меня ведь грубая ошибка - я каждый раз внутри цикла по новой подписываюсь на свечки и ставлю колбек? Подскажите пожалуйсте где грамотно размещать заказ свечек и обновлений? Функция MA - это готовый пример с сайта ARQA
Код
ticker_list = "AFLT,ALRS,BANE,CHMF,FEES,GAZP,GMKN,HYDR,IRAO,LKOH,MAGN,MFON,MGNT,MOEX,MTSS,NLMK,NVTK,RASP,ROSN,RSTI,RTKM,SBER,SNGS,SNGSP,TATN,URKA,VTBR"
is_run = true
function OnStop(s)
is_run = false
return 1000
end
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua") --взято с сайта ARQA
function main()
while is_run do
for sec in string.gmatch(ticker_list,"%a+") do
ds = CreateDataSource("TQBR", sec, INTERVAL_M1)
ds:SetUpdateCallback()
sleep(100)
func = MA()
ma_out=func(ds:Size(), {Period=60, Metod = "SMA", VType="Typical", round=4}, ds)
end
end
end
Сейчас формула такая. На примере 5-периодной Moving Average:
Код
..............................
ds=CreateDataSource(p_classcode, p_seccode, INTERVAL_M1)
ds:SetUpdateCallback(cb)
while is_run do
length=ds:Size()
sum=0
for i=0,4,1 do
sum=sum+ds:C(length-i)
end
moving5=sum/5
sleep(100)
end
end
Добрый день. Хочу вычислять скользящую среднюю внутри кода. Что при этом нужно учитывать? Период 14, часовик, по ценам close Казалось бы всё просто, но есть особенности: 1. Старые свечки можно не обрабатывать, а обрабатывать только текущую. 2. Но обрабатывать старые всё же придётся, ведь рисуются новые свечки, поэтому каждый раз при формировании новой свечи придётся разок пересчитать старые. Помогите пожалуйста выразить это в красивом коде. Спасибо.
Спасибо за ответы. Последний вопрос. В RDP можно выбрать опцию и заходить на виртуалку с доступом к жёсткому диску ноутбука (домашнего компа). Системный администратор виртуалки может ли также залезть ко мне на ноутбук?
Спасибо за ответ! А системный администратор может залогиниться и зайти на мою виртуалку как к себе домой? Увидеть рабочий стол, открытый КВИК и так далее...
Добрый день. Хочу арендовать у брокера виртуальную машину. Для меня важно, чтобы сотрудники брокера не имели доступа к кодам моих роботов и файлам с настройками КВИКа типа info.wnd. Прошу знатоков ответить на такие вопросы. 1. Имеет ли администратор виртуальной машины доступ к файлам, которые хранятся на моём диске на виртуалке? Пароль входа разумеется будет изменён. 2. Скомпилированные файлы .luac работают также быстро как .lua? 3. Если файлы роботов вида .lua не хранятся на виртуалке, может ли администратор виртуалки увидеть эти коды из .dat-файлов КВИКа или ещё откуда-нибудь? Спасибо за ответы.
Добрый день. Я получаю данные Moving Average с графика через идентификатор. На днях понял, что можно удалить график Price, так как я к нему не обращаюсь. В итоге стало так:
Вопросы. Не вредит ли отсутствие Price расчётам индикатора? Не происходит ли расчёт текущего значения индикатора медленнее? Нет ли из за этого каких то особых проблем с расчётом именно текущего значения?
for sec in string.gmatch(ticker_list,"%a+") do
if IsSubscribed_Level_II_Quotes(class, sec)==false then
Subscribe_Level_II_Quotes(class, sec)
end
local qt = getQuoteLevel2(class, sec)
local bid_1 = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)+0].price))
local bid_1_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)+0].quantity))
local bid_2_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-1].quantity))
local bid_3_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-2].quantity))
local bid_4_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-3].quantity))
local bid_5_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-4].quantity))
local bid_6_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-5].quantity))
local bid_7_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-6].quantity))
local bid_8_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-7].quantity))
local bid_9_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-8].quantity))
local bid_10_q = tonumber(toPrice(sec, qt.bid[tonumber(qt.bid_count)-9].quantity))
end
Как это реализовать в коде? Сначала - до main - я заказываю стаканы по нужным инструментам через Subscribe_Level_II_Quotes, а потом внутри main - получаю стакан с помощью getQuoteLevel2? Или нужно обязательно через колбек OnQuote?
Добрый день. Я по старинке держу все стаканы открытыми, когда считываю с них информацию с помощью getQuoteLevel2(class_code, sec_code) это просиходит внутри main Колбеком OnQuote не пользуюсь, нет особой надобности. Натолкнулся на сообщение, что открытое окно стакана уже не требуется. Его можно не открывать. Так ли это? Изменится ли способ получения информации со стакана? Не отразится ли это на качестве получаемой информации? Спасибо
Очень не хватает информации во сколько скрипт на Луа перестал работать из за ошибки. В строке с ошибкой пишется скупое Attempt to index field ... (a nil value).... а во сколько это произошло не понятно. Прошу добавить эту информацию в строку об ошибке.
Добрый день. подскажите пожалуйста, что оптимизирует эта опция?
У меня открыты две сотни графиков, поэтому вопрос не праздный. Это экономит трафик? Это экономит загрузку процессора? Это экономит загрузку памяти? Это позволяет работать быстрее роботам на Луа, который обращаются к этим графикам? Ради чего полезна эта опция? Спасибо
function status_container(file_path,value)
cf=io.open(file_path,"w+")
cf:write(value)
cf:flush()
cf:close()
end
status_container ("\\1-пк\trash\VBZ6.log", "uraaaa") --пишем слово в файл
Выдаёт ошибку: Это попытка написать слово в файл по сети. Ошибка в адресе, так как на "родной" комп всё пишет. Как правильно написать адрес файла на другом компьютере?
Господа, прошу помочь оптимизировать код. Я знаю что опытные программисты полностью избегают многократного получения одних и тех же данных индикатора. Я так не умею, мой код выглядит так:
Код
до функции main
ticker_list = "AFLT,ALRS,BANE,CHMF,FEES,GAZP,GMKN,HYDR,IRAO,LKOH,MAGN,MFON,MGNT,MOEX,MTLR,MTSS,NLMK,NVTK,RASP,ROSN,RSTI,RTKM,SBER,SIBN,SNGS,SNGSP,TATN,URKA,VTBR"
indicator={}
внутри main:
for sec in string.gmatch(ticker_list,"%a+") do
sleep (1000)
--получаем данные индикатора RSI
chart_inst=tostring("RSI_"..sec)
RSI_n = getNumCandles (chart_inst)
indicator[sec].rsi_0 = getCandlesByIndex(chart_inst,0,RSI_n-1,1)[0].close
indicator[sec].rsi_1 = getCandlesByIndex(chart_inst,0,RSI_n-2,1)[0].close
indicator[sec].rsi_2 = getCandlesByIndex(chart_inst,0,RSI_n-3,1)[0].close
indicator[sec].rsi_3 = getCandlesByIndex(chart_inst,0,RSI_n-4,1)[0].close
indicator[sec].rsi_4 = getCandlesByIndex(chart_inst,0,RSI_n-5,1)[0].close
indicator[sec].rsi_5 = getCandlesByIndex(chart_inst,0,RSI_n-6,1)[0].close
indicator[sec].rsi_6 = getCandlesByIndex(chart_inst,0,RSI_n-7,1)[0].close
indicator[sec].rsi_7 = getCandlesByIndex(chart_inst,0,RSI_n-8,1)[0].close
indicator[sec].rsi_8 = getCandlesByIndex(chart_inst,0,RSI_n-9,1)[0].close
indicator[sec].rsi_9 = getCandlesByIndex(chart_inst,0,RSI_n-10,1)[0].close
indicator[sec].rsi_10 = getCandlesByIndex(chart_inst,0,RSI_n-11,1)[0].close
indicator[sec].rsi_11 = getCandlesByIndex(chart_inst,0,RSI_n-12,1)[0].close
indicator[sec].rsi_12 = getCandlesByIndex(chart_inst,0,RSI_n-13,1)[0].close
indicator[sec].rsi_13 = getCandlesByIndex(chart_inst,0,RSI_n-14,1)[0].close
indicator[sec].rsi_14 = getCandlesByIndex(chart_inst,0,RSI_n-15,1)[0].close
indicator[sec].rsi_15 = getCandlesByIndex(chart_inst,0,RSI_n-16,1)[0].close
indicator[sec].rsi_16 = getCandlesByIndex(chart_inst,0,RSI_n-17,1)[0].close
indicator[sec].rsi_17 = getCandlesByIndex(chart_inst,0,RSI_n-18,1)[0].close
indicator[sec].rsi_18 = getCandlesByIndex(chart_inst,0,RSI_n-19,1)[0].close
indicator[sec].rsi_19 = getCandlesByIndex(chart_inst,0,RSI_n-20,1)[0].close
indicator[sec].rsi_20 = getCandlesByIndex(chart_inst,0,RSI_n-21,1)[0].close
анализируем полученные данные. Для анализа нужны все 21 значение.
end
То есть каждый раз робот делает лишние действия - получает свечи, которые не поменялись и уже не поменяются. Прошу подсказки как не получать все значения на каждой итерации, а получать только свежую свечу - текущую, то есть indicator[sec].rsi_0
log="тесты.log"
ticker_list = "AFKS,AFLT,AKRN,ALRS,AVAZP,BANE,BANEP,CHMF,DIXY,FEES,GAZP,GCHE,GMKN,GRAZ,HYDR,IRAO,KMAZ,LKOH,LNTA,LSRG,MAGN,MFON,MGNT,MOEX,MSNG,MSRS,MSTT,MTLR,MTLRP,MTSS,MVID,NLMK,NMTP,NVTK,OGKB,PHOR,PIKK,PLZL,POLY,PRTK,RASP,ROSN,RSTI,RSTIP,RTKM,RTKMP,RUALR,SBER,SBERP,SIBN,SNGS,SNGSP,SVAV,TATN,TATNP,TGKA,TRMK,TRNFP,URKA,VTBR,VZRZ,VZRZP,YNDX"
lot={}
for sec in string.gmatch(ticker_list,"%a+") do
lot[sec]=getParamEx("TQBR",sec,"lotsize").param_value
end
toLog (log, lot)
toLog (log, #lot)
Таблица заполняется правильно: YNDX=1.000000;LNTA=1.000000;VZRZ=1.000000;BANEP=1.000000;...................и так далее. Вопрос: Почему #lot=0 и table.maxn (lot)=0? Ведь должен посчитаться размер таблицы.
Никогда не пользовался колбеком OnInit. Обычно я инициализирую переменные до начала main как то так:
Код
stop_loss_pc=3
MAsteps=1
is_run = true
send_order=false
for sec in string.gmatch(ticker_list,"%a+") do
lot[sec]=getParamEx(class,sec,"lotsize").param_value
step[sec]=getParamEx(class,sec,"SEC_PRICE_STEP").param_value
--задаём первоначальные бид, аск и ласт
last_price[sec]=tonumber(getParamEx(class,sec,"last").param_value)
if last_price[sec]==0 or last_price[sec]==nil then
last_price[sec]=tonumber(getParamEx(class,sec,"prevprice").param_value)
toLog (log, sec.." при запуске нет цены последней сделки "..type(last_price[sec]))
end
tablebid = getParamEx(class, sec, "bid") --получаем таблицу "bid"
bid_best[sec]=tonumber(toPrice(sec, tablebid.param_value)) --из таблицы берЄм значение
tableoffer = getParamEx(class, sec, "offer") --получаем таблицу "offer"
offer_best[sec]=tonumber(toPrice(sec, tableoffer.param_value)) --из таблицы берЄм значение
end
Зачем нужен OnInit? В него помещается такой же кусок кода? В чём преимущество? Спасибо.
Добрый день. Мануал по QLUA очень скупо сообщает про функцию ParamRequest. Не могу понять как с ней работать. Мне надо получить цену последней сделки по RIZ6.
s=ParamRequest("SPBFUT", "RIZ6", "last") s приобретает значение true.
Нет. Предложенный вами алгоритм будет считать каналом любые лежащие рядом два фрактала. Мне нужен алгоритм, который шерстит график на предмет наличия как минимум трёх (а лучше четырёх-пяти) идущих подряд фракталов, лежащих на одной прямой. И то же самое - 4 или 5 фракталов с противоположной стороны на противоположной параллельной прямой. И только тогда робот скажет: о, это же канал! Я не вижу другого способа кроме как: 1. Измеряем количество свечек между двумя фракталами последним и предпоследним. 2. Считаем скорость от фрактала к фракталу: например 3,7789 пункта за таймфрейм. 3. Измеряем количество свечек между двумя фракталами: предпоследним и пред-предпоследним. 4. Считаем скорость между ними. 5. Если она близка к 3,7789, значит три подряд фрактала лежат на прямой линии. 6. В этом случаем проверяем аналогичные условия у верхних фракталов 7. Если верхние фракталы (три подряд) тоже лежат на прямой, измеряем параллельность двух прямых. 8. По факту параллельности-непараллельности делаем вывод о том канал это или нет. (Это может оказаться не каналом а сходящимся-расходящимся треугольником)
Владимир, канал должен быть ровным, то есть три фрактала лежат так, что по ним можно провести прямую линию. Ваш алгоритм этот момент никак не описывает.
swerg написал: Для этого вам надо на русском языке сформулировать правила, по которым вы определяете, что есть канал.
это не просто, и это тоже вопрос к другим участникам форума. Есть версия идти по пути наложения фракталов. Считается скорость отрезка от фрактала к фракталу: пунктов за 1 тайм-фрейм. Если она одинаковая у двух близлежащих отрезков, значит это канал.
Господа, прошу помочь советом. Как на луа описать наличие на графике канала? Чтобы робот мог продать, когда цена пробьёт канал вниз или вверх. Спасибо за помощь и советы.
function status_container(file_path,value)
cf=io.open(file_path,"w+")
cf:write(value)
cf:flush()
cf:close()
end
Если файл существует, не трогать его. Если не существует, то с помощью функции status_container(file_path,value) создать его и вписать в него переменную x. Спасибо
Добрый день. Можно ли средствами Луа получить таймфрейм графика. Это нужно вот для чего. Если таймфрейм = 15 минутка, то StopLoss=x, иначе StopLoss=y. Спасибо.
Добрый день. У меня робот мониторит больше сотни акций, по всем открыты графики. Это не праздный вопрос, а злободневный. Что продуктивнее - получать данные индикатора с графика через getCandlesByIndex или НЕ открывать графики и всё делать через заказ данных с помощью DataStore, а индикаторы считать внутри робота? 1. Что быстрее? 2. Что экономнее для ресурсов компьютера?
Добрый день. можно ли в КВИКе наложить фракталы не на график цены, а на график индикатора RSI? То есть источником данных для построения фракталов должна быть кривая RSI