вот функция для расчета и расчет для 3-х значений:
Код
function EMA(y,x,N,i) if i==1 then return x; else return (y*(N-1)+2*x)/(N+1); end
----------
--Вот есть три цены закрытия:
local N=3;
x=193.6 i=1
y=EMA(y,x,N,i) print(y)
x=193.98 i=2
y=EMA(y,x,N,i) print(y)
x=200.16 i=3
y=EMA(y,x,N,i) print(y)
Очевидно у Вас нет средств для торговли на валютном рынке, поэтому Вам этот класс не подключили. В любом случае, свяжитесь с брокером и узнайте что Вы должны сделать чтобы этот класс Вам подключили. ------------------ класс: МБ Валюта: ETC(металлы)
и еще... При обработке сигналов есть такое понятия как окно наблюдения. так вот на приведенном вами графике сигнал слева от первого видимого значения свечи считается равным нулю как и сигнал справа от текущего видимого значения т е мы предполагаем что применяем прямоугольное окно. в итоге у вас не два отсчета для расчета третьего, а бесконечное множество отсчетов слева от третьего, но лишь два из них не равны нулю. поэтому можно считать что у вас всегда отсчетов столько, сколько желаете, т е в вашем случае их N+1 даже для первой свечи на графике. ------------------- читайте учебники.
nikolz написал: от периода зависит весовой коэффициент "альфа" читайте учебники
От периода так же зависит, то с какой свечи от начала будет произведен расчет. Можете читать учебники или не читать - это ни как не изменит данный факт.
Рассказываю начальные понятия. ------------------- В цифровых фильтрах, как и в аналоговых есть понятие - "переходной процесс" Т е это процесс установления на выходе EMA сигнала равного входному при условии что входной сигнал постоянный. время за которое сигнал на выходе станет равный входному - это время запаздывания сигнала или время переходного процесса. --------------------- Это время зависит от периода т е от N но не равно ему. ------------------- Вы спросили про расчет значения на выходе EMA, а не про время запаздывания (установления) сигнала. =============== поэтому повторяю еще ...надцатый раз Для расчета достаточно одного значения на входе и предыдущего значения на выходе. Т е число отсчетов для расчета не зависит от периода. ===================== От периода зависит время запаздывания сигнала на выходе. Время запаздывания больше чем период. -------------------- Точно равенство сигнала на выходе сигналу на входе будет в бесконечности. ------------------------- Фильтр EMA - это фильтр с бесконечной импульсной характеристикой. В аналоговом варианте - это RC цепочка. Период - это постоянная времени этой цепи. Выходной сигнал EMA - это эквивалент заряда емкости через резистор. ------------------ Если Вы подадите на вход EMA постоянный уровень например 100, то на выходе сигнал будет изменятся от 0 до 100, но 100 будет лишь в бесконечности.
Вы увидите, что там лишь 3 значения - текущий входной предыдущий входной и предыдущий выходной.
Неправильно. ------------------------ Для расчета RSI и EMA для третьей с начала свечи с периодом 3, нужно кол-во свечей равное: period + 1, то есть в данном случае для расчета нужны 4 свечи с указанным периодом.
Если есть желание разобраться в математике обработки сигналов, то для начала почитайте учебник, чтобы иметь хотя бы начальные знания по цифровой обработке сигналов. -------------------- Например, можно почитать это: http://www.pselab.ru/Books/Gold_Rader_1973.pdf
nikolz написал: НЕправильно ------------------- В цифровой обработке сигналов эти индикаторы называются БИХ фильтрами. Новое значение таких индикаторов рассчитывается на основе предыдущего значения и приращений значений на входе. Так как это простейшие фильтры ,то для их расчета достаточно приращения текущего значения относительно предыдущего. Таким образом, необходимое для расчета число отсчетов на входе не зависит от периода.
Что именно "Неправильно" ?
Вот есть три цены закрытия:
193,6
193,98
200,16
Рассчитайте "Правильно" значение EMA для третьей свечи с периодом 3.
мне лень считать. возьмите формулу и посмотрите какие значение туда ставить. Вы увидите, что там лишь 3 значения - текущий входной предыдущий входной и предыдущий выходной. т е два входных отсчета. если непонятно, то покажите свой расчет. Скажу, где ошибка.
НЕправильно ------------------- В цифровой обработке сигналов эти индикаторы называются БИХ фильтрами. Новое значение таких индикаторов рассчитывается на основе предыдущего значения и приращений значений на входе. Так как это простейшие фильтры ,то для их расчета достаточно приращения текущего значения относительно предыдущего. Таким образом, необходимое для расчета число отсчетов на входе не зависит от периода.
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 - Продажа от стоплосса
Прошу, измените мой код, чтобы он нормально обрабатывал эти битовые флаги.
В документации в скобках указано значение в 16 формате для каждого бита (до 8 это тоже самое что и в 10 формате) если надо несколько бит то складывайте эти значения Флаги для таблиц «Заявки», «Заявки на внебиржевые сделки»
Флаг установлен
Значение
бит 0 (0x1)
Заявка активна, иначе – не активна
бит 1 (0x2)
Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена
бит 2 (0x4)
Заявка на продажу, иначе – на покупку
бит 3 (0x8)
Заявка лимитированная, иначе – рыночная
бит 4 (0x10)
Исполнить заявку по разным ценам
бит 5 (0x20)
Исполнить заявку немедленно или снять (FILL OR KILL)
бит 6 (0x40)
Заявка маркет-мейкера. Для адресных заявок – заявка отправлена контрагенту
бит 7 (0x80)
Скрытая заявка
бит 8 (0x100)
Снять остаток
бит 9 (0x200)
Айсберг-заявка
бит 10 (0x400)
Заявка отклонена торговой системой
бит 20 (0x100000)
Поле «linkedorder» заполняется номером стоп-заявки
поясняю, для тех кто пишет на "чистом" луа. --------------- в исходном примере операторы типа _G.QTABLE_CLOSE заменил на QTABLE_CLOSE так как исходная запись это - масло масленое _G - это глобальная таблица а QTABLE_CLOSE - это функция в ней поэтому _G.QTABLE_CLOSE это тоже самое , что просто QTABLE_CLOSE ------------------ такая запись используется в создании модулей , а здесь не модуль, поэтому смысла в ней нет.
если взять пример выше и убрать последний параметр в функции SetCell и Highlight , то все обновляется. Может пример другой кто-нибудь напишет?
Код
local sec_code = 'SBER'
local class_code = 'QJSIM'
local SeaGreen = 12713921 -- RGB(193, 255, 193) нежно-зеленый
local RosyBrown = 12698111 -- RGB(255, 193, 193) нежно-розовый
local getParamEx = getParamEx
local GetCell = GetCell
local Highlight = Highlight
local SetCell = SetCell
local function get_price()
if flag then
local last_price = tonumber(getParamEx(class_code, sec_code, 'LAST').param_value) or 0
local lp = GetCell(t_id, 1, 0).value or last_price
SetCell(t_id, 1, 0, tostring(last_price))--, last_price)
-- if lp < last_price then Highlight(t_id, 1, 0, SeaGreen, 0, 1000)
-- elseif lp > last_price then Highlight(t_id, 1, 0, RosyBrown, 0, 1000)
-- end
end
flag=false
end
function OnParam(class, sec)
if t_id and sec == sec_code and class == class_code then flag=true end
end
function CreateTable()
t_id =AllocTable()
AddColumn(t_id, 0, "price", true, QTABLE_DOUBLE_TYPE, 15)
CreateWindow(t_id)
SetWindowPos(t_id, 90, 120, 170, 100)
InsertRow(t_id, 1)
InsertRow(t_id, 2)
end
local function Animate(sym,maxSym)
if sym and maxSym>string.len(sym) then sym=sym..'|' else sym='|' end
return sym
end
function event_callback(_, msg)
if (msg == _G.QTABLE_CLOSE) then
isRun = false
end
end
function OnInit()
CreateTable()
SetTableNotificationCallback(t_id, event_callback)
flag=true
get_price()
end
function main()
ds = CreateDataSource(class_code, sec_code, 1)
isRun = ds ~= nil
if ds then
ds:SetEmptyCallback()
end
while isRun and ds do
get_price();
sym=Animate(sym,20)
SetCell(t_id, 2, 0, sym, 0)
sleep(100)
end
end
у SetCell 5 параметров ---------------------------------------1 ---------------2---------------3----------------4-----------------5----------- BOOLEAN SetCell(NUMBER t_id, NUMBER key, NUMBER code, STRING text, NUMBER value) если оставить 3 ,то что тогда будет обновлять ячейку? ---------------- Но спорящим видимо один ... продолжайте =======================
TGB, исправленный скрипт не виснет Вы вместо брызжания проверьте тест. ------------------- если есть другие проблемы , то пишите я исправлю. ---------------------- И очевидно, и у кого что болит тот о том и говорит
nikolz написал: _sk_ ,вот Ваш тест с исправленными Вашими ошибками. Работает без проблем.
Вы до сих пор не поняли, что у _sk_ нет проблем со скритом ( он делает flag = true и все у него хорошо ). Его интерисует странное поведение скрипта когда flag =false и это нормально. Вообще, из того что видно невооруженным взглядом, у вас постоянный зуд отметиться на форуме (как у собачки, выпущенной на прогулку :: ). Зачем вы работаете на форуме «прокладкой» между комментариями? Явно, что у вас проблемы с вашими комплексами и вы пытаетесь здесь их скомпенсировать. Но вы до сих пор не научились выделять фрагменты текстов комментариев, которые вы цитируете. Вас можно пожалеть (девочки точно не любят), но вы постоянно спамите на форуме и скоро переполните его базу :: . Меня это беспокоит и только поэтому я на вас реагирую :: .
Вы не поняли, я исправил у него ошибки и можете делать хоть faLSE
Сегодня в Сбербанке повторилось. Дата торгов была вчера. И естественно вчерашний день пропал. -------------- Проблема решилась лишь после разрыва связи , длительного ожидания и установки связи заново. ---------------- Так как такую и подобные проблемы наблюдал неоднократно, то хочу высказать свое предположение о ее источнике. =================== проблема возникает, если установить соединение до начала торгов, либо в момент начала. Предположу, что при этом происходит не полная загрузка с сервера начальных данных, но после начала торгов сервер не проверяет некорректность данных у клиентов а продолжает работу с неполными либо с неверными данными. ============ Полагаю, это недоработка разработчиков QUIK. Но это лишь мои предположения. =============== Проблема решается иногда лишь перезагрузкой но после начала торгов и длительного ожидания.
если бы сделали возможность подгружать в архив данные из файлов , то было бы совсем хорошо. но и без этого все вполне работает и историю можно подгружать но без графического изображения.
Г.Растопаефф написал: Сбербанк предоставляет торговый доступ только к валютным парам USD_RUB и EUR_RUB. Посоветуйте пожалуйста российского брокера без кухни, который поддерживает QUIK и предоставит доступ к торгам по всем или большинству валютных пар Мосбиржи или СПбиржи.
у сбербанка есть все валюты имеющиеся на мос бирже
_sk_, вот Ваш тест с исправленными Вашими ошибками. Работает без проблем.
Код
local flag =false -- можно и false и true
local foregroundColor = RGB(0, 0, 0)
local backgroundColor = RGB(192, 255, 192)
local function setTableColors(foregroundColor, backgroundColor)
local nRows, nCols = GetTableSize(tableId)
if nRows and nCols then
for row = 1, nRows do
for col = 1, nCols do
SetColor(tableId, row, col,
backgroundColor, foregroundColor,
backgroundColor, foregroundColor)
end
end
end
end
local function ensureWindowOpened()
if tableId == nil then return end
if IsWindowClosed(tableId) then
CreateWindow(tableId)
SetWindowPos(tableId, 0, 0, 300, 100)
SetWindowCaption(tableId, "hang_test")
InsertRow(tableId, 1)
InsertRow(tableId, 2)
SetCell(tableId, 1, 1, "11")
SetCell(tableId, 1, 2, "12")
SetCell(tableId, 2, 1, "21")
SetCell(tableId, 2, 2, "22")
SetSelectedRow(tableId, 1)
end
setTableColors(foregroundColor, backgroundColor)
end
function OnInit(scriptPath)
tableId = AllocTable()
AddColumn(tableId, 1, "col1", true, QTABLE_STRING_TYPE, 5)
AddColumn(tableId, 2, "col2", true, QTABLE_STRING_TYPE, 5)
SetTableNotificationCallback(tableId, function(tId, msg, par1, _)
if msg == QTABLE_SELCHANGED then
SetSelectedRow(tId, 1)
end
end)
ensureWindowOpened()
end
local function run()
ensureWindowOpened()
if tableId then
SetSelectedRow(tableId, 2)
end
end
function OnStop(flag)
DestroyTable(tableId);
interrupted = true
end
function main()
message("STARTED", 1)
while not interrupted do
run()
if flag then
sleep(0)
end
end
message("SHUTDOWN", 1)
end
в колбеке в этой функции Вы уничтожаете окно ---------------------------- local function closeWindow() local t = tableId tableId = nil if t then DestroyTable(t) end end ------------------ А в main вы уничтожаете nil. Очевидно у Вас все вылетает по ошибке и вы вместо того чтобы правильно сделать ставите pcall ---------------- Т е не зная причину Вы блокируете сообщение об ошибке. полный дилетантизм.
зачем закрывать окно и в колбеке и в main? ---------------------------- function OnStop(flag) pcall(closeWindow) interrupted = true end
function main() message("STARTED", 1) while not interrupted do run() if flag then sleep(0) end end pcall(closeWindow) message("SHUTDOWN", 1) end ====================
читайте внимательно документацию прежде чем писать тесты. ---------------- Например, OnStop - Функция вызывается терминалом QUIK при остановке скрипта из диалога управления и при закрытии терминала QUIK.
Функция возвращает количество миллисекунд, которое дается скрипту на завершение работы.
Если функция не возвращает число, то таймаут завершения работы скрипта остается равным 5 секундам.
По истечении интервала времени, данного скрипту на завершение работы, функция main() завершается принудительно. При этом возможна потеря системных ресурсов.
=======================
Т е Вам дали время на завершение потока майн
Там и надо закрывать окна. А Вы делаете это в колбеке.
nikolz написал: Предположу, что это ошибка автора скрипта, так как в нем не учитывается многопоточность.
Филосов :: . Укажите конкретно в чем ошибка автора. --- Ошибки автора нет. Есть ошибка в QUIK, состоящая в том, что длинные участки фрагментов кода скрипта на "чистом Lua" (без вызова C-функций) блокируют переключение потоков обслуживающего колбеки и выполняющего main. Я не буду повторять свои комментарии по этому поводу. Читайте форум.
ошибка автора в отсутствии знаний. И Ваша тоже так как Вы пишите про "чистый луа" который существует лишь в виде функций на чистом СИ. Это профанация и дилетанты вам верят.
_sk_ написал: 1) В числах разделитель разрядов должен быть точкой. 2) Если после знака равно стоит строка, её надо взять в кавычки. 3) В самом конце строк таблицы stop нужны запятые, а не точки с запятой, как сейчас в некоторых местах. 4) TRANS_ID должно быть числом.
Спасибо. Я имел ввиду сделать из вышенаписанного кода массив для sendtransaction?
для этого надо все параметры записать либо в кавычках либо с помощью функции tostring()
_sk_ написал: Берём следующий скрипт. Если в первой строке стоит flag = true, то скрипт нормально запускается и останавливается из меню скриптов. Если в первой строке поставить flag = false, происходит зависание терминала при остановке скрипта. В зависимости от значения переменной flag либо имеется sleep(0) в функции main(), либо отсутствует на пути выполнения кода.
У меня зависание воспроизводится в терминалах версий 10.0.0 и 10.0.1.
Три вопроса: 1) Может ли кто-то ещё подтвердить, что зависание происходит (чтобы исключить особенность моего компьютера)? 2) Знает ли кто-то причину такого поведения? 3) Что разработчики терминала могут сказать по этому поводу?
Сам скрипт:
Код
local flag = true -- если установить в false, то при остановке скрипта происходит зависание (убирается sleep(0) в функции main)
local foregroundColor = RGB ( 0 , 0 , 0 )
local backgroundColor = RGB ( 192 , 255 , 192 )
local interrupted = false
local tableId
local function setTableColors (foregroundColor, backgroundColor)
local nRows, nCols = GetTable Size (tableId)
if nRows and nCols then
for row = 1 , nRows do
for col = 1 , nCols do
SetColor (tableId, row, col,
backgroundColor, foregroundColor,
backgroundColor, foregroundColor)
end
end
end
end
local function ensureWindowOpened ()
if tableId = = nil then
return
end
if IsWindowClosed (tableId) then
CreateWindow (tableId)
SetWindowPos (tableId, 0 , 0 , 300 , 100 )
SetWindowCaption (tableId, "hang_test" )
InsertRow (tableId, 1 )
InsertRow (tableId, 2 )
SetCell (tableId, 1 , 1 , "11" )
SetCell (tableId, 1 , 2 , "12" )
SetCell (tableId, 2 , 1 , "21" )
SetCell (tableId, 2 , 2 , "22" )
SetSelectedRow (tableId, 1 )
end
setTableColors(foregroundColor, backgroundColor)
end
local function closeWindow ()
local t = tableId
tableId = nil
if t then
DestroyTable (t)
end
end
function OnInit (scriptPath)
tableId = AllocTable ()
AddColumn (tableId, 1 , "col1" , true , QTABLE_STRING_TYPE, 5 )
AddColumn (tableId, 2 , "col2" , true , QTABLE_STRING_TYPE, 5 )
SetTableNotificationCallback (tableId, function (tId, msg, par1, _)
if msg = = QTABLE_SELCHANGED then
SetSelectedRow (tId, 1 )
end
end )
ensureWindowOpened()
end
local function run ()
ensureWindowOpened()
if tableId then
SetSelectedRow (tableId, 2 )
end
end
function OnStop (flag)
pcall(closeWindow)
interrupted = true
end
function main ()
message ( "STARTED" , 1 )
while not interrupted do
run()
if flag then
sleep ( 0 )
end
end
pcall(closeWindow)
message ( "SHUTDOWN" , 1 )
end
причина зависания вероятнее всего в том, что функция main будет исполнена один раз до загрузки всех необходимых для корректной работы данных. Предположу, что это ошибка автора скрипта, так как в нем не учитывается многопоточность.
Sergey Gorokhov, По большому счету так как каналы связи без проблем - оптика 100 Мбод, а сервер и терминалы - это ваше произведение , то хрень тоже Ваше произведение .
сегодня у сбера вообще полный .... подключение к серверу есть работает стакан и TTT -------------- но не работают графики и ГЛАВНОЕ нет фирмы брокера - т е сбербанка и следовательно нет никакого портфеля ------------------
nikolz написал: пардон, поправлю, интенсивно создаете объекты или расширяете таблицы, но не уничтожаете не нужные объекты
Так и не смог найти причину, так как ошибка плавающая. Переписал код по другому - ошибка исезла. Все таки гарантировано, что это проблема в Квике не могу на данный момент сказать.
Рекомендую по возможности не создавать новые таблицы вместо старых, а просто очищать старые. В итоге у вас не будет объектов для уничтожения и частое обращение к куче за новым блоком памяти.
Дмитрий написал: Не могу нигде найти описание ошибки "attempt to perform arithmetic on a table value" - в переводе "попытка выполнить арифметику над табличным значением". Ну а почему нельзя выполнить арифметику над табличным значением? Или что имеется ввиду?
скорее всего, значение таблицы не является числом. Возможно что это либо функция либо таблица. покажите скрипт, если хотите помощь.
nikolz написал: и откуда взялся график после экспирации GAZR-12.22?
мне хотелось бы отобрзить после даты экспирации GAZR-12.22 графики: 1) историю цены GAZR-12.22 до его собственной экспирации 2) историю цены GAZR-03.23 и др. до даты экспирации GAZR-12.22 и после
Возможно не понял, но после экспирации фьючерса его нет, т к он выполнен. --------------- Зачем Вам это, если не секрет. По-моему мнению это не имеет практической пользы.
Шорты осиновые написал: 1. Как можно отобразить график фьючерса с истекшим сроком действия? 2. При замене истекшего инструмента, напрмер GAZR-12.22 на GAZR-03.23, склеиваются графики не GAZR-12.22 + GAZR-03.23, а части графиков GAZR-03.23 до и после экспирации GAZR-12.22?
и откуда взялся график после экспирации GAZR-12.22?