Попробуйте что-то типа такого. Передается базовое текущее ГО по направлению сделки, цена сделки.
Код
---@param Sec table
---@param go number
---@param deal_price number
---@param Type string SELL|BUY
local function CalcPriceGO(Sec, go, deal_price, Type)
if type(Sec) ~= 'table' then error(("bad argument Sec (table expected, got %s)"):format(type(Sec)),2) end
if type(go) ~= 'number' then error(("bad argument go (number expected, got %s)"):format(type(go)),2) end
if type(deal_price) ~= 'number' then error(("bad argument deal_price (number expected, got %s)"):format(type(deal_price)),2) end
if Type ~= 'BUY' and Type ~= 'SELL' then error(("bad argument Type (string 'SELL' or 'BUY' expected, got %s)"):format(tostring(Type)),2) end
local status, res = pcall(function()
if getParamEx(Sec.CLASS_CODE, Sec.SEC_CODE, "CLPRICE").result ~= '1' then
log.warn([[ Для точного расчета ГО необходимо включить в поток данных параметр "Котировка последнего клиринга".
Сейчас он не включен. Будет взято базовое ГО]])
return go
end
if getParamEx(Sec.CLASS_CODE, Sec.SEC_CODE, "PRICEMAX").result ~= '1' then
log.warn([[ Для точного расчета ГО необходимо включить в поток данных параметр "Максимально возможная цена". Сейчас он не включен.
Сейчас он не включен. Будет взято базовое ГО]])
return go
end
if getParamEx(Sec.CLASS_CODE, Sec.SEC_CODE, "PRICEMIN").result ~= '1' then
log.warn([[ Для точного расчета ГО необходимо включить в поток данных параметр "Минимально возможная цена". Сейчас он не включен.
Сейчас он не включен. Будет взято базовое ГО]])
return go
end
local priceKoeff = Sec.STEPPRICE/Sec.SEC_PRICE_STEP
local cl_price = tonumber(getParamEx(Sec.CLASS_CODE,Sec.SEC_CODE,'CLPRICE').param_value) or 0
local max_price = tonumber(getParamEx(Sec.CLASS_CODE,Sec.SEC_CODE,'PRICEMAX').param_value) or 0
local min_price = tonumber(getParamEx(Sec.CLASS_CODE,Sec.SEC_CODE,'PRICEMIN').param_value) or 0
if cl_price==0 or max_price == 0 or min_price == 0 then return go end
local L2 = (max_price-min_price)*math_pow(10, Sec.SCALE)
local R = (go/(L2*priceKoeff) - 1)*100
local sign = Type == 'BUY' and -1 or 1
return go + sign*(cl_price - deal_price)*priceKoeff*(1 + R/100)
end)
if not status then
log.error('Error CalcPriceGO: '..tostring(res))
return go
end
return res
end
означает лишь то, что для данной бумаги существует параметр с именем param_name, не более. И не гарантирует, что он транслируется на клиентское место или что он хотя бы заказан. И в общем случае проверить транслируется ли параметр не представляется возможным.
Вот эту строку вообще не понял:
Код
local L2 = (max_price-min_price)*math_pow(10, Sec.SCALE)
Вот так, наверное, должно быть, тогда совпадает с квиковскими значениями в окне ввода заявки:
Код
local L2 = max_price-min_price
НО! Написал скрипт, который считает ГО по вашей формуле (с моей поправкой) и сравнил с фактически блокируемым ГО под заявку. Значения не совпадают от слова совсем: В таблице: БГО - ГО продавца, взятое из ТТТ Мин., Макс. - соответственно мин. и макс. возможные цены ГО Buy - Фактически заблокированное ГО под заявку на покупку по мин. цене ГО Sell - Фактически заблокированное ГО под заявку на продажу по макс. цене Buy - ГО, рассчитанное по формуле (с моей поправкой) на покупку по мин. цене
Вниманию саппорта: Функция ParamRequest возвращает true даже если параметр не удалось заказать. Чтобы убедиться в этом достаточно включить галку «С учетом настроек, выбранных пользователем вручную через пункт меню Система/Заказ данных/Поток котировок» и вызвать ParamRequest с параметром, которого ещё нет в списках.
Значение в поле Объем ГО в окне ввода заявки не совпадает с фактически блокируемым ГО под заявку по той же цене. См. табличку выше. В окне ввода заявки транслируется значение Buy +- 1 копейка, а блокируется ГО Buy
В расчете L2 нет ошибки. Он ведется в пунктах (т.к. далее пункты переводятся в рубли, через умножение на priceKoeff), поэтому и умножается на размерность инструмента. Проверьте, что передаете правильные значения по направлению. Если покупка, то БГО покупателя и наоборот. Значения же разные.
getParamEx возвращает строку "1" если параметр получен и строку "0" если нет. Если не ошиблись с написание параметра (а этом можно сделать организовав словарь), то возврат "0" или не равно "1" - это значит параметр не транслируется.
Впрочем, Вы правы. Я выдернул часть расчета из другой части кода и не увидел, что здесь перевод в деньги от цены, не от пунктов. Т.к. большинство фьючерсов имеют цену как целое число, то это не влияло на результат. Да, надо убрать приведение цены к целому значению.
Nikolay написал: getParamEx возвращает строку "1" если параметр получен и строку "0" если нет.
Проведите небольшой эксперимент: включите галку «С учетом настроек, выбранных пользователем вручную через пункт меню Система/Заказ данных/Поток котировок» и попробуйте получить значение параметра, который не добавлен в списки получаемых параметров (Заказ данных/Поток котировок...) getParamEx вернёт таблицу с result == "1", но без значения самого параметра.
Чего-то я не понимаю. Возьмём к примеру, SiM0: ГО покупателя = 5577,68 ГО продавца = 5595,86 Макс.возм.цена = 71598 Мин.возм.цена = 65454
2L = Макс.возм.цена - Мин.возм.цена = 71598 - 65454 = 6144, что меньше ГО Исходя из формулы в статье радиус валютного курса R получается отрицательный: -9.1% Всё так?
Nikolay написал: getParamEx возвращает строку "1" если параметр получен и строку "0" если нет.
Проведите небольшой эксперимент: включите галку «С учетом настроек, выбранных пользователем вручную через пункт меню Система/Заказ данных/Поток котировок» и попробуйте получить значение параметра, который не добавлен в списки получаемых параметров (Заказ данных/Поток котировок...) getParamEx вернёт таблицу с result == "1", но без значения самого параметра.
Такой варинт настроек не самый удачный для использования скриптов. Нельзя гаратнтировать, что пользователь не сменит (закроет) таблицу и поток данных исчезнет. Поэтому есть процедуры: ParamRequest, CancelParamRequest.
Nikolay, Я вам просто хочу донести, что result == "1" не гарантирует, что параметр включен в поток данных. Если же result ~= "1", то вы не найдёте его в списках доступных параметров.
Незнайка написал: Nikolay, Я вам просто хочу донести, что result == "1" не гарантирует, что параметр включен в поток данных. Если же result ~= "1", то вы не найдёте его в списках доступных параметров.
Да, это так. Но я свои скрипты пишу из расчета, что включена настройка независимого получения данных, что отмечаю в описании и инструкции.
Незнайка написал: В QUIK есть же эта функция. Можете сделать её доступной в Lua?
Здравствуйте!
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
в документации указанной выше Вы узнаете что ГО зависит от направления сделки: Эффекты: • Асимметричное ГО на покупку и продажу • Увеличение ГО по однонаправленным позициям из-за учета процентного риска • Снижение изменений из-за влияния IR с увеличением срока • Снижение ГО по позициям в ММС и по «Календарным спредам» ---------------------
Egor Zaytsev написал: В форме ввода заявки ГО рассчитывается, оно не "едет" напрямую из таблицы текущих торгов в форму ввода заявки. Считаете по формуле.
У вас сходится ГО, рассчитанное по этой формуле, с тем, что считает квик?
Egor Zaytsev, какая ещё информация необходима, чтобы начать разбор проблемы "QUIK неверно рассчитывает Объем ГО заявки и, => максимальное возможное количество лотов в заявке" ?
Незнайка написал: Egor Zaytsev, какая ещё информация необходима, чтобы начать разбор проблемы "QUIK неверно рассчитывает Объем ГО заявки и, => максимальное возможное количество лотов в заявке" ?
Добрый день.
Максимальное кол-во у Вас не рассчитано возможно потому что не подставлен торговый счет на форме ввода заявки, либо не включена опция пункт меню Система/Настройки/Основные настройки/Программа/Получение данных/ "Исходя из настроек открытых пользователем таблиц"
Что касается объема ГО на форме ввода заявки, то выше выложили формулу для расчета, подставьте значения и проверьте результат.
Egor Zaytsev, то ли я плохой рассказчик, то ли вы... плохой читатель. Попробуем ещё раз. Открываем Руководство пользователя QUIK и читаем:
Цитата
Ввод заявок на Срочном рынке FORTS «Объем ГО» – совокупный размер ГО, который блокируется по заявке исходя из количества контрактов и настроек брокера.
Проверяем, ставим заявку и сравниваем со значением Тек. чист. поз. из таб. Ограничения по клиентским счетам. В сообщении #17 привёл скрины с реального счёта, не демо. Даже обвёл красненьким, на что обратить внимание. Видите, циферки не совпадают?
1. У Вас должна быть версия не ниже 8.7.1. Ранее действительно Объем ГО мог не верно считаться, но
не верно он считался именно исходя из наших формул. 2. В текущий момент Объем ГО может не совпадать с биржевыми расчетами, так как у нас представлена упрощенная формула расчета.
В первом приближении ГО можно рассчитать по формуле: Покупка: ГО = ГО_покупателя - (РЦ - Цена_сделки) * Стоимость_шага_цены / Мин_шаг_цены * (1 + R / 100) Продажа: ГО = ГО_продавца + (РЦ - Цена_сделки) * Стоимость_шага_цены / Мин_шаг_цены * (1 + R / 100) где R - радиус валютного курса Для контрактов, шаг цены которых рассчитывается в рублях, R = 0
Судя по значениям, QUIK рассчитывает R для всех контрактов, в т.ч. рублёвых, по формуле, приведённой в сообщении #4. Не знаю, как определить R, но после релиза Спектры 6.0 он точно не рассчитывается по той формуле. Например, на сегодня для USD R = 6% Если считать по формуле для RIU0 получается 5,44%, для BRQ0 -19,7%. Короче, невпопад.
При цене сделки, близкой к верхнему или нижнему лимиту, ГО считается как-то иначе. Как именно, не разобрался ( В методике расчёта ГО не нашёл, плохо искал наверное.
Если все таки у вас не верно считается объем ГО на форме ввода заявки, то просьба предоставить архив рабочего места на момент проблемы и ваши расчеты, по каким формулам и какие значения подставляете.
Расчет ГО для выставляемой заявки в форме ввода носит прежде всего информационный предварительный характер. В силу ряда причин мы не можем в точности повторить биржевой расчет. Расчет рисков и проверку покупательной способности по операциям срочного рынка МБ для конфигураций ПО QUIK, не использующих единую денежную позицию с фондовым рынком, выполняет полностью торговая система. Тем не менее, мы стараемся актуализировать этот расчетный алгоритм и устранять найденные ошибки. В данный момент мы признаем, что расчет ГО для фьючерсов, использующих радиус курса иностранных валют, может быть неточным. Данную ошибку мы исправим в одной из следующих версий клиентского места QUIK. Приносим извинения за доставленные неудобства и задержку с ответом.