Господа, хочу простенький индикатор, который накладывает на график содержимое файла. Структура файла такая: Дата- значение Дата - значение
Пытаюсь прочитать этот файл в блоке Settings, но не получается. Надо чтобы было как-то так:
Settings= { Name="!MyIndicator", multiplier=1, read_table=читаем файл. read_table становится table_data из файла
line={ {Color=#ff0000, Width=2 } } }
Но в этом виде не работает. Подскажите пожалуйста в каком блоке это лучше сделать. dofile("путь") read_table=table_data из файла read_table может быть, а может и не быть частью Settings, мне всё равно.
Добрый день. Не могу сообразить как написать код внутри колбека, чтобы он реагировал на нужные фьючерсы и акции. Прошу дать подсказку. Заранее спасибо.
Разработчики сделали доброе дело - написали функцию фракталов. Но как её вызывать не понятно. Я пробую это делать так (для списка бумаг), но безрезультатно. Судя по коду индикатора, он выдаёт на выходе 2 переменные - ближайший верхний и ближайший нижний фрактал. Колбек ДатаСорс работает, но f_1 и f_2 не получают никаких значений.
Код
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size()
if index==num_candles then
last_price[sec]=ds[sec]:C(num_candles)
message (sec.." here "..last_price[sec])
tbl:SetValue(line_count_table[sec],'last', last_price[sec])
tbl:Highlight(line_count_table[sec],'SEC',WHITE,RED,1000)
func =FRACTALS()
for i=1,ds[sec]:Size() do
f_1,f_2=func(i, {Period=30}, ds[sec])
message (sec.." "..f_1.." "..f_2)
end
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
Вот сам код индикатора. Прошу помочь. Второй вопрос. Как с его помощью вызывать не только ближайшие фракталы, но и многие другие фракталы - поза-предыдущий, поза-поза-предыдущий? Спасибо.
Код
Settings = {
Name = "*FRACTALS (Fractals)",
Period = 5,
line = {{
Name = "FRACTALS - Down",
Type = TYPE_TRIANGLE_DOWN,
Color = RGB(255, 0, 0)
},
{
Name = "FRACTALS - Up",
Type = TYPE_TRIANGLE_UP,
Color = RGB(0, 255, 0)
}
}
}
function Init()
func = FRACTALS()
return #Settings.line
end
function OnCalculate(Index)
return func(Index, Settings)
end
function FRACTALS() --Fractals ("FRACTALS")
local H_tmp={}
local L_tmp={}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
P = math.floor(P/2)*2+1
H_tmp[I]=Value(I,"High",ds)
L_tmp[I]=Value(I,"Low",ds)
if I>=P then
local S = I-P+1+math.floor(P/2)
local val_h=math.max(unpack(H_tmp,I-P+1,I))
local val_l=math.min(unpack(L_tmp,I-P+1,I))
local L = Value(S,"Low",ds)
local H = Value(S,"High",ds)
if (val_h == H) and (val_h >0)
and (val_l == L) and (val_l > 0) then
if ds then return S,S else
SetValue(S, 1, val_l)
SetValue(S, 2, val_h)
end
else
if (val_h == H) and (val_h >0) then
if ds then return S,nil else
SetValue(S, 1, nil)
SetValue(S, 2, val_h)
end
end
if (val_l == L) and (val_l > 0) then
if ds then return nil,S else
SetValue(S, 1, val_l)
SetValue(S, 2, nil)
end
end
end
end
return nil,nil
end
end
function Value(I,VType,ds)
local Out = nil
VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
if VType == "O" then --Open
Out = (O and O(I)) or (ds and ds:O(I))
elseif VType == "H" then --High
Out = (H and H(I)) or (ds and ds:H(I))
elseif VType == "L" then --Low
Out = (L and L(I)) or (ds and ds:L(I))
elseif VType == "C" then --Close
Out = (C and C(I)) or (ds and ds:C(I))
elseif VType == "V" then --Volume
Out = (V and V(I)) or (ds and ds:V(I))
elseif VType == "M" then --Median
Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
elseif VType == "T" then --Typical
Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
elseif VType == "W" then --Weighted
Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
elseif VType == "D" then --Difference
Out = (Value(I,"H",ds) - Value(I,"L",ds))
elseif VType == "A" then --Any
if ds then Out = ds[I] end
end
return Out
end
Добрый день Как можно считывать средствами Луа значения с графических линий? Вот с таких: Ну например, какое значение оранжевой линии на текущей свече?
while tonumber(getParamEx(class,"GAZP","tradingstatus").param_value)~=4 or tonumber(getParamEx(class,"GAZP","tradingstatus").param_value)~=3 do
sleep (1000)
end
"Спать 1 секунду, пока не наступил пре-маркет или пост-маркет". Но в первой строчке - ошибка. Это условие не выполняется никогда. Подскажите пожалуйста как написать правильно.
Добрый день. Вот функция от разработчиков - записывать в файл любую таблицу КВИКа. Не понятно как её вызывать. Способ: table_save("orders", "C:\\111.lua", trans_result) не работает. Выдаёт нил на строчке
local tables,lookup = { tbl },{ [tbl] = 1 }
Код
--[[
*******************************************************************
Функция для сохранения произвольной таблицы (инструменты, сделки,
заявки и т.п.) в файл. В качестве параметра принимает тэг, хендл
файла (после открытия с помощью io.open) и таблицу.
Пример вызова функции:
table_save("orders", file, trans_result)
*******************************************************************
]]
function exportstring( s )
return string.format("%q", s)
end
function table_save( tag, file, tbl)
local charS,charE = " ","\n"
local tables,lookup = { tbl },{ [tbl] = 1 }
file:write( charE ..tag .. "{"..charE )
for idx,t in ipairs( tables ) do
file:write( "-- Table: {"..idx.."}"..charE )
file:write( "{"..charE )
local thandled = {}
for i,v in ipairs( t ) do
thandled[i] = true
local stype = type( v )
if stype == "table" then
if not lookup[v] then
table.insert( tables, v )
lookup[v] = #tables
end
file:write( charS.."{"..lookup[v].."},"..charE )
elseif stype == "string" then
file:write( charS..exportstring( v )..","..charE )
elseif stype == "number" then
file:write( charS..tostring( v )..","..charE )
end
end
for i,v in pairs( t ) do
if (not thandled[i]) then
local str = ""
local stype = type( i )
if stype == "table" then
if not lookup[i] then
table.insert( tables,i )
lookup[i] = #tables
end
str = charS.."[{"..lookup[i].."}]="
elseif stype == "string" then
str = charS.."["..exportstring( i ).."]="
elseif stype == "number" then
str = charS.."["..tostring( i ).."]="
end
if str ~= "" then
stype = type( v )
if stype == "table" then
if not lookup[v] then
table.insert( tables,v )
lookup[v] = #tables
end
file:write( str.."{"..lookup[v].."},"..charE )
elseif stype == "string" then
file:write( str..exportstring( v )..","..charE )
elseif stype == "number" then
file:write( str..tostring( v )..","..charE )
end
end
end
end
file:write( "},"..charE )
end
file:write( "}"..charE )
end
function OnParam (class, sec)
if string.find(ticker_list,sec)~=nil and class=="TQBR" then --and class=="TQBR" нужен если есть классы с такими же акци¤ми.
if last_price[sec]~=tonumber(getParamEx(class,sec,"last").param_value) then
last_price[sec]=tonumber(getParamEx(class,sec,"last").param_value)
end
tablebid=getParamEx(class, sec, "bid")
tableoffer=getParamEx(class, sec, "offer")
if bid_best[sec]~=tablebid.param_value then
bid_best[sec]=tonumber(toPrice(sec, tablebid.param_value))
end
if offer_best[sec]~=tableoffer.param_value then
offer_best[sec]=tonumber(toPrice(sec, tableoffer.param_value))
end
end
end
Брокер Открытие, у них несколько серверов. 1. Код работает, всё хорошо, никаких претензий. 2. Разлогиниваюсь и подключаюсь к другому серверу. Дожидаюсь пока всё прогрузится. 3. bid_best[sec] становится нил, код перестаёт работать. 4. Попытка получить данные без колбека, а напрямую через getParamEx не приводят к успеху - bid_best[sec] по прежнему нил. 5. Делаю "Система" - "Заказ Данных" - "Перезаказать данные". 6. Проблема устраняется, всё работает. 7. Стоит подключиться к новому серверу - проблема опять появляется.
Требует ли OnAllTrade открытой таблицы обезличенных сделок? Если да, то требуется ли в неё добавлять каждый требуемый инструмент или достаточно поставить птички в Система-Заказ данных-Таблица обезл.сделок?
сравниваю двух брокеров - Неттрейдер и Открытие. Когда открывал счёт в Открытии, опасался что через них данные будут приходить медленно и заявки отсылаться тоже медленно. У них много клиентов, канал забит, и мои заявки будут долго улетать на биржу. Я когда-то был сотрудником брокера с единственным сервером. Хорошо помню, как мои многочисленные заявок вешали сервер и у других клиентов, по разным городам и весям из за моего робота медленно уходили заявки. Моя активность приводила к задержкам у клиентов до 5 секунд. То есть я могу столкнуться с таким же дефектом у любого крупного брокера с гигантским количеством клиентов. Открытие - топ брокер, поэтому как раз в группе риска.
Но к моему удивлению, серьёзных претензий к Открытию нет. Скорость улёта-прилёта заявки сегодня была 30-75 миллисекунд на обычный сервер, не выделенный. Заявки уходили с московской виртуалки, измерял через OnTransReply. Теперь перехожу к вопросу. Я научился пинговать. Хе-хе. Пингую, сравниваю. Вот пинг Неттрейдера.
Вот пинг Открытия
Открытие существенно обгоняет. Вопрос 1. О чём говорит это превосходство в скорости? О железе блокера или об интернете брокера или о том и другом сразу? Вопрос 2. У Открытия несколько серверов, но пропинговать получается только первый. На остальных - превышен интервал ожидания. Как их пропинговать? Или это невозможно?
Вот ай пи серверов Открытия. Пингуется только первый. Спасибо за помощь.
Добрый день. К сожалению, информации в мануале не достаточно, чтобы понять как пользоваться функцией PrintDbgStr 1. Где её ставить? 2. Что писать в аргументы? 3. Как отслеживать результаты? 4. Она сработает, когда скрипт вылетит с ошибкой nil?
Прошу дать более детальную информацию с примерами. Спасибо
На виртуалке стоят два КВИКа двух брокеров: Неттрейдер и Открытие. версии одинаковые - 7.5.072 Рынки включены одинаковые, всё отфильтровано одинаково. Почему такая разница в загрузке памяти? КВИК открытия жрёт 200 мегабайт, квик неттрейдера 8 Вечер, торги на мамбе закрыты, робот торгует только на ММВБ, все роботы ВЫКЛЮЧЕНЫ!!! таблицы всех сделок прогружены в обоих квиках, новых данных не поступает, фортс точно выключен везде. Как это объяснить?
Тестирую три колбека на предмет прихода цены последней сделки. Удивительно, но OnParam всегда реаигрует быстрее. Не было случая чтобы его кто то опередил.
Код
function OnAllTrade (alltrade)
if string.find(ticker_list,alltrade.sec_code)~=nil then
last_price[alltrade.sec_code]=alltrade.price
if alltrade.sec_code==speed_check then
time_diff=os.clock()-remember_time
remember_time=os.clock()
local datatime_table=alltrade.datetime
toLog (log, speed_check.." пишет OnAllTrade "..alltrade.price.." time="..datatime_table.hour..":"..datatime_table.min..":"..datatime_table.sec.." "..datatime_table.ms.." "..datatime_table.mcs.." time_diff="..math.ceil(time_diff*1000))
end
end
end
function OnParam (class, sec)
if string.find(ticker_list,sec)~=nil then --and class=="TQBR" нужен если есть классы с такими же акци¤ми.
if sec==speed_check and last_price[sec]~=getParam(sec,'last') then
time_diff=os.clock()-remember_time
remember_time=os.clock()
toLog (log, speed_check.." пишет OnParam "..getParam(sec,'last').." time_diff="..math.ceil(time_diff*1000))
end
if last_price[sec]~=getParam(sec,'last') then
last_price[sec]=getParam(sec,'last')
end
end
end
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size()
if index==num_candles then
if sec==speed_check then
time_diff=os.clock()-remember_time
remember_time=os.clock()
toLog (log, speed_check.." пишет DataSource "..ds[sec]:C(num_candles).." time_diff="..math.ceil(time_diff*1000))
end
last_price[sec]=ds[sec]:C(num_candles)
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
вот логи с результатами (выборка). Единственное что плохо и странно - в некоторых случаях OnParam не срабатывает, хотя должен:
Код
01/09/17 10:59:18,762 APTK пишет OnParam 10.32 time_diff=2437 --долго не было сделки
01/09/17 10:59:18,794 APTK пишет DataSource 10.32 time_diff=32
01/09/17 10:59:18,794 APTK пишет OnAllTrade 10.32 time=10:59:18 668 668769 time_diff=0
01/09/17 10:59:18,794 APTK пишет OnAllTrade 10.32 time=10:59:18 668 668769 time_diff=0
01/09/17 11:01:26,475 APTK пишет OnParam 10.35 time_diff=39949 --долго не было сделки
01/09/17 11:01:26,585 APTK пишет OnAllTrade 10.33 time=11:1:26 537 537267 time_diff=109
01/09/17 11:01:26,585 APTK пишет OnAllTrade 10.34 time=11:1:26 537 537267 time_diff=0
01/09/17 11:01:26,585 APTK пишет OnAllTrade 10.34 time=11:1:26 537 537267 time_diff=0
01/09/17 11:01:26,585 APTK пишет OnAllTrade 10.35 time=11:1:26 537 537267 time_diff=0
01/09/17 11:01:26,803 APTK пишет DataSource 10.35 time_diff=219
01/09/17 11:01:36,314 APTK пишет OnParam 10.36 time_diff=3827 --долго не было сделки
01/09/17 11:01:36,314 APTK пишет DataSource 10.36 time_diff=0
01/09/17 11:01:36,314 APTK пишет OnAllTrade 10.36 time=11:1:36 196 196312 time_diff=0
01/09/17 11:01:36,314 APTK пишет OnAllTrade 10.36 time=11:1:36 196 196947 time_diff=0
OnParam не пришёл!!!!
01/09/17 11:05:55,150 APTK пишет OnAllTrade 10.37 time=11:5:55 349 349008 time_diff=158045
01/09/17 11:05:55,259 APTK пишет DataSource 10.37 time_diff=109
01/09/17 11:11:47,931 APTK пишет OnParam 10.35 time_diff=352672 --долго не было сделки
01/09/17 11:11:47,931 APTK пишет OnAllTrade 10.35 time=11:11:48 153 153625 time_diff=0
01/09/17 11:11:48,025 APTK пишет DataSource 10.35 time_diff=95
01/09/17 11:12:21,931 APTK пишет OnAllTrade 10.35 time=11:12:22 265 265944 time_diff=33906
01/09/17 11:12:22,024 APTK пишет DataSource 10.35 time_diff=95
01/09/17 11:15:27,376 APTK пишет OnAllTrade 10.35 time=11:15:27 778 778281 time_diff=185352
01/09/17 11:15:27,470 APTK пишет DataSource 10.35 time_diff=94
Вопрос 1: почему OnParam не всегда срабатывает, хоть и было изменение цены? (у меня в ОнПарам фильтр - не реагировать если цена прежняя). Я бы отказался от других колбеков, раз они медленные, но получается ОнПарам иногда даёт сбои. Вопрос 2: у других участников форума тоже OnParam срабатывает первым? Или это зависит от брокера? Спасибо.
Добрый день. 1. Можно ли средствами Луа разлогиниваться и перелогиниваться в КВИКе? 2. Если да, то можно ли выбирать нужный сервер из числа предложенных роботом? Спасибо
Добрый день. Как быстро моя заявка попала в стакан? Если я засекаю время и пользуюсь OnTrnsReply, то информация о времени придёт увеличенная: заявка улетит на биржу (тратится время), а обратно придёт ответ (тратится время). Мне нет дела знать, сколько шёл ответ, мне надо знать когда заявка появилась в боевой очереди в стакане на бирже. Как это сделать?
Сейчас я считаю так:
Код
function OnTransReply(reply)
orders[reply.trans_id].tr_receive_time=os.clock()
local latency=(orders[reply.trans_id].tr_receive_time-orders[reply.trans_id].tr_send_time)*1000
end
ну и перед отправкой засекаю через os.clock() В итоге полученное время дольше, чем есть на самом деле из за того, что ответу нужно идти ко мне в терминал, хотя заявка на бирже уже стоит.
добрый день. прошу подсказать как корректно написать на луа
Код
test_table={}
test_table.s=1
next_table={}
next_table.[test_table.s]=3 --иными словами в этой строчке создать элемент next_table[1] и присвоить значение 3
Господа, прошу дать совет в выборе конфигурации виртуалки. Арендую у UltraVDS. Пользовался конфигурацией 4 ядра (2,2 Ггц), 4 гб оперативки. Загрузка процессора всегда была ниже 30%. Оперативной памяти тоже использовалось мало, намного меньше 4 Гб. Я решил ради экономии уменьшить конфигурацию до 2 ядра, 2 гига оперативки. Пользуюсь. Всё хорошо. Проц загружен меньше 50%, памяти хватает. Вопрос 1. От понижения железа станут ли роботы медленнее реагировать на события? Колбек DataSourse, приход данных в стакан, колбек OnParam, колбек таблицы всех сделок? У меня такая стратегия, что чем быстрее реакция на события, тем лучше она зарабатывает, поэтому я готов вернуться на старую конфигурацию, если это реально влияет. Вопрос 2. Стоит ли играться с настройками "Приоритет"? Это в диспетчере задач, где выставляется приоритет для процессов. Если да, то какому процессу давать повышенный приоритет: info.exe, winRos или обоим? Спасибо. С Новым Годом!!!
добрый вечер. С наступающими! Выбираю между двумя вариантами: 1. два скрипта (фортс+ММВБ) внутри одного КВИКА 2. скрипт фортс внутри одного КВИКа (свой UID), скрипт ММВБ внутри другого КВИКа (другой, отдельный UID). Нужно выбрать тот вариант, который будет работать быстрее.
Оба скрипта работают с DataSource по колбеку.
Наводящий вопрос. Если два скрипта (один фортс, другой ММВБ) крутятся внутри одного КВИКа, то в какой очерёдности обрабатываются новые сделки ФОРТС и ММВБ? Обрабатывается сделка ММВБ, и тут подоспела сделка ФОРТС. Сделка ФОРТС начнёт обрабатываться параллельно или будет ждать, пока обработается ММВБ? Иными словами будет очередь или параллельная работа? Спасибо.
добрый день. У меня три скрипта. Код одинаковый, отличаются только настройки и таймрфейм - пятниминутки в одном, часовик в другом, дневки в третьем. Робот работает по колбеку в каждом из 3 случаев. Набор бумаг одинаковый. То есть при получении данных по каждой новой бумаге он три раза обновляет дата сорс. Я хочу объединить эти роботы в один скрипт, и чтобы колбек был один. Будет ли один колбек обновлять три DataSource?
Сейчас работа с дата сорс выглядит вот так.
Код
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size()
if index==num_candles then
...................................
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
У моего брокера есть необычная странность. Если я сегодня поторговал акциями с плечом, внутри дня вошёл и вышел, ночевал в кэше, на следующий день я всё равно не смогу торговать через КВИК фьючерсами. Будет ошибка Превышен лимит. В брокере мне объяснили, что это из за Т+2. На следующий день по Т+2 у меня нет денег, - они "в пути". В то же время, торговать через брокерскую платформу (веб-терминал) можно и через API можно. Поэтому вопрос. Как мне отправлять транзакции через АПИ брокера. Вот исходные данные. 1. У меня робот на луа. Он делает анализ. 2. При наличии сигнала нужно отправить транзакцию через АПИ
Вот коды, которые предлагает брокер: Там есть примеры для Browser / PHP / PHYTON
Отлично что есть примеры, но я не могу понять что мне с ними делать. Нужен какой то дополнительный софт? Нужно ли ставить платформу для питона или пхп? Прошу подсказать для чайника что делать чтобы отсылать эти приказы. Спасибо
Добрый день. В базе кодов есть индикатор RSI написанный разработчиками. У меня не получается вызвать его обычным способом. Спотыкается на строчке внутри индикатора:
Код
val_Up[I] = (val_Up[I-1] * (P-1) + Up[I]) / P
Вызываю так:
Код
DataSource("TQBR","RASP",INTERVAL_M5)
local num_candles=ds:Size()
func=RSI()
local a=func(num_candles, {Period=12, VType="Typical", round=7}, ds)
Вот сам индикатор. Спасибо за подсказки.
Код
Settings = {
Name = "*RSI (Relative Strength Index)",
round = "off",
Period = 14,
VType = "Close", --Open, High, Low, Close, Volume, Median, Typical, Weighted, Difference
line = {{
Name = "RSI",
Type = TYPE_LINE,
Color = RGB(255, 0, 0)
}
}
}
function Init()
func = RSI()
return #Settings.line
end
function OnCalculate(Index)
return func(Index, Settings)
end
function RSI() --Relative Strength I("RSI")
local Up = {}
local Down = {}
local val_Up = {}
local val_Down = {}
return function (I, Fsettings, ds)
local Out = nil
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 14)
local VT = (Fsettings.VType or "Close")
local R = (Fsettings.round or "off")
if I == 1 then
Up[I] = 0
Down[I] = 0
end
if I>1 then
local Val = Value(I,VT,ds)
local ValPrev = Value(I-1,VT,ds)
if ValPrev < Val then
Up[I] = Val - ValPrev
else
Up[I] = 0
end
if ValPrev > Val then
Down[I] = ValPrev - Val
else
Down[I] = 0
end
if (I == P) or (I == P+1) then
local sumU = 0
local sumD = 0
for i = I-P+1, I do
sumU = sumU + Up[i]
sumD = sumD + Down[i]
end
val_Up[I] = sumU/P
val_Down[I] = sumD/P
end
if I > P+1 then
val_Up[I] = (val_Up[I-1] * (P-1) + Up[I]) / P
val_Down[I] = (val_Down[I-1] * (P-1) + Down[I]) / P
end
if I >= P then
Out = 100 / (1 + (val_Down[I] / val_Up[I]))
return rounding(Out, R)
end
end
end
end
function rounding(num, round)
if round and string.upper(round)== "ON" then round=0 end
if num and tonumber(round) then
local mult = 10^round
if num >= 0 then return math.floor(num * mult + 0.5) / mult
else return math.ceil(num * mult - 0.5) / mult end
else return num end
end
function Value(I,VType,ds)
local Out = nil
VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
if VType == "O" then --Open
Out = (O and O(I)) or (ds and ds:O(I))
elseif VType == "H" then --High
Out = (H and H(I)) or (ds and ds:H(I))
elseif VType == "L" then --Low
Out = (L and L(I)) or (ds and ds:L(I))
elseif VType == "C" then --Close
Out = (C and C(I)) or (ds and ds:C(I))
elseif VType == "V" then --Volume
Out = (V and V(I)) or (ds and ds:V(I))
elseif VType == "M" then --Median
Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
elseif VType == "T" then --Typical
Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
elseif VType == "W" then --Weighted
Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
elseif VType == "D" then --Difference
Out = (Value(I,"H",ds) - Value(I,"L",ds))
elseif VType == "A" then --Any
if ds then Out = ds[I] else Out = nil end
end
return Out
end
Уж простите за странный вопрос. Можно ли писать на Луа роботов для Плазы? Увы, я кроме Луа ничего не знаю... А то корявое что я умею писать на Луа - далось с огромным трудом. Учить Си++, Джаву и Си# для меня долго... Спасибо за ответ.
Добрый день. Из документации не понятно как работать с функцией OnConnected. Хочу чтобы она писала в глобальную переменную true если квик онлайн и false если не в сети. Увы, руководство пользователя не даёт понимания как это сделать.
Подскажите пожалуйста, что срабатывает быстрее при условии использования колбеков: Цена последней сделки в 1. ДатаСорс 2. Текущая таблица 3. Таблица обезличенных сделок Лучший бид-аск в 1. Стакане 2. Текущая таблица?
Субботний вечер. Тестирую функцию DataSourse с колбеком. Робот работает по 40 акциям. Колбек SetUpdatCallback начинает обрабатывать все то ли свечки, то ли тики, и на полчаса вешает квик. В рабочее время - в пятницу днём - такого не было, всё работало как надо. Почему? И как с этим бороться?
Вот мои функции:
Код
function mycallbackforallstocks(class,sec,index)
toLog (log, sec)
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
Добрый день. Два дня мучился, осваивал работу через DataSourse. Заработало. Но код работает в 5 раз медленнее, чем когда я получал данные индикатора через идентификатор.
Прошу подсказать почему. Вот код. Боллинджер считается внутри файла BB.lua, который выложили разработчики вот здесь: ftp://ftp.quik.ru/public/INDICATORS.zip
Код
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetEmptyCallback ()
return ds[sec]
end
function main()
dofile(getWorkingFolder().."\\LuaIndicators\\BB.lua")
for sec in string.gmatch(ticker_list,"%a+") do
DataSource(class,sec,interval)
end
while is_run do
stime=getSTime()
if stime==nil then stime=0 end
if stime>100000 and stime<184005 then --не считаем вне сессии
for sec in string.gmatch(ticker_list,"%a+") do
toLog (log, sec)
toLog (log, "1")
func = BB()
toLog (log, "2")
local num_candles=ds[sec]:Size()
toLog (log, "3")
line_10,_,line_3=func(num_candles, {Period=12, Metod = "SMA", VType="Typical", round=4, Shift=2}, ds[sec])
toLog (log, "4")
-- tbl:SetValue(line_count_table[sec],'BB_middle', line_10)
-- tbl:SetValue(line_count_table[sec],'BB_lower', line_3)
--sleep (1)
дальше не сложный анализ.
end
А теперь - самое интересное. Места с задержками. Где скорость как у ласточки я не трогал, подсветил только места задержек:
То есть задержка то есть, то нету. Она равна 15 миллисекунд. И она бывает не только между 3 и 4, но и на разных участках кода. Вот например между 1 и 2 шагом.
Вопросы по ds:Size() 1. Почему у акций на минутном графике разный ds:Size() ? 2. От чего это зависит? 3. Он у каждой акции всегда одинаковый или менятся? Если меняется, то когда и почему?
Добрый день. Хочу вычислять скользящую среднюю внутри кода. Что при этом нужно учитывать? Период 14, часовик, по ценам close Казалось бы всё просто, но есть особенности: 1. Старые свечки можно не обрабатывать, а обрабатывать только текущую. 2. Но обрабатывать старые всё же придётся, ведь рисуются новые свечки, поэтому каждый раз при формировании новой свечи придётся разок пересчитать старые. Помогите пожалуйста выразить это в красивом коде. Спасибо.
Добрый день. Хочу арендовать у брокера виртуальную машину. Для меня важно, чтобы сотрудники брокера не имели доступа к кодам моих роботов и файлам с настройками КВИКа типа info.wnd. Прошу знатоков ответить на такие вопросы. 1. Имеет ли администратор виртуальной машины доступ к файлам, которые хранятся на моём диске на виртуалке? Пароль входа разумеется будет изменён. 2. Скомпилированные файлы .luac работают также быстро как .lua? 3. Если файлы роботов вида .lua не хранятся на виртуалке, может ли администратор виртуалки увидеть эти коды из .dat-файлов КВИКа или ещё откуда-нибудь? Спасибо за ответы.
Добрый день. Я получаю данные Moving Average с графика через идентификатор. На днях понял, что можно удалить график Price, так как я к нему не обращаюсь. В итоге стало так:
Вопросы. Не вредит ли отсутствие Price расчётам индикатора? Не происходит ли расчёт текущего значения индикатора медленнее? Нет ли из за этого каких то особых проблем с расчётом именно текущего значения?
Добрый день. Я по старинке держу все стаканы открытыми, когда считываю с них информацию с помощью 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.
Господа, прошу помочь советом. Как на луа описать наличие на графике канала? Чтобы робот мог продать, когда цена пробьёт канал вниз или вверх. Спасибо за помощь и советы.
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
Интересная опция появилась - показывать на графике не все свечи, а только последние 100 (200,300) штук. Но не могу сообразить, что эта опция экономит, позволяет ли она оптимизировать работу процессора, квика, трафик интернета? Что она экономит? У меня робот прочёсывает около 150 графиков, все они открыты на полную катушку, думаю мне эта опция пригодится, но прошу разъяснить, что же всё таки она даёт в плане производительности?