local num = getNumCandles(graphId)
local candles, num, _ = getCandlesByIndex(graphId,0,0,num)
Возникают две проблемы, которые есть суть одной. Если вот так я хочу перебрать внутри свечки все значения с минимальным шагом инструмента (MinPriceStep), то...
Код
for z = candles[i].low, candles[i].high, MinPriceStep do
...то: 1. candles[i].low фьючерса нефти, например, может оказаться такой: 73.270000000001 при шаге цены 0.01 2. в результате такой штуки цикл регулярно выполняется на итерацию меньше (что, в общем, понятно, когда low или high на 0.00000000001 больше или меньше допустимой
Как бы вопрос-то сформулировать... ЧТО ЗА ФИГНЯ?! :)
Сергей, как корректно округлить до нужного знака, чтобы в итоге не получить новое подобное число? Насколько плохая идея использовать в таблицах индексы в виде чисел с плавающей точкой?
sergei написал: Насколько плохая идея использовать в таблицах индексы в виде чисел с плавающей точкой?
Вопрос не понятен, просьба уточнить подробней что имеется ввиду, можно на примере.
Код
for z = candles[i].low, candles[i].high, MinPriceStep do
ZZZ[z] = ZZZ[z] + что-то
end
Сейчас мне кажется, что подобные конструкции совершенно непредсказуемы, т.к.
z может принимать значения на 0.000000000001 больше или меньше ожидавшегося, в результате чего вместо суммирования значений в одном ZZZ[67.55] мы можем получить до трех или более разных ZZZ: ZZZ[67.5499999999999], ZZZ[67.55], ZZZ[67.5500000000001]
for z = candles[i].low, candles[i].high, MinPriceStep do
Код
ZZZ[z] = ZZZ[z] + что - то
end
Сейчас мне кажется, что подобные конструкции совершенно непредсказуемы, т.к.
z может принимать значения на 0.000000000001 больше или меньше ожидавшегося, в результате чего вместо суммирования значений в одном ZZZ[67.55] мы можем получить до трех или более разных ZZZ: ZZZ[67.5499999999999], ZZZ[67.55], ZZZ[67.5500000000001]
Кроме того, еще и ошибки полезут, когда ZZZ[z] внезапно окажется nil вопреки ожиданиям
graphId = "BRK9"
candleCount = 100
MinPriceStep = 0.01
function math.round(value, p)
local e = 10 ^ (p or 0)
if value >= 0 then return math.floor(tonumber(value) * e + 0.5) / e
else return math.ceil(tonumber(value) * e - 0.5) / e end
end
local num = getNumCandles(graphId)
local candles, num, _ = getCandlesByIndex(graphId,0,0,num)
local lst = ""
ff = io.open(getScriptPath().."\\".."tst.txt", "w+t")
for i = num-1, num-candleCount, -1 do
for ii = math.round(candles[i].low, 2), math.round(candles[i].high, 2), math.round(MinPriceStep, 2) do
lst = lst..i.." --- "..ii.." --- "..candles[i].low..", "..candles[i].high.."\n"
end
end
ff:write("============\n\n"..lst)
ff:flush()
ff:close()
...и тогда пишет округленное в файл, но, блин, мне при любом использовании ii писать его через функцию округления?! Как это - округление работает только в момент округления? :)
sergei написал: ...и тогда пишет округленное в файл, но, блин, мне при любом использовании ii писать его через функцию округления?!Как это - округление работает только в момент округления? :)
Что именно не понятно? Вы округляли только стартовое значение ii, а не все которые рождаются при переборе цикла. Кто сказал что округлив самое первое значение цикла все остальные тоже округлятся? нигде такого в программировании нет, и LUA не исключение. Хотите видеть округленное значение так и округляйте это значение, а не первую цифру в цикле. И кто мешает один раз округлить полученную цифру и сохранить ее в переменной? for ii = candles[i].low, candles[i].high, MinPriceStep do local round_ii = math.round(ii,2) lst = lst..i.." --- "..round_ii.." --- "..candles[i].low..", "..candles[i].high.."\n" end
Цитата
sergei написал: Кроме того, вот на первых свечках вообще не видно проблемы с 000000001
Это не имеет значения, появление 000000001 может произойти при любой арифметической операции. Например: message(tostring(124.4 - 124.3)) выдаст 0.10000000000001
Цитата
sergei написал: но цикл не доходит одну итерацию. Почему?
появление 000000001 может произойти при любой арифметической операции.
Этого не хватало для понимания проблемы. Спасибо!
Наличие погрешности при простом запросе свечки в виде candles[i].low без необходимости каких-либо операций даже внутри функции getCandlesByIndex все равно выглядит странно как-то. Эта функция же просто стат. данные выдает. Как там эти эффекты от плавающей точки появляются - загадка для меня :)
Цитата
Цитата
sergei написал: но цикл не доходит одну итерацию. Почему?
не понятно что имеется ввиду.
Вот в этом цикле:
Код
for z = candles[i].low, candles[i].high, MinPriceStep do
Последняя итерация должна бы проходить для z == candles[i].high, а фактически последней является z == candles[i].high - MinPriceStep
sergei написал: Наличие погрешности при простом запросе свечки в виде candles.low без необходимости каких-либо операций даже внутри функции getCandlesByIndex все равно выглядит странно как-то. Эта функция же просто стат. данные выдает.
Так она просто стат. данные и выдает. У вас значения типа 73.940000000001 возникают при исполнении оператора for, где выполняется вычитание шага (Руководство 3.3.5). Попробуйте сперва вычислять количество уровней свечи: local qty_levels = math.round ((candles[i].high - candles[i].low) / MinPriceStep), а затем уже выполняйте цикл for ii = 1, qty_levels do block end.