Добрый день. Заметил странность в работе math.ceil(). Почему math.ceil(14.0)=14, а math.ceil(15.0)=16?
Для выставления цены с заданным количеством знаков после запятой, использую округление:
Код
function round_step_price(price, ty)
local x=0
if (ty=="sell") -- Продаем ->округлить в бОльшую сторону
x= math.ceil(price/options.price_step) * options.price_step
else -- Покупаем - округлим в меньшую сторону
x= math.floor(price/options.price_step) * options.price_step
end
return x*1
end
Задача, при шаге цены 0.1, для продаж округлять так: 1.400 ->1.4, 1.4001 ->1.5, и так же 1.50->1.5, 1.50001->1.6. Но мой код, не работает, как ожидалось.
Как вы округляете в большую/меньшую сторону, с заданным количеством десятичных знаков?
nikolz написал: Можете привести оценку скорости обучения для каких либо примеров и сравнение скорости например с факелом.
Я пока сравнивал только с такой же нейронкой на C#. На шарпе сильно медленней работает. Скорость и качество обучения зависит от параметра "e". Сейчас эксперементирую с изменением "е" во время обучения в зависимосит от средней квадратической ошибки.
В NeuralNetwork.Training первые строки до коммента "--Теперь правим веса": ошибки(delta) собираются в обратной порядке: выходной слой, далее остальные(for tmpl =self.layers-1, 1, -1 do -- слои) до первого.
Всем привет. Сделал нейронку на LUA. Может кому пригодится:
Код
NeuralNetwork = {}
NeuralNetwork.__index = NeuralNetwork
function NeuralNetwork.new(inputs, layers, neyrons) -- Инициализация
local self = setmetatable({}, NeuralNetwork)
self.layers=layers -- слоев
self.inputs=inputs -- входов
self.neyrons=neyrons --нейронов в слое
self.k=0.5
self.e=0.01 -- Скорость обучения
self.im=0.01 -- импульс
self.traininig_count=0 --Будем считать обучения
self.w={}
self.nout={}
self.dw={}
self.delta={}
self.w[1]={}
self.nout[1]={}
self.dw[1]={}
self.delta[1]={}
local i
local l
for i = 1, self.neyrons, 1 do
self.w[1][i]={}
self.dw[1][i]={}
self.delta[1][i]={}
self.nout[1][i]={}
for ii = 1, self.inputs+1, 1 do
self.w[1][i][ii]=math.random()
self.dw[1][i][ii]=0
end
end
for l = 2, self.layers, 1 do --перебор остальных слоев
self.w[l]={}
self.dw[l]={}
self.delta[l]={}
self.nout[l]={}
for i = 1, self.neyrons, 1 do
self.w[l][i]={}
self.dw[l][i]={}
self.delta[l][i]={}
self.nout[l][i]={}
for ii = 1, self.neyrons+1, 1 do
self.w[l][i][ii]=1*math.random()
self.dw[l][i][ii]=0
end
end
end
--Выходной нейрон
self.w[self.layers+1]={}
self.dw[self.layers+1]={}
self.w[self.layers+1][1]={}
self.dw[self.layers+1][1]={}
self.delta[self.layers+1]={}
self.delta[self.layers+1][1]={}
for ii = 1, self.neyrons+1, 1 do -- +w0
self.w[self.layers+1][1][ii]=1*math.random()
self.dw[self.layers+1][1][ii]=0
end
return self
end
function NeuralNetwork.Save(self, filename)
local f,err = io.open(filename,"w")
if not f then
return false
end
f:write(table.tostring(self))
f:close()
return true
end
function NeuralNetwork.Load(self, filename)
local f,err = io.open(filename,"r")
if not f then
return false
end
local tbl = assert(load("return " .. f:read("*a")))
f:close()
for k,v in pairs(tbl()) do
if (type(v)=="table") then
self[k]=table_copy(v)
else
self[k] = v
end
end
return true
end
function NeuralNetwork.Training(self, data, res) --Одно обучение
self.traininig_count=self.traininig_count+1 -- счетчик обучений
local nres=self:Play(data) --Свой результат
self.delta[self.layers+1][1]=(res-nres) --Начинаем с выходного слоя
for tmpi = 1, self.neyrons, 1 do -- последний перед выходом слой
self.delta[self.layers][tmpi] = self.w[self.layers + 1][1][tmpi] * self.delta[self.layers + 1][1]*dsigmoda(self.nout[self.layers][tmpi], self.k)
end
for tmpl =self.layers-1, 1, -1 do -- слои
for tmpn = 1, self.neyrons, 1 do-- нейроны в слое
self.delta[tmpl][tmpn] = 0
for tmpi = 1, self.neyrons, 1 do
self.delta[tmpl][tmpn] = self.delta[tmpl][tmpn] + (self.w[tmpl + 1][tmpi][tmpn] * self.delta[tmpl + 1][tmpi])
end
self.delta[tmpl][tmpn] = self.delta[tmpl][tmpn] * dsigmoda(self.nout[tmpl][tmpn],self.k)
end
end
--Теперь правим веса
--Правим в первом/входном слое *************************** первый(0) *************************************
for tmpn = 1, self.neyrons, 1 do -- нейроны в слое
self.dw[1][tmpn][self.inputs + 1] = (self.e * self.delta[1][tmpn] * (1 - self.im)) + (self.im * self.dw[1][tmpn][self.inputs + 1])
self.w[1][tmpn][self.inputs + 1] = self.w[1][tmpn][self.inputs + 1] + self.dw[1][tmpn][self.inputs + 1]
for tmpi = 1, self.inputs, 1 do -- нейроны в слое
self.dw[1][tmpn][tmpi] = (data[tmpi] * self.e * self.delta[1][tmpn] * (1 - self.im)) + (self.im * self.dw[1][tmpn][tmpi])
self.w[1][tmpn][tmpi] = self.w[1][tmpn][tmpi] + self.dw[1][tmpn][tmpi]
end
end
--Остальные слои
for tmpl = 2, self.layers, 1 do
for tmpn = 1, self.neyrons, 1 do
self.dw[tmpl][tmpn][self.neyrons + 1] = (self.e * self.delta[tmpl][tmpn] * (1 - self.im)) + (self.im * self.dw[tmpl][tmpn][self.neyrons + 1])
self.w[tmpl][tmpn][self.neyrons + 1] = self.w[tmpl][tmpn][self.neyrons + 1] + self.dw[tmpl][tmpn][self.neyrons + 1]
for tmpi = 1, self.neyrons, 1 do --нейроны в слое
self.dw[tmpl][tmpn][tmpi] = (self.nout[tmpl-1][tmpi] * self.e * self.delta[tmpl][tmpn] * (1 - self.im)) + (self.im * self.dw[tmpl][tmpn][tmpi])
self.w[tmpl][tmpn][tmpi] = self.w[tmpl][tmpn][tmpi] + self.dw[tmpl][tmpn][tmpi]
end
end
end
-- Выходной слой из одного нейрона
self.dw[self.layers+1][1][self.neyrons + 1] = (self.e * self.delta[self.layers + 1][1] * (1 - self.im)) + (self.im * self.dw[self.layers + 1][1][self.neyrons + 1])
self.w[self.layers+1][1][self.neyrons + 1] = self.w[self.layers + 1][1][self.neyrons + 1] + self.dw[self.layers + 1][1][self.neyrons + 1]
for tmpi = 1, self.neyrons, 1 do -- нейроны в слое
self.dw[self.layers + 1][ 1][tmpi] = (self.nout[self.layers][tmpi] * self.e * self.delta[self.layers + 1][1] * (1 - self.im)) + (self.im * self.dw[self.layers + 1][1][tmpi])
self.w[self.layers + 1][1][tmpi] = self.w[self.layers + 1][1][tmpi] + self.dw[self.layers + 1][1][tmpi]
end
end
function NeuralNetwork.Play(self, tick_data) -- Принятие решения
local l
local n
local i
for l = 1, self.layers, 1 do -- проход по всем слоям, 1 - входной слой
for n = 1, self.neyrons, 1 do
local mmax
if (l==1) then --входной слой
self.nout[l][n]=1*self.w[l][n][self.inputs+1] --W0 последний
mmax=self.inputs
else
self.nout[l][n]=1*self.w[l][n][self.neyrons+1] --W0 последний
mmax=self.neyrons
end
for i = 1, mmax, 1 do
if (l==1) then --входной слой
self.nout[l][n]=self.nout[l][n]+(tick_data[i]*self.w[l][n][i]) --W0 последний
else
self.nout[l][n]=self.nout[l][n]+(self.nout[l-1][i]*self.w[l][n][i]) --W0 последний
end
end
self.nout[l][n]=sigmoda(self.nout[l][n], self.k)
end
end
--Выходной нейрон
self.nout[self.layers+1]=self.w[self.layers+1][1][self.neyrons+1] --W0
for i = 1, self.neyrons, 1 do
self.nout[self.layers+1]=self.nout[self.layers+1]+(self.nout[self.layers][i]*self.w[self.layers+1][1][i])
end
return sigmoda(self.nout[self.layers+1], self.k)
end
function dsigmoda(x, k)
local r
r = k * x * (1 - x)
return r
end
function sigmoda(x, k)
local r
r = 1 / (1 + math.exp(-x * k))
return r
end
function table_copy(originalTable)
local copyTable = {}
for k,v in pairs(originalTable) do
if (type(v)=="table") then
copyTable[k]=table_copy(v)
else
copyTable[k] = v
end
end
return copyTable
end
Пример:
Код
--Обучающие данные
local TrainingData={}
for i=1, 100, 1 do
local d1=math.random() -- Обучающие данные
local d2=math.random() -- Обучающие данные
local result=0 -- Правильный ответ
if (d1>d2) then
result=1
end
local td={d1, d2, result}
TrainingData[#TrainingData+1]=td
end
--Обучение
local nn=NeuralNetwork.new(2, 3, 3)
for age=1, 100, 1 do -- Эпохи
for i=1, #TrainingData, 1 do
local td=TrainingData[i]
nn:Training(td, td[#td])
end
end
--Проверка
local d1=math.random()
local d2=math.random()
td={d1, d2}
local result=nn:Play(td)
PrintDbgStr(d1.." "..d2.." "..result)
--Сохраним обученную нейронку
fn=getScriptPath().."\\test.nn"
nn:Save(fn)
Добрый день! Вчера, начиная с 18:20 не выставлялись заявки на срочном рынке, при этом терминал никаких ошибок не выдавал(но заявки в таблице заявок не появлялись), свечи обновлялись. sendTransaction ошибок не выдавал. OnTransReply - тоже ничего не зафиксировал, как будто заявок и не было. В 18:44 попытался выйти в деньги и выставить заявку вручную - тоже не получилось. В 19:00 посыпались ошибки "невозможно выставить заявку т.к. сессия неактивна". Брокер(Альфа-директ) сообщил, что у них всё работало штатно, проблема, вероятно, с моей стороны. Что это могло быть, и как избежать подобных ситуаций.
Посоветуйте, пожалуйста, мощный редактор для LUA. Есть что-то типа PhpStorm, чтобы можно было работать с проектом из нескольких файлов, с навигацией внутри проекта (например, переход к процедуре при нажатии на ее имя с Ctrl), с закладками и подсветкой кода? Идеально, если бы еще ошибки LUA подсвечивались.
Сейчас использую Notepad++ с плагином, но в нем нет никакой навигации.
local test_tab={}
if (test_tab[0]==nil) then
say("1")
else
say("2")
end
Однако всё работает. Результат "1". Подозреваю, что getCandlesByIndex - иногда выдает не таблицу, и тогда #tab2~=0 - тоже выдаст ошибку. Видимо, в моем случае, надо перед проверкой индекса так же добавить проверку на тип "table".
Игорь Б написал: В справке по Qlua, к сожалению, не указано, что возвращается в случае не получения данных данной функции.Я при проверке этой функции сравниваю получаемую таблицу и ее значения не с nil, а с false (т.е. if (not tab2) и if (not tab2[0])).Пока работает.
Спасибо, попробую Ваш вариант. Странно, что вообще это происходит днем, когда свечи есть.
Здравствуйте! Есть функция чтения последней свечи, которая несколько лет работала стабильно, но последнее время, раз в несколько дней выдает ошибку(хотя свечи на графике есть). Функция читает таблицу с одной последней свечой в tab2. Иногда при попытке обратиться к таблице по индексу " if (tab2[0]==nil) then " - вылетает ошибка "attempt to index a function value (local 'tab2')" Добавил проверку tab2==nil, и она в момент ошибки не срабатывает, т.е. tab2 - задана.
Код
function last_condle() -- самая последняя свеча
local tmp_max=getNumCandles(options.future.."_price")
local tab2, n1, tmpname=getCandlesByIndex(options.future.."_price", 0,tmp_max-1, 1)
-- Костыль №1
if (tab2==nil) then
say(" Ошибка 1748 - нет данных!!! - входим в режим ожидания данных tmp_max="..tmp_max)
while (tab2==nil) do
sleep(731)
tab2, n1, tmpname=getCandlesByIndex(options.future.."_price", 0,tmp_max-1, 1)
end
end
-- Костыль №2
if (tab2[0]==nil) then -- Тут иногда ошибка "attempt to index a function value (local 'tab2')"
say(" Ошибка 1739 - нет данных!!! - входим в режим ожидания данных tmp_max="..tmp_max)
while (tab2[0]==nil) do
sleep(731)
tab2, n1, tmpname=getCandlesByIndex(options.future.."_price", 0,tmp_max-1, 1)
end
end
return tab2[0]
end
Если я правильно понимаю, LUA считает что tab2 - функция? Но getCandlesByIndex не должен функий выдавать. Как это вылечить?
function table_copy(originalTable)
local copyTable = {}
for k,v in pairs(originalTable) do
if (type(v)=="table") then
copyTable[k]=table_copy(v)
else
copyTable[k] = v
end
end
return copyTable
end
Здравствуйте! Нужно скопировать таблицу, так, чтобы изменения сделанные в дубликате не отображались в оригинальном экземпляре. Использую для этой цели рекурсивную функцию, но связь сохраняется.
Код
function main()
local t1={}
t1.x={}
t1.x.y=1
local t2=table_copy(t1)
t2.x.z="Hi!"
PrintDbgStr(""..t1.x.z)
end
function table_copy(originalTable)
local copyTable = {}
for k,v in pairs(originalTable) do
if (type(v)==table) then
copyTable[k]=table_copy(v)
else
copyTable[k] = v
end
end
return copyTable
end
Ночью пропадают во второй вкладке некоторые графики и таблицы (состояние счета рынка ценных бумаг, диаграммы акций) и не восстанавливаются после подключения. «Обновить» - не помогает. Помогает только перезагрузка. При этом в первой вкладке диаграммы инструментов и состояние счета срочного рынка обновляются корректно.
Quik 8.11.0.66 В настройках стоит интервал обновления данных с текущим состоянием 10с, в котировках включен "умный" заказ данных.
swerg написал: Дополнительные DLL библиотеки используются?
Дополнительные DDL библиотеки не использую. В этом же терминале у меня 6-7 ресурсоемких(постоянные циклы с вычислениями) скриптов работают, возможно в этом причина. Хотя, ошибка вылезла в скрипте, который не нагружает процессор и использует мало памяти. Раньше я и по 12-16 скриптов с обучением нейросетей запускал, процессор загружал до 100% на несколько недель, но такой ошибки не было.
Здравствуйте! В рабочем скрипте раз в несколько дней возникает ошибка: Critical error ACCESS_VIOLATION in script. Quik 8.11.0.66 Номера строки с ошибкой нет. Запустить скрипт заново невозможно, без перезапуска Quik. Тот же скрип работает без ошибок на другом компьютере у другого брокера (Quik 9.2.3.15)
Evgeniy Karnaukhov написал: В таком случае, как и ранее, просьба прислать скриншоты, на которых подобное поведение будет явно видно.
Вот еще сегодняшние скриншоты. До перезагрузки(13:59) Quik показывает на 10 фьючерсов меньше, чем на самом деле. После перезагрузки программы (14:04) - количество фьючерсов корректное +15. Видно, что сделок в указанный период не было
Evgeniy Karnaukhov написал: В таком случае, как и ранее, просьба прислать скриншоты, на которых подобное поведение будет явно видно.
Сегодня день начинал в деньгах. После нескольких сделок, реально на счете 2 фьчерса Sim1 (это можно посчитать по сделкам). Скрипты LUA видят реальный остаток (+2 фьючерса). Однако, квик показывает -8. Ошибка с отображением обычно появляется, когда скрипты часто снимают и выставляют заявки.
Правильно понимаем, что параметр "Позиция" изменяется некорректно? Просьба, при повторном наблюдении подобных эффектов, прислать скриншоты (снимки экрана) таблицы состояния счета до совершения какой-либо сделки и после , чтобы было видно, на какое количество параметр "Позиция" должен был измениться, и на какое количество он изменился .
Да, параметр "Позиция" иногда отображает некорректную информацию. Например, сегодня должен был измениться с "0" на "2", однако изменение было с "0" на "4"(возможно поэтапное, я заметил уже результат).
Последнее время все чаще в Состоянии счета отображается некорректная информация по количеству позиций. Например, сегодня скрипт на LUA купил 2 фьючерса, а в позициях отображается 4. В данный момент QUIK v. 8.8.4.3. win10. Такие же проблемы наблюдались и на более ранних версиях QUIK.
Похоже на то, что задваиваются(иногда затраиваются) совершенные сделки, либо учитываются снятые заявки… После перезапуска QUIK информация отображается корректно.
В тоже время, количество позиций getItem( в LUA) возвращает корректное.
Nikolay написал: local function round(num, idp) if num then local mult = 10^(idp or 0) 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
Тоже самое, при вызове round(55.3, -2) в результате мусор в районе 15-го знака после запятой. Я так понимаю, этот мусор "не лечится", исходя из самих принципов хранения вещественных чисел. Поэтому сейчас в код добавил некую погрешность pogr, которая меньше шага цены, но больше возможного "мусора". if (x1+pogr>x2) then , В итоге (55.3+0.00001>=55.3) -> верно.
Попробовал найти разницу между x1 и x2, вот результат: x=-7.105427357601e-15 А вот, как выглядят вещественные числа в 17 знаками после запятой: x1=55.30000000000000426 x2=55.29999999999999716 x1*10=553.00000000000000000 x2*10=553.00000000000000000 В общем, проблема понятна... В качестве решения, первое что приходит в голову: использовать условия только "больше"/"меньше" без равенств, и добавить некую погрешность(меньше шага цены) local pogr=0.001 if (x1>x2+pogr) then ...
Владимир написал: Сергей, Скорее всего, никакой ошибки нет, поскольку на самом деле числа там что-то вроде 55.30001 и 55.29999 или что-то в этом роде. а вот "переводить в целые и работать в целых" не получится - никаких целых в этом языке просто нет. ::
Тогда, что значит "на самом деле" ? В лог файле они именно как 55.3 пишутся, без всяких хвостов и "-e". И если нет никаких целых, то почему два новых числа, полученные путем умножения старых на 10, сравниваются иначе?
Добрый день! Посоветуйте пожалуйста брокеров поддерживающих Quik. Надежных(в техническом плане), ну и с адекватными тарифами.
Ранее я имел негативный опыт работы с ВТБ - они заблокировали счет без объяснения. Средства смог вывести с большим гемороем. В данный момент на альфа-директе. Часто Quik отваливается(сейчас например "Удаленный хост принудительно разорвал...", а я торгую между прочим). Иногда свечи не приходят по несколько минут. а потом вываливаются кучей.
qt написал: Открываю файл в блокноте и запись прекращается. Как открыть файл на запись чтобы можно было читать?
Добрый день. Я пишу в файл так. При этом запись продолжается, если открыть файл сторонними программами, типа блокнота.
Код
function save_log(st)
local path=getScriptPath().."\\"..options.script_name..".log"
local fn=io.open(path, "a") -- a-дозапись, w-перезапись, r-чтение
fn:write(st.."\n")
fn:close()
end
Anton написал: Не стоит, это приведет к тому, что процессор будет молотить на полной частоте вхолостую, греться только и ничего более. Что-то другое должно быть.
Как ни странно, выставление этого параметра на 100% - помогло. И при отсутствии нагрузки процессор не греется. Буду еще экспериментировать с промежуточными значениями.
Anton написал: В настройках энергосбережения посмотрите "дополнительно"
Возможно Вы правы. Прошелся еще раз по этим настройкам, одна очень подозрительная: "Минимальное состояние процессора - 5%". Описания о том как, когда и что именно устанавливается на 5% сходу нагуглить не смог. Попробую выставить этот параметр на 100%.
Anton написал: Погуглите away mode, не оно ли часом.
Погуглил, не оно. У меня ни в реестре, ни в настройках упоминаний этого режима нет. Да и "сон" в энергосбережении вообще отключен. Как будто это какая-то бага/фича винды, которая анализирует пользовательскую(а может еще какую) активность и снижает приоритет.
Скрипты LUA запускаю с вечера. Обнаружил, что утром, пока ноутбуком не пользуюсь (погашен экран), на скрипт LUA выделяется очень мало процессорного времени. Например, вывод 20-ти строк в файл занял 4-5 минут(!), обнаружение появления новой свечи срабатывало раз из 7-10 положенных. В итоге скрипт не выставляет своевременно заявки. После того, как я сажусь за ноутбук – всё работает корректно.
У меня Quik 7.27.2.1, windos 8.1, i7, спящий режим и режим гибернации – отключены, экранной заставки нет, есть только "погасить экран". Подскажите, как настроить, чтобы LUA скрипты не обделялись процессорным временем?
Добрый день. Только что MA(периодов 2, метод Vol Adjusted, поле цены Close) на фьючерсе сбера показал аномально-высокое значение. На 150р выше всех ближайших свечей. Фото прилагается. Это глюк?
Вопрос по комиссии биржи. С брокером-то всё просто(уже звонил им) - брокер дублирует комиссию биржи. На сайте МБ непонятно, по крайней мере для новичка. В некоторых примерах расчета в интернете комиссия берется с каждого фьючерса, но этим примерам уже более 5 лет.
Цитата
Anna Lozenko написал: Комиссия взымается за каждую свершенную сделку, в независимости от количества инструментов в заявке.
Т.е. не важно сколько фьючерсов покупаю/продаю за один раз, комиссия всё равно будет 1,74р (ну или какая-то другая, назначена биржей на данный момент) ?
Добрый день! Отправляю из LUA заявку на покупку фьючерса и получаю ошибку Не найдено поле "Лоты" для транзакции "Ввод заявки" по классу "FORTS: Фьючерсы" Вот код:
Видимо да. Получается внутрь свечи стандартным EMA не влезть. Я в итоге свою EMA написал: через заданный период беру LastPrice и далее по стандартной формуле: self.value=(self.Alfa*price)+((1-self.Alfa)*self.last_value)
Коллеги, посоветуйте, пожалуйста, инструмент, который бы отображал среднее значение цены в не закрывшейся свече по принципу EMA. Т.е. была бы средняя цена всех тиков, и при этом цена последнего тика имела бы более высокий вес.
Визуально, очень похоже на то, что мне нужно - EMA с периодом 1 и с полем цены Typical. Или экспоненциальное вычисление там только для периодов 2 и более, а в рамках одной свечи простое усреднение(SMA) по всем тикам? Кто-то знает по какой формуле этот инструмент вычисляется в рамках не закрывшейся свечи?
В скрипте поменял ma1 на последнюю цену одноминутной свечи - всё заработало с точностью до тысячных, что вполне устраивает. Задача решена.
Цитата
Anton написал: Довольно геморройным. Рассматриваем емашку как БИХ-фильтр первого порядка, определяем круговую частоту среза для заданного периода, денормируем на текущую частоту дискретизации (на пятиминутках это 1/(5*60) Гц), получаем частоту среза в герцах, нормируем на частоту дискретизации минуток (1/60 Гц), получаем круговую частоту среза на минутках, и самый гемор из нее выводим период емашки для минуток. В принципе, можно технологию упростить, повозившись с формулами, но тут уже из разряда шашечки или ехать, быстрей было таким образом, чем математические исследования затевать. Там еще обнаруживается такая вещь, что с ростом периода исходной емашки рассчитанный период постепенно приближается к ожидаемому 5x. На заданных же малых периодах оказывается настолько ниже ожидаемого, поскольку, строго говоря, емашка с периодом 2 (и альфой 0.66) находится выше частоты Найквиста и усредняет уже "неизвестно что", кашу из реальных значений и отраженных высших гармоник. У емашки 4 ситуация получше. Впрочем, сама нарезка на свечи без предварительной фильтрации (как требует теорема Котельникова) уже создает довольно-таки кашу в спектрах.
Круто. Действительно EMA по закрывающей цене на малых периодах напоминает "цену на яблоки в дождливый день" )
Спасибо за код, завтра проверю (сейчас имел неосторожность перезаказать данные, а сервер не алё). На самом деле, мне графическое отображение не так важно. Нужны значения. В скрипте я попытался воссоздать значения MA пятиминутного графика: ma4s – это итоговое значение закрывшейся пятиминутной свечи, а ma4 – значение незакрытой свечи в момент, когда минутная свечка внутри неё закрылась, т.е. значения которые мы видим, пока свеча не закрылась. Посмотрел на C(idx) в вашем коде и, кажется, понял, где я накосячил: в v, видимо, должна быть цена закрытия свечи, а я нагородил там велосипедов – MA с периодом 1 влепил.
Цитата
Anton написал: Пересчитал периоды емашек 2 и 4 с пяти минут на минуту, получаются такие периоды:M5 EMA(2) -> M1 EMA(8.205459971)M5 EMA(4) -> M1 EMA(19.18033544)
В общем, проверил на имеющихся реальных значениях. Значения не совпадают, причем существенно. В качестве ma1s - пробовал брать ma с периодом 1 с разными настройками -никакие не дали желаемого результата. Еще вопрос к алгоритму: может после каждого вычисления значения "в моменте" price_con[i+sdvig].ma4=(alfa4*(ma1s))+((1-alfa4)*last_ma4_t5) - это значения и становиться последним. Т.е. надо дописать в следующей строке last_ma4_t5=price_con[i+sdvig].ma4. Хотя так тоже, значения не те получаются. Может туда вообще цены всех сделок пишутся?
Открытый вопрос: как по данным с минутном графика самому рассчитать MA пятиминутного графика.
Я потом и сам понял, что графики "такие же" никогда не получатся.
Мне на самом деле нужно вот что: история минутных свечей, где-то 6-7 мес, и для проверки алгоритма, потребовались дополнительно MA с пятиминутного графика. А на 5-мин истории не оказалось. Помогла бы подкачка данных в Quilk на пятиминутный график, но поддержка Альфы не знает, как это сделать. Я тоже(((
Сегодня я в LUA скрипт сделал, который рассчитывает и добавляет к минутным свечкам значения MA (как бы с пятиминутного графика). Есть сомнения в корректности вычислений. Буду благодарен за замечания.
Например, не уверен, в том, насколько корректно брать среднее ценовое значение минутной свечи из минутного MA с периодом 1.
Код
function add_five_ma() -- Добавим к минутным свечам price_con значение 5-ти минутных ma
local count
local alfa2=1*2/(1+2)
local alfa4=1*2/(1+4)
--в ma4s к минутным свечам добавляем значение ma с интервалом 4 пятиминутного графика, которое соответствует исторической свече
--в ma4 запишем значения ma с пятиминутного графика, которые видно на графике в моменте (т.е. когда минутная свеча завершена, а
-- 5-минутная еще нет "дыхание" )
--Начальные значения - SMA
count=0 --индекс одноминутных свечей в таблице price_con
sum_m1=0 -- сумма минутных ma1 (это же средняя цена свечи???)
for i=1, 4, 1 do -- в первые 3 пятиминутные свечи пишем 0, в 4ю обычное SMA
for j=1, 5, 1 do -- перебор одноминутных свечей
price_con[count].ma4s=0
price_con[count].ma4=0
sum_m1=sum_m1+ma1[count].high
count=count+1
end
end
--четвертая пятиминутка на одноминутных свечах
local ma4s=sum_m1/count
for j=1, 5, 1 do -- перебор одноминутных свечей
price_con[14+j].ma4s=ma4s
price_con[14+j].ma4=0
sum_m1=sum_m1+ma1[count].high
count=count+1
end
local last_ma4_t5=ma4s -- предыдущее значение ma4
count = 1 --счетчик одминуных свечей (1..5)
local ma1s=0
-- Далее перебор всех одноминутных свечей, кроме уже заданных первых 20ти (0..19)
for i=20, min_len-1, 1 do -- перебор минутных свечей
price_con[i].ma4s=0 --определим для последних, попавших в незакрытую 5мин свечу
ma1s=((ma1s*(count-1))+ma1[i].high)/count --средняя цена в моменте (в незакрытой 5-ти минутной свече) (сумма минутных ma1)
price_con[i].ma4=(alfa4*(ma1s))+((1-alfa4)*last_ma4_t5) --значение в моменте ("дыхание")
if (count==5) then -- Закончилась 5-ти мин. свеча - занесем итоговое значение ma4 в ma4s
for j= 0, -4, -1 do
price_con[i+j].ma4s=price_con[i].ma4 -- итоговое значение
end
count = 0
last_ma4_t5=price_con[i].ma4 --для следующе свечи
end
count=count+1
end
end
Пояснение к коду: price_con – минутные свечи, к которым дописываем два свойства: ma4s –значение MA пятиминутной свечи в которую входит минутная(данное значение должно соответствовать тому, которое в это время выдавала бы MA с пятиминутного графика ), ma4 – это значение в моменте(когда минутная свеча закрылась, а соответствующая 5-ти мин. свеча еще нет). Каждым пяти одноминутным свечам, начиная с 0, соответствует одна воображаемая пятиминутная свеча.
За начальное значение для EMA – принимает среднее арифметическое.
Помогите разобраться: есть график с интервалом 5 мин, на нем два Moving Average с количеством периодов 2 и 4, оба Exponencial, поле цены Close. Нужно получить такие же (т.е. чтобы значения в одно и тоже время совпадали с MA на 5-ти минутке) на графике с интервалом 1 мин.
Простое увеличение периодов MA на минутном графике до 10 и 20 не приносит желаемого результата. Есть идеи?