26

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

osr,
вот библиотека, о которой говорит toxa
[url]https://quik2dde.ru/viewtopic.php?id=306[/url]

27

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

osr пишет:

На сколько я понял тут обсуждается статья [url]https://quik2dde.ru/viewtopic.php?id=16[/url]
в которой есть скрипт:

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

local __version = _VERSION
local __creator_path = "C:\\CreatorEx"
package.cpath=package.cpath..";"..__creator_path.."\\lib\\"..__version.."\\scripts/?.dll"

local sh = require'lua_share'
local qs = sh.GetNameSpace('queues')
local exitflag = false

--направление обезличенной сделки
local function tlr_bs(flags)
    if bit.band(flags, 0x1) ~= 0 then
        return -1, "S"
    else
        return 1, "B"
    end
end

local events = {
    TQBR_SBER = {B = 0, S = 0, FirstN = 0, EndN = 0},
}
function events.message(key)
    if events[key].FirstN == 0 then return end
    message(
        key .. "\n" ..
        "с  №: " .. events[key].FirstN .. "\n" ..
        "по №: " .. events[key].EndN .. "\n" ..
        "Купили  лот: " .. events[key].B .. "\n" ..
        "Продали лот: " .. events[key].S
    )
    events[key] = {B = 0, S = 0, FirstN = 0, EndN = 0}
end
function events.OnAllTrade(t)
    local key = t.key
    local _, bs = tlr_bs(t.flags)
    if events[key].EndN == 0 then
        events[key].FirstN = t.trade_num
    end
    events[key].EndN = t.trade_num
    events[key][bs] = events[key][bs] + t.qty
end

local function sh_event()
    local t
    repeat
        t = qs.evn
        if t then
            events[t.fname](t)
        end
    until not t or exitflag
end

function main()
    while not exitflag do
        events.message("TQBR_SBER")
        
        sleep(2000)
        
        sh_event()
    end
end

function OnStop()
    exitflag = true
end

function OnAllTrade(t)
    local key = t.class_code .. "_" .. t.sec_code
    if not events[key] then return end
    t.fname = "OnAllTrade"
    t.key = key
    qs.evn = t
end

--[[ так делать в калбэках - нельзя!!!
function OnTrade(trade_data)
    qty = trade_data.qty
    sum = trade_data.value
    n = getNumberOf("trades")
    for i=0, n-1 do
        t = getItem("trades", i)
        sum = sum + t.value
        qty = qty + t.qty
    end
    message("Total: qty=" .. tostring(qty) .. " sum=" .. tostring(sum), 1)
end
--]]

28

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

не могу сам разобраться sad
но такого точно не должно быть
function main()
    while not exitflag do
        events.message("TQBR_SBER")
       
        sleep(2000)
       
        sh_event()
    end
end

зачем тогда события вообще нужны? я и сам могу через каждые 2с опрашивать таблицу.
нужно что бы событие само будила спящий поток и передавала ему управление
например функции sh_event()

я нашел что то вроде lua_thread.create_suspended(sh_event)
но это почему то не работает :
attempt to index a nil value (global 'lua_thread')

29 (2022-11-23 10:19:35 отредактировано kalikazandr)

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

osr пишет:

не могу сам разобраться sad
но такого точно не должно быть

т.е. вы хотите, что бы некая функция, пихала main, со словами "Вставай скотина - на посчитай.."
Так что-ли? Вы в каком то своем мире живете. Вас никто не заставляет пользоваться событиями, делайте как умеете, когда придёт понимание "событие" тогда будут другие вопросы, а не хотелки.
И да, поставьте sleep(1) - вижу, что вам нужно попробовать...

30

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

kalikazandr пишет:

т.е. вы хотите, что бы некая функция, пихала main, со словами "Вставай скотина - на посчитай.."

что то в это духе да! smile
ну я не знаю lua может ли он так.
видимо для этого должны были позаботится разработчики qlua
вот пример из какой то игры lua_thread.create_suspended(sh_event)
там можно создавать потоки и будить их.
Ну в принципе если сделать в main  маленькую задержку sleep(1), попробую пока  так.
Спасибо!

31

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

osr пишет:

вот пример из какой то игры lua_thread.create_suspended(sh_event)
там можно создавать потоки и будить их.

не возможно, вас обманывают.

osr пишет:

Ну в принципе если сделать в main  маленькую задержку sleep(1), попробую пока  так.
Спасибо!

