Мне надо сделать, чтобы папка Luaindicators для терминалов была задана принудительно(единая), чтобы терминал искал индикаторы в назначенной папке.
Другими словами, необходимо вынести папку LuaIndicators за пределы каталога установки терминала QUIK и настроить терминал так, чтобы он всегда обращался к этой конкретной папке при поиске индикаторов.
Перестал работать getCandlesByIndex причем время свечек видно в datetime, а остальные параметры open, high, low, close, volume и doesExist - нулевые. Написал код для тестирования, индикатор ставим на график с идентификатором SBER_Chart:
Код
Settings=
{
Name = '#test'
}
function writeToFile(filename, content)
local file_handle = io.open(filename, 'w')
if file_handle then
file_handle:write(content)
file_handle:close()
return true
else
return false
end
end
function Init()
return 1
end
function OnCalculate(index)
id_chart = 'SBER_Chart'
local need_right_candles_count = 10
local line_number = 0
local candles_count = getNumCandles(id_chart)
local candles_from = candles_count - need_right_candles_count
check1 = tostring(id_chart)..'\n'..tostring(line_number)..'\n'..tostring(candles_from)..'\n'..tostring(need_right_candles_count)..'\n'..tostring(candles_count)..'\n'
local result_table, result_candles_count, result_chart_name = getCandlesByIndex(id_chart, line_number, candles_from, need_right_candles_count)
if result_table == nil or #result_table == 0 then
return "Empty result_table"
end
local fieldNames = {}
for field, _ in pairs(result_table[1]) do
table.insert(fieldNames, field)
end
check1 = check1..'My_Time\t'..table.concat(fieldNames, '\t') .. '\n'
for i = #result_table, 1, -1 do
if result_table[i].datetime == nil or
result_table[i].datetime.day == nil or
result_table[i].datetime.month == nil or
result_table[i].datetime.year == nil or
result_table[i].datetime.hour == nil or
result_table[i].datetime.min == nil or
result_table[i].datetime.sec == nil then
return nil
end
local candle_datetime = string.format("%02d.%02d.%04d %02d:%02d:%02d",
result_table[i].datetime.day,
result_table[i].datetime.month,
result_table[i].datetime.year,
result_table[i].datetime.hour,
result_table[i].datetime.min,
result_table[i].datetime.sec)
local formattedFields = {
candle_datetime
}
for j, fieldName in ipairs(fieldNames) do
local fieldValue = result_table[i][fieldName]
table.insert(formattedFields, tostring(fieldValue))
end
check1 = check1 .. table.concat(formattedFields, '\t')..'\n'
end
local filename_w = getWorkingFolder()..'\\check1.txt'
if writeToFile(filename_w, check1) then
return
else
return "Failed to write to file"
end
end
На выходе получаем, нулевые данные (кроме времени свечей)
Однако есть проблема, что иногда код неправильно считает. т.е. Money2Lot выдаёт иногда 0, потому что Мосбиржа ставит большой LOTSIZE, но обычно правильно.
Наверно я что-то упустил в алгоритме. Подскажите где я ошибся.
Код
function Lot2Money(zCLASSCODE,zSECCODE,Lot)
local Price=tonumber(Get_gLast_Price_gr(zCLASSCODE,zSECCODE))
if Price==nil or Price==0 then return nil end
local LOTSIZE=getParamEx(zCLASSCODE,zSECCODE,"LOTSIZE").param_value
if LOTSIZE==nil then return nil end
message('Lot2Money'
..'\n'..'zCLASSCODE= '..tostring(zCLASSCODE)
..'\n'..'zSECCODE= '..tostring(zSECCODE)
..'\n'..'Lot= '..tostring(Lot)
..'\n'..'Price= '..tostring(Price)
..'\n'..'LOTSIZE= '..tostring(LOTSIZE)
..'\n'..'Lot*Price*LOTSIZE= '..tostring(Lot*Price*LOTSIZE)
)
return Lot*Price*LOTSIZE
end
Здесь я поставил заплатку, что не есть хорошо.
Код
function Money2Lot(zCLASSCODE, zSECCODE, Money)
if Money==nil then return 0 end
local Price=tonumber(Get_gLast_Price_gr(zCLASSCODE,zSECCODE))
if Price==nil or Price==0 then return nil end
local LOTSIZE=getParamEx(zCLASSCODE,zSECCODE,"LOTSIZE").param_value
if LOTSIZE==nil then return nil end
message('Money2Lot'
..'\n'..'zCLASSCODE= '..tostring(zCLASSCODE)
..'\n'..'zSECCODE= '..tostring(zSECCODE)
..'\n'..'Money= '..tostring(Money)
..'\n'..'Price= '..tostring(Price)
..'\n'..'LOTSIZE= '..tostring(LOTSIZE)
..'\n'..'Money/(Price * LOTSIZE= '..tostring(Money/(Price * LOTSIZE))
)
local RetLot=math.floor(Money/(Price * LOTSIZE))
if RetLot==0 then -- ЗАПЛАТКА: если брокер поставил избыточный LOTSIZE
RetLot=math.floor(Money/Price)
end
return RetLot
end
В стакане цен есть настройка, которая вызывается по Ctrl+E. Там можно поставить галочку "Нижняя панель". После этого внизу стакана будет видна панель лотов.
Вопрос: как мне получить программно эти цифры стакана цен.
Примечание: простое складывание объёмов в стакане (а там их всего 20 строк) всегда меньше цифр в Нижней панели)
Пытаюсь получить из таблицы "Клиентский портфель [SUR]" данные из графы << Плечо >> по строке Т2
Использую для этого код:
Код
local PortfolioInfoExTable=getPortfolioInfoEx (gFIRMID, gCLIENT_CODE, 2) -- https://luaq.ru/getPortfolioInfoEx.html
local zPortfolio_value=PortfolioInfoExTable.portfolio_value -- Стоимость портфеля
local zCash_leverage=PortfolioInfoExTable.cash_leverage -- Плечо
message(tostring(zPortfolio_value)..'\n\n'..tostring(zCash_leverage))
Но значение плеча zCash_leverage нулевое, хотя я вижу этот размер плеча явно в таблице "Клиентский портфель [SUR]" в строке Т2.
При этом мне успешно показывается стоимость портфеля - zPortfolio_value.
У меня такое ощущение, что в синтаксисе команды getPortfolioInfoEx должно быть ещё указание на валюту т.к. она указана в титуле окна.
На самом деле мне нужна графа <<Прибыль/Убытки>>, но для упрощения вопроса спрашиваю про графу <<Плечо>>.
Как мне получить размер Плеча или Прибыль/Убыток с начала дня по спотовому рынку?
В десктопном терминале QUIK на языке lua я даю команду buy_sell_info=getBuySellInfo('MC0002500000','404JNEF','TQBR','RUAL',0) -- https://luaq.ru/getBuySellInfo.html Мне возвращается таблица: table: 000000000A9B9750 Из таблицы я беру значение buy_sell_info.can_buy и оно равно nil (не определено) У других брокеров всё работает.
Техническая поддержка моего брокера порекомендовала брать данные о количестве доступных лотов для покупки из подтаблицы "Купить/Продать" таблицы "Клиентский портфель". Как обратиться к "Клиентскому портфелю" мне понятно portfolio = getPortfolioInfoEx ('MC0002500000','404JNEF', 2) и даже успешно оттуда вызывается плечо portfolio.leverage
Однако надо получить доступ именно к той таблице "Купить/Продать", котрая вызывается из таблицы "Клиентского портфеля" (а не из таблицы "Состояние счета") Как мне получить can_buy при для фондового рынка?
FIRMID и ACCOUNT для спотового рынка мне получить удалось из таблички фьючерсов
Код
function set_ACCOUNT_FIRMID()
if gACCOUNT~='' then return gACCOUNT end
if gSpot==true then
local TableName='trade_accounts' -- https://luaq.ru/getItem.html#param_table_26
local rows_total=getNumberOf(TableName);
for r=rows_total-1, 0, -1 do
local table_row=getItem(TableName,r);
if tonumber(table_row.firmuse)==1 and tonumber(table_row.trdacc_type)==4 then
gFIRMID=table_row.firmid
gACCOUNT=table_row.trdaccid
if gCLIENT_CODE=='' then gCLIENT_CODE=gACCOUNT end
if gACCOUNT~='' then return; end
end
end
stop();
end
end
Как получить CLIENT_CODE? В какой таблице он лежит?
Как определить доступна ли торговля по инструменту до открытия позиции., При отправке транзакции появляется ошибка брокера "Вам запрещена работа по данному инструменту".
При отправке транзакции появляется ошибка брокера "Вам запрещена работа по данному инструменту".
Как выяснилось брокер работает с ограниченным списком фьючерсных контрактов (и отправлят смотреть список доступных для торговли фьючерсов в эксель файл на своём сайте).
Однако котировки по всем фьючерсам брокер транслирует, но доступны для торговли только инструменты из их эксель-файла на сайте.
Потому при отправе транзакции появляется вышеназванная ошибка.
Какой командой мне определить, что инструмент доступен для торговли?
В окне "Фьючерсы FORTS Ввод заявки" есть кнопка [Max], которая позволяет автоматически подставить максимальное количество лотов в форму ручного ввода заявки.
По какой формуле идёт расчёт максимального количества лотов для фьючерсов в этом окне?
function CntTradesSellPosition(zCLASSCODE,zSECCODE)
cnt=0
local TableName='trades'
local rows_total = getNumberOf(TableName)
for r=rows_total-1, 0, -1 do
local table_row=getItem(TableName,r)
--message(tostring(table_row.flags));stop()
if table_row.class_code==zCLASSCODE and table_row.sec_code==zSECCODE and table_row.flags==36 then -- сделка продажа
cnt=cnt+1
end
end
return cnt
end
Пишу как самоучка, но мне как-то сложно (невозможно) вытаскивать из битовых флагов эти нужные значения, которые там закодированы в двоичной системе. В частности мне нужно определить только тип заявки ордера Buy или Sell.
Я так и не нашёл нигде пример алгоритма получения этих битовых значений, поэтому беру 10-тичные числа, но это кривовато, ибо по причине изменения других свойств и числа будут другие. Вот я методом научного тыка определил коды для продаж и второй флаг (бит) принимает разные значения: 64 = 1000000 36 = 100100 28 = 11100 1048604 = 100000000000000011100 - Продажа от стоплосса
Прошу, измените мой код, чтобы он нормально обрабатывал эти битовые флаги.
1.фьюченые инструменты постоянно меняются, но базовый актив - постоянный. 2.как я установил одному базовому активу может быть присвоено несколько фьючерсов по срокам истечения, например: BR = BRH3, BRG3, BRF3
Вопросы: 1.в какой таблице лежит список базовых активов? 2.какая таблица привязывает базовый актив к фьючерсам?
Хотелось бы получить Любой фьючерс по базовосу активу.