126

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Тем не менее нигде не нашел ответа, могу ли я из скрипта луа получить доступ к параметрам сортировки? Т.е. у меня программно создается визуальная таблица для отображения информации.
Могу ли я получить доступ из скрипта луа к этому параметру и включить ее при запуске скрипта?

Увы, такую возможность QLua API не предоставляет.

127 (2022-12-22 18:57:08 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

Подскажите такую вещь. Все прошлые выходные провел за изучением

ds, Error = CreateDataSource (settings[sec].CLASS, settings[sec].SEC, INTERVAL_M5). 

Вот именно в таком виде все работает без проблем.
НО! Мне необходимо ds и Error упаковать в таблицу. Если с Error вроде как не должно возникнуть проблем, то с ds проблемка. Не допонимаю...
В общем есть настроечная таблица,

settings = {
    common =    {    
        _KIND                = 0,                
        TRADE_ACC            = "NL0011100043",    
        CLIENT_CODE            = "10444",        
        FILE_NAME            = "DEMO_"
        },
    SPBE =    {                                
        SEC                    = "SPBE",            
        CLASS                = "TQBR",            
        portfolio            = 1,                
        uniq_trans_id        = 0x01000,        
        strategy            = "Graph_Gibrid",    
        Block_sell_Case        = 0,                
        },
    FLOT =    {                                
        SEC                    = "FLOT",    
        CLASS                = "TQBR",    
        portfolio            = 3,            
        uniq_trans_id        = 0x02000,    
        strategy            = "Graph_Gibrid",
        Block_sell_Case        = 0,            },
    MAGN =    {                                
        SEC                    = "MAGN",
        CLASS                = "TQBR",    
        portfolio            = 4,        
        uniq_trans_id        = 0x03000,
        strategy            = "Graph_Gibrid",
        Block_sell_Case        = 0,
        },
}

по ее образу и подобию создается еще одна таблица, но там хранятся уже переменные скрипта

    local i = 0
    tool = {}
    for k, v in pairs(settings) do
        if k ~= "common" then
            i = i + 1
            local temp = settings[k].SEC
            tool[temp] = {}
            security_info = getSecurityInfo(settings[k].CLASS, settings[k].SEC)
            tool[temp].NAME = security_info.short_name
            tool[temp].PRICE_STEP    = security_info.min_price_step    -- Инструмент
            tool[temp].PRICE_SCALE    = security_info.scale            -- точность задания цены инструмента
            tool[temp].LOT_SIZE        = security_info.lot_size        -- Размер лота
                        .............................
            tool[temp].ds, tool[temp].Error = CreateDataSource(settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5)
            Add_row(-1)
            Table_row(i, temp)
        end
    end

Для краткости привожу только часть таблицы.
В данном случае у каждого из 3 скриптов свой источник данных

tool[temp].ds, Error = CreateDataSource (settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5). 

Его надо запихать в таблицу tool с индексом [temp]. Просто

tool[temp].ds = CreateDataSource (settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5).

И если память мне не изменила с выходных, то вроде даже прокатило, но считать данные не получилось, ошибка что то вроде попытка индексировать значение nil. Извиняюсь что не точно помню. Я понимаю, что ds это тоже таблица, но в ней спрятаны функции. Пробовал и так

            tool[temp].data = {}
            tool[temp].data, tool[temp].Error = CreateDataSource(settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5);
            if tool[temp].Error ~= "" and tool[temp].Error ~= nil then message(tool[temp].NAME .. " Не удалось подключиться к графику: " .. Error) end
            message(tostring(tool[temp].data))

Месседж выводит table и адрес, ну вроде как то что то там есть, раз все таки распознает таблицу и адрес в памяти... а вот как выдернуть оттуда свечи я не понимаю. Отваливается с сообщением примерно "попытка индексировать значение nil". Пробовал по разному

numPrice = tool[temp].ds:Size() для первого варианта и
numPrice = tool[temp].data:Size() для второго.

Теоретически первый вариант правильный. Что я делаю не так? temp однозначно правильный, тут сомнений быть не может, проверял.

128

Re: Общие вопросы по написанию скриптов LUA.

Подскажите почему у меня коллбэк OnDepoLimit вызывается дважды на одном и том же инструменте и в одной сделке или заявке(на самом деле если не ошибаюсь он вообще вызывается 4 или даже 5 раз, но из за фильтра в начале теперь только 2 раза)? Причем это происходит при любом действии с заявкой. В частности если нужно убить заявку, то из за двойного вызова OnDepoLimit функция KillOrder также вызывается дважды еще до прихода OnTransReply и до того, как заявка получит статус "снята". Ну и как следствие, первый вызов киллордер проходит, а второй естественно выдает ошибку. В киллордере у меня предусмотрена проверка на наличие активных заявок! Т.е. мне даже лишний вызов киллордера не мешает, а мешает сам факт опоздания смены статуса заявки на "снята". Логично предположить, что возвращаемая коллбэком таблица(а точнее ее поля) изменяются не одним махом, а частями... С этим вообще можно что-либо сделать?

129 (2023-01-22 21:06:31 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Подскажите почему у меня коллбэк OnDepoLimit вызывается дважды на одном и том же инструменте и в одной сделке или заявке

Вообще в QUIK есть проблема со множественным вызовом колбеков.
С другой стороны, именно для лимитов какие-то поля всё же меняются на каждый вызов. Например, поле флагов.

130 (2023-01-22 22:19:17 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

Под лимитами вы имеете ввиду лимитные заявки? Я действительно их использую. Вобщем наверное придется все поля перебрать и проанализировать... Способа лечения  видимо не существует?

131

Re: Общие вопросы по написанию скриптов LUA.

Я про лимиты по деньгам и лимиты по бумагам.

132

Re: Общие вопросы по написанию скриптов LUA.

Мне необходимо ds и Error упаковать в таблицу.

По предыдущему вопросу. Которую неделю набегами пытаюсь упаковать таблицу ds в другую, но свою таблицу. Не получается, все время ошибка попытка индексировать значение nil. Вижу только две причины:
1. Я не допонимаю формат возвращаемой таблицы ds, а следовательно и не могу упаковать. Да, я действительно не понимаю что это за таблица и как с ней работать. Сколько не читал, еще больше запутываюсь и меньше понимаю из за того, что все это свалено в кучу и обозвано таблицей. Хотя на самом деле по идее это вообще разный тип данных. В любом случае нигде толком не описывается что значит ":" и почему именно используется двоеточие. Вообще судя по [url]https://luaq.ru/CreateDataSource.html#param_table_38[/url] это самая что на есть обычная таблица, но в качестве полей функции.
2. Упаковать таблицу ds в свою таблицу в принципе нельзя.
Можете пояснить где я ошибаюсь, а где нет...

133

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Упаковать таблицу ds в свою таблицу

Объясните, что есть "Упаковать в свою таблицу" ?

dark184 пишет:

формат возвращаемой таблицы ds
это самая что на есть обычная таблица, но в качестве полей функции.

Примерно так. И это катастрофически отличает её от "просто таблиц".
Просто таблица хранит в себе все данные.
Соответственно мы ей можем сказать:
"дай данные по индексу 8" --> на
"дай данные по индексу 10" --> на
"дай все свои данные " --> на - потому что таблица все свои данные знает.

А метатаблица может лишь сказать:
"дай данные по индексу 8" --> на
"дай данные по индексу 10" --> на
"дай все свои данные " --> а фик, нет у меня итератора, не знаю я какие данные во мне лежат.
Потому что "в качестве полей функции" подразумевает, что эти функции обращаются в какое-то внешнее по отношению к Lua хранилище. Т.е. по индексам получить можно, а "дай все" - такой интерфейс в Lua не проброшен.

(Справедливости ради в метатаблице тоже можно реализовать свой итератор, но не обязательно; да и данные он может возвращать другие, хотя бы шутки ради.)

Кроме того, насколько я помню, вы ds хотели как-то сохранить, чтобы попользоваться им потом. Но эта метатаблица запросто может быть не предназначена для корректного копирования в рамках языка Lua, это просто никому не требуется. А потому её можно получить, к ней можно обращаться; но вовсе факт, что её можно как-то склонировать и обращаться к клону в другой произвольный промежуток времени. Вероятно реализовать это можно, но никому не нужно.

Так что ваши задачи следует решать другими средствами, осталось лишь понять какими, а для этого надо понимать что же вы по сути-то хотите сделать, по смыслу.

134

Re: Общие вопросы по написанию скриптов LUA.

С терминологией в луа у меня уже сносит крышу smile Ну впрочем это мои проблемы smile
Т.е. как я понял CreateDataSource возвращает все таки метатаблицу? Ну в любом случае, при работе с ds чтобы получить данные, все таки действительно вызывается функция? Если это так, то теперь мне понятно в чем проблема, мой подход в корне не верен с учетом вашего пояснения про возможности луа.
В чем смысл. На данный момент в одном майн работают 43 робота(т.е. робот один, но он обрабатывает сразу 43 инструмента в одном майн). Как это реализовано, для упрощения пусть будут 3 инструмента. Есть настроечная таблица в которую я вписываю нужные мне инструменты и их параметры

settings = {
    common =    {    
        _KIND                = 0,                
        TRADE_ACC            = "NL0011100043",    
        CLIENT_CODE            = "10444",        
        FILE_NAME            = "DEMO_"
        },
    SPBE =    {                                
        SEC                    = "SPBE",            
        CLASS                = "TQBR",            
        portfolio            = 1,                
        uniq_trans_id        = 0x01000,        
        strategy            = "Graph_Gibrid",    
        Block_sell_Case        = 0,                
        },
    FLOT =    {                                
        SEC                    = "FLOT",    
        CLASS                = "TQBR",    
        portfolio            = 3,            
        uniq_trans_id        = 0x02000,    
        strategy            = "Graph_Gibrid",
        Block_sell_Case        = 0,            },
    MAGN =    {                                
        SEC                    = "MAGN",
        CLASS                = "TQBR",    
        portfolio            = 4,        
        uniq_trans_id        = 0x03000,
        strategy            = "Graph_Gibrid",
        Block_sell_Case        = 0,
        },
}

При запуске робот их читает и по образу и подобию создает для каждого инструмента отдельное поле в таблице tool с набором переменных

    local i = 0
    tool = {}
    for k, v in pairs(settings) do
        if k ~= "common" then
            i = i + 1
            local temp = settings[k].SEC
            tool[temp] = {}
            security_info = getSecurityInfo(settings[k].CLASS, settings[k].SEC)
            tool[temp].NAME = security_info.short_name
            tool[temp].PRICE_STEP    = security_info.min_price_step    -- Инструмент
            tool[temp].PRICE_SCALE    = security_info.scale            -- точность задания цены инструмента
            tool[temp].LOT_SIZE        = security_info.lot_size        -- Размер лота
                        .............................
            Add_row(-1)
            Table_row(i, temp)
        end
    end

Теперь к каждой переменной любого инструмента я могу обратиться по коду инструмента, который выдает мне коллбэк, т.к. индекс полностью совпадает с кодом инструмента. Да, все это работает не только на демо счете, но и на реальном счете. Левые коды я фильтрую. Под левыми я подразумеваю те инструменты, которые не внесены в настроечный файл. Тут только одна проблема осталась, это множественные вызовы коллбэков(это оставил на закуску, особо не вредит и ладно).
А вот более серьезная проблема пока не решена. Для каждого инструмента мне нужен источник данных, который я создаю примерно так

ds, Error = CreateDataSource (settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5)

Если бы не множество инструментов, проблемы бы не было, создал и забыл, насколько я понял его достаточно один раз создать и он сам обновляется, достаточно в нужный момент получить интересующие данные

open = ds:open()

И когда то давно вроде даже проверял, и вроде даже обновлялся без проблем, и даже коллбэк срабатывал если его включал...
Но теперь возникла проблема. Колбэки я назначить не могу, ибо их отличить друг от друга будет нельзя, а прописывать новый коллбэк с уникальным именем каждый раз при добавлении инструмента тоже не айс. К тому же имена источников также должны быть уникальными. Сейчас пока проблема с источниками данных не решена, у меня каждый раз создается новый источник данных во всех инструментах с одним и тем же именем, из которого дергаю нужные мне данные и помещаю в нужные переменные. НО! Подозреваю что именно из за такого подхода через пару дней работы, оператива компа забивается напрочь, что приходится перезапускать квик...
Вот и кубатурю как при запуске робота один раз создать все источники данных для прописанных инструментов...
Была мысль создать коллбэк, но пришлось отказаться.
Сейчас кубатурил как скопировать в свою таблицу, но видимо действительно не судьба...
Т.е. по сути все сводится к тому, чтобы создавать 3(в реальности, сколько инструментов прописано) источника данных, каждый для своего инструмента, из которых можно будет вытаскивать нужные данные по типу таблицы со строковыми индексами

open[SEC_CODE] = ds[SEC_CODE]:open()

135

Re: Общие вопросы по написанию скриптов LUA.

Объясните, что есть "Упаковать в свою таблицу" ?

Стоп. Похоже я сморозил чушь smile
Вобщем, есть таблица tool. В качестве индексов ее полей я использую код инструмента

tool = {
    SPBE =    {                                
        },
    FLOT =    {                                
        },
    MAGN =    {                                
        },
}

Каждое поле таблицы, это массив индивидуальных переменных для каждого инструмента, само собой имена здесь уже не уникальны, так как находятся в разных массивах

tool = {
    SPBE =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
        },
    FLOT =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
        },
    MAGN =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
        },
}

