Функция pcall вызывает функцию f с аргументами, переданными в параметрах и возвращает результат успешности вызова функции. Если функция f была вызвана успешно, то остальные возвращаемые значения pcall являются результатом вызова функции f, иначе второе возвращаемое значение является сообщением об ошибке. Например:
local callResult, result = pcall(dofile, fileName)
if callResult then
-- все в порядке, result это то, что вернула функция dofile
else
-- result это сообщение об ошибке
print(result)
end
Второй способ загрузки файла использует переключение окружения и уже знакомую функцию loadfile:
-- загружаем чанк из файла
local result
local func, errorMsg = loadfile('data2.lua')
if func then
-- создаем таблицу для окружения,
-- в котором будет выполняться функция func
local P = {}
-- устанавливаем окружение для функции func
setfenv(func, P)
-- вызываем функцию func
func()
-- все "глобальные" переменные,
-- объявленные внутри чанка, попадут в таблицу P
result = P.a
else
print(errorMsg)
end
Но хотелось бы понимать чем они отличаются друг от друга.
Есть файл №2 со скриптом Lua подключаемый в основной скрипт Lua №1 через dofile(). Можно как-то создать исключение если в этом файле №2 есть ошибка - проигнорировать его и не прерывать работу скрипта №1. Проводимые вычисления и операции в скрипте №2 никак не затрагивают работу скрипта №1.
Для общего развития хотелось бы понимать: Последовательность событий OnTrancReply(), OnOrder(), OnTrade(), имеют всегда жесткую последовательность исполнения, или же могут в разном порядке сработать?
Т.к. изменение ордера это 2 транзакции, первая удаление, вторая добавление, может быть такой случай что ордер не удалится, а добавиться, или наоборот удалиться, но не добавиться, хотя обе транзакции отправлены без ошибок?
При разработке скрипта на LUA, который запускается через "Сервис > Lua-скрипты..." используется следующая конструкция:
Код
IsRun = true; -- Флаг поддержания работы скрипта
function OnInit()
-- настройки
end;
function main()
-- Цикл будет выполнятся, пока IsRun == true
while IsRun do
if IsWindowClosed(t_id) then --закрываем скрипт, когда окно закрыто
OnStop();
end;
sleep(2000);
end;
end;
Когда создается индикатор используется следующая конструкция:
Код
Settings =
{ ["Name"] = "NAMEINDICATOR",
line =
{ { Name = "NAMEINDICATOR",
Color = 0xff0000,
Type = TYPE_HISTOGRAM,
Width = 2
},
}
};
function Init()
return #Settings.line;
end;
Возможно ли в создаваемых индикаторах делать создание окон таблиц и сделать такой же цикл function main() sleep(2000). Или индикаторы затачиваются только на работу и изменение значений графика?
Максим Николаевич написал: Доброго времени суток. Не отображаются данные FORTS фьючерсы в создании таблиц на текущие торги. Могу я как нибудь получить доступ? Логин: Q54370
В нерабочие дни насколько знаю они у всех не отображаются, не только в Quik Junior. Мне кстати тоже всегда был интересен вопрос возможности загрузки данных в нерабочие дни. Пока обходил это отключением от интернета в последний день торгов.
Функция как получаю текущее число открытых позиций:
Код
-- QUIK Получить: текущее кол-во открытх позиций
function _QuikGetTotalnetByIndex(code)
for i = 0,getNumberOf("futures_client_holding") - 1 do
if getItem("futures_client_holding",i).sec_code == code then
return getItem("futures_client_holding",i).totalnet;
end;
end;
return 0;
end;
Сейчас 0 контрактов. Купили 2 контракта. Приходит ответ в функции в OnTrade() что куплено 2 контракта. Но если внутри данной функции сделать запрос на кол-во контрактов _QuikGetTotalnetByIndex() - то будет 0.
Если купить еще 3 контракта, и сделать запрос в OnTrade() - то он выведет значение 2. Складывается впечатление что таблица ограничений по клиентским счетам "futures_client_holding" обновляется после таблицы сделок, либо чего-то не понимаю?
Иван написал: И получается что вы снимаете всю пачку стоп-пов и их по новому переставляете.
Нет не получается. Из примера видно что стоп эта одна заявка объемом в 10 лотов. Если бы у меня было 10 заявок по 1 лоту, то в этом случае вообще ни чего не нужно переставлять.
Изначально тема - "Жизнеспособность идеи - 100 контрактов = 100 стоп-ордеров по 1 контракту каждый".
Мне на самом деле больше всего сейчас понравилась идея пойти дальше: человек покупает 30 контрактов - будет сделано 30 транзакций по 1 лоту каждый. Т.е. 1 контрат = 1 установленный стоп = 1 снятый стоп. Но получается при торговле 50 контрактами = 50 сделок = 50 транзакций = 50 стопов. 100 контрактов = 100 сделок = 100 стопов и т.д.. Все по 1 лоту. Не надо заморачиваться ни на какие изменения стоп ордеров (только добавить, только снять). Возможно это не очень удобно с точки зрения производительности и избыточно - возможно вернусь к этой идее 1=1=1 позже. Подобный подход кто так реализовывал смог найти только в 1 приводе. Кроме того если какой-то из стоп-ордеров начал исполняться, это тоже удобно анализировать, вернее это не нужно анализировать, т.к. всегда знаешь что исполнился 1 лот, в отличие от стопа когда он весит например на 7 лотов. Хотя это одно и тоже.
Из последний вариантов что осталось попробовать - это реализовать алгоритм отслеживания очереди и по 1 ордеру отрабатывать в main() с подтверждением исполнения ордера в onStopOrder(). Т.е. скажем в 1 раз в 100 мил. отслеживать состояние очереди с заявками на стоп ордера - где добавить, а где снять.
Константин Рейм написал: Простой пример. Есть робот - отслеживает ваши ручные манипуляции. Открыли руками 10 лотов - робот это увидел через Таблицу сделок (они - сделки там появились). Как только открыли 10 лотов, бот самостоятельно уже без вашего участия выставил по за ранее заданным вами параметрам стоп и тейк. Потом вы решили закрыть руками 3 лота - закрываем 3 лота - 3 закрытых лота так же появились в Таблице сделок - бот видит что закрыто 3 лота - значит открытая ранее позиция на 10 лотов сократилась и стала 7 лотов. Бот заявки стоп и тейк по 10 лотов снимает и выставляет по 7 лотов.
И получается что вы снимаете всю пачку стоп-пов и их по новому переставляете.
Константин Рейм написал: Простой пример. Есть робот - отслеживает ваши ручные манипуляции. Открыли руками 10 лотов - робот это увидел через Таблицу сделок (они - сделки там появились). Как только открыли 10 лотов, бот самостоятельно уже без вашего участия выставил по за ранее заданным вами параметрам стоп и тейк. Потом вы решили закрыть руками 3 лота - закрываем 3 лота - 3 закрытых лота так же появились в Таблице сделок - бот видит что закрыто 3 лота - значит открытая ранее позиция на 10 лотов сократилась и стала 7 лотов. Бот заявки стоп и тейк по 10 лотов снимает и выставляет по 7 лотов.
Получается это никак не отличается от события OnTrade(). Вы отслеживаете число. Хотя я пробовал отслеживать кол-во из таблицы ограничений по клиентским счетам.
Николай Камынин Поэтому пока вы снимаете старый стоп и выставляете новый - это все будет исполнять сервер квика, сервер биржи уже продаст следующую часть в вашей заявке. -----------------
Можно пожалуйста про эту часть поподробнее что имеется в виду?
Всё подробно написано как устанавливать. Надеюсь, у вас не 8.5 версия (где Lua версию изменили)
Да эту библиотеку видел w32. Но пока решил отказаться от звуков для кнопочек, т.к. опять проблема совместимости начинается в 8. Решил оставить только звуки для важных событий - а на них не вижу страшным что экран будет черный показываться и скрываться по крайней мере на данном этапе работ.
Можно создать стоп ордер - NEW_STOP_ORDER Можно удалить стоп ордер - KILL_STOP_ORDER
Каждое из действий является 1 транзакцией и 1 событием.
Как грамотно написать функцию изменения текущего ордера, что-то вроде MODIFY_STOP_ORDER? Не нашел в сети материалов на данную тему. На форуме есть несколько не развернутых примеров. Хотелось бы больше информации.
Константин Рейм, а как понять какие сделки актуальны на данный момент в таблице сделок? Допустим было куплено 10 контрактов, и в ручную закрыто 3. 7 никак не висят в статусе активно в отличие от таблицы заявок и таблицы стоп-ордеров.
Иван написал: А вот как быть когда начинаем закрытие частями этих 30 лотов.
Закрываем то не по стопу, а по тейку? Есть поза 30 лотов и есть уже 2е стоп-заявки 10 и 20 лот. Закрыли по тейку 7 лотов - поза = 23, стопов пока что 30, снимаем скажем стоп 10 лот и вместо него ставим стоп на 3 лота. OnTrade() - давно уже не пользуюсь. 7 лотов прошли - отследили по Таблице сделок. Бот видит что поза стала 23 - пересчитали объем стоп-заявок.
Я имею в виду про ручное закрытие. Цена может подойти к стопу, в ручную закрылись. Цена может подойти к тейку. В ручную закрылись.
Суть проблемы описал выше. У меня стоп выставляется сейчас когда срабатывает событие OnTrade().
Купили 30 лотов. Сработало в OnTrade() 10 лотов - выставиться стоп 10 лотов. Сработало в OnTrade() 20 лотов - выставиться стоп 20 лотов. Итого 2 стопа на 30 лотов.
А вот как быть когда начинаем закрытие частями этих 30 лотов. Как объем стопов пересчитать? Если бы у меня стояло не 2 стопа, а 30 стопов по 1 лоту каждый, то здесь также можно сделать через OnTrade(). Закрыли 15 лотов (50% позиции), убрали 15 стопов.
Да это забавно - согласен. Речь была не про это - а про то, что бы посмотреть. У меня он так и не запустился. Единственная библиотека которую я смог запустить для звуков это w32.dll.
Но хотелось бы также что бы можно было остановить звук. То получается могут проигрываться два параллельны звука.
Добавил:
Код
-- /i Передает начальные установки среды интерпретатора Cmd.exe в новое окно командной строки.
-- /min Запускает новое окно командной строки в свернутом виде.
-- /b Запускает приложение без открытия нового окна командной строки. Обработка комбинации клавиш CTRL+C не производится, пока приложение не разрешит обработку CTRL+C. Для прерывания приложения следует использовать CTRL+BREAK.
Иван написал: LogWrite("report", comment, {Trade=100, Code=Si, Q="-"..10, Price=10000, Pips=1}); В функции делаю чтение массива:Код function LogWrite(name, log_type, log_array)
local content = ""; local i = 1; for key, value in pairs(log_array) do content = content.."\t"..value..";"; content = string.gsub(content,"([.]+)",","); i = i + 1; end; message(tostring(content));
end;
function LogWrite(name, log_type,t) local content = ""; local i = 1; for m=1,#t do local value=tostring(t[m]) content = content.."\t"..value..";"; content = string.gsub(content,"([.]+)",","); i = i + 1; end; message(tostring(content)); end; local Si=123 LogWrite("report", "", {100,Si,"-"..10,10000,1}); ------------------- 100; 123; -10; 10000; 1; >Exit code: 0
Не совсем понял при чем здесь HFT роботы (высокочастотники как понимаю)?
Сейчас у меня стоп выставляется через функцию OnTrade(). Прошла сделка объемом 7 = выставился стоп объемом 7.
Сложность начинается тогда, когда мне нужно сделать закрытие частями. К примеру хочу закрыть 30% сделки - это будет 3 контракта.
Соответственно сделка прошла и OnTrade() вижу что мне нужно изменить стоп на 7 контрактов. И здесь начинаются сложности - удали стоп 7, выставь стоп 4. Это хорошо сработает если исполнится 3 контракта сразу. А если они исполнятся по 1, 1 и 1. Т.е. мне нужно удалить стоп 7, выставить стоп 6. Удалить стоп 6 (которого возможно еще нет в живых), поставить стоп 5, удалить стоп 5 (которого также еще нет), поставь стоп 4. Сложность в этом.
Обычно выставление стоп-лосса затачивается на то какой объем был куплен или продан. Продали 100 контрактов = 1 стоп на 100 контрактов Учитывая то что продажа 100 контрактов может происходить частями по 45 по 5 и по 50 контрактов, то соответственно можно и стопы также выставить по 45 по 5 и по 50. И здесь при закрытии позиции начинаются сложности - закрытие также может произойти частями по 30, по 20 и по 50. И сложно пересчитать каждый из ордеров.
Другое дело если каждый ордер это 1 контракт. Продалось 30 контрактов - сняли 30 стопов. Продалось еще 20 - сняли 20 и т.д. Насколько вообще в принципе жизнеспособна идея купив к примеру 100 контрактов выставить не 1 стоп, а 100 стопов по 1 контракту.
При торговле на 10 контрактов по инструменту допускаю что все это допустимо 10 продано = 10 ордеров. А вот когда число контрактов 100, 500?
Подскажите пожалуйста, есть ли возможность выбирать отфильтрованные, отсортированные данные из таблиц хотя би примитивными способами на уровне SEL ECT * FR OM table SORT sec_code WHERE sec_code = Si. А то получается при запросе данных нужно каждый раз обходить таблицу.
Но звук будет проигран не в фоновом режиме. Обычно воспроизведение звука занимает 5-10 секунд, что останавливает основную работу скрипта. Можно ли как-то проиграть данную команду в фоновом режиме. Либо как-то запустить проигрыватель VLC.exe для проигрывания звука в фоновом режиме?
Возможно ли данную команду запустить в фоновом режиме? Или к примеру переключить на использование VLC.exe проигрывателя? Интересует именно фоновый режим.
function LogWrite(name, log_type, log_array)
local content = "";
local i = 1;
for key, value in pairs(log_array) do
content = content.."\t"..value..";";
content = string.gsub(content,"([.]+)",",");
i = i + 1;
end;
message(tostring(content));
end;
Массив считывается через цикл, но почему-то у него получается иная последовательность. На выходе ожидаю строку: 100; Si; -10; 10000; 1; По факту последовательность другая: Si; 1; 100; -10; 10000;