Всё же есть вопрос в продолжение темы. В отдельном файле ggg.lua лежит таблица. Её структура table_ggg={} table_ggg[20000101]=095.23313 table_ggg[20000102]=065.27389 подобных таблиц с названиями sss.lua или yyy.lua будет много. внутри них будут поля с использованием этих букв sss, yyy
Цитата
Settings= { Name="!MyInd", letter="ggg", line={ {Color=#ff0000, Width=2 } } } function Init () dofile("C:\\_E\\"..Settings.letter..".lua") --тут всё работает --как правильно построить эту строчку: s="table_"..Settings.letter[20000101] --в таком виде она не правильная
Господа, хочу простенький индикатор, который накладывает на график содержимое файла. Структура файла такая: Дата- значение Дата - значение
Пытаюсь прочитать этот файл в блоке 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, мне всё равно.
Добрый день. Не могу сообразить как написать код внутри колбека, чтобы он реагировал на нужные фьючерсы и акции. Прошу дать подсказку. Заранее спасибо.
Сергей, на примере индикатора RSI подскажите пожалуйста что нужно изменить, чтобы код работал на новой версии КВИКа? Спасибо
Код
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
Сергей, не обижайтесь, но когда на мои идиотские вопросы дают ответ Камынин, сверг или Майк, мне сразу всё понятно и я остаюсь доволен. А они не сотрудники Арки!!! А с вами постоянно проблемы.
Я уже давно пользуюсь функцией, которая ищет фрактал через GetCandlesByIndex. Не понятно в чём прорыв при использовании вашей функции, если я и так могу это делать.
Код
function SearchFractals()
local bars_count=getNumCandles(fractal_name)
--toLog(log,"SearchFractals started. Bars_count="..bars_count)
for i=bars_count-4,0,-1 do
local candle,_,_=getCandlesByIndex(fractal_name,0,i,1)
if upFractal==0 and candle[0].high~=0 then
upFractal=candle[0].high
upFractalBar=i
--toLog(log,"SearchFractals upFractal="..upFractal.." upFractalBar="..upFractalBar)
end
if downFractal==0 and candle[0].low~=0 then
downFractal=candle[0].low
downFractalBar=i
--toLog(log,"SearchFractals downFractal="..downFractal.." downFractalBar="..downFractalBar)
end
if downFractal~=0 and upFractal~=0 then
--toLog(log,"SearchFractals all fractals found")
return
end
end
end
Космонавт написал: Не понятно. Покажите пожалуйста на примере.
Что именно не понятно. Конкретику пожалуйста.
Мне нужно переменной Fractal_Up задать значение последнего верхнего фрактала, а переменной Fractal_Up_prev значение предыдущего верхнего фрактала. Как это сделать с помощью Вашей функции?
Не понятно. Покажите пожалуйста на примере. Доведите доброе дело до конца, раз уж начали. Заранее спасибо. Мне действительно очень нужен ваш индикатор. И как считывать не только последние но и другие предыдущие фракталы
Sergey Gorokhov написал: Вы не поверите, но эти примеры писал лично я, по своей личной инициативе.
я сразу заподозрил, что этот код - ваших рук дело. Вы в него добавили побольше упоминаний ds, чтобы все думали, что можно использовать ДатаСорс. Но не тут-то было ;)))))
Сергей, ответ не понятен Мне нужно положить этот индикатор в папку LuaIndicators? Или надо на график накладывать фракталы и присваивать идентификатор? А потом как обратиться к значениям фракталов? Передайте привет человеку, который писал этот прекрасный код, но ключики от него спрятал на дне океана.
Разработчики сделали доброе дело - написали функцию фракталов. Но как её вызывать не понятно. Я пробую это делать так (для списка бумаг), но безрезультатно. Судя по коду индикатора, он выдаёт на выходе 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
Я всё же решил идти другим путём. Моя задача - научиться идентифицировать канал на графике. Буду отталкиваться от фракталов. ... Если у Вас или других форумчан есть идеи получше, пишите, буду признателен.
О, Майк, спасибо, уже не помню сколько раз Вы меня выручали. Куча моих роботов имеет элементы, позаимствованные из ваших ответов на форуме или кодов на сайте.
Добрый день Как можно считывать средствами Луа значения с графических линий? Вот с таких: Ну например, какое значение оранжевой линии на текущей свече?
я не знаю что такое хендл Человек, который писал эту функцию, делал по сути бессмысленную работу. Предполагается, что он типа помог новичкам, но понять как пользоваться функцией, новичок не может. Разобраться с функцией может только тот, кто и без посторонней помощи может её написать. Поэтому зачем он её писал и выкладывал - не понятно.
Николай, циферка 3 - аукцион открытия, 4 - аукцион закрытия (перед ней и после неё есть ещё периоды со своими цифрами, не помню их названий) 0 - сессия закрыта.
Я понял вашу мысль про оператор and, но не могу понять как это работает. Мне ведь нужно срабатывание либо одного условия (премаркет), либо второго (постмаркет), а не одновременно обоих (and)
while tonumber(getParamEx(class,"GAZP","tradingstatus").param_value)~=4 or tonumber(getParamEx(class,"GAZP","tradingstatus").param_value)~=3 do
sleep (1000)
end
"Спать 1 секунду, пока не наступил пре-маркет или пост-маркет". Но в первой строчке - ошибка. Это условие не выполняется никогда. Подскажите пожалуйста как написать правильно.
Ишимоку есть в базе кодов, которые выложили разработчики КВИКа
Код
Settings = {
Name = "*ICHIMOKU (Ichimoku Kinko Hyo)",
round = "off",
Tenkan = 9,
Kijun = 26,
Senkou = 52,
Chinkou = 26,
Shift = 26,
line = {{
Name = "ICHIMOKU - Tenkan",
Type = TYPE_LINE,
Color = RGB(255, 0, 255)
},
{
Name = "ICHIMOKU - Kijun",
Type = TYPE_LINE,
Color = RGB(255, 0, 0)
},
{
Name = "ICHIMOKU - Senkou Span1",
Type = TYPE_LINE,
Color = RGB(0, 255, 255)
},
{
Name = "ICHIMOKU - Senkou Span2",
Type = TYPE_LINE,
Color = RGB(0, 255, 0)
},
{
Name = "ICHIMOKU - Chinkou",
Type = TYPE_LINE,
Color = RGB(128, 0, 0)
}
}
}
function Init()
func = ICHIMOKU()
return #Settings.line
end
function OnCalculate(Index)
return func(Index, Settings)
end
function ICHIMOKU() --Ichimoku ("ICHIMOKU")
local OutSenkou1 = {}
local OutSenkou2 = {}
local H_tmp={}
local L_tmp={}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local Tenkan = (Fsettings.Tenkan or 9)
local Kijun = (Fsettings.Kijun or 26)
local Senkou = (Fsettings.Senkou or 52)
local Chinkou = (Fsettings.Chinkou or 26)
local Shift = (Fsettings.Shift or 26)
local R = (Fsettings.round or "off")
function sen(I,P, R)
if I>=P then
local mx=math.max(unpack(H_tmp,I-P+1,I))
local mn=math.min(unpack(L_tmp,I-P+1,I))
return rounding((mx+mn)/2, R)
else return nil end
end
H_tmp[I]=Value(I,"High",ds)
L_tmp[I]=Value(I,"Low",ds)
local OutTenkan = sen(I, Tenkan, R)
local OutKijun = sen(I, Kijun, R)
local OutChinkou = nil
if I >= math.max(Tenkan, Kijun) then
OutSenkou1[I] = (OutTenkan + OutKijun)/2
else
OutSenkou1[I] = nil
end
OutSenkou2[I] = sen(I,Senkou, R)
if I<Size()-Chinkou then
OutChinkou= Value(I+Chinkou, "Close", ds)
else
OutChinkou=nil
SetValue(I-Chinkou, 5, rounding(Value(I, "Close", ds), R))
end
return sen(I,Tenkan, R),sen(I,Kijun, R),rounding(OutSenkou1[I-Shift], R),rounding(OutSenkou2[I-Shift], R),rounding(OutChinkou, R)
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
Добрый день. Вот функция от разработчиков - записывать в файл любую таблицу КВИКа. Не понятно как её вызывать. Способ: 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
И ещё вопрос. Он не праздный. Может быть у дохлого брокера с одним сервером это будет проблемой.
Когда я заказываю данные с сервера, например, стакан, это создаёт нагрузку на сервер брокера? ну например бесконечный цикл:
Код
class="SPBFUT"
sec="SRH7"
for i=1,10000000000000000000 do
qt=getQuoteLevel2(class, sec)
end
Вредит ли это способности брокера обслуживать других клиентов? Например отправка заявок бесконечным потоком точно вредит. У других клиентов заявки будут дольше улетать на биржу.
"ABRD,AESL,AGRO,ALBK,ALNU,AMEZ,APTK,AQUA,.......................... и до конца класса TQBR
в брокере Неттрейдер квик НЕ выдавал ошибку "Превышено число открытых стаканов", а в брокере Открытие появляется такая ошибка. Это зависит от настроек брокера? У всех разное число стаканов можно открыть? Поэтому и пришлось использовать Unsubscribe_Level_II_Quotes(class, sec) внутри прохода каждой акции
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. Стоит подключиться к новому серверу - проблема опять появляется.
Очень странно. Без открытой таблицы обезл. сделок сделки не принимаются. Стоит её открыть - сразу же начинают идти. Вот код, который пишет в лог принимаемые сделки.
Код
function OnAllTrade (alltrade)
if string.find(f_ticker_list,alltrade.sec_code)~=nil then
last_price[alltrade.sec_code]=alltrade.price
toLog (log, alltrade.sec_code.." "..last_price[alltrade.sec_code])
end
end
Требует ли OnAllTrade открытой таблицы обезличенных сделок? Если да, то требуется ли в неё добавлять каждый требуемый инструмент или достаточно поставить птички в Система-Заказ данных-Таблица обезл.сделок?
Николай, у Открытия этого параметра нет в Информационном окне. Это не только у меня, я у многих спрашивал, в том числе у менеджера когда счёт открывал. Там у всех пусто... Эта странность у них на всех серверах
сравниваю двух брокеров - Неттрейдер и Открытие. Когда открывал счёт в Открытии, опасался что через них данные будут приходить медленно и заявки отсылаться тоже медленно. У них много клиентов, канал забит, и мои заявки будут долго улетать на биржу. Я когда-то был сотрудником брокера с единственным сервером. Хорошо помню, как мои многочисленные заявок вешали сервер и у других клиентов, по разным городам и весям из за моего робота медленно уходили заявки. Моя активность приводила к задержкам у клиентов до 5 секунд. То есть я могу столкнуться с таким же дефектом у любого крупного брокера с гигантским количеством клиентов. Открытие - топ брокер, поэтому как раз в группе риска.
Но к моему удивлению, серьёзных претензий к Открытию нет. Скорость улёта-прилёта заявки сегодня была 30-75 миллисекунд на обычный сервер, не выделенный. Заявки уходили с московской виртуалки, измерял через OnTransReply. Теперь перехожу к вопросу. Я научился пинговать. Хе-хе. Пингую, сравниваю. Вот пинг Неттрейдера.
Вот пинг Открытия
Открытие существенно обгоняет. Вопрос 1. О чём говорит это превосходство в скорости? О железе блокера или об интернете брокера или о том и другом сразу? Вопрос 2. У Открытия несколько серверов, но пропинговать получается только первый. На остальных - превышен интервал ожидания. Как их пропинговать? Или это невозможно?
Вот ай пи серверов Открытия. Пингуется только первый. Спасибо за помощь.
Добрый день. К сожалению, информации в мануале не достаточно, чтобы понять как пользоваться функцией PrintDbgStr 1. Где её ставить? 2. Что писать в аргументы? 3. Как отслеживать результаты? 4. Она сработает, когда скрипт вылетит с ошибкой nil?
Прошу дать более детальную информацию с примерами. Спасибо