Теперь я пытаюсь создать, именно создать, источник данных в каждом из этих массивов

tool = {
    SPBE =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
       ds, Error = CreateDataSource (settings[SPBE].CLASS, settings[SPBE].SEC, INTERVAL_M5)
        },
    FLOT =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
       ds, Error = CreateDataSource (settings[FLOT].CLASS, settings[FLOT].SEC, INTERVAL_M5)
        },
    MAGN =    {                                
       var1 = 0
       var2 = 0
       var3 = 0
       ds, Error = CreateDataSource (settings[FLOT].CLASS, settings[FLOT].SEC, INTERVAL_M5)
        },
}

С той целью, чтобы в нужный момент вытащить из него данные по коду инструмента, полученному из любого коллбэка. И самое интересное, источник создается, НО! Я не понимаю как из него вытащить данные...
К примеру, если попробовать скопировать open в var1 получим ошибку попытки индексирования значения nil

tool[MAGN].var1 = tool[MAGN].ds:open()

Таблица tool создается в майне перед вечным циклом. Вообще такой фокус возможен или нет?

136 (2023-01-25 23:05:11 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

Про ds для разных инструментов.
Вроде всё просто:

settings[temp].ds, Error = CreateDataSource (settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5)

потом обращаться, когда требуется open получить:

open = settings['FLOT'].ds:open()

То что надо?

137

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

К примеру, если попробовать скопировать open в var1 получим ошибку попытки индексирования значения nil

tool[MAGN].var1 = tool[MAGN].ds:open()

Где кавычки для константы MAGN ??

138

Re: Общие вопросы по написанию скриптов LUA.

То что надо?

Ну вроде ничем не отличается

numPrice = tool[temp].ds:Size()

За исключением таблицы, в settings константы, необходимые для настройки, в tool уже уникальные для каждого инструмента переменные. Соответственно settings только чтение, tool чтение и запись и здесь все оперативные данные по инструменту.
где

temp = settings[k].SEC

К темпу вопросов нет, там именно то, что нужно.
Тем не менее происходит ошибка

Где кавычки для константы MAGN ??

Прошу прощения за ввод в заблуждение, здесь должна быть не константа, а имя переменной в которой хранится строковое значение "MAGN", именно строка. В моем случае эта переменная temp(после инита всего скрипта в роли этой переменной выступает код инструмента, возвращаемый из коллбэка), вопросов к ней нет, ибо вся таблица создается, инициализируется и прекрасно работает. Проблема как раз возникает при попытке чтения

139

Re: Общие вопросы по написанию скриптов LUA.

Тогда я вообще не понимаю в чем вопрос.

dark184 пишет:

К примеру, если попробовать скопировать open в var1 получим ошибку попытки индексирования значения nil

tool[MAGN].var1 = tool[MAGN].ds:open()

Так кто здесь nil? выясните это.

Вы приводите какие-то фрагменты кода, в которых проблемы не видно.

Приведите максимально упрощенный пробный и полный скрипт, на котором было бы видно проблему, тогда можно будет что-то предметно сказать.

140

Re: Общие вопросы по написанию скриптов LUA.

Сейчас покопался, привел мысли в порядок, причесал тестовую программку, убрал лишнее, переосмыслил все с учетом ответов. Вроде ничего особо не менял в программе, разве что из серьезного убрал Error и позже создание таблицы data, что то изменилось, и даже вроде заработало...

function main()
    local i = 0
    tool = {}
    for k, v in pairs(settings) do
        if k ~= "common" then
            i = i + 1
            local temp = settings[k].SEC
            tool[temp] = {}
            security_info = getSecurityInfo(settings[k].CLASS, settings[k].SEC)
            --message(temp)
            tool[temp].NAME = security_info.short_name
            tool[temp].PRICE_STEP    = security_info.min_price_step    -- Инструмент
            tool[temp].PRICE_SCALE    = security_info.scale            -- точность задания цены инструмента
            tool[temp].LOT_SIZE        = security_info.lot_size        -- Размер лота
            tool[temp].Open            = 0                                -- Цена окрытия свечи
            tool[temp].High            = 0                                -- Максимум свечи
            tool[temp].Low            = 0                                -- Минимум свечи
            tool[temp].Close        = 0                                -- Цена закрытия свечи
            tool[temp].Volume        = 0                                -- Объем свечи
            tool[temp].buy_price    = 0                                -- Цена покупки
            tool[temp].sell_price    = 0                                -- Цена продажи
            tool[temp].Total        = 0                                -- Итого, руб.
            tool[temp].Date_Time    = ""                            -- Дата и время продажи
            tool[temp].Total_perc    = 0                                -- Итого, %

[b]
            tool[temp].data, Error = CreateDataSource(settings[temp].CLASS, settings[temp].SEC, INTERVAL_M5);
            if Error ~= "" and Error ~= nil then message(tool[temp].NAME .. " Не удалось подклдчиться к графику: " .. Error) end
[/b]
            Add_row(-1)
            Table_row(i, temp)
        end
    end

    while not stopped do 
        ........
    sleep(500)
    end
end

Что изменилось? Посмотрел свои старые сообщения, да вроде ничего! Все чего я сделал, это убрал строку

tool[temp].data = {}

перед созданием источника данных, которая вообще никак не должна была повлиять на работу, ибо какая разница, создать сразу таблицу, или при создании источника данных переменная сама примет вид этой же таблицы.
Теперь данные в tool[temp].data более менее похожи на истину, надо потестить еще как меняются, и меняются ли вообще... Остальную часть программы за все это время не трогал вообще... К сожалению более старые версии я удалил, так что теперь даже не глянуть в чем изначально заключалась ошибка sad А она там была однозначно, ибо перекочевала в более свежие версии, которые неоднократно переписывались в "поисках истины".
В любом случае спасибо за советы, реально помогли некоторые вещи осознать smile

141

Re: Общие вопросы по написанию скриптов LUA.

Можете подсказать, в qlua есть встроенная функция с округлением до заданного количества знаков после запятой? Или возможно производить арифметические действия сразу с заданной точностью?

142 (2023-02-06 18:46:42 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

math.floor(x) - возвращает наибольшее целое число, меньшее или равное x (округление «вниз»)
math.ceil(x) - возвращает наименьшее целое число, большее или равное x (округление «вверх»)

Ну и не забывать, что для подачи транзакции цену надо представлять строкой с правильным количеством знаков после запятой

143 (2023-02-06 19:06:34 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

swerg пишет:

math.floor(x) - возвращает наибольшее целое число, меньшее или равное x (округление «вниз»)
math.ceil(x) - возвращает наименьшее целое число, большее или равное x (округление «вверх»)

Ну и не забывать, что для подачи транзакции цену надо представлять строкой с правильным количеством знаков после запятой

именно их я и использую в своей функции округления. Вот только это до целого, а нужно до заданного знака после запятой sad Похоже придется и дальше пользоваться самописной функцией.
Ну и конечно же кратной шагу smile С этим проблем нет, как и с самописной функцией округления, вот только опасненько, можно с такой функцией словить глюк. Правда пока не наблюдал, но мало ли. Подстраховаться.

144

Re: Общие вопросы по написанию скриптов LUA.

А вообще, такая конструкция в луа выдаст ожидаемый результат

round = tonumber(string.format("%.3f", num))

где round число, округленное до 3 знаков после запятой
num исходное число, от целого до... почти бесконечного количества знаков после запятой.
Если да, то возможно ли в эту конструкцию вставить вместо 3 в "%.3f" переменную, в которой будет нужное число или число в виде строки, необходимого количества знаков после запятой?
Или может быть есть уже готовая и проверенная функция округления для всех чисел, от знаковых и безнаковых целых, до знаковых и беззнаковых с плавающей точкой?

145

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Вот только это до целого, а нужно до заданного знака после запятой

Блин, ну так это классика жанра же:

math.floor(x * 1000) / 1000

вот и будет до 3-го знака, например.
И да, можно свою функцию запилить при надобности, которая вторым аргументом возьмет кол-во знаков и сначала вычислит

local L = math.power(10, n)

146

Re: Общие вопросы по написанию скриптов LUA.

Это только для положительных чисел, для отрицательных нужны дополнительные телодвижения. Да и округление только вверх, а нужно еще учитывать отбрасываемый хвост. Типа 2.54 округляем до 1 знака 2.5, а 2.56 = 2.6. У меня это реализовано сейчас так

function Rounding(digit, sign)

    local n,m = math.modf(digit)
    local l = string.len(n)
    if sign ~= 0 then l = l + 1 end
    if digit < 0 and n == 0 then l = l + 1 end
    local s = tonumber("0." .. string.rep('0', sign) .. "5")
    if digit >= 0 then
        digit = digit + s
    else
        digit = digit - s
    end
    return tonumber(string.sub(tostring(digit), 1, l+sign))
    
end

Писалась функция уже полгода назад наверное, когда вообще в языке еще ни бум бум. Да и масштабирование не догадался применить... Хотя... Фиг знает, может так даже быстрее будет...

147

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Писалась функция уже полгода назад наверное, когда вообще в языке еще ни бум бум

Зачем такие сложности, все гораздо проще можно сделать

function NumberFormat(value,accuracy) -- Округление числа до заданной точности
  return string.format("%."..(accuracy==nil and 0 or accuracy).."f",value)
end

148 (2023-02-07 18:01:39 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

Вот именно об этом я и спрашивал smile Правда конкатенацию так и не дошурупил вставить smile

Если да, то возможно ли в эту конструкцию вставить вместо 3 в "%.3f" переменную

Вот только данная функция насколько я понял не умеет округлять. Но с округлением попроще, сложнее форматировать.

(accuracy==nil and 0 or accuracy)

Хотелось бы еще уточнить. В луа данные логические операторы отрабатываются слева направо? То есть сначала лог. И и лог. ИЛИ полученный результат с accuracy. Т.е. если расставить скобки

((accuracy==nil and 0) or accuracy)

149

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Хотелось бы еще уточнить. В луа данные логические операторы отрабатываются слева направо?

На сколько я знаю порядок определяется приоритетом, как в классической мат логике
1. Инверсия
2. Конъюнкция
3. Дизъюнкция

150 (2023-02-08 09:50:04 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

Из документации:

3.4.8 – Приоритет операций

Приоритет операторов в Lua представлен далее, от меньшего к большему приоритету:

     or
     and
     <     >     <=    >=    ~=    ==
     |
     ~
     &
     <<    >>
     ..
     +     -
     *     /     //    %
     unary operators (not   #     -     ~)
     ^