"на фига козе баян", Кто же не умеет считать среднее арифметическое и стандартное отклонение, это фундамент тех. анализа. А все дело в производных, в "побочных продуктах" как говорит автор, которые мы можем рассчитать определив оптимального f.
Заметил ошибку надо исправить строку local standard_deviation = math.sqrt(variance_HPR), т.е. перейти от дисперсии к отклонению.
И так правило номер два торгуем с левой стороны от оптимального f, в в теории конечно нужно на вершине, но на практике есть маржинальные требования. Что дает нам расчет побочных продуктов, прежде всего отвечает на вопрос, каким количеством эффективно нужно торговать, какое нужно количество сделок нужно для достижения цели, какой необходимо поддерживать депозит для эффективной торговли и много еще чего, кроме того сделка ка бы хеджируется, но просадки все рано могут быть значительно глубокими. Всего не возможно рассказать в рамках поста, добавлю лишь как я всем этим пользуюсь, рассчитываю 2 раза, в начале при проектировании сделок, затем по результатам моей ТС, анализирую и провожу корректировку. Сейчас все приделываю под портфель, ввожу 3 стратегии управления, и здесь есть существенные отличия! Дерзайте, всем хорошей торговли.
VPM, Все, что Вы повторяете из прочитанных Вами книжек есть лишь пересказ чужих рассуждений. ------ Возможно будет работать, а возможно и нет. ----- Есть еще множество различных рассуждений в подобных книжках. ------------------------ Было бы интересно увидеть результат применения ваших скриптов хотя бы на истории, которая уже есть в КВИКЕ. А написать что-то на луа ,да еще без тестов - это может любой начинающий. ------------------------- Покажите хотя бы какой-нибудь результат. Ну хотя бы советника , который будет иметь положительное мат ожидание сделок хотя бы на истории. ------------------- Уверен, что не получится. Можете доказать иное?
nikolz написал: Все, что Вы повторяете из прочитанных Вами книжек есть лишь пересказ чужих рассуждений. ------Возможно будет работать, а возможно и нет.-----Есть еще множество различных рассуждений в подобных книжках.
Так и я про это, очень много чего понаписано на тему трейдинга, полезного мало, вот и заостряю внимание на полезном на мой взгляд, рассуждаю о том что практикую, а цитирую для понимания вопроса.
Цитата
nikolz написал: Было бы интересно увидеть результат применения ваших скриптов хотя бы на истории, которая уже есть в КВИКЕ.А написать что-то на луа ,да еще без тестов - это может любой начинающий.
Так я же говорю, что у меня стадия разработки, довожу программу, вот тесты показали недостатки в управлении капиталом переделываю и некоторыми соображениями делюсь, вообще мои посты это последовательность разработки моей программы. Торговые стратегии еще даже не отлаживал, на кидал примеры, это собственно основное ради чего все делается. К стати если не жалко поделитесь индикатором для вывода кривой Equity, наглядно а руки не доходят. Что касается вопроса писать на луа, это простой пример, почему удобно строить структуры, и ими оперировать, плюс не сколько простых формул.
Цитата
nikolz написал: Покажите хотя бы какой-нибудь результат. Ну хотя бы советника , который будет иметь положительное мат ожидание сделок хотя бы на истории.-------------------Уверен, что не получится. Можете доказать иное?
Ну Вы меня тут удивляете, Вы выкладываете картинки, где у Вас показан рост кривой Equity, я не думаю что Вы не знаете как рассчитывается мат ожидание? Я лишь покажу как я это применяю, да и делал про это сообщения ранее. У меня написан класс local result={}; в нем определяю параметры необходимые для учета и анализа сделки, сделка здесь своя (т.е. закрытие или уменьшение позиции). далее реализую метод (функцию) function result:Evaluating_Trading_Systems(res) на вход которой, подаю массив res={} local symbol=res.id; local d=res.d;local t=res.t;local sW=res.w;local nW=res.nw;local sL=res.l; local nL=res.nl; local Q = nW+nL; где nW,nL - количество выигрышных, проигрышных сделок; sW,sL - выигрыш, проигрыш в пиктах. расчет 3 основных показателей:
Мат. Ожидание считаю по формуле: МО = (%прибыльных Х средняя прибыль) - (%убыточных Х средний убыток). ПРОФИТ-ФАКТОР (profit factor) - отношение суммарного выигрыша от всех прибыльных сделок к суммарному проигрышу от всех убыточных. Имеет смысл с реинвестированием. Процент прибыльных сделок (Percent Winning Trades) local pWT = Q~=0 and pWT = nW/Q or 0;
Это основные без которых не возможно спроектировать систему, остальные вспомогательные.
в роботе делаю вызов после каждой сделки, ну собственно про это уже писал нет смысла повторяться.
Относительно не давно на форуме обсуждалась тема различных проверок до исполнения приложения и во время исполнения. Ветку честно говоря поленился искать, так как тема подходит для освящения данного вопроса и в этой, какие уж тут принятия решений, если данные получены не верные. Решил обсудить здесь, подход к этому вопросу предлагаю не совсем традиционный. Суть в следующем: В Lua относительно легко реализуется, событийно-ориентированная модель программирования, она хорошо подходит для обработки асинхронных событий. Такой подход позволяет приложениям Lua обрабатывать несколько событий одновременно без блокировки основного потока выполнения приложения. События обрабатываются в фоновом режиме, не прерывая поток выполнения приложения. В приложениях регистрируют функции обратного вызова для обработки конкретных событий. Когда происходит событие, соответствующая функция обратного вызова вызывается для его обработки, а затем управление возвращается потоку выполнения приложения. Такой подход (обработка асинхронных событий) мне показался логичным для обработки не торговых операций, к примеру отслеживаем время торгов, торги идут передаем управление в основной поток для проведения операций, отследили время остановки (событие пришло) остановили выполнение. Этот подход обеспечивает эффективное использование ресурсов, поскольку обработка событий происходит в фоновом режиме, быстро реагировать на изменения рынка. При последовательном выполнении все задачи выполняются одна за другой, в порядке их появления, часто это приводит к блокировке потока выполнения, особенно если отдельные задачи занимают много времени. К недостатком асинхронной обработки событий можно отнести - сложность отладки, сложно отладить проблемы, связанные с событиями, поскольку они происходят асинхронно. Не что не мешает регистрировать обработчик с управлением рисками, обработчик управлением позициями, стакана, чего угодно. Собрать полностью - Модель, ориентированною на события, обрабатывать большое количество одновременных событий без перегрузки системы. Помучившись один раз можно легко масштабироваться.
Код
coroutine.wrap(function() -- пример функции обратного вызова для отслеживания времени торгов
while run do
-- Получить текущее время торгов
local trading_time = get_trading_time()
print('trading_time =',trading_time)
-- Проверить, находится ли рынок в рабочее время
if is_market_open(trading_time) then
-- Перейти в режим торговли
start_trading()
else
-- Перейти в режим ожидания торгов
stop_trading()
end
-- Задержка перед следующим обновлением времени торгов
coroutine.yield()
end
end)()
coroutine.wrap(function() -- пример функции обратного вызова для обработки событий котировок акций
while run do
local quote = generate_quote() -- Получить котировку
process_quote(quote) -- Обработать котировку
end
end)()
VPM написал: Суть в следующем: В Lua относительно легко реализуется, событийно-ориентированная модель программирования, она хорошо подходит для обработки асинхронных событий. Такой подход позволяет приложениям Lua обрабатывать несколько событий одновременно без блокировки основного потока выполнения приложения. События обрабатываются в фоновом режиме, не прерывая поток выполнения приложения.
Вы зачем вносите "смуту" в неокрепшие умы ? Откуда вам известно, что коллбеки не блокируют поток main? Вы прежде чем писать свои сообщения, почитайте сообщения, квалифицированно объясняющие взаимодействие коллбеков и потока main (их много, написанных ранее чем вы появились на форуме). Оттуда вы сможете почерпнуть, что коды на Lua (это не C-функции) синхронизируются (выполняются последовательно, то есть, когда выполняется Lua-код, то Lua-код потока main блокируется и наоборот). Вообще, я не стал бы комментировать ваше сообщение, но вы своими безопеляционными сообщениями можете сбить с толку тех, кто не в теме. Свои неокрепшие мысли, наверное, можно записывать в своем локальном дневнике.
TGB, "Зачем козе баян"? В Ваш "неокрепший ум смуту" внести мне не под силу. Вам бы не мешало для начало научиться читать, от начало до конца, улавливая смыслы. А поэтов здесь хватает и без Вас. Что писать, о чем писать когда, писать, кому писать .... позвольте мне решать, заранее благодарю.
Теперь по сути вот целиком к прочтению Специально для Вас дублирую.
Цитата
VPM написал: Суть в следующем: В Lua относительно легко реализуется, событийно-ориентированная модель программирования, она хорошо подходит для обработки асинхронных событий. Такой подход позволяет приложениям Lua обрабатывать несколько событий одновременно без блокировки основного потока выполнения приложения. События обрабатываются в фоновом режиме, не прерывая поток выполнения приложения. В приложениях регистрируют функции обратного вызова для обработки конкретных событий. Когда происходит событие, соответствующая функция обратного вызова вызывается для его обработки, а затем управление возвращается потоку выполнения приложения. Такой подход (обработка асинхронных событий) мне показался логичным для обработки не торговых операций, к примеру отслеживаем время торгов, торги идут передаем управление в основной поток для проведения операций, отследили время остановки (событие пришло) остановили выполнение.
Ниже приведен пример, да же моей "козе" понятно что это сопрограмма. Функция обратного вызова зарегистрирована как сопрограмма для обработки различных событий. Известный факт, что поток выполнения приложения не блокируется при ожидании событий. Не знаю что тут еще нужно комментировать,
Да я и не настаиваю ни на чем, гоняю тесты с данным подходом вызывая срабатывание разных событий, и предлагаю к обсуждению этот подход.
VPM написал: TGB , "Зачем козе баян"? В Ваш "неокрепший ум смуту" внести мне не под силу. Вам бы не мешало для начало научиться читать, от начало до конца, улавливая смыслы. А поэтов здесь хватает и без Вас.
Вы меня, наверное, не поняли. Все-таки надо читать историю форума. Если вы хотите продолжить общение со мной в стиле (посмотрите начиная со ссылки и до конца ветки): https://forum.quik.ru/messages/forum10/message62917/topic7277/#message62917, то, при том что это мне не интересно, я вам это обеспечу.
TGB, История у форума огромная, и если есть на что сослаться, лучше давать ссылку, мы с Вами не так давно общаемся, чтоб я читал Ваши мысли, и давно уже всем предлагаю, обсуждать не мой стиль изложения а излагаемую проблематику, программирование на луа, меня это интересует. Да я не всегда бываю прав, и если это обосновано представлено всегда готов признать. А если нечего сказать по теме, то зачем плодить флуд, тем более что есть код.
VPM написал: Вы вообще о чем? Вы себя о позиционируете как опытного знающего программиста, не хотите обсудить код?
Причем тут опытный, знающий программист. Почитайте про взаимодействие коллеков и потока main в истории форума. Там много не моих сообщений. После чтения истории, вы, наверное, сможете понять, что коллбеки и поток main выполняются последовательно и тогда зачем мне читать ваш текст, в котором присутствуют какие то фоновые потоки вашего воображения.
TGB написал: После чтения истории, вы, наверное, сможете понять, что коллбеки и поток main выполняются последовательно
"что коллбеки и поток main выполняются последовательно" - не буду это комментировать, оставлю специалистам!!! И совсем не понимаю, что Вас так разволновало, Вы не знакомы сопрограммами или функциями обратного вызова? Или Вам не известно что в LUA реализована неблокирующая, асинхронная обработка сопрограммы : События обрабатываются в фоновом режиме, что позволяет приложению продолжать выполнять другие задачи без блокировки, до вызова события? Ну так попробуйте пример. Уже все рассказал и показал.
Вот, что тут не так? Библиотека coroutine в Lua предоставляет функции для работы с сопрограммами. Сопрограмма - это легкий поток выполнения, который может быть приостановлен, возобновлен и выполняться параллельно с другими сопрограммами. Сопрограммы могут быть полезны в различных сценариях, таких как:
Асинхронное программирование: Сопрограммы можно использовать для выполнения задач в фоновом режиме, не блокируя основной поток.
Конкурентность: Сопрограммы можно использовать для выполнения нескольких задач одновременно, используя одну и ту же среду выполнения.
Моделирование: Сопрограммы можно использовать для моделирования поведения различных агентов или объектов в системе.
VPM написал: что Вас так разволновало, Вы не знакомы сопрограммами или функциями обратного вызова? Или Вам не известно что в LUA реализована неблокирующая, асинхронная обработка сопрограммы : События обрабатываются в фоновом режиме, что позволяет приложению продолжать выполнять другие задачи без блокировки, до вызова события? Ну так попробуйте пример. Уже все рассказал и показал.
Если бы вы это писали в своем локальном дневнике, то мне бы было "по баробану", но вы это заявляете публично и безопяляционно, с уверенностью "отбитого" дилетанта. Вы же вводите в заблуждение тех пользователей, для которых программирование не является профессиональной деятельностью. Вы, что не понимаете, что сопрограммы выполняются в общем потоке с функцией, вызвавшей ее? Никакого фона выполнения сопрограмм не существует. Вообще, прежде чем выкладывать свои завиральные идеи, наверное, вам было бы полезно что-то почитать по IT.
VPM написал: Они не имеют собственного стека вызовов, а используют стек вызовов основного потока.
Опять не поняли (хотя написали формально правильно), что сопрограммы не могут выполняться параллельно с потоком, в котором вызваны, Вы понимаете что представляет собой поток в windows?
VPM написал: Так как складывается впечатление что Вы часть лекций пропускали, ни какой аргументации, одни эмоции, извините ну мне не интересно
У вас не только тексты, но впечатления сильно ошибочные . На всякий случай, я закончил ведущий московский институт с красным дипломом. И хорошо что вам стало неинтересно.
TGB, То что Вы пропустили это не страшно, всегда можно почитать или взять курсы, самомнение с этим обычно жизнь разбирается. А то что красный диплом не научил высказываться аргументировано это не ко мне, удачи. В качестве примера можете взять HackTrade чтоб до разобраться. Да и я до соберу простую "рыбу" выложу.
VPM написал: Да и я до соберу простую "рыбу" выложу.
Это не лечится :: Сдаюсь
Не лечится на этом форуме только одно - флуд, (хотя если на жизнь этим зарабатываете, то и ладно, не понятно зачем вообще тогда диплом, хотя в жизни всякое бывает). Посчитай те сколько сообщений и хоть одно бы по теме было?
Пример с отслеживанием времени работы, событиями котировок и исполнением сделок, использующий случайные числа для входов:
math.randomseed(os.time())-- Модуль для генерации случайных чисел
function generate_trading_time()-- Функция для получения случайного времени торгов
return math.random(0, 24) -- Возвращает случайное время в часах (0-24)
end
function is_market_open(trading_time)-- Функция для проверки, находится ли рынок в рабочее время
return trading_time >= 9 and trading_time <= 17
end
function generate_quote()-- Функция для получения случайной котировки
return {
bid = math.random(100, 110),
ask = math.random(110, 120),
volume = math.random(1000, 5000)
}
end
local threshold = 110
function generate_event(quote)-- Функция для генерации события "купить" или "продать"
if quote.bid > threshold then
return "buy"
else
return "sell"
end
end
--function execute_trade(event)-- Функция для имитации исполнения сделки
-- print("Исполнена сделка:", event)
--end
----- Функции для тестового примера:
--[[Описание:
generate_buy_event() и generate_sell_event() генерируют события “купить” и “продать” соответственно на основе предоставленной котировки. События включают тип сделки, цену и количество акций.
receive_event() имитирует получение события “купить” или “продать” из внешнего источника.
execute_trade() имитирует исполнение сделки на основе предоставленного события.
--]]
function generate_buy_event(quote)-- Функция для генерации события "купить"
return {
type = "buy",
price = quote.bid,
quantity = math.random(100, 1000)
}
end
function generate_sell_event(quote)-- Функция для генерации события "продать"
return {
type = "sell",
price = quote.ask,
quantity = math.random(100, 1000)
}
end
function receive_event()-- Функция для имитации получения события "купить" или "продать"
-- В реальном приложении эта функция должна получать события из очереди событий или другого источника.
-- Здесь мы имитируем получение события, используя случайное число.
math.randomseed(os.time())
local event_type = math.random() < 0.5 and "buy" or "sell"
local price = math.random(100, 120)
local quantity = math.random(100, 1000)
return {
type = event_type,
price = price,
quantity = quantity
}
end
function execute_trade(event)-- Функция для имитации исполнения сделки
print("Исполнена сделка:", event.type, event.price, event.quantity)
end
coroutine.wrap(function()-- Отслеживание времени торгов
while true do
-- Получить текущее время торгов
local trading_time = generate_trading_time()
-- Проверить, находится ли рынок в рабочее время
if is_market_open(trading_time) then
-- Перейти в режим торговли
print("Переход в режим торговли")
else
-- Перейти в режим ожидания торгов
print("Переход в режим ожидания торгов")
end
-- Задержка перед следующим обновлением времени торгов
coroutine.yield()
end
end)()
coroutine.wrap(function()-- Отслеживание котировок и генерация событий
while true do
-- Получить котировку акции
local quote = generate_quote()
-- Сгенерировать событие "купить" или "продать"
local event = generate_event(quote)
-- Отправить событие
print("Сгенерировано событие:", event)
end
end)()
coroutine.wrap(function()-- Исполнение сделок
while true do
-- Получить событие "купить" или "продать"
local event = receive_event() -- В этом примере мы имитируем получение события
-- Исполнить сделку
execute_trade(event)
end
end)()
-- Основной цикл приложения
while true do
-- Выполнять другие задачи, такие как управление пользовательским интерфейсом
end
end
Ну вот можно попробовать, в тестом варианте, асинхронный подход.
Это вывод скрипта: Переход в режим ожидания торгов Сгенерировано событие: sell Сгенерировано событие: sell ......
Видимо что не так с Модулем для генерации случайных чисел. Пробуйте критикуйте, пишите! Это один из подходов, он мне показался наиболее отражающим суть.
VPM написал: Видимо что не так с Модулем для генерации случайных чисел. Пробуйте критикуйте, пишите! Это один из подходов, он мне показался наиболее отражающим суть.
Проверил, генератор красавчик, ошибка в фикции вот поправленная function generate_quote() local bid = math.random(100, 120) return { bid = bid, ask = bid-1, volume = math.random(1000, 5000) } end
Специально для "не окрепших умов", кто все таки решится попробовать в своих приложения использовать сопрограммы луа.
Вот вкратце: Сопрограммы - это легкие потоки, которые позволяют выполнять код асинхронно в Lua. Функция coroutine.wrap() в Lua используется для обертывания обычной функции в сопрограмму. Функция coroutine.wrap() принимает одну функцию в качестве аргумента и возвращает сопрограмму, которая может быть запущена и приостановлена независимо от основного потока.
Синтаксис: coroutine.wrap(func) Где: func - функция, которая будет обернута в сопрограмму. Пример:
Код
-- Обернуть функцию в сопрограмму
local my_coroutine = coroutine.wrap(function()
print("Hello from coroutine")
end)
-- Запустить сопрограмму
coroutine.resume(my_coroutine) -- Выведет "Hello from coroutine"
В этом примере мы обернули функцию my_coroutine в сопрограмму с помощью функции coroutine.wrap(). Затем мы запустили сопрограмму с помощью функции coroutine.resume(), которая вывела “Hello from coroutine” в консоль.
Особенности: Сопрограммы могут быть приостановлены и возобновлены с помощью функций coroutine.yield() и coroutine.resume(). Сопрограммы совместно используют глобальную таблицу переменных с основным потоком. Сопрограммы могут использоваться для реализации асинхронных задач, таких как обработка событий, сетевые запросы и т. д.
Важно: Нельзя вызывать функцию coroutine.yield() в основном потоке. Нельзя вызывать функцию coroutine.resume() с сопрограммой, которая уже завершена.
Не буду вступать в полемику, но lua, как язык, без доп. библиотек - однопоточный. Поэтому о параллелизме не может быть речи. То что coroutine может останавливать исполнение и переключаться на другую - не означает, что они будут выполняться параллельно. Это всего лишь означает, что если Вы разделили пирог на куски, то можете откусывать от каждого по очереди, но не от двух сразу.
Nikolay, Последовательное исполнение это когда мы за пустили скрипт и он сверху вниз читает этот скрипт и его исполняет шаг за шагом. Сопрограмма меняет этот порядок, может в любом месте возникнуть и туда же вернуться после исполнения, это и есть асинхронное исполнение, меняется последовательность исполнения задач! Уж не знаю где я утверждал что Сопрограмма создает новый поток? Я лишь говорил что не блокируется основной. Ну да ладно с этим. Вы лучше скажите, что Вы думаете о таком подходе?
Это просто один из подходов, чаще всего используемый в сетевом взаимодействии. Но все это можно сделать и на очереди, когда вы создаете объекты - задачи и просто их перебираете, проверяете пока очередь не опустеет. Это называется неблокирующее ожидание. Есть задача - готова, очищаем. Нет - переходим к следующей, ожидая эту. Т.к. терминал - это передача команд на сервер и ожидание ответа, то такой подход конечно необходимо применять.
Мое понимание сопрограмм такое: ------------------------- Сопрограмма это VMLua, для которой выделен локальный стек в области памяти основной VMLua. ---------------------------- Поэтому у сопрограммы и основной программы общие глобальные переменные и функции. ------------------------- Запуск скрипта как сопрограммы позволяет останавливать выполнение скрипта сопрограммы и не портить локальные параметры функции,которая вызвана как сопрограмма, так как у каждой сопрогаммы свой стек VMLua. ---------------------- Если функцию вызвать без создания сопрограммы, то другая функция может быть запущена лишь по завершению этой, так как они исполняются в одном стеке ---------------------------- Использование сопрограмм не приводит к параллельному вычислению, а лишь позволяет последовательно исполнять функции по частям. -------------------------- В QUIK сопрограмма запущена в отдельном потоке и называется main.
VPM написал: и туда же вернуться после исполнения, это и есть асинхронное исполнение
Нет. Это не оно.
Асинхронность (asynchrony) часто подразумевает, что операция может быть выполнена кем-то на стороне: удаленным веб-узлом, сервером или другим устройством за пределами текущего вычислительного устройства. Т.е. вы передали запрос. Та сторона его приняла, долго выполняла (час), а по окончанию позвонила и сказала - готово. Т.е. есть бригада землекопов, копает яму, а вы на диване сидите, читаете. Часто это путают с многопоточностью, параллельным исполнением. Что как раз означает, что есть два землекопа и копают одновременно.
Вы же описываете немногопоточный concurrency. Как бы квази-парраллелизм. Хотя этот термин лучше не переводить. Впрочем, если считать, что задача 2 (поставленная позже) завершится раньше задачи 1, т.к. она просто быстрее выполняется, то да, наверно, чисто семантически, разбирая слово (a)sync это можно назвать асинхронностью. Хотя в данном случае просто мы переключались между задачами каждый квант и на вторую ушло меньше квантов, вот она раньше и выполнилась. Собственно в книге автора языка это описано в разделе 9.4. Невытесняющая многонитевость.
А сама концепция async/await была представлена в F# в 2007:
nikolz, Ну о какой Вы последовательности исполнения говорите, событие или пришло в основную последовательность, забрав на себя исполнение, и сломав последовательность, или не пришло и все исполняется последовательно. На минутку подставим что у нас не одно событие, а отслеживаем несколько? И каждое выскакивает когда вздумается. Похоже нужно дать определения. Но ведь у нас не абстрактные рассуждения мы говорим о луа (а это значить по умолчанию один поток). последовательность исполнения в котором постоянно ломают сопрограммы.
Nikolay, Асинхронность - это свойство системы или процесса, при котором операции выполняются независимо друг от друга и не блокируют друг друга. В асинхронной системе операции могут запускаться и завершаться в разное время, не дожидаясь завершения других операций. Какой из принципов луа нарушает?
Кажется я понял в чем идет путаница, асинхронность и параллельность - это два разных понятия! Асинхронность означает, что операции выполняются независимо друг от друга и не блокируют друг друга. Это позволяет системе выполнять несколько задач одновременно. Параллельность означает, что несколько операций выполняются одновременно на разных процессорах или ядрах.
Асинхронные операции могут выполняться на одном или нескольких процессорах, в то время как параллельные операции всегда выполняются на нескольких процессорах.
Асинхронные операции могут приостанавливаться и возобновляться, в то время как параллельные операции обычно выполняются без приостановок.
Асинхронный код обычно использует сопрограммы или обратные вызовы, в то время как параллельный код обычно использует потоки или процессы.
VPM написал: Кажется я понял в чем идет путаница, асинхронность и параллельность - это два разных понятия! Асинхронность означает, что операции выполняются независимо друг от друга и не блокируют друг друга. Это позволяет системе выполнять несколько задач одновременно. Параллельность означает, что несколько операций выполняются одновременно на разных процессорах или ядрах. Асинхронные операции могут выполняться на одном или нескольких процессорах, в то время как параллельные операции всегда выполняются на нескольких процессорах. Асинхронные операции могут приостанавливаться и возобновляться, в то время как параллельные операции обычно выполняются без приостановок. Асинхронный код обычно использует сопрограммы или обратные вызовы, в то время как параллельный код обычно использует потоки или процессы.
Не надо приписывать свойства какому-то определению. Я дал ссылку на, по сути, автора.
Цитата
Если вы считаете имитологию слова "асинхронным", существует два элемента:
"a", то есть "нет".
"синхронный", то есть "одновременно".
При объединяя эти два термина, вы увидите, что "асинхронный" означает "не одновременно".
Луа не нарушает принципы, а не обладает ими. То что есть сопрограммы, не делает язык Lua полноценно поддерживающим концепцию async/awit. Вы можете сопрограмму остановить. Вот и все. Из этого не следует, что она асинхронна. В Lua вы все равно будете сами проверять состояние сопрограммы, вызвав ее. Т.е. вы должны написать код так, что будете перебирать все активные сопрограммы последовательно. А вот уходить из очереди перебора они будет не последовательно. Все.
В языках где поддерживается полноценная асинхронная модель, вы не занимаетесь постоянным "дерганьем" сопрограмм. Она САМА сообщит, вызвав колбек. И кардинальное отличие будет в том, что асинхронная функция не блокирует основной код, а в Lua так не выйдет, будете просто переключаться между сопрограммами, остальные заблокированы, т.е. не выполняются.
1. Мой пример и мои рассуждения касаются луа и только луа (а не абстракций); 2. луа - одно поточен (пока, и "слава богу"!), 3. Сопрограмма в луа создает легкие потоки, они выполняются в одном потоке интерпретатора Lua. 4. Сопрограмму в луа, не нужно путать с параллельным выполнением задач на нескольких ядрах, используя потоки операционной системы. 5. Синхронность и Асинхронность это понятия технические, заимствованные в IT, наверняка так как Вы описываете и даете ссылки, только луа тут причем. 6. Синхронность в луа это последовательное выполнение задачи. 7. Асинхронность в луа это "черт из табакерки"
И это не истина в последнем инстанции, это мое понимание возможностей программирования на луа, описание конкретного примера для более легкого понимания проблематики, вообще даже не собирался это обсуждать, если бы не пафос отдельных представителей данного форума, меня интересуют возможности данного подхода и недостатки, накидал другую модель из очереди, но опасаюсь сюда уже выкладывать.
Lua ни при чем, да. Я вступил в дискуссию только потому, что начали применять термины, уже давно устоявшиеся, в применении к языку. Что может привести к иллюзии, что язык это поддерживает. Это также как применение функционального подхода к программированию на Lua. Сам язык, в чистом виде, не функциональный. Но если использовать определенные техники и конструкции, то вполне себе можно писать в функциональном стиле. Так и с асинхронностью.
Но здесь важно понимать зачем и для чего эта асинхронность была придумана. В первую очередь для клиент-серверного взаимодействия, когда стало очевидно, что прямой подход очень неэффективен для web разработки, работой с базой данных и т.д. Lua же - язык из 90-х, он даже раньше Питона, когда подходы к написанию программ были иные.
Nikolay, Легкий поток в Lua - это сопрограмма, которая может быть приостановлена и возобновлена независимо от основного потока приложения. Это позволяет выполнять код асинхронно, не блокируя основной поток. Легкие потоки являются более легкими и эффективными, чем потоки операционной системы, что делает их подходящими для приложений с большим количеством одновременных задач. Именно этот подход я и хочу обсудить, применительно к нашей прикладной задачи. Отслеживать события способом сопрограмм с обратным вызовом, ну к примере как Вы предлагали сделать общею таблицу событий и ее обрабатывать, удобней наверно даже в виде класса, что можно было масштабироваться и забыть про эту проблематику.
Да, но все это про переключение между сопрограммами. И если считать, что заканчивать свое выполнение они будут не в том же порядке, что создавались, то притянуть термин асинхронность можно. Вам надо самому реализовать алгоритм переключения между задачами (thread scheduler). Надо его постоянно вызывать в бесконечном цикле. Т.е. ни о каком фоновом исполнении речи не идет.
Впрочем, думаю это уже не столь важно. Лишь бы не думали, что сопрограмма магическим образом сама выполнится пока я вызываю другую функцию. Это не про Lua.
VPM написал: nikolz, Ну о какой Вы последовательности исполнения говорите, событие или пришло в основную последовательность, забрав на себя исполнение, и сломав последовательность, или не пришло и все исполняется последовательно. На минутку подставим что у нас не одно событие, а отслеживаем несколько? И каждое выскакивает когда вздумается. Похоже нужно дать определения. Но ведь у нас не абстрактные рассуждения мы говорим о луа (а это значить по умолчанию один поток). последовательность исполнения в котором постоянно ломают сопрограммы.
Не соглашусь с Вами. Обычно механизм прерываний по одной из двух схем. 1) Для событий делается очередь. События обрабатываются из очереди. пришло новое , встало в очередь. Если у событий есть приоритет, то оно может прервать выполняемое событие, если оно ниже по приоритету. 2) Пришло событие. Оно блокирует прием новых событий до исполнения этого. ---------------- Обе схемы обеспечивают последовательное выполнение событий. ---------------- Я говорю не абстрактно. Именно так реализуется обработка событий на уровне железа и OC. --------------------- Кораунды это яля потоки на уровне виртуальной машины. Бесспорно, так как железное ядро одно, то все работает последовательно. ----------------------- Если софт написан правильно, то ничего никто не ломает.
VPM написал: Nikolay, Легкий поток в Lua - это сопрограмма, которая может быть приостановлена и возобновлена независимо от основного потока приложения. Это позволяет выполнять код асинхронно, не блокируя основной поток. Легкие потоки являются более легкими и эффективными, чем потоки операционной системы, что делает их подходящими для приложений с большим количеством одновременных задач. Именно этот подход я и хочу обсудить, применительно к нашей прикладной задачи. Отслеживать события способом сопрограмм с обратным вызовом, ну к примере как Вы предлагали сделать общею таблицу событий и ее обрабатывать, удобней наверно даже в виде класса, что можно было масштабироваться и забыть про эту проблематику.
По-моему мнению, Вы ошибаетесь. Если железо одноядерное, то последовательное выполнение - это есть блокирование . При сопрограммах у вас основной поток луа останавливается. иначе это будет параллельное исполнение. Я говорил выше, что сопрограммы это всего диль отдельный стек для луа машины. т е не надо сохранять содержимое основного стека , так как отельный стек не занимается основным потоком. При работе с сопрограммами делается просто переход на другой стек вместо его сохранения и восстановления. Это позволяет прерывать исполнение функций в лбом месте и продолжат их исполнения с этого места. Это все. Но все это последовательно с остановкой всех , кроме одного.
Nikolay написал: Вам надо самому реализовать алгоритм переключения между задачами (thread scheduler). Надо его постоянно вызывать в бесконечном цикле.
Вот вариант предложенный.
Код
--Пример реализации алгоритма переключения между задачами в Lua. Планировщик задач извлекает задачи из очереди и выполняет их одну за другой, пока очередь не станет пустой.
--Алгоритм (thread scheduler) в Lua
--1. Первым шагом является создание очереди задач, которая будет хранить задачи, ожидающие выполнения. В Lua это таблица в качестве очереди.
local task_queue = {}
--2. Затем мы создадим несколько функций задач, которые будут выполняться нашим планировщиком задач.
function task1()
print("Выполнение задачи 1")
end
function task2()
print("Выполнение задачи 2")
end
function task3()
print("Выполнение задачи 3")
end
--3. Теперь мы можем добавить наши задачи в очередь задач.
table.insert(task_queue, task1)
table.insert(task_queue, task2)
table.insert(task_queue, task3)
--4. Далее мы реализуем сам планировщик задач. Планировщик будет извлекать задачи из очереди и выполнять их одну за другой.
function thread_scheduler()
while #task_queue > 0 do
-- Извлекаем первую задачу из очереди
local task = task_queue[1]
table.remove(task_queue, 1)
-- Выполняем задачу
task()
end
end
--5. Наконец, мы запускаем планировщик задач, вызвав функцию thread_scheduler().
thread_scheduler()
--Пример вывода:
--Выполнение задачи 1
--Выполнение задачи 2
--Выполнение задачи 3
nikolz, Не буду с Вами спорить но техническим аспектам, наверняка Вы лучше меня разбираетесь, да и интересуют они меня только в рамках прикладных задач.
То что имеется ввиду про асинхронность в луа можно представить следующим образом: Вариант1. Запустили поток main() и в нем шаг за шагом идет исполнение кода 1, 2, 3, 4, 5; допустим 5 задача это сопрограмма, запустили ее, сделала свое дело и остановили. То этот подход конечно последовательный. Вариант2. Моя текущая реализация программы следующая: Запустили поток main() в нем запускаю сопрограмму в ней выполняются стратегии, задачей которых создать приказ для выставления ордера, получив приказ, следует остановка сопрограммы, управление переходит в основной поток, в котором идет работа с ордерами и взаимодействие с терминалом, на новой интеграции основного потока все повторяется. Асинхронность здесь достигается за счет того что неизвестно когда сработает переход в основной поток. В синхронном варианте мы просто последовательно опрашиваем задачи, в мое варианте не известно когда будет событие повлёкшее переход (мой "черт из табакерки").
VPM написал: Асинхронность здесь достигается за счет того что неизвестно когда сработает переход в основной поток
Может я что-то не понял, но это просто аналогично вызову функции с ожиданием. И теперь представьте что вам надо установить 100 ордеров. Асинхронный подход был бы таким: отправили транзакцию с режимом ожидания ответа, вернулись в основной поток, занимаемся чем-то еще. Начинают приходить ответы транзакций, на них запускаем следующие асинхронные задачи по их обработке. И все это без блокировки. А если я буду ждать ответ от одной транзакции, то пока он не придет, я не могу отправить следующую. В результате эти 100 транзакций вместо 1 секунды, будут уходить минуту.
Nikolay, Не совсем понял что такое функции с ожиданием (нужно попробовать). Я про второй вариант описанный мной, не что не мешает выполнять все последовательно, просто нужно не ждать событие, а на каждой итерации основного цикла опрашивать. Но в мое варианте сопрограмма идет с задержками которые мы выставляем, у меня 1сек так как данные приходят так, здесь же идет расчет алгоритмом стратегий, расчет позиции, RM и тд. Основной цикл без задержек на что способна луа ну и машина, есть свой алгоритм управление активной заявкой , ответы от терминала стандартны через функции обратного вызова. На мой взгляд это наиболее быстрый метод обработки ордеров, позволяет с тиками работать.
Не очень понятно зачем задержки. При работе с сервером Вы не знаете когда придет ответ. У кого-то связь - GPRS, какой-то брокер не рассчитал нагрузку на сервера. В результате в тепличных условиях ответ транзакции приходит за 200 мс, а в плохих за 10 минут (реальная цифра). Поэтому эта 1 секунда не просто не нужна, а вредна.
Задача состоит из последовательных шагов: 1. Отправить транзакцию. 2. Обработать ответ транзакции. 3. Обработать появление ордера. 4. Обработать исполнение ордера. 5. Что-то еще, например, обработка изменения позиции
И все это вполне можно разбить на разные задачи. Т.е. надо отправить 100 транзакций - отправляем все разом. В колбеках (за неимением таблицы транзакций) проверяем ответы транзакций. Если ответ корректный, переходим к дальнейшей обработке - созданием последующих задач.
При этом есть параллельные задачи, например алгоритм принятия решений на появление нового бара. Если будете ждать на транзакциях, то появление нового бара вполне можете обработать с сильным запозданием.
При этом на языке поддерживающим async/await - это можно было бы сделать проще. В Lua мы должны создавать задачи (не важно каким образом) и обрабатывать их квантами, не блокируя и не ожидая какие-то фиксированные секунды.
Также, для примера, можно организовать заказ данных через CreateDataSource. Это задача, которая не должна блокировать исполнение скрипта. Иногда надо заказать десятки таких потоков и если ждать по каждому из них по секунде, то через сколько же времени приедет последний. А если это заказ, проверка, то всегда можно перейти к следующей задаче, если на данный момент еще данных нет. И так проверять пока данные не приедут.
Собственно, чтобы лучше понять как это все должно работать, лучше попробовать работу с базой данных для сотен пользователей. Если заниматься блокировками, то работы не будет, т.к. все будут ждать пока там у одного закончится задача. А если это еще web сервис с тысячами подключений, то и входящие запросы надо обрабатывать.
Nikolay, Возможно так понятней будет, накидал "рыбу".
Код
-- это main() создали основной поток
-- создается сопрограмма
local routine = coroutine.create(Robot)
while working do
---Запускается сопрограмма
local res, errmsg = coroutine.resume(routine)
--(Обработка заказов (Orders) вызывает на каждой итерации сопрограммы)
for trans_id, smartorder in pairs(SmartOrder.pool) do
smartorder:process()
end
-- Здесь нет задержки
end
function Robot()--сопрограмма
-- Выполняется сопрограмма
while working do
for i=1,#sec do
--... Обрабатываются стратегии
rule[i] = 'buy'
if then
smartorder = 'buy'
coroutine.yield() -- Переход в основной цикл
end
end
sleep(1000)-- Здесь задержка
end
end
Это просто вариация hack_trade. Если речь была про задержку потока main, то да она должна быть. Но секунда как-то много, хотя зависит от задачи, конечно. Но т.к. в данном примере Robot - это сопрограмма, то не очень понятно зачем там задержка. Чтобы что?
Да Вы абсолютно правы, я лишь варьирую вызовом, задержка нужна убрать лишние итерации слишком много не нужного образуется, да и логи тяжелые к концу торгового дня. Но это просто пример как можно.