Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Когда у Вас скрипт на тысячи, десятки тысяч строк, то писать в одном файле это смело. А когда у Вас уже написано много скриптов, то придешь к модулям, т.к. каждый раз писать одно и тоже - это тоже смело. При этом модуль - это не команда dofile в глобальном окружении, а нормальный модуль, подключаемый через require.
Nikolay написал: Когда у Вас скрипт на тысячи, десятки тысяч строк, то писать в одном файле это смело. А когда у Вас уже написано много скриптов, то придешь к модулям, т.к. каждый раз писать одно и тоже - это тоже смело. При этом модуль - это не команда dofile в глобальном окружении, а нормальный модуль, подключаемый через require.
Я тоже думаю об этом, но вижу определенные минусы - если блок кода выносишь в отдельную функцию / подключаемый модуль, мы теряем в загрузке памяти и скорости. Вызов отдельной функции требует больше времени, чем исполнения кода в основном потоке. Универсальный функционал модуля требует бОльшего числа полей, которые должны удовлетворять самые широкие потребности. Вот и интересно, кто как пишет, в каких ситуациях какие варианты предпочитают. Используют ли подгружаемые классы-таблицы... и т.п.
Медленней чем, что? У меня код с использованием десятка библиотек выполняется с одной итерация цикла где-то за 150-250 мс. При этом 60 мс - это установленная задержка. Вариантов то нет, если надо писать сложный код. Это будут классы, модули, функциоанальный подход и т.д. Иначе будет совсем не разобраться через некоторое время, открыв свой же код.
Это относится не только к скриптам для Квика. Это общая практика программирования.
Цитата
Вызов отдельной функции требует больше времени, чем исполнения кода в основном потоке
А где, собственно, это функция вызывается... Все выполняется в дополнительном потоке Квика - функции main. Функцию можно только упрекать в расходовании памяти на дополнительные локальные переменные, но скорость то тут причем.
А универсальное пишем как раз для того, чтобы писать скрипты быстро и удобно. Иначе код придется писать с нуля каждый раз. А если ошибка, то что, исправлять в каждом файле.
Иван Ру написал: Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно.
Иван Ру написал: Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Признаться, все более склоняюсь в сторону такой модели, в первую очередь из-за разрастания скрипта и усложнения его логики из-за чего работа и модификация скрипта становится все более затруднительной... Полагаю можно использовать такую структуру: - базовый скрипт, который определяет статус сессии и агрегирует информацию из коллбэков - описание классов (стратегия, позиция и т.п.) - типовые универсальные модули, например, удаление устаревшей части данных таблиц (цены, бид аск и т.п.), ежедневное определение ключевых временных точек сессии в формате posix, визуализация и логгирование информации и т.п. - собственно скрипты с описанием стратегий, логики определение сигналов на вход и выход и сопутствующих действий...
Если кто-то поделится своим видением организационной структуры - буду признателен
Поясню свое прежнее беспокойство - у меня большинство скриптов работает одновременно с большим числом инструментов, предполагается большой объем расчетов, опасаюсь, что в тех случаях когда они осуществляются не в теле основного потока (main), а путем многократного вызова функции, это может негативно сказаться на быстродействии скрипта.
Иван Ру написал: Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Признаться, все более склоняюсь в сторону такой модели, в первую очередь из-за разрастания скрипта и усложнения его логики из-за чего работа и модификация скрипта становится все более затруднительной... Полагаю можно использовать такую структуру: - базовый скрипт, который определяет статус сессии и агрегирует информацию из коллбэков - описание классов (стратегия, позиция и т.п.) - типовые универсальные модули, например, удаление устаревшей части данных таблиц (цены, бид аск и т.п.), ежедневное определение ключевых временных точек сессии в формате posix, визуализация и логгирование информации и т.п. - собственно скрипты с описанием стратегий, логики определение сигналов на вход и выход и сопутствующих действий...
Если кто-то поделится своим видением организационной структуры - буду признателен
Поясню свое прежнее беспокойство - у меня большинство скриптов работает одновременно с большим числом инструментов, предполагается большой объем расчетов, опасаюсь, что в тех случаях когда они осуществляются не в теле основного потока (main), а путем многократного вызова функции, это может негативно сказаться на быстродействии скрипта.
Проблема усложняется тем, что разработчики не утруждают себя документацией по API к их библиотеке, нигде не описывают интерфейс взаимодействия скриптов с терминалом на уровне API C for LUA. На основе ответов основного разработчика QLUA(не будем показывать пальцем) , по-моему мнению, схема взаимодействия скриптов с терминалом следующая: ------------------------------- Каждый скрипт условно можно разделить на три части 1) действия вне колбеков и функции main - это отдельный поток и VM Lua 2) функция main каждого скрипта - это отдельный поток и VMLua 3) вызов и исполнение функций колбек осуществляется в одном основном потоке термина. --------------------------- В итоге получаем следующее. Если Вы не профессионал , то скорее всего будете много делать в колбеках - так проще . Все колбеки будете вызывать в каждом из скриптов. ------------------------------- Получается прикольно. Даже если у Вас суперкомпьютер с 128 ядрами , то все колбеки будут тупо работать на одном ядре и в одном потоке, в котором крутится еще и основное ядро терминала КВИК. ------------------ Сейчас версию 7 заменяют на версию 8 В итоге XP с одним ядром не работает вообще. Но зато у Вас теперь win10 64 бита и ядер хоть 128. А что реально в сухом остатке? -------------------------- Представим что на телегу прикрутить двигатель от болида формулы 1, а впереди телеги все та же лошадь . Вопрос, насколько быстрее эта телега теперь довезет Вас из пункта А в пункт В? ----------------------------------------- Конечно есть решение костыльное - ничего не делать в колбеках, а делать все в main. Но резонно спросить разработчиков, а о чем думали они когда разрабатывали концепцию встраиваемой виртуальной машины? -------------------------------- Да и это костыльное решение не решает проблему многократного дублирования кода в различных скриптах. --------------------------------- На самом деле все могло быть существенно проще и исполняться существенно быстрее, но именно это никому не требуется. -------------------------- На рынке всегда решается лишь одна задача, за разработку инструмента для решения которой платят разработчикам, - как у буратины отобрать пять золотых. ----------------------------------- В итоге для целей конструирование игрушечных роботов, чем занимаются посетители данного форума, все сделано просто замечательно. ==================================================================================== "Теперь попросим на трибуну начальника транспортного цеха. Пусть доложит об изыскании внутренних резервов. "
nikolz написал: Каждый скрипт условно можно разделить на три части1) действия вне колбеков и функции main - это отдельный поток и VM Lua2) функция main каждого скрипта - это отдельный поток и VMLua3) вызов и исполнение функций колбек осуществляется в одном основном потоке термина.
Не совсем оно так, стейт для тела скрипта и колбеков один и выполняется в основном потоке квика, стейт для мейна второй и выполняется в специально для него созданном потоке. То есть ваш п.1 лишний, нет отдельного стейта для тела.
Ваши мысли насчет 128 ядер это из разряда давайте загрузим проц бесполезной работой, чо он простаивает-то. В любом случае ваши 100500 потоков будут сериализоваться на доступе к общим ресурсам, т.е. в основном (в таком количестве) они будут крутить спинлок. Для примера предлагаю прогу из directx sdk, где можно отрисовать одно и то же либо одним потоком, либо многими. Запустите и убедитесь, что проц оно жрет в N раз больше, а fps растет процентов на 5.
Это, конечно, похвально написать свой RabbitMQ, но, в результате, получится схема не меньшей сложности. Т.е. мы пишем свой терминал. Он будет собирать события терминала, исполнять команды скриптов и читать их ответы, передавать им поток данных.
При этом мы итак находимся внутри такого окружения... Что мешает написать скрипт исполняющий сразу несколько алгоритмов, по многим инструментам. Будет один скрипт, одно окружение. А колбеки Квика слишком ненадежная конструкция. Проще без них. Хотя, конечно, от части из них отказаться сложно, как, например, OnTransReply.
nikolz написал: Каждый скрипт условно можно разделить на три части1) действия вне колбеков и функции main - это отдельный поток и VM Lua2) функция main каждого скрипта - это отдельный поток и VMLua3) вызов и исполнение функций колбек осуществляется в одном основном потоке термина.
Не совсем оно так, стейт для тела скрипта и колбеков один и выполняется в основном потоке квика, стейт для мейна второй и выполняется в специально для него созданном потоке. То есть ваш п.1 лишний, нет отдельного стейта для тела.
Ваши мысли насчет 128 ядер это из разряда давайте загрузим проц бесполезной работой, чо он простаивает-то. В любом случае ваши 100500 потоков будут сериализоваться на доступе к общим ресурсам, т.е. в основном (в таком количестве) они будут крутить спинлок. Для примера предлагаю прогу из directx sdk, где можно отрисовать одно и то же либо одним потоком, либо многими. Запустите и убедитесь, что проц оно жрет в N раз больше, а fps растет процентов на 5.
Я вам предлагаю для примера посмотреть алгоритм БПФ либо нейронной сети
Nikolay написал: Это, конечно, похвально написать свой RabbitMQ, но, в результате, получится схема не меньшей сложности. Т.е. мы пишем свой терминал. Он будет собирать события терминала, исполнять команды скриптов и читать их ответы, передавать им поток данных.
При этом мы итак находимся внутри такого окружения... Что мешает написать скрипт исполняющий сразу несколько алгоритмов, по многим инструментам. Будет один скрипт, одно окружение. А колбеки Квика слишком ненадежная конструкция. Проще без них. Хотя, конечно, от части из них отказаться сложно, как, например, OnTransReply.
вообще-то я написал о том, что сделал сам лет ...надцать назад, т е фактически сразу как внедрили VMlua в квик. А перед этим примерно года за два я сам в переписке с руководством разработчика предлагал внедрить вместо QPILE LUA. не утверждаю, что они меня послушались, но в результате появился луа в квике. --------------------- Тот механизм, о котором я написал, позволяет очень просто делать много роботов по различным алгоритмом для одного инструмента. Колбеки не дублируются в скриптах Каждый колбек существует в своем скрипте и вызывается всего один раз квиком для получения данных вне зависимости от числа роботов. Роботы получают требуемые данные от этого скрипта. т е потоки синхронизируются и обмениваются данными , а также чтобы не дублировать код, могут запускать функции других скриптов через механизм колбеков между скриптами. Сравнительно просто в этом варианте отдавать данные совершенно независимым процессам. ----------------------- Но если не мечтать о вечном, то проще всего делать роботов как индикаторы.
Ребята, вы о высоком, признаться я уже не все понимаю. Если вернуться к реальности, где основная масса, включая меня - любители, а не профессионалы в программировании, и мы имеем, то что имеем, остаются интересные вопросы с потенциально возможными интересными ответами.
- Целесообразно ли минимизировать использование колбэков и как? - Стоит ли писать общие классы-таблицы для роботов? - Как конкретно оптимально подгружать универсальные функции... И т.п. и т.д.
nikolz написал: Я вам предлагаю для примера посмотреть алгоритм БПФ либо нейронной сети
Не спорю, тяжелая вычислялка, пригодная для распараллеливания, от потоков выиграет. Но такое на луа писать несколько самонадеянно, даже и в виде длл. Если данные в виде луа-таблицы, мы больше потеряем на доступе к ней, тут нужны плейн массивы. В сухом остатке на долю луа остается периодически подбрасывать новые данные по мере их приезда с сервера, а для этого много потоков не нужно и даже вредно, сеть-то сама по себе труба в одну нитку. Равно и в обратную сторону, можно натыкать миллион транзакций и они встанут в очередь на сокете и ничего более. В данном случае асинхронность лучше многопоточности, а у этого подхода есть ограничительный фактор - целевая аудитория может ниасилить.
Иван Ру написал: - Целесообразно ли минимизировать использование колбэков и как?
Это вопрос архитектурный. Варианта два.
Первый - это event-driven архитектура, тут колбеки движущая сила всего, пришел колбек - это событие, вы это событие как-то обрабатываете, если обработка предполагает что-то тяжелое - вы только запускаете операцию и возвращаетесь из колбека, а о ее завершении вам сообщит другой колбек, уже ваш собственный.
Второй это поллинг, ваш мейн шаг за шагом следует какому-то плану. Где ему нужны какие-то данные, он их заказывает и ждет ответа, где нужно что-то отправить он отправляет и ждет ответа. Уже по описанию видно, насколько шустро оно будет работать, хотя есть, несомненно, задачи, в которых и так сойдет. Другой недостаток - вы видите какое-то событие только в тот момент, когда решили на него посмотреть, а оно может уже часа два как произошло. Например, пока вы считали что-то и готовили транзакцию, квик потерял соединение, но вы еще об этом не знаете и продолжаете готовиться к своей сделке века, которая закончится ничем, бо нет коннекта. Утрирую для наглядности.
Третий вариант это как тут часто в вопросах попадается, когда смешали все в кучу и получилась, естественно, куча.
Иван Ру написал: - Целесообразно ли минимизировать использование колбэков и как?
Это вопрос архитектурный. Варианта два.
Первый - это event-driven архитектура, тут колбеки движущая сила всего, пришел колбек - это событие, вы это событие как-то обрабатываете, если обработка предполагает что-то тяжелое - вы только запускаете операцию и возвращаетесь из колбека, а о ее завершении вам сообщит другой колбек, уже ваш собственный.
Второй это поллинг, ваш мейн шаг за шагом следует какому-то плану. Где ему нужны какие-то данные, он их заказывает и ждет ответа, где нужно что-то отправить он отправляет и ждет ответа. Уже по описанию видно, насколько шустро оно будет работать, хотя есть, несомненно, задачи, в которых и так сойдет. Другой недостаток - вы видите какое-то событие только в тот момент, когда решили на него посмотреть, а оно может уже часа два как произошло. Например, пока вы считали что-то и готовили транзакцию, квик потерял соединение, но вы еще об этом не знаете и продолжаете готовиться к своей сделке века, которая закончится ничем, бо нет коннекта. Утрирую для наглядности.
Третий вариант это как тут часто в вопросах попадается, когда смешали все в кучу и получилась, естественно, куча
Что касается этого аспекта - выбор я уже давно сделал в пользу второго варианта, коллбэки я либо не использую, либо они играют второстепенную роль. Колбэк я считаю вариантом не надежным (задержки, не сработал и т.п.), в то время как обработка в теле main позволяет не только получать данные, но и разные статусы, например, соединения нет, торгов нет, данные ни фига не получены, или они получены, но вряд ли актуальны. Картина получается куда полнее. С учетом того, что скорость транзакции у меня составляет порядка 150 мс, мне достаточно раз в 50 мс пробежаться по нужным параметрам в main, не вижу особого смысла в коллбэках разве только как в страховке или способе финальной верификации данных (о транзакции). Меня больше интересует архитектура в плане разделения на модули и классы, степени их универсальности, способе подгрузки, компоновки рабочей стратегии из разных элементов конструктора.
Простой пример. Торгую я (вы) фьючерсами. Скрипт не трогаем, хотим чтобы он работал сам многие дни. Значит у нас периодически, желательно ежедневно, надо инициировать инструментов вплоть до выбора их корректного названия кода, на основе соответствующей таблицы из Квик, которая периодически меняется/обновляется. У меня эта задача реализована так - в двух случаях, 1) при смене даты, 2) при проходе через временную точку 9 часов 40 минут вызывается функция инициализации инструментов-стратегий. Задача делается отчасти с помощью подгружаемого модуля, который сравнивает короткие коды инструментов, их календарный индекс с данными настроек стратегии в роботе. Раньше вызов этих функций делал в OnInit и Main, теперь - только в main. Правда периодически случается что дата на сервере меняется после 10.00 !! По крайней мере такие данные прилетают... Интересно, кто как решает типовые задачи, какую архитектуру при этом использует. Например, чтение последней цены, бид-аск - в пределах main (быстрее) или вызовом отдельной функции. Ну ок, у вас отдельная функция, что функционально, пардон за тавтологию. Но если я читаю бид-аск 20 раз за секунду, по 10-ти инструментам, позволительно ли это делать в отдельной функции? Все относительно, но все же - какое количество вызовов сторонней функции позволительно для ресурсов мощной машины на ваш взгляд (очень грубой оценки достаточно).
Иван Ру написал: Но если я читаю бид-аск 20 раз за секунду, по 10-ти инструментам, позволительно ли это делать в отдельной функции?
Вызов функции не то чтобы тяжелая операция. Грубо ориентировочно наброшу цифр.
Если функция находится в длл, луа перед ее вызовом снимает лок, а после - снова захватывает, это самая тяжелая часть вызова (самого по себе вызова, не тела функции). Пара EnterCriticalSection/LeaveCriticalSection занимает порядка 100нс, новее железо - меньше. Всем остальным оверхедом вызова в сравнении с этим можно пренебречь, т.е. время на порядок меньше. Ок, чтобы получить оверхед в одну секунду, надо сделать порядка 10 миллионов вызовов функций из длл в одном цикле без слипов и прочих ожиданий.
Если функция написана на луа, лок не выпускается и остается только то, чем мы выше пренебрегли. Предполагая разницу на один порядок, получим, что секундный оверхед будет достигнут на порядка 100 миллионах вызовов.
Любопытства ради небольшой тест, тксть поверим теорию практикой (вариант с длл писать лень)
Код
function add_global(a, b)
return a + b
end
local function add_clocal(a, b)
return a + b
end
function main()
local count = 10000000
local function toftime(a)
local aa = a.hour
aa = aa * 60
aa = aa + a.min
aa = aa * 60
aa = aa + a.sec
aa = aa * 1000000
aa = aa + a.mcs
return aa
end
local function add_flocal(a, b)
return a + b
end
-- perform 'count' function-level function calls
local sum = 0
local tm = os.sysdate()
for i = 0, count - 1 do
sum = add_flocal(sum, i)
end
local tflevel = toftime(os.sysdate()) - toftime(tm)
-- perfrom 'count' chunk-level function calls
sum = 0
tm = os.sysdate()
for i = 0, count - 1 do
sum = add_clocal(sum, i)
end
local tclevel = toftime(os.sysdate()) - toftime(tm)
-- perform 'count' global function calls
sum = 0
tm = os.sysdate()
for i = 0, count - 1 do
sum = add_global(sum, i)
end
local tglobal = toftime(os.sysdate()) - toftime(tm)
-- perform 'count' inlined pseudocalls
sum = 0
tm = os.sysdate()
for i = 0, count - 1 do
sum = sum + i
end
local tinline = toftime(os.sysdate()) - toftime(tm)
-- show results
message("Function call overheads:\n" ..
" function-level function: " .. (tflevel - tinline) / count .. "us\n" ..
" chunk-level function : " .. (tclevel - tinline) / count .. "us\n" ..
" global function: : " .. (tglobal - tinline) / count .. "us\n")
end
nikolz написал: Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Цитата
nikolz написал: Тот механизм, о котором я написал, позволяет очень просто делать много роботов по различным алгоритмом для одного инструмента. Колбеки не дублируются в скриптах Каждый колбек существует в своем скрипте и вызывается всего один раз квиком для получения данных вне зависимости от числа роботов. Роботы получают требуемые данные от этого скрипта. т е потоки синхронизируются и обмениваются данными , а также чтобы не дублировать код, могут запускать функции других скриптов через механизм колбеков между скриптами. Сравнительно просто в этом варианте отдавать данные совершенно независимым процессам.
Здравствуйте. Подскажите пожалуйста, как реализовать подобный механизм ?
Владислав, вроде бы уже писал, но повторю. ------------------- чтобы не дублировать колбеки надо обеспечить возможность скриптам обращаться к общим данным. это можно сделать различными методами. ------------------------- Реализую это с помощью memory mapping. Кроме того, для реализации неблокирующей синхронизации потоков использую shared memory. Для параллельной работы с множеством инструментов использую пул потоков. ------------------ Примерно так.
Владислав, Лучше всего организовать ОДИН скрипт, работающий в ОДНОМ потоке и использующий ОДИН коллбек, а не заниматься всей этой фигнёй. Размер кода у меня в данный момент 37050 байт (это с диалогом, работой с файлами, обработкой коллбеков и всем остальным для срочного и фондового рынка), так что дробить его на куски не вижу ни малейшего смысла.
Владимир, nikolz, Благодарю за советы. На примере кода представленного Антоном выше, сделал тесты скорости получения ответа на транзакцию. По итогу думаю, что в рамках нескольких скриптов действительно смысла с заморочками нет. Тем более если скрипт работает с различными таблицами в QUIK. В моем случае, после отправки транзакции, происходит расчет прибыли от совершенной сделки, запись этой сделки в файл и т.п. Для того, что бы исключить возможные несостыковки, связанные с длительностью поступления данных в таблицу сделок и таблицу поз. по. кл. счетам, скрипт делает паузу в 1000мс. При такой реализации программы, смысла в заморочках точно нет. Но если речь идет о большом количестве скриптов, в которых все завязано на коллбеках, смысл думаю что есть.
Код для тестирования скорости:
Скрытый текст
Код
_G.client = {}
_G.client.account = "SPBFUT000he"
_G.client.class_code = "SPBFUT"
_G.client.sec_code = "BRV2"
_G.time = 0
local function toftime(a)
local aa = a.hour
aa = aa * 60
aa = aa + a.min
aa = aa * 60
aa = aa + a.sec
aa = aa * 1000000
aa = aa + a.mcs
return aa
end
function OnTransReply (trans_reply)
if trans_reply.sec_code == _G.client.sec_code then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("OnTransReply: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с")
end
end
function OnTrade (trade)
if trade.sec_code == _G.client.sec_code then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("OnTrade: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с")
end
end
function sendMarketOrder (client, quantity, comment)
local number = getNumberOf("trades")
local transaction = {
["TRANS_ID"] = '1',
["CLASSCODE"] = client.class_code,
["SECCODE"] = client.sec_code,
['ACCOUNT'] = client.account,
['OPERATION'] = quantity > 0 and 'B' or 'S',
['QUANTITY'] = tostring(math.abs(quantity)),
["ACTION"] = "NEW_ORDER",
["TYPE"] = "M",
['PRICE'] = "0",
["CLIENT_CODE"] = comment
}
_G.time = os.sysdate()
local result = sendTransaction(transaction)
if result == '' then
for count = 1, 30000 do
local new_number = getNumberOf("trades")
if new_number ~= number then
for i = new_number -1, 0, -1 do
local item = getItem("trades", i)
if item.trans_id == tonumber(transaction.TRANS_ID) then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("sendMarketOrder: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с "..count)
return true
end
end
end
sleep(1)
end
end
local fields = ""
for k, val in pairs(transaction) do
val = tostring(val)
fields = fields == '' and fields..k.." = ".."\""..val.."\"" or fields..", "..k.." = ".."\""..val.."\""
end
PrintDbgStr("sendMarketOrder: Ошибка транзакции: "..result..' '..fields)
return false
end
function main()
for i = 1, 10 do
PrintDbgStr("i: "..i)
sendMarketOrder(_G.client, 1)
sleep(3000)
end
end
Владислав, Тут уже не раз обсуждалось, что сама специфика торговли в Квике через Инет говорит о том, что время реакции на что бы то ни было измеряется в секундах. Не в миллисекундах, не в микросекундах, не в минутах, а именно в секундах. Ну или в диапазоне от десятых долей секунды до десятков секунд. А потому все эти дурацкие "тесты" с ловлей микросекунд есть Бред Сивой Кобылы. Мне всегда было плевать на "скорость получения ответа на транзакцию", но мой личный (зарегистрированный) "рекорд", когда прерывание OnTrade пришло через 17.5 минут (!!!) после отправки заявки (а снимаю заявки я через три минуты активности). И у меня вопрос: НА КОЙ кому сдались эти тесты скорости? Что бы они там ни показывали - И ЧТО? Поэтому Ваш оптимизм "Для того, что бы исключить (!) возможные несостыковки, связанные с длительностью поступления данных в таблицу сделок и таблицу поз. по. кл. счетам, скрипт делает паузу в 1000мс" кажется мне слишком уж оптимистичным. Про несколько скриптов я и вообще говорить не хочу - это алгоритмический идиотизм. Кстати, у меня "расчет прибыли от совершенной сделки, запись этой сделки в файл и т.п." происходит не "после отправки транзакции", а после прихода прерывания OnTrade.
Владислав, Несколько бесплатных советов. ------------------------- Тестирование скорости исполнения скриптов или отдельных функций делается для оценки имеющихся вычислительных ресурсов . ----------------------- Эти оценки необходимы для разработки в дальнейшем алгоритмов работы роботов, реализующих конкретную стратегию поведения. --------------- Если вы начинающий писатель, то начинать надо с выбора метода торговли (если это торговый робот) затем разработки алгоритма и реализации его. ---------------------------------- После этого наступает этап тестирования и определения адекватности его работы ожиданиям автора. --------- Частота совершения сделок а следовательно и скорость реакции робота зависит от выбранной стратегии торговли. ----------- Если Вы решили заниматься скальпингом, то скорость сделка в секунду может быть низкой, а если займетесь арбитражем, то возможно что и 1 сделка в минуту будет достаточно. ------------------ Поэтому рекомендую начать не с написания скрипта для торговли, а с разработки алгоритма торговли и тестирования его на истории. =============== И еще, если торгуете конкретным инструментом, то можно торговать без колбеков а робота написать в индикаторе. При этом скорость будет не ниже чем с колбеками а скрипт на порядок проще. ==================== Если используете колбеки, то более важной задачей является синхронизация сообщений и транзакций между собой так как интернет и биржевая торговля это источники асинхронных событий. ------------------ Если сделаете правильно, то робот будет работать без затыков и сообщениях об ошибках и всегда быстро будете получать реакцию на сделки. --------------- Примерно так.
nikolz, Ну каких, в жопу, "вычислительных ресурсов", лапуль? Для такой примитивной задачи, как организация торговли через Инет вполне хватило бы даже дохленького 8086, и уж за глаза любого компа, выпущенного в 21 веке. Это Вы тут постоянно зудите про многоядерные чудовища, которые нафиг никому не нужны. А криворукие бездари сожрут с аппетитом ЛЮБЫЕ ресурсы, им всё равно будет мало. В который раз уж советую: займитесь чем-нибудь другим, кроме программирования - тем, где Вы хоть что-то соображаете.
Владислав, Я не понимаю, что Вы подразумеваете под различными стратегиями, но да, всё в одном скрипте, и алгоритмы адаптируемые, их поведение зависит от состояния портфеля кошелька и от поведения рынка в данный момент времени на данном таймфрейме, от статуса, качества и текущей ликвидности тикера и ещё от ряда параметров.