_sk_ написал: Есть следующий "хак", гарантирующий, что выполнение кода будет только в одном потоке.
Код
table.ssort ({ 0 , 1 }, function (a, b)
тут_ваш_код
return true
end )
Запускаю одновременно два скрипта. Использую "хак", рассчитывая, что скрипты будут писать в файл по очереди:
Скрытый текст
Код
local f
function OnInit()
f = assert(io.open(getScriptPath() .. "\\file.txt", "a"))
end
function main()
table.ssort({0, 1}, function ()
for i = 1, 100 do
f:write("1\n")
f:flush()
end
return true
end)
f:close()
end
Код
local f
function OnInit()
f = assert(io.open(getScriptPath() .. "\\file.txt", "a"))
end
function main()
table.ssort({0, 1}, function ()
for i = 1, 100 do
f:write("22\n")
f:flush()
end
return true
end)
f:close()
end
Если писать только внутри колбеков, то в пределах одного квика запись в один файл из разных скриптов корректна. Из разных квиков пока не придумал, как сделать.
s_mike@rambler.ru написал: правильный путь - это формирование флага. Например, если один скрипт хочет писать, он пробует создать папку-семафор на диске. Если папка создалась удачно, дописывает файл. Если при создании папки была ошибка (папка существует), то надо подождать. По окончании записи нужно закрыть файл и удалить папку.
В Lua есть штатные средства создания папки? Если только создавать файл-флаг. Но это не поможет: несколько скриптов увидят, что флага нет и начнут запись одновременно. Результат будет тот же.
Цитата
s_mike@rambler.ru написал: использовать механизмы мютексов или что то в этом роде, Но это уже с++
Для торговых ботов использую только QLua. Если только Арка когда-нибудь сделает мютексы. Но рассчитывать, что это произойдёт в ближайшем будущем я бы не стал.
Цитата
s_mike@rambler.ru написал: а ещё лучше пересмотреть логику скриптов, чтобы писать из одного скрипта
У каждого скрипта свои данные, которые он пишет в общий файл. Если вести запись только из одного скрипта, то другие скрипты должны будут ему эти данные передать. По сути это будет та же самая задача - обмен данным между скриптами.
Daniil Pozdnyakov, сам скрипт прислать не могу. Но вы можете воспользоваться, например, этим:
Код
local run = true
function OnStop()
run = false
end
local trans_id, order_num
function OnTransReply(trans_reply)
if trans_reply.trans_id == trans_id then
if trans_reply.status == 3 and trans_reply.order_num > 0 then
order_num = trans_reply.order_num
end
end
end
function main()
trans_id = getUniqTransID()
local err = sendTransaction{
TRANS_ID = tostring(trans_id),
ACTION = "NEW_ORDER",
ACCOUNT = account,
CLASSCODE = class_code,
SECCODE = sec_code,
OPERATION = "B",
TYPE = "L",
PRICE = price,
QUANTITY = "1"
}
if err ~= "" then
message(err, 3)
return
end
local n = 0
while run and n < 100 do
if order_num then
trans_id = getUniqTransID()
if sendTransaction{
TRANS_ID = tostring(trans_id),
ACTION = "MOVE_ORDERS",
CLASSCODE = class_code,
SECCODE = sec_code,
MODE = "0",
FIRST_ORDER_NUMBER = tostring(order_num),
FIRST_ORDER_NEW_PRICE = price,
FIRST_ORDER_NEW_QUANTITY = "1"
} == "" then
order_num = nil
n = n + 1
else trans_id = nil end
end
sleep(1)
end
end
Обратите внимание, что статус транзакции и номер заявки, выставленной в торговую систему, проверяются.
Цитата
Daniil Pozdnyakov написал: данная ошибка появляется постоянно при попытке заменить заявку или какие-то заявки меняются (то есть транзакция срабатывает), а какие-то нет ?
Daniil Pozdnyakov написал: OnTransReply, помимо номера заявки, возвращает ещё и поле status, которое может показывать, что, например, транзакция была отвергнута ТС.
Цитата
Daniil Pozdnyakov написал: добавить логику проверки в скрипт, чтобы поле status было равно "3"
Во-первых, проверка поля status давно есть. Во-вторых, если транзакция была отвергнута ТС, то order_num = 0.
Так это не у меня проблема, а у вас с сервером какая-то шляпа. Заявка выставлена в торговую систему биржи. Сервер прислал номер заявки в OnTransReply, но утверждает "Вы не можете заменить заявку". С чего вдруг?
Часто при MOVE_ORDERS заявки от сервера прилетает такое сообщение. Это происходит, если изменять заявку по номеру, полученному из OnTransReply, не дожидаясь OnOrder. С чего вдруг я не могу заменить заявку?!! Ведь заявка существует в ТС, я получил номер заявки.
Roman Azarov написал: Обе заявки успешно изменены, либо не изменена ни одна, либо ошибка. Это уже можно понять по реплаю.
Не совсем так:
Цитата
Если при сдвиге пары заявок одна из них наткнулась на кросс-сделку (сведение с заявкой от того же ИНН, либо клиентского регистра), она откатывается, а другая заявка сдвигается.
Андрей написал: На момент onTransReply нет еще onOrder и записи в заявках
Если в OnTransReply вернулся номер заявки(ок), это значит, что новая заявка была зарегистрирована, что приведет к срабатыванию OnOrder и появлению соответствующей записи в таблице заявок.
OnOrder сработает потом когда-нибудь, а информация по новой заявке нужна уже сейчас в OnTransReply.
Цитата
Roman Azarov написал: Зарегистрировали пожелание на добавление полей price, quantity и order_num для второй заявки.
Лично проверял: на демке - рыночную заявку на бою - лимитированную с условием "Снять остаток". О чем пришел ответ по транзакции с сообщением "Заявка XXX успешно зарегистрирована." и ордером со статусом "Снята" и withdraw_datetime = datetime
При включении признака «Рыночная» в пустое поле «Цена» подставляется значение «Максимально возможная цена», а при подаче заявки на продажу – «Минимально возможная цена» для данного инструмента (значение берется из Таблицы текущих торгов)
При таком раскладе в стакане не должно быть встречных заявок, чтобы ваша заявка осталась висеть.
Возможно, вы используете какой-то привод, который формирует цену заявки: текущая цена + отступ или в квике есть какая-то настройка для рыночных цен, о которой мне не известно.
Добавить колбек OnSendTransaction(number trans_id), вызываемый, когда из терминала отправляется транзакция любым способом: вручную, скриптом, из файла, по API. Чтобы любой скрипт, подписавшись на этот колбек мог знать, сколько транзакций отправлено на сервер. Цель: контроль общего количества отправляемых транзакций в единицу времени, чтобы не натыкаться на ограничения брокера: https://forum.quik.ru/forum14/topic6093/ https://forum.quik.ru/messages/forum1/message45728/topic2916/#message45728
Факультативно решается вопрос контроля уникальности id транзакций.
Также не лишним было бы иметь доступ к таблице транзакций через getNumberOf, getItem, чтобы знать общее количество транзакций за торговую сессию.
Незнайка написал: упаковать значения в две таблицы, а потом объединить их
Но есть косяк: если функции могут возвращать nil, то unpack работает криво. Когда таблица сразу заполняется при создании, то распаковывается нормально:
Код
local G = {1, 2, nil, 4, nil, 6}
return print(unpack(G)) --> 1 2 nil 4 nil 6
А когда значения дописываются после, то работает криво
Nikolay написал: Когда число линий действительно больше, то тогда уже лучше хранить значения в таблице, а возвращать через unpack(table).
Не придумал ничего лучше, чем упаковать значения в две таблицы, а потом объединить их
Код
function OnCalculate(index)
local G = {glo1(index)}
local n = #G
local G_ = {glo2(index)}
for i = 1, #G_ do
n = n + 1
G[n] = G_[i]
end
return table.unpack(G)
end
rpns написал: Кстати, и без вызова SetEmptyCallback. Зачем он тогда?)
Он нужен для подписки на данные. Ровно эту же подписку можно выполнить через терминал, открыв нужный график. Если Вы откроете график то по сути SetEmptyCallback не нужен, данные и так будут поступать. Но не всем удобно открывать графики, по этому существует SetEmptyCallback.
Sergey Gorokhov написал: На самом деле, заказ данных после CreateDataSource происходит независимо от заданного коллбэка. Для данных на основании обезличенных сделок будут получаться все данные, Для данных ТТТ в зависимости от настроек терминала для получения ТТТ, т.е. если получение пропущенных данных выключено, то будут доступны только новые данные ТТТ.
function main()
local filename = "file.txt"
local f = assert(io.open(filename, "w"))
os.execute("start cmd.exe")
message(tostring(f:close()) .. "\n" .. tostring(f))
assert(os.remove(filename)) -- file.txt: Permission denied
end
Если поместить вызов os.execute() после закрытия файла, то удаляется.
Daniil Pozdnyakov написал: Вы хотите иметь именно функции QLUA, чтобы использовать их в lua-скриптах и при помощи них устанавливать определённое окно поверх других или отражать на других вкладках?
Андрей написал: ошибки типа данный инструмент запрещен в шорт
Цитата
Андрей написал: Сделайте вторую версию sendTransaction, которая бы не проверяла подобные локальные условия. Чтобы можно было вызывать 2 транзакции сразу друг за другом.
Вы не подумали, что первая заявка может исполниться, пока транзакция на её снятие дойдёт до биржи? Тогда, при исполнении второй заявки, получится как раз шорт. А это нарушение. Брокер будет вынужден закрывать ваш шорт принудительно.
Здравствуйте. А сильно сложно будет добавить для Lua-окон команды "Поверх всех окон" и "Показывать на всех"? Можно, конечно использовать для этого WinAPI, но не хочется подключать ради двух команд стороннюю библиотеку, тем боле что QUIK с библиотеками работает не стабильно.
s_mike@rambler.ru написал: Когда задают вопрос про версию, это означает, что никто даже и не пошевелился, чтобы найти ошибку. Она проявляется на любой версии ккогда спрашивают код скрипта, это означает, что никто даже не почесался прочитать первые три сообщения ветки когда спрашивают скриншот окна сообщения, это значит, что никто даже не пробовал поискать в текстах терминала слово "видеопамяти "
Ну если вместо того, чтобы просто открыть график, неделю задавали тупые вопросы, то тут задачка посложнее.
Можно ли внутри скомпилированного luac-скрипта, выполняемого через dofile, узнать его расположение? Очевидный вариант - передать параметром из запускающего скрипта - не интересует.