Здравствуйте, К сожалению в текущей реализации нет доступа к таблице параметров опционов, поэтому получить данные не получится. Вы можете решить задачу произведя расчеты Формулы есть в википедии Премия_по_опциону
Sergey Gorokhov пишет: Если упомянутая выше настройка не помогает, пришлите нам архив всей папки с Вашим терминалом (без ключей доступа) на адрес 911@quik.ru
max max пишет: Подскажите какие настройки указывать в тек таблице ? Может в этом проблема
Цитата
Sergey Gorokhov пишет: в таблице должны быть добавлены колонки "Расчетная цена", "Страйк", "До исполнения" и "Волатильность" И в этих колонках должны быть данные.
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
В таблицу текущих параметров загнал фьюч и все опционы по этому фьючу Включил все параметры (и волу и теорию и пр) Потом запустил скрипт. Ничего не менял. Инструмент RIU5 и тп Опять не показывает Брокер Октрытие и Втб24 И там и там пусто
Могу Вас уверить что данный скрипт прекрасно работает. Проблема именно в настройках о чем было сказано в последнем посте. Если упомянутая выше настройка не помогает, пришлите нам архив всей папки с Вашим терминалом (без ключей доступа) на адрес 911@quik.ru
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
Для работы скрипта в таблице должны быть добавлены колонки "Расчетная цена", "Страйк", "До исполнения" и "Волатильность" И в этих колонках должны быть данные. Если их нет, проверьте настройки терминала. в меню Настройки - Основные - Программа - Получение данных, должно быть "Исходя из настроек открытых пользователем таблиц
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
Egor Zaytsev пишет: Греки только в доске опционов.
В доске нет греков Они только в "Таблице параметров опционов"
Здравствуйте, Если Вам нужны греки в LUA единственный способ их получить это рассчитать по формулам. У нас есть готовый пример скрипта, можете взять формулы от туда:
Скрытый текст
Код
--[[
Что делает:
По Таблице текущих параметров строит таблицу опционов с расcчитанными греками
Формулы взяты отсюда:
http://en.wikipedia.org/wiki/Black%96Scholes
http://en.wikipedia.org/wiki/Greeks_%28finance%29
Как использовать:
откройте Таблицу Текущих Параметров (меню Таблицы -> Текущая Таблица)
Укажите настройки, после чего, запустите скрипт (меню Таблицы - Lua - Доступные скрипты)
чтобы сохранить в CSV файл, текущее состояние таблицы, нужно нажать комбинацию клавиш Ctrl+S файл сохраняется в папку со скриптом, с именем HHHMMDD.csv
]]
-------------------------------НАСТРОЙКИ-------------------------------
RiskFree=0/100 --безрисковая ставка %, Указывается вручную
BaseClassCode = "SPBFUT" --Класс базового актива
ClassCode = "SPBOPT" --Класс опционов
--Список базовых активов, через запятую, по которым отображать опционы:
BaseSecList = "RIU5" --getClassSecurities(BaseClassCode) --все сразу
--Список опционов через запятую:
SecList = getClassSecurities(ClassCode) --все сразу
INTERVAL = 1000 --Интервал обновления таблицы
doLogging=false --включает запись в файл, формата csv.
log_file=getScriptPath() .. "\\Greek.csv" --путь к csv файлу
-----------------------------------------------------------------------
-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
--Параметры таблицы
tbl = {
["caption"]="Greek",
[1]="Название",
[2]="Код опциона",
[3]="Тип опциона",
[4]="Баз. актив",
[5]="Расчетная цена",
[6]="Страйк",
[7]="Волатильность",
[8]="До исполнения",
[9]="Дельта",
[10]="Гамма(%)",
[11]="Тэта",
[12]="Вега",
[13]="Ро",
["t_id"]=0
}
abTable = {}
BaseCol = {}
Sec2row = {}
file = nil
Sep = ";"
YearLen=365.0 --Число дней в году
WORK = true
CALC = false
G_ROW = -1
if (BaseSecList == "") or (BaseSecList == nil) then
BaseSecList = getClassSecurities(BaseClassCode)
end
if (SecList == "") or (SecList == nil) then
SecList = getClassSecurities(ClassCode)
end
-------------------------------ФУНКЦИИ------------------------------------------------------------------
function Logging(str) --Пишет лог
if file~=nil and doLogging then
file:write(str .. "\n")
file:flush()
end
end
function N(x) --Нормальное среднее
if (x > 10) then
return 1
elseif (x < -10) then
return 0
else
local t = 1 / (1 + 0.2316419 * math.abs(x))
local p = 0.3989423 * math.exp(-0.5 * x * x) * t * ((((1.330274 * t - 1.821256) * t + 1.781478) * t - 0.3565638) * t + 0.3193815)
if x > 0 then
p=1-p
end
return p
end
end
function pN(x) --производная от функции нормального среднего
return math.exp(-0.5 * x * x) / math.sqrt(2 * math.pi)
end
function Greek(tmpParam)
local b = tmpParam.volatility / 100 --"b" волатильность доходности (квадратный корень из дисперсии) базисной акции.
local S = tmpParam.settleprice --"S" текущая цена базисной акции;
local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
local K = tmpParam.strike --"K" цена исполнения опциона;
local r = RiskFree --"r" безрисковая процентная ставка;
local d1 = (math.log(S / K) + (r + b * b * 0.5) * Tt) / (b * math.sqrt(Tt))
local d2 = d1-(b * math.sqrt(Tt))
local Delta = 0
local Gamma = 0
local Theta = 0
local Vega = 0
local Rho = 0
local e = math.exp(-1 * r * Tt)
Gamma = pN(d1) / (S * b * math.sqrt(Tt))
Vega = S * e * pN(d1) * math.sqrt(Tt)
Theta = (-1 * S * b * e * pN(d1)) / (2 * math.sqrt(Tt))
if tmpParam.Optiontype == "Call" then
Delta = e * N(d1)
Theta = Theta - (r * K * e * N(d2)) + r * S * e * N(d1)
----Theta = Theta - (r * K * e * N(d2))
Rho = K * Tt * e * N(d2)
else
Delta = -1 * e * N(-1*d1)
Theta = Theta + (r * K * e * N(-1 * d2)) - r * S * e * N(-1 * d1)
----Theta = Theta + (r * K * e * N(-1 * d2))
Rho = -1 * K * Tt * e * N(-1 * d2)
end
return {
["Delta"] = Delta,
["Gamma"] = 100 * Gamma,
["Theta"] = Theta / YearLen,
["Vega"] = Vega / 100,
["Rho"] = Rho / 100
}
end
function GetRow(ID,row) --возвращает строку таблицы
local rows, col = GetTableSize(ID)
local result = ""
if rows~=nil and row<=rows then
for i=1,col do
result=result..GetCell(ID,row,i).image .. Sep
end
end
return result
end
function CSV(T) --пишет таблицу в csv файл
function FTEXT(V) --ПРОВЕРЯЕМ КОРРЕКТНОСТЬ КОЛИЧЕСТВА СИМОЛОВ ПЕРЕМЕННОЙ
V=tostring(V)
if (string.len(V)==1) or (string.len(V)==5) then
V="0".. V
end
return V
end
local temp = os.date("*t")
local Fname =getScriptPath() .. "\\" .. FTEXT(temp.year) .. FTEXT(temp.month) .. FTEXT(temp.day) .. ".csv"
CSVFile = io.open(Fname, "w+")
if CSVFile~=nil then
local rows, col = GetTableSize(T.t_id)
for i=1,col do --расставляем заголовки
CSVFile:write(T[i] .. Sep)
end
CSVFile:write("\n")
for i=1,rows do --пишем таблицу
CSVFile:write(GetRow(T.t_id,i).."\n")
end
CSVFile:flush()
CSVFile:close()
message("Файл успешно сохранен:\n"..Fname, 1)
else
message("Ошибка при сохранении файла:\n"..Fname, 3)
end
end
function round(num, idp) --округляет до указанного количества знаков
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function comma_value(n) --ставит разделители в числах
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1 '):reverse())..right
end
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while ds:Size()==0 do
sleep(100)
end
return true
end
end
function Stop()
if doLogging then
file:close()
end
WORK = false
end
function Calculate(row,do_calc)
if (row~=nil) and (row>=0) and (do_calc) then
local T=BaseCol[row]
local tmpParam ={
["Optiontype"] = T.Optiontype,
["settleprice"] = getParamEx(BaseClassCode,T.Optionbase,"settleprice").param_value+0,
["strike"] = getParamEx(ClassCode,T.SecCode,"strike").param_value+0,
["volatility"] = getParamEx(ClassCode,T.SecCode,"volatility").param_value+0,
["DAYS_TO_MAT_DATE"] = T.DAYS_TO_MAT_DATE
}
local tmpGreek = Greek(tmpParam)
SetCell(tbl.t_id, row, 5, comma_value(tmpParam.settleprice), tmpParam.settleprice) -- "Расчетная цена",
SetCell(tbl.t_id, row, 6, comma_value(tmpParam.strike), tmpParam.strike) --"Страйк",
SetCell(tbl.t_id, row, 7, tostring(tmpParam.volatility), tmpParam.volatility) -- "Волатильность",
SetCell(tbl.t_id, row, 8, tostring(tmpParam.DAYS_TO_MAT_DATE), tmpParam.DAYS_TO_MAT_DATE) --"До исполнения",
SetCell(tbl.t_id, row, 9, tostring(round(tmpGreek.Delta,2)), tmpGreek.Delta) --"Дельта",
SetCell(tbl.t_id, row, 10, tostring(round(tmpGreek.Gamma,4)), tmpGreek.Gamma) -- "Гамма(%)",
SetCell(tbl.t_id, row, 11, tostring(round(tmpGreek.Theta,2)), tmpGreek.Theta) -- "Тэта",
SetCell(tbl.t_id, row, 12, tostring(round(tmpGreek.Vega,2)), tmpGreek.Vega) -- "Вега",
SetCell(tbl.t_id, row, 13, tostring(round(tmpGreek.Rho,2)), tmpGreek.Rho) -- "Ро",
Logging(os.date().. Sep .. GetRow(tbl.t_id,row))
end
return false
end
-------------------------------Колбэки------------------------------------------------------------------
function f_cb(t_id,msg,par1,par2) --событие на нажатие клавиш
if (msg==QTABLE_CHAR) and (par2==19) then --сохранить в CSV файл текущее состояние таблицы нужно нажать комбинацию клавиш Ctrl+S
CSV(tbl)
end
if (msg==QTABLE_CLOSE) then --закрытие окна
Stop()
end
end
function OnStop()
Stop()
DestroyTable(tbl.t_id)
end
function OnInit()
local STR = ""
if doLogging then
file = io.open(log_file, "w+")
end
tbl.t_id = AllocTable()
for i=1,table.maxn(tbl) do --добавляем колонки
if i<=4 then
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_CACHED_STRING_TYPE, string.len(tbl[i])*2)
else
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_DOUBLE_TYPE, 10)
end
if doLogging then
STR=STR..tbl[i]..Sep
end
end
Logging("Дата Время".. Sep .. STR)
CreateWindow(tbl.t_id)
SetWindowCaption(tbl.t_id,tbl.caption)
SetTableNotificationCallback(tbl.t_id, f_cb)
end
function OnParam(class, sec)
if (class==ClassCode) and (WORK) and (string.find(SecList,sec)~=nil) then
G_ROW = Sec2row[sec]
if (G_ROW~=nil) and (G_ROW>=0) then
Highlight(tbl.t_id, G_ROW, QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
CALC=true
end
end
end
function main()
WORK = false
CALC=true
for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
local Optionbase=getParamEx(ClassCode,SecCode,"optionbase").param_image
local Optiontype=getParamEx(ClassCode,SecCode,"optiontype").param_image
if (string.find(BaseSecList,Optionbase)~=nil) then
local row = InsertRow(tbl.t_id,-1)
local T={
["Name"] = getSecurityInfo(ClassCode,SecCode).name,
["SecCode"] = SecCode,
["Optiontype"] = Optiontype,
["Optionbase"] = Optionbase,
["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value+0
}
BaseCol[row]=T
--заполняем статичные параметры
Sec2row[SecCode]=row
SetCell(tbl.t_id, row, 1, BaseCol[row].Name) -- "Название опциона",
SetCell(tbl.t_id, row, 2, BaseCol[row].SecCode) --"Код опциона",
SetCell(tbl.t_id, row, 3, BaseCol[row].Optiontype) -- "Тип опциона",
SetCell(tbl.t_id, row, 4, BaseCol[row].Optionbase) --"Баз. актив",
--заказ данных
CreateDataSourceEX(BaseClassCode,T.Optionbase,"settleprice")
CreateDataSourceEX(ClassCode,T.SecCode,"strike")
CreateDataSourceEX(ClassCode,T.SecCode,"volatility")
--заполняем динамичные параметры
CALC=Calculate(row,true)
end
end
WORK = true
while WORK do
CALC=Calculate(G_ROW,CALC)
sleep(INTERVAL)
end
end
Поверьте эта тема уже миллион раз подымалась, на каждое предложение всегда найдется контр аргумент. И наше обсуждение заведомо ни к чему не приведет.
Цитата
Passport пишет: 1) Можно ли добавить функцию NUMBERgetDataCount(STRING class_code, STRING sec_code, NUMBER interval, [, STRING param]) которая бы сообщала сколько на данный момент есть данных на сервере для данного инструмента? (подозреваю, что отличие будет только COUNT в SQL запросе, но повысит нагрузку на сервер...)
Такая функция уже есть называется Size, однако она ведь не решает проблему не так ли?
Цитата
Passport пишет: Или же добавить функции getSecurityInfo() ещё один возвращаемый параметр. По хорошему конечно дату-время последней известной серверу сделки
Это уже есть, смотрите параметр time из ТТП, однако и она не решает проблему не так ли?
Цитата
Passport пишет: Поэтому может не очень элегантно, но зато просто и надёжно - true-false параметр указывающий были ли сделки до начала сегодняшней торговой сессии
Это уже есть, достаточно посмотреть на график. Но и это не является решением.
Цитата
Passport пишет: Выглядит может и не очень красиво, но я уверен, что это решит 99% случаев возникновения моего вопроса.
Sergey Gorokhov пишет: Здравствуйте, Вопрос уже многократно поднимался на форуме. Ответ: никак.
Прошу понять, что прочитать весь форум довольно затруднительно, а поиском не всегда находится нужное. Поэтому ещё вопрос - а планируется ли добавление срабатывания callback'а в такой ситуации? Ведь это решило бы проблему.
Вы не совсем понимаете. Дело в том, что нет такого критерия который позволил бы отличить ситуацию "продолжения ожидания" от "отсутствия данных", а значит и решить эту проблему нельзя.
green_X5 пишет: Сергей, ответ "Не будем заниматься этой проблемой, потому что - не будем!" - тоже ответ, имеет право на жизнь. ) А вот "выполнил ли брокер процедуру - мы не знаем" и "какой именно форс-мажор имел место трудно установить" - не принимается. Я Вам дал описание проблемы, её дату, временной диапазон, назвал брокера, который имеет моё обращение (и не только моё), вроде как можете связаться с брокером (своим клиентом) и разобраться в проблеме. И в третий раз укажу Вам на важность проблемы - Если данные исправились только после "Перезаказать данные с сервера", значит терминал не получал обновленные данные, когда они уже лежали (но почему-то не принимаются клиентским местом) на сервере. В результате клиентское место имеет неправильный параметр торгуемой бумаги, а именно "0", на не "28". Была бы пустая строка "" или nil, мы бы могли обнаружить это скриптом. Терминал отображал данные, не соотв. данным на сервере.
Если это проблема на серверной части, Вы наверное имеете возможность взаимодействовать и с их разработчиками. Подскажу адрес - support@quik.ru
Критика это конечно хорошо, но есть ли у Вас конкрентое предложение в изменении текущего поведения?
Да нет никакой критики. Есть просьба смоделировать проблемную ситуацию у себя. Наверняка у вас есть тестовая пара сервер-клиент. Перед "началом новой сессии" забейте фьючерсам "до погашения" ноль. Дайте соединение клиенту с сервером, клиент должен получить этот ноль. Затем, не разрывая соединения и не меняя сессии и даты торгов измените принудительно у сервера этот ноль на например 10. Посмотрите, изменились ли данные на клиентском месте. И как скоро изменились. Вот и предложение.
Здравствуйте, Для анализа проблемы мы связались с Вашим брокером Промсвязьбанк К сожалению по имеющейся информации и логам брокера нам не удалось установить причину произошедшего, ровно как и найти какие-либо следы "сбоя". Возможно это следствие недостатка информации. Сообщите, точную дату и время когда наблюдалась проблема с трансляцией параметра "до погашения". А также сообщите свой UID и ip адрес сервера брокера к которому Вы подключаетесь.
еще сообщите код инструмента и код класса на котором на котором была проблема с трансляцией параметра "до погашения".
green_X5 пишет: Сергей, ответ "Не будем заниматься этой проблемой, потому что - не будем!" - тоже ответ, имеет право на жизнь. ) А вот "выполнил ли брокер процедуру - мы не знаем" и "какой именно форс-мажор имел место трудно установить" - не принимается. Я Вам дал описание проблемы, её дату, временной диапазон, назвал брокера, который имеет моё обращение (и не только моё), вроде как можете связаться с брокером (своим клиентом) и разобраться в проблеме. И в третий раз укажу Вам на важность проблемы - Если данные исправились только после "Перезаказать данные с сервера", значит терминал не получал обновленные данные, когда они уже лежали (но почему-то не принимаются клиентским местом) на сервере. В результате клиентское место имеет неправильный параметр торгуемой бумаги, а именно "0", на не "28". Была бы пустая строка "" или nil, мы бы могли обнаружить это скриптом. Терминал отображал данные, не соотв. данным на сервере.
Если это проблема на серверной части, Вы наверное имеете возможность взаимодействовать и с их разработчиками. Подскажу адрес - support@quik.ru
Критика это конечно хорошо, но есть ли у Вас конкрентое предложение в изменении текущего поведения?
Да нет никакой критики. Есть просьба смоделировать проблемную ситуацию у себя. Наверняка у вас есть тестовая пара сервер-клиент. Перед "началом новой сессии" забейте фьючерсам "до погашения" ноль. Дайте соединение клиенту с сервером, клиент должен получить этот ноль. Затем, не разрывая соединения и не меняя сессии и даты торгов измените принудительно у сервера этот ноль на например 10. Посмотрите, изменились ли данные на клиентском месте. И как скоро изменились. Вот и предложение.
Здравствуйте, Для анализа проблемы мы связались с Вашим брокером Промсвязьбанк К сожалению по имеющейся информации и логам брокера нам не удалось установить причину произошедшего, ровно как и найти какие-либо следы "сбоя". Возможно это следствие недостатка информации. Сообщите, точную дату и время когда наблюдалась проблема с трансляцией параметра "до погашения". А также сообщите свой UID и ip адрес сервера брокера к которому Вы подключаетесь.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Здравствуйте, Согласно документации на терминал (вызывается клавишей Ф1) -Раздел 6. Совместная работа с другими приложениями --Импорт транзакций ---Формат .tri-файла с параметрами транзакций Цитата:
Цитата
«KILL_ALL_STOP_ORDERS» - снять все заявки на рынке ФОРТС,
То есть KILL_ALL_STOP_ORDERS не предназначен для снятия условных заявок, а только для обычных и только по ФОРТС Для снятия стоп заявок используется KILL_ALL_STOP_ORDERS, однако через TRANS2QUIK.dll данная транзакция не поддерживается Единственный вариант, снимать стоп заявки по одной используя KILL_STOP_ORDER
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Sergey Gorokhov пишет: Кстати у нас даже готовый пример есть:
Просматривая код скрипта, я сразу обратил внимание, что в нём без нужды используется OnInit(), OnStop(), while WORK do. Я делаю без этого. Запустил скрипт, жду... А он всё работает и работает... Пришлось останавливать. А выход из while WORK do ... end сделать нельзя?
Скрипт написан так чтобы постоянно записывать свежие данные. Если это не устраивает никто не запрещает написать так как Вам нужно. Следует понимать разницу между примером и готовой программой под Ваши задачи.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Некто пишет: вместо элементарного использования getCandlesByIndex?
Так в чем проблема, используйте getCandlesByIndex если он больше нравится.
Кстати у нас даже готовый пример есть:
Скрытый текст
Код
--[[
Что делает:
Сохраняет график в текстовый файл.
Формат файла такой:
<DATE>;<TIME>;<OPEN>;<HIGH>;<LOW>;<CLOSE>;<VOL>
Как использовать:
Постройте график
В параметрах графика, зайдите на вкладку 'Дополнительно'.
В поле 'Идентификатор' укажите уникальный идентификатор этого графика. По умолчанию GRAPH
Точно такой же идентификаор укажите в переменной TAG
]]
-------------------------------НАСТРОЙКИ-------------------------------
TAG='GRAPH' --Идентификатор графика
separator = ',' --Разделитель колонок
GraphPath=getScriptPath() --папка в которую будет записываться файл с графиком
-----------------------------------------------------------------------
-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
tbl = {
[1]='DATE', --Дата свечи
[2]='TIME', --Время свечи
[3]='OPEN', --Цена открытия
[4]='HIGH', --Максимальная цена
[5]='LOW', --Минимальная цена
[6]='CLOSE', --Цена закрытия
[7]='VOL' --Объем
}
WORK = true
file = nil
last_candle=0
first_candle=0
function OnInit()
WORK = true
end
function OnStop()
WORK = false
end
function FTEXT(int)
local Output = ""
if int<10 then
Output = "0"
end
return Output .. tostring(int)
end
function dt2str(dt)
return {['DATE']=FTEXT(dt.year)..FTEXT(dt.month)..FTEXT(dt.day), ['TIME']=FTEXT(dt.hour)..FTEXT(dt.min)..FTEXT(dt.sec)}
end
function main()
local line = 0
local t, n, l = getCandlesByIndex(TAG, line, 0, 1)
if n>0 then
local file = io.open(GraphPath..'\\'..l..'.csv', 'w+')
file:write(table.concat(tbl,separator) .. '\n')
file:flush()
while WORK do
last_candle = getNumCandles(TAG)-1
if last_candle>first_candle then
local t, n, l = getCandlesByIndex(TAG, line, first_candle, last_candle-first_candle)
for i=0,n-1 do
tbl = {
[1]=dt2str(t[i].datetime).DATE, --Дата свечи
[2]=dt2str(t[i].datetime).TIME, --Время свечи
[3]=tostring(t[i].open), --Цена открытия
[4]=tostring(t[i].high), --Максимальная цена
[5]=tostring(t[i].low), --Минимальная цена
[6]=tostring(t[i].close), --Цена закрытия
[7]=tostring(t[i].volume) --Объем
}
file:write(table.concat(tbl,separator) .. '\n')
file:flush()
end
first_candle=last_candle
end
end
file:close()
end
end
Некто пишет: А я уж начал с getCandlesByIndex возиться... Все темы на этом форуме, в инете, которые через поиск нашел посмотрел, но не нашёл инфу о структуре TABLE t, которую возвращает эта функция. Может, кто подскажет?
Попробуйте поискать например в документации Qlua.chm -Функции для работы с графиками --Функции для работы с графиками ---Функции O, H, L, C, V, T
Цитата
Время свечи возвращается с точностью до миллисекунд в виде таблицы с полями: {year, month, day, week_day, hour, min, sec, ms, count}
Цитата
Некто пишет: А это не "из пушки по воробьям"? Мне всего-то надо раз в день сохранить в файл истории новые данные.
Нет это не "из пушки по воробьям" а вполне нормальный доступ к данным.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Возможно ли сделать в QUIK общее хранилище данных для обмена информацией между скриптами?
Я знаю, что есть стороннее решение . Но оно не удобно тем, что при обращении к объекту из общего "пространства имён" создаётся новый экземпляр объекта (вместо ссылки), что негативно сказывается на ресурсах.
Здравствуйте, К сожалению штатной возможности не предусмотренно
s_mike@rambler.ru пишет: Создайте таблицу с целочисленными индексами и присваивайте по этим индексам таблицы с нужными вам полями.
С этим разобрался.
Теперь подскажите, пожалуйста, как получать год, месяц, число, час, минута, OHLC для свечи? Пытался по справке разобраться, по разделу "Функции для доступа к источнику данных" и "Функции O, H, L, C, V, T", но там всё очень сумбурно - не понял.
Здравствуйте, Задачу можно решить без открытия окна с графиком, через функции CreateDataSource и SetUpdateCallback Пример есть в руководстве QLUA.chm -Функции взаимодействия скрипта Lua и Рабочего места QUIK --Функции для работы с графиками ---SetUpdateCallback
Старатель пишет: Чтобы иметь возможность самостоятельно указывать границы оси и не зависеть от автомасштабирования. Скрытый текст Мне, например, в данной ситуации хотелось бы задать другие границы оси.
К сожалению реализация доступа к параметрам диаграммы через LUA сейчас вызывает ряд технических трудностей. На сколько становится понятно, цель масштабировать по графику цены, а не по индикатору. Ранее мы уже регистрировали пожелание на то чтобы при автомасштабировании учитывать какой-то конкретный график. Поэтому предлагаю зарегистрировать еще одно от Вас.
function main() local ImyaCFGFaila=getScriptPath().."\" .. "1.txt" local file = io.open(ImyaCFGFaila, "w") file:seek("set", 0) file:write(tostring("11")) file:seek("set", 6) file:write(tostring("....... его рот")) file:flush() file:close() end
Исходная строка в файле "1.txt" такая: "11111111111111111111111111111111111111111111111111111111111111111" (без всяких переносов и без кавычек) После работы скрипта: строка в файле "1.txt" такая: "11<NUL><NUL><NUL><NUL>....... его рот", где <NUL> - то самое. Как видите никакого смещения в пустоту.
Вас не удивляет что NUL символов 4 штуки? Может это потому что Вы смещаете курсор на шесть символов влево, в то время как в строке всего 2 символа? 6-2=4
function main() local ImyaCFGFaila=getScriptPath().."\" .. "1.txt" local file = io.open(ImyaCFGFaila, "w") file:seek("set", 0) file:write(tostring("11")) file:seek("set", 6) file:write(tostring("....... его рот")) file:flush() file:close() end
Исходная строка в файле "1.txt" такая: "11111111111111111111111111111111111111111111111111111111111111111" (без всяких переносов и без кавычек) После работы скрипта: строка в файле "1.txt" такая: "11<NUL><NUL><NUL><NUL>....... его рот", где <NUL> - то самое. Как видите никакого смещения в пустоту.
Deserf пишет: Прочитайте текст скрипта, который выше - я его ВООБЩЕ НИКУДА НЕ СМЕЩАЛ, а он все равно тупит
Читаю.
Код
local file = io.open(ImyaCFGFaila, "w+") --Открыли файл и стерли в нем все что есть, так как режим w+
file:seek("set", 15) --смефаем курсор на 15 символов в пустоту,, так как файл пустой.
file:write("22") --пишем строку "22" после 15 пустых символов
file:flush() --обновляем файл
file:close() -- закрываем
Еще читаю:
Код
local file = io.open(ImyaCFGFaila, "w+") --Открыли файл и стерли в нем все что есть, так как режим w+
file:flush() --обновляем файл
file:close() -- закрываем
Еще раз пишу, режим w+ полностью затирает файл при открытии. Таким образом, если Вам нужно изменить уже имеющиеся данные в этом файле, ищите другой способ.
Deserf пишет: Можно и не смещать никуда курсор - те же яйца. И смещаю не в пустоту а там, где есть символы, если в пустоту сместить он так то ошибку викидывает сразу
Простите но Вы именно смещаете в пустоту. Так как режим w+ перезаписывает файл. То есть стирает все и пишет по новой.
Sergey Gorokhov пишет: Если функционал Вам нужен, достаточно просто попросить его добавить, мы зарегистрируем обращение и рассмотрим возможность его реализации.
Прошу добавить этот функционал.
Я правильно оформил обращение ?
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Виталий пишет: В фирме-разработчике, экономя деньги на доработке продукта, возможно, так и считают.
Если какого-то функционала нет это совсем не значит что его нет умышленно. Следует понимать что в любом софте у пользователей возникает желание что-либо добавить/доработать И с нашей стороны для реализации таких желаний существует специальна процедура (без всяких "их проблема"). Если функционал Вам нужен, достаточно просто попросить его добавить, мы зарегистрируем обращение и рассмотрим возможность его реализации.