sleep(2000) стоит, что бы квиковские сообщения не убили вам терминал,
по этому events.message("TQBR_SBER") лучше отключить.
Событие вы можете увидеть раньше - в main, в соответствующей таблице квика, добавилась строка, изменился параметр и т.д.
Для этого нужно постоянно что-то мониторить и даже то, что нафик не нужно.
Другое дело, когда вы создаете себе событийную ленту по нужным вам изменениям и уже её обрабатываете.
Если ПК мощный, то sleep(1) вполне себе, но если это винда, то от 1 до 50 ms, ну потому что винде так хочется.

32

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

kalikazandr пишет:

не возможно, вас обманывают.

для меня такое поведение потоков обычное дело. может это в lua не возможно.

kalikazandr пишет:

sleep(2000) стоит, что бы квиковские сообщения не убили вам терминал,

да это я понимаю. моя задача конечно же не в том что бы сообщения выводить, а принимать торговые решения купить/ продать.

kalikazandr пишет:

Если ПК мощный, то sleep(1) вполне себе, но если это винда, то от 1 до 50 ms, ну потому что винде так хочется.

у меня как раз ubuntu smile

33

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

osr пишет:

не могу сам разобраться sad

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

34

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

toxa пишет:

с библиотекой идут примеры.

я не про вашу библиотеку, а про потоки. как можно пробудить поток.

35 (2022-12-23 11:55:52 отредактировано igor)

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

Здравствуйте.
У меня вопрос про функцию table.remove.
Если индекс массива имеет целочисленный тип, то она работает без проблем.
Т.е. результатом выполнения такого кода будет 2:

a={}; a[1]='2'; a[2]='4'; a[3]='8'
table.remove(a, 2)
message(tostring(#a))

А вот если индекс массива имеет строковый тип, то table.remove не работает. Т.е. такой код выдаст ошибку:

a={}; a['1']='2'; a['2']='4'; a['3']='8'
table.remove(a, '2')

Как можно удалить элемент массива, если его индекс имеет строковый тип?

36

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

igor, используйте такую функцию:

function table.removekey(table, key)
    local element = table[key]
    table[key] = nil
    return element
end

Пример использования:

local t = { a = 1, b = 2 }

for k,v in pairs(t) do
  print(k, v)
end

print('---')

table.removekey(t, 'a')

for k,v in pairs(t) do
  print(k, v)
end

выведет:

b    2
a    1
---
b    2

37

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

Swerg, спасибо.
Получается, если я правильно понял, что если какому-нибудь элементу массива со строковым индексом присвоить nil, то этот элемент удаляется и освобождается память.

Я ради любопытства попробовал сделать то же самое с массивом с целочисленным индексом. Т.е. такой код:

aa={}; aa[1]='2'; aa[2]='4'; aa[3]='8'
aa[2]=nil
message(tostring(#aa))

Результат всё равно 3. И непонятно, освобождается ли при этом память или нет. Я думал, что и с массивом со строковым индексом такая же ситуация.
Похоже массивы с целочисленным индексом и строковым индексом хранятся в памяти как-то по-разному...

38

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

Вообще никогда не используйте # !!!
Это полная шляпа.
Он дает валидные результаты только в том случае, если вы используете Lua-таблицы как массивы с непрерывными числовыми индексами. Всё !!

см. [url]https://www.lua.org/pil/19.1.html[/url]
(здесь # эквивалент table.getn)

39

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

Swerg, спасибо.
Действительно полезная информация.
Но тогда непонятно, как же определять длину массива.
Получается только с помощью цикла...
Что-то вроде:
local t = { a = 1, b = 2 }
n=0
for k,v in pairs(t) do
  n=n+1
end

40

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

igor пишет:

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

Да, других вариантов нет.

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

41

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

Swerg, действительно, если использовать такой цикл - "for k,v in pairs(t) do...", то размер таблицы знать необязательно.

Но если элементу таблицы присвоить nil, то освобождается ли память, которую он занимал? Не произойдёт ли утечки памяти?
Я полагал, что это как раз и можно определить функцией #.

42 (2022-12-27 15:45:17 отредактировано swerg)

Re: Основы программирования LUA в QUIK (QLUA): обсуждение

igor,
на мой взгляд это какой-то бессмысленный и непрактичный вопрос.
Обещана автоматическая сборка мусора - значит она работает. Ну мы ж не на Си программируем в самом-то деле. Специально же даден нам скриптовый язык, чтобы мы не думали о памяти и её выделении / освобождении. Так я считаю.
Да и как # может сказать об освобождении памяти? про память говорит диспетчер задач Windows.

И да,

Но если элементу таблицы присвоить nil,

то, по справке - память освобождается. Так что всё в порядке, можно не поверять smile