nikolz (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 ... 8 9 10 11 12 13 14 15 16 17 18 ... 72 След.
GetParamEx2(). А что, так можно?
 
Цитата
Kolossi написал:
local aaa=getParamEx(p_classcode,"GMKN","EV_SESS_ALLOWED").param_value local bbb=getParamEx(p_classcode,"LSRG","EV_SESS_ALLOWED").param_value message(aaa.."/"..bbb)- aaa=getParamEx(p_classcode,"GMKN","EV_SESS_ALLOWED").param_image local bbb=getParamEx(p_classcode,"LSRG","EV_SESS_ALLOWED").param_image message(aaa.."/"..bbb)
Все правильно.
Данное поле имеет тип 3 .
И если прочитаете документацию, то там черным по белому на русском написано:
param_valueSTRINGЗначение параметра. Для param_type = 3 значение параметра равно «0», в  остальных случаях – числовое представление. Для перечислимых типов значение  равно порядковому значению перечисления
Вы это и получили
getParamEx
 
Цитата
Alexander написал:
Подскажите кто знает если. С помощью getParamEx есть ли параметры в ТТТ такие, чтобы отсортировать фьючерсы на акции от остальных фьючерсов. В квике по названию вроде ничего не подходит. Или как-то такое сделать по другому. Т.е. я получаю: sec_list = getClassSecurities("SPBFUT") и потом мне из всей этой кучи надо выделить только фьючерсы на акции. По класскоду у всех "SPBFUT", что у индексных, что у товарных, что у акционных. Пока вижу только вариант через string.gmatch и шаблон, но тогда для каждого варианта(смотрим на мосбирже все фьючи на акции) надо указать шаблон. Так пока делаю, но это длинно, для каждой акции свой шаблон. И спиок на бирже могут поменять и придётся менять код. Типа бы какого-нибудь не только класскоде, а ещё бы и подкласса иметь на фьючерсы на акции.
Когда-то давно делал так. На бирже находим правила формирования названия фьючерса. Далее по имени нужных нам акций формируем имена фьючерсов. При этом еще учитываем правило формирования даты фьючерса. Все вроде бы работало правильно.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:они как раз у тех у кого миллионные обороты.
Включите таблицу "всех сделок" и посмотрите на исполнение, когда пройдут пройдут 100 млн $ посчитайте сколько на берется сделок.
HFT роботы - это скорее инструмент маркетмейкера и тех кого он привлекает для подержания определенной ликвидности, есть конечно и частники как же без них.00 лет назад на современном рынке уже как телега с кобылой на шоссе.
Вы про айсберг -заявки знаете?
Я вам вообще-то про мировые рынки, которые подобно океану,  говорю, а не про российский рынок, подобный небольшому озерку.
Рекомендую почитать про обвалы на биржах США и кто их создал.  
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Цитата
Хотелось бы увидеть картину как трейдер с миллионными оборотами сидит и рассматривает минутки а лучше тики.
Это называется HFT роботы, они как раз у тех у кого миллионные обороты.
---------------------
Трейдер не сидит и не смотрит, так как это высокочастотный робот.
---------------------
Таких роботов сейчас на биржах из всей массы торгующих процентов 70.
-----------------
В инете, правда на английском, можно встретить статьи реальных крупных трейдеров,  которые торгуют сами . Они рассказывают как было до прихода HFT и как теперь стало трудно торговать и как они теперь меняют свои стратегии.
В итоге, то что в популярных книжках и сделано 100 лет назад на современном рынке уже как телега с кобылой на шоссе.
--------------------------------
Безусловно HFT не для частных инвесторов - это инструмент крупных банков, инвест. фондов, короче монстров фондового рынка.
move_orders, move_orders
 
Цитата
krabykraby написал:
GetParamEx?
эта функция получения параметра из архива терминала QUIK, а не сервера QUIK.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Цитата
nikolz написал:
из предполагаемой модели движения цены.
Сейчас расскажу с начала:
1) "Где деньги Зин"?
2) Чем цену двигают на рынке?
3) кто может поволить, безопасно для себя двинуть цену?

Вот Вам модель:
накопление позиции,  когда с рынка выбрано предложение, цена летит до уровня где встретит сопротивление.
Если сопротивление серьезное, буде распределение актива. И все сначала.

Вы поймите никто на рынке не устраивает игрушки с моделями и распределениями,
все рулит конъектура подчиненая закону Спроса и Предложения.  
Опять Вы ошибаетесь.
Закон Спроса и Предложения - это и есть модель рынка.
Модель - это упрощенное представление действительности.
Мозг всегда явно или неявно на основе опыта и знаний создает модели действительности и прогнозирует реальные события на основе этих моделей.
-------------------
Человек в своей деятельности всегда создает модели , прежде чем реализует что-то в будущем.
Закон - это формулировка некоторой закономерности на основе упрощенной модели действительности.
 
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
nikolz,
Цитата
nikolz написал:
Вероятностные события, это события которые могут произойти, но не обязательно. А прогноз - это и есть Ваше ожидание каких-то событий.
Индикаторы в основном отвечают на два постулата:
1) Определить направление тенденции;
2) Определить зоны Перекупленности / Перепродонасти.
Чтоб они стали статистически значимы нужна серьезная выборка.
А это значит и серьезное отставание от события.

Мы ищем приемлемое между сглаженностью и отставанием.
Так прогностический у нас взгляд или вероятностный?

При составлении рыночных прогнозов надо учитывать главное (фундаментальное)

Цены меняются согласно закона "спроса и предложения".
Когда спрос превышает предложение, то цены растут;  
Когда предложение превышает спрос, то цены падают.

Опытные трейдеры не торгуют против рынка!

управления через прогнозируемое, правильнее наверно подбор целей,
как и сам технически анализ основывается на ряде аксиом.
Одна из них "Если мы определили тенденцию то она будет какое то время продолжаться"

Ну к примеру делаем прогноз:

посчитали что измененни цены за прошлый год в среднем 0.5% роста в день.
   252р.д * 0.5% = 126% годовых нас устраевает.
Допустим есть отличный алгаритм определения точки входа.
Входим цель соответсвует нашему прогнозу,
но тут событие 02.22г. все рухнуло.
Пересчитываем теперь у нас измененни цены за прошлый год в среднем -0.5% снижения в день. Меняем цель.

Тут операторы заметили что рынок ушел сильно в зону перепроданости цены интересны и начинают накпление.

Это Вам не чего не на поминает?

подбор целей посмотрите Т.Демарка у него хотябы структурировано.
Возражая, Вы лишь подтверждаете то, что я сказал.
Попробую Вам это показать на Ваших ответах.

Вы возражаете против того, что всегда используете прогнозирование, но пишите

Индикаторы в основном отвечают на два постулата:
1) Определить направление тенденции;
2) Определить зоны Перекупленности / Перепродонасти.

1) и 2) - это и есть прогноз поведения цены и состояние рынка в будущем. Вы называете прогноз поcтулатом, но термин Постулат в данном случае не применим.
ПОСТУЛА́Т, - Исходное положение, принимаемое без доказательств.  
Т е постулат - это некие исходные предположения (аксиома)  но 1) и 2) - не содержат предположений, а определяют лишь Ваши желания.
---------------------------
Ваше утверждение: При составлении рыночных прогнозов надо учитывать главное (фундаментальное)
является  вашим ПОСТУЛАТОМ.
-------------
На самом деле что и как учитывает игрок на рынке зависит от его знаний и опыта, но любой игрок, делает прогноз перед тем как сделает ставку.
--------------------
Относительно Т.Демарка
Любой автор книжки или лектор на курсах всегда выстраивает некоторую логику в своих интересах, подбирает только те примеры из бесконечного множества, которые наглядно показывают, что он прав.
-----------------
Проблема в том, что на рынке будут обязательно ситуации, когда Ваш прогноз  по правилам Демарка будет ошибочным. Если бы было не так, то не было бы ни кризисов, ни постоянного притока буратин и оттока проигравших.  
Уверен< что Вы не читали, поэтому рекомендую почитать книгу Джорджа Сороса «Новая парадигма финансовых рынков», он ее написал после кризиса 2008 года.
Она сложнее, чем популярные книжки Демарка и других "прославленных"  брокерами гуру.  
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Цитата
nikolz написал:
является прогностическим и это не зависит от выбранных вами индикаторов.
А с чего  вдруг, в лучшем случае вероятным, если умеете ее считать.
Вы путаете понятия.
--------------------
Вероятностные события, это события которые могут произойти, но не обязательно.
А прогноз - это и есть Ваше ожидание каких-то событий.
Все решение о покупке или продаже Вы примите в будущем, так как в прошлом вы их уже приняли.
-----------------------
Вы принимаете решения на основе Вашего убеждения, что это решение правильное.
Если Вы покупаете, то Вы ожидаете,что цена пойдет вверх т е Ваш мозг прогнозирует.
Если Вы берете правила из книжки, то Вы используете чей-то алгоритм, который по мнению автора позволяет прогнозировать движение цены в ожидаемом направлении.
======================
В основе любого прогноза лежит статистика или иначе сказать накопленный опыт.
В итоге любое наше действие по жизни всегда связано с прогнозом его последствий.
-----------------------
То каким образом мы формируем свои ожидания определяется методом, который используем для прогноза.
--------------------------------
Если используете монте-карло, цепи Маркова или максимального правдоподобия , то это будет вероятностный прогноз т. е. решение  принимаем на основе вычисления оценки вероятности наступления данного события.
---------------------
Если используете индикаторы, а решения принимаете на основе их пересечения между собой или с уровнями, то Вы прогнозируете на основе статистических наблюдений в прошлом, но и в этом случае Вы используете априорную вероятность наступления событий.
-------------------
Т.е. Вы сознательно или нет всегда прогнозируете последствия своих действий и прогноз этот строите на основе статистики (опыта) связывая это с вероятности успешного решения.
 
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
и еще...
Относительно индикаторов в том числе RSI Вы немного заблуждаетесь.
Любое решение на рынке, кроме решений методом монте-крало, является прогностическим и это не зависит от выбранных вами индикаторов.
А вот индикаторы должны выбираться исходя из предполагаемой модели движения цены.
-------------------
Если Вы списываете индикаторы из книжки , то Вы должны быть уверены что рынок сейчас соответствует  модели рынка, которую взял автор этой книги.
----------------------
Самое прикольное, что все авторы этих бестселлеров на самом деле рассказывают одно и тоже и берут одни и те же индикаторы - самые простейшие цифровые фильтры как правило не выше 2-го порядка.
Поэтому с точки зрения цифровой обработки сигналов все эти гуру жонглируют примитивной арифметикой, при этом показывают специально подобранные эффективные картинки движения цены.
===============
В интернете Вы можете найти объемные статистические исследования практически всех книжных алгоритмов и доказательство что на большом интервале времени эти алгоритмы ничего существенного вам не дадут.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Цитата
Nikolay написал:
Уже давно были проведены количественные эксперименты по случайным методикам входа в позицию. Элементарно монеткой, кубиком. Все сводится к управлению рисками.
Про вход в позицию каждый день каждый из нас случайным образом, кому то удается вероятность подтянуть на свою сторону.
Знания арифметики в этом случае полезны, можно прикинуть сколько средств нужно чтоб двинуть рынок.
Цитата
Nikolay написал:
Впрочем, тем, кто не гадает, а изучает компании в которые собирается инвестировать, монетка не нужна, как и скользящие средние и т.д.
Плюс есть но не более. см мой пример с нефтью.
Рынки живут по закону Спроса и Предложения!
Не зная этих основ, тяжело рассчитывать на стабильность  и учитывать с кем имеешь дело.
Вы заблуждаетесь. Маркет -мейкер - это игрок на бирже, задача которого  сжимать спред. Т е у него просто стратеги играть против движения рынка. Ему за это биржа платит.
Но на рынке есть и обычные игроки которые играют против рынка. Поэтому маркет-мейкер ни при чем.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
На мой взгляд важней здесь математика. Вот пример.

Если считать простую среднею и использовать при определении тренда то и получишь что насчитал,
а данном случае отставание результата составляет Period/2+1, то есть заметил тренд после половины периода этой средней.
И что с этим делать я не знаю,
я использую фильтры, ведь космические корабли стыкуют в автоматическом режиме в заданный момент времени.
Ну отставание 1 - 2 бара при выявленной тенденции можно себе позволить.

Мне вот  в начале работы над скриптом казалось, что торговать нужно НА ВСЕХ таймфреймах одновременно.
Это все описано и опубликовано и есть подходы, к примеру 3 окна Эльдера.
Попробую высказать свое мнение.
------------
Интересно, как Вы ответите на такие вопросы:
1) Почему известные в книгах методы торговли встречаются в литературе как успешные лишь единожды.
Например метод черепах. Никто не похвалился, что он повторил то, что прочитал и стал миллионером положив изначально на депозит 1000 руб?
2) Почему победители различных трейдерских соревнований выигрывают лишь один раз.
----------------
Кратко мой ответ состоит в том, что все перечисленные выше события являются случайными.
=============
Относительно методов, например Эльдера или еще каких-то известных гуру, которые никогда не были не то что математиками, но и не изучали ее. Все их методы - это арифметика.
--------------------------------------
В таких  книгах примеры эффективности этих методов всегда подобраны именно так, чтобы доказать то, о чем пишет автор.
Никто из них не привел доказательство работы этих методов тогда, когда рынок не движется так, как думает автор,
=================
Когда человек торгует на рынке сам или пишет некоторую программу торговли, то он сознательно или нет использует некоторую модель (картинку) будущего движения цены.  Если Вы используете какие либо индикаторы - свечи, скользящее среднее, RSI и т д, то успешность торговли зависит от того позволяют ли эти индикаторы, которые являются фильтрами, сформировать из движения цены нужное Вам решение
купить/ продать.
=================
К сожалению, большинство частных инвесторов опираясь на знания полученные на курсах, на которых пересказывают книжки этих гуру строят стратегию торговли методом "рекле"  - режу-клею.
Т е нарезали индикаторов и рекомендаций из разных книжек и склеили их в один скрипт  не получилось снова рекле.
--------------------------
Таблицы lua
 
Цитата
Nikolay написал:
for key in pairs(T) do
end
for key, val in pairs(t) do
Как запустить скрипт qlua из командной строки?
 
Цитата
swerg написал:

Хотелось просто иметь возможность запускать Lua-скрипт для отладки какого-то алгоритма или какой-то функции. Потом этот отлаженный функционал использовать уже в реальных торговых скриптах.

Однако, если запустить скрипт написанный для QLua в штатном lua.exe, то скрипт вовсе не будет работать, т.к. он в любом случае использует некоторые функции, которые добавлены в QLua. Та же message. Если используется в скрипте - он будет тупо ломаться. А менять постоянно print / message не очень-то удобно.

Вот такие задачи и ставились при написании этой штуковины, не более.
Непонятно, зачем делать отдельное приложение для запуска скрипта вне терминала, если скрипт можно запускать и отлаживать в SciTe?
Как запустить скрипт qlua из командной строки?
 
пардон, опечатка
Так как обмен между процессами делается иначе , чем обмен между потоками в одном процессе.
Как запустить скрипт qlua из командной строки?
 
и еще...
функция main имеет доступ к функциям библиотеки QLUA потому, что main запускается в дочерней VMLUA, которая запущена в отдельном потоке, но в том же процессе.
Функции QLUA предназначены для получения данных из архивов QUIK.
------------------------------------
Если Вы запустите VMLua в новом процессе, например запустив Lua53.exe и в нем загрузите QLua.dll, то в этом процессе функции этой библиотеки не смогу получить доступ к архивам QUIK.  
Так как обмен между процессорами делается иначе , чем обмен между потоками в одном процессе,
---------------------
Т е библиотека QLUA не предназначена для связи процессов.
Поэтому для Вашей хотелки надо писать новую библиотеку , а для этого надо SDK который разработчики не дают,
либо делать связь между процессами внутри скрипта в QUIK или через файлы или иным способом.
Как запустить скрипт qlua из командной строки?
 
Цитата
Alexander написал:
Цитата
nikolz написал:
 
Цитата
Alexander  написал:
 
Цитата
 nikolz   написал:
VMLua - это программа и она запускается вызовом lua_pcall, в которой вызываетсясобственно VMLua  - эта функция  Вот ее тест из sorce code Lua 5.4
  Ну тут всё правильно написали про VMLua, что она именно ЗАПУСКАЕТСЯ, а ранее писали, что VMLua РАБОТАЕТ как самостоятельная единица.
 Любая программа сначала запускается, а потом работает как самостоятельная единица. Поэтому я и написал - запускается и работает.  
Отсюда все и недопонимания возникли. Программа конечно, чтобы начать работать должна быть сначала быть загружена в память, а потом ей должно быть передано управление(call, jmp, return с адресом в стеке, int, может и ещё что есть). Так вот в моём понимании VMLua сначала просто загружена в качестве библиотеки lua53dll и НЕ работает, а работать начинает только тогда, когда нужные функции из неё для компиляции, интерпретации начинают ВЫЗЫВАТЬСЯ, ну или начинает вызываться специальная функция, которая начинает интерпретировать весь скрипт тем же самым образом, но в любом случае библиотека есть и она НЕ работает пока её функции не начнут вызывать. Поэтому Вы всё объединили в кучу - загрузка и передача управления в функцию одной фразой - VMLua уже работает.
Если в скрипте есть операторы, то они исполнятся при загрузке скрипта т е до вызова функций, вернее сказать после компиляции в байт код, но до вызова OnInit и запуска main и вызова каких либо колбеков терминалом.
А VMLua до загрузки скрипта.
Cкрипт загружается функцией  библиотеки Lua. VMLua это интерпретатор байт-кода. Поэтому естественно, что загрузка и компиляция скрипта в байт код выполняется не VM Lua а библиотечной функцией, а вто исполнение этого кода выполняет функция VMLua.  
Как запустить скрипт qlua из командной строки?
 
Цитата
Alexander написал:
Тут вот, что хотелось попробовать. Запускаем скрипт QLUA из вне через lua53.exe. В скрипте подключаем qlua.dll. При работающем скрипте она может быть уже загружена и поток квика её использует. Да, пространства потоков разные у lua53.exe и у квика будут. Но функции qlua будут иметь доступ ко всем данным(таблицы например) потока квика если их умудриться вызвать. Чтобы их вызывать например из exe, dll, нам нужны заголовки с объявлениями. Можно ли их получить? А чтобы их вызывать из скрипта, нужно перменным скрипта задать адреса этих функций, как окружение, которое строит квик в виде _G. ... Как организовать то или другое? Или при загрузке qlua.dll уже будет окружение _G? И достаточно просто extern тип _G? Но опять же нужен заголовок с описание типа того же _G. Попробую потом посмотреть qlua.dll на предмет экспорта, и что там с символами. У квика вообще код закрытый? Они предоставляют lib файлы? Заголовки?
Вы ошибаетесь.
QLua - это не скрипт, а dll - написана на СИ или С++.  Т е скрипт на луа вызывает из нее функции.
Lua53.exe  - это приложение и внутри него запускается VMLua так же как и в терминале QUIK.

Более того, перед запуском VMLua в память грузится куча функций на СИ, которые позволяют в скрипте обращаться к строкам, таблицам, математическим функциям.   Все они написаны на СИ и находятся в Lua53.dll

Т е Вы хотите к этой куче догрузить свою dll. Ну и что Вы этим проверите? Лишь есть или нет у Вас в dll ошибки.
Но так делается при разработке любых приложений на любых языках . Ни луа ни квик ни причем.
--------------------
Я же Вам написал что так и делаю много много раз, как Вы хотите.
---------------------
Даже на форуме выкладывал пример , в котором запускал скрипт, загружал dll и обменивался данными с QUIK
================
Про функции qlua - к чему они имеют доступ описано в документации.
----
Заголовки к функциям из dll, если их нет, то делаются самостоятельно на основе dll и документации.
Для этого Вам надо изучить технологию разработки программ на СИ.
-----------------------
Разработчики уже объясняли, что они не дадут SDK (software development kit  на С)  для разработки пользовательских dll для QUIK.
Взамен этого они слепили QLua.dll и внедрили в терминал VMLua.
---------------
Поэтому спасение утопающих -дело рук самих утопающих.
Как запустить скрипт qlua из командной строки?
 
Цитата
Alexander написал:
Цитата
nikolz написал:
VMLua - это программа и она запускается вызовом lua_pcall, в которой вызываетсясобственно VMLua  - эта функция  Вот ее тест из sorce code Lua 5.4
Ну тут всё правильно написали про VMLua, что она именно ЗАПУСКАЕТСЯ, а ранее писали, что VMLua РАБОТАЕТ как самостоятельная единица.
Любая программа сначала запускается, а потом работает как самостоятельная единица. Поэтому я и написал - запускается и работает.  
Как запустить скрипт qlua из командной строки?
 
Цитата
TGB написал:
Цитата
nikolz написал:
void luaV_execute (lua_State *L, CallInfo *ci) {
...............
    Зачем вы постоянно гадите на форуме чужими длинными текстами?
   Вы испытываете терпение поддержки QUIK?
   Вы думаете, что чем длиннее ваши комментарии, тем умнее выглядите?
Помните, что говорил А.П. Чехов?:"Краткость, сестра таланта" :: . И куда вы относитесь по этой классификации?
Если не понимаете, то не читайте. Классификатор Вы наш.
Как запустить скрипт qlua из командной строки?
 
и еще...
скрипт исполняется в VMLua ,которую запускает КВИК, потом  в отдельном потоке запускает в дочерняя VMLua  и в ней Ваша функцию main
в которой крутится бесконечный цикл.
Вот этот цикл бесконечно и исполняет приведенная выше функция VMLua.
терминал никак не контролирует эту функции.
В потоке терминала сделана синхронизация обращения к глобальному стеку VMLua
Вы в своем main скрипте в вызываете функции из QLUA для обмена данными с основным потоком QUIK.
Так все и работает.  
как получить размер плеча по инструменту (DLong) через QuikSharp?
 
Цитата
swerg написал:
Официальная поддержка чгео?
QuikSharp - сторонний продукт. Обратитесь к его разработчикам.
поддержка буратин, которым лень читать документацию.
Как запустить скрипт qlua из командной строки?
 
Цитата
Alexander написал:
Alexander
Вы же сами написали как исполняется скрипт.
Код
luaL_openlibs(L); /* открывает стандартные библиотеки
*/
while (fgets(buff, sizeof(buff), stdin) != NULL) {
error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
if (error) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1); /* выталкивает сообщение об ошибке из стека
*/
}

Я точно также запускаю свои скрипты внутри КВИКА в потоках из пула.
Т е запускаю сколько мне надо новых VMLua внутри КВИКА и КВИК ничего в них не контролирует.
более того, можно вообще запустить вне квика VMLua и в нем скрипт чего-угодно, а необходимые данные передавать из квика с помощью библиотеки QLUA, которая собственно и сделана для передачи данных из терминала в скрипт луа.
-----------------------
VMLua - это программа и она запускается вызовом lua_pcall, в которой вызывается
собственно VMLua  - эта функция  Вот ее тест из sorce code Lua 5.4
Код
void luaV_execute (lua_State *L, CallInfo *ci) {
  LClosure *cl;
  TValue *k;
  StkId base;
  const Instruction *pc;
  int trap;
#if LUA_USE_JUMPTABLE
#include "ljumptab.h"
#endif
 startfunc:
  trap = L->hookmask;
 returning:  /* trap already set */
  cl = clLvalue(s2v(ci->func.p));
  k = cl->p->k;
  pc = ci->u.l.savedpc;
  if (l_unlikely(trap)) {
    if (pc == cl->p->code) {  /* first instruction (not resuming)? */
      if (cl->p->is_vararg)
        trap = 0;  /* hooks will start after VARARGPREP instruction */
      else  /* check 'call' hook */
        luaD_hookcall(L, ci);
    }
    ci->u.l.trap = 1;  /* assume trap is on, for now */
  }
  base = ci->func.p + 1;
  /* main loop of interpreter */
  for (;;) {
    Instruction i;  /* instruction being executed */
    vmfetch();
    #if 0
      /* low-level line tracing for debugging Lua */
      printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
    #endif
    lua_assert(base == ci->func.p + 1);
    lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p);
    /* invalidate top for instructions not expecting it */
    lua_assert(isIT(i) || (cast_void(L->top.p = base), 1));
    vmdispatch (GET_OPCODE(i)) {
      vmcase(OP_MOVE) {
        StkId ra = RA(i);
        setobjs2s(L, ra, RB(i));
        vmbreak;
      }
      vmcase(OP_LOADI) {
        StkId ra = RA(i);
        lua_Integer b = GETARG_sBx(i);
        setivalue(s2v(ra), b);
        vmbreak;
      }
      vmcase(OP_LOADF) {
        StkId ra = RA(i);
        int b = GETARG_sBx(i);
        setfltvalue(s2v(ra), cast_num(b));
        vmbreak;
      }
      vmcase(OP_LOADK) {
        StkId ra = RA(i);
        TValue *rb = k + GETARG_Bx(i);
        setobj2s(L, ra, rb);
        vmbreak;
      }
      vmcase(OP_LOADKX) {
        StkId ra = RA(i);
        TValue *rb;
        rb = k + GETARG_Ax(*pc); pc++;
        setobj2s(L, ra, rb);
        vmbreak;
      }
      vmcase(OP_LOADFALSE) {
        StkId ra = RA(i);
        setbfvalue(s2v(ra));
        vmbreak;
      }
      vmcase(OP_LFALSESKIP) {
        StkId ra = RA(i);
        setbfvalue(s2v(ra));
        pc++;  /* skip next instruction */
        vmbreak;
      }
      vmcase(OP_LOADTRUE) {
        StkId ra = RA(i);
        setbtvalue(s2v(ra));
        vmbreak;
      }
      vmcase(OP_LOADNIL) {
        StkId ra = RA(i);
        int b = GETARG_B(i);
        do {
          setnilvalue(s2v(ra++));
        } while (b--);
        vmbreak;
      }
      vmcase(OP_GETUPVAL) {
        StkId ra = RA(i);
        int b = GETARG_B(i);
        setobj2s(L, ra, cl->upvals[b]->v.p);
        vmbreak;
      }
      vmcase(OP_SETUPVAL) {
        StkId ra = RA(i);
        UpVal *uv = cl->upvals[GETARG_B(i)];
        setobj(L, uv->v.p, s2v(ra));
        luaC_barrier(L, uv, s2v(ra));
        vmbreak;
      }
      vmcase(OP_GETTABUP) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
        TValue *rc = KC(i);
        TString *key = tsvalue(rc);  /* key must be a string */
        if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
          setobj2s(L, ra, slot);
        }
        else
          Protect(luaV_finishget(L, upval, rc, ra, slot));
        vmbreak;
      }
      vmcase(OP_GETTABLE) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = vRB(i);
        TValue *rc = vRC(i);
        lua_Unsigned n;
        if (ttisinteger(rc)  /* fast track for integers? */
            ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot))
            : luaV_fastget(L, rb, rc, slot, luaH_get)) {
          setobj2s(L, ra, slot);
        }
        else
          Protect(luaV_finishget(L, rb, rc, ra, slot));
        vmbreak;
      }
      vmcase(OP_GETI) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = vRB(i);
        int c = GETARG_C(i);
        if (luaV_fastgeti(L, rb, c, slot)) {
          setobj2s(L, ra, slot);
        }
        else {
          TValue key;
          setivalue(&key, c);
          Protect(luaV_finishget(L, rb, &key, ra, slot));
        }
        vmbreak;
      }
      vmcase(OP_GETFIELD) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = vRB(i);
        TValue *rc = KC(i);
        TString *key = tsvalue(rc);  /* key must be a string */
        if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
          setobj2s(L, ra, slot);
        }
        else
          Protect(luaV_finishget(L, rb, rc, ra, slot));
        vmbreak;
      }
      vmcase(OP_SETTABUP) {
        const TValue *slot;
        TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
        TValue *rb = KB(i);
        TValue *rc = RKC(i);
        TString *key = tsvalue(rb);  /* key must be a string */
        if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
          luaV_finishfastset(L, upval, slot, rc);
        }
        else
          Protect(luaV_finishset(L, upval, rb, rc, slot));
        vmbreak;
      }
      vmcase(OP_SETTABLE) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = vRB(i);  /* key (table is in 'ra') */
        TValue *rc = RKC(i);  /* value */
        lua_Unsigned n;
        if (ttisinteger(rb)  /* fast track for integers? */
            ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot))
            : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) {
          luaV_finishfastset(L, s2v(ra), slot, rc);
        }
        else
          Protect(luaV_finishset(L, s2v(ra), rb, rc, slot));
        vmbreak;
      }
      vmcase(OP_SETI) {
        StkId ra = RA(i);
        const TValue *slot;
        int c = GETARG_B(i);
        TValue *rc = RKC(i);
        if (luaV_fastgeti(L, s2v(ra), c, slot)) {
          luaV_finishfastset(L, s2v(ra), slot, rc);
        }
        else {
          TValue key;
          setivalue(&key, c);
          Protect(luaV_finishset(L, s2v(ra), &key, rc, slot));
        }
        vmbreak;
      }
      vmcase(OP_SETFIELD) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = KB(i);
        TValue *rc = RKC(i);
        TString *key = tsvalue(rb);  /* key must be a string */
        if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
          luaV_finishfastset(L, s2v(ra), slot, rc);
        }
        else
          Protect(luaV_finishset(L, s2v(ra), rb, rc, slot));
        vmbreak;
      }
      vmcase(OP_NEWTABLE) {
        StkId ra = RA(i);
        int b = GETARG_B(i);  /* log2(hash size) + 1 */
        int c = GETARG_C(i);  /* array size */
        Table *t;
        if (b > 0)
          b = 1 << (b - 1);  /* size is 2^(b - 1) */
        lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0));
        if (TESTARG_k(i))  /* non-zero extra argument? */
          c += GETARG_Ax(*pc) * (MAXARG_C + 1);  /* add it to size */
        pc++;  /* skip extra argument */
        L->top.p = ra + 1;  /* correct top in case of emergency GC */
        t = luaH_new(L);  /* memory allocation */
        sethvalue2s(L, ra, t);
        if (b != 0 || c != 0)
          luaH_resize(L, t, c, b);  /* idem */
        checkGC(L, ra + 1);
        vmbreak;
      }
      vmcase(OP_SELF) {
        StkId ra = RA(i);
        const TValue *slot;
        TValue *rb = vRB(i);
        TValue *rc = RKC(i);
        TString *key = tsvalue(rc);  /* key must be a string */
        setobj2s(L, ra + 1, rb);
        if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
          setobj2s(L, ra, slot);
        }
        else
          Protect(luaV_finishget(L, rb, rc, ra, slot));
        vmbreak;
      }
      vmcase(OP_ADDI) {
        op_arithI(L, l_addi, luai_numadd);
        vmbreak;
      }
      vmcase(OP_ADDK) {
        op_arithK(L, l_addi, luai_numadd);
        vmbreak;
      }
      vmcase(OP_SUBK) {
        op_arithK(L, l_subi, luai_numsub);
        vmbreak;
      }
      vmcase(OP_MULK) {
        op_arithK(L, l_muli, luai_nummul);
        vmbreak;
      }
      vmcase(OP_MODK) {
        savestate(L, ci);  /* in case of division by 0 */
        op_arithK(L, luaV_mod, luaV_modf);
        vmbreak;
      }
      vmcase(OP_POWK) {
        op_arithfK(L, luai_numpow);
        vmbreak;
      }
      vmcase(OP_DIVK) {
        op_arithfK(L, luai_numdiv);
        vmbreak;
      }
      vmcase(OP_IDIVK) {
        savestate(L, ci);  /* in case of division by 0 */
        op_arithK(L, luaV_idiv, luai_numidiv);
        vmbreak;
      }
      vmcase(OP_BANDK) {
        op_bitwiseK(L, l_band);
        vmbreak;
      }
      vmcase(OP_BORK) {
        op_bitwiseK(L, l_bor);
        vmbreak;
      }
      vmcase(OP_BXORK) {
        op_bitwiseK(L, l_bxor);
        vmbreak;
      }
      vmcase(OP_SHRI) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        int ic = GETARG_sC(i);
        lua_Integer ib;
        if (tointegerns(rb, &ib)) {
          pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic));
        }
        vmbreak;
      }
      vmcase(OP_SHLI) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        int ic = GETARG_sC(i);
        lua_Integer ib;
        if (tointegerns(rb, &ib)) {
          pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib));
        }
        vmbreak;
      }
      vmcase(OP_ADD) {
        op_arith(L, l_addi, luai_numadd);
        vmbreak;
      }
      vmcase(OP_SUB) {
        op_arith(L, l_subi, luai_numsub);
        vmbreak;
      }
      vmcase(OP_MUL) {
        op_arith(L, l_muli, luai_nummul);
        vmbreak;
      }
      vmcase(OP_MOD) {
        savestate(L, ci);  /* in case of division by 0 */
        op_arith(L, luaV_mod, luaV_modf);
        vmbreak;
      }
      vmcase(OP_POW) {
        op_arithf(L, luai_numpow);
        vmbreak;
      }
      vmcase(OP_DIV) {  /* float division (always with floats) */
        op_arithf(L, luai_numdiv);
        vmbreak;
      }
      vmcase(OP_IDIV) {  /* floor division */
        savestate(L, ci);  /* in case of division by 0 */
        op_arith(L, luaV_idiv, luai_numidiv);
        vmbreak;
      }
      vmcase(OP_BAND) {
        op_bitwise(L, l_band);
        vmbreak;
      }
      vmcase(OP_BOR) {
        op_bitwise(L, l_bor);
        vmbreak;
      }
      vmcase(OP_BXOR) {
        op_bitwise(L, l_bxor);
        vmbreak;
      }
      vmcase(OP_SHR) {
        op_bitwise(L, luaV_shiftr);
        vmbreak;
      }
      vmcase(OP_SHL) {
        op_bitwise(L, luaV_shiftl);
        vmbreak;
      }
      vmcase(OP_MMBIN) {
        StkId ra = RA(i);
        Instruction pi = *(pc - 2);  /* original arith. expression */
        TValue *rb = vRB(i);
        TMS tm = (TMS)GETARG_C(i);
        StkId result = RA(pi);
        lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR);
        Protect(luaT_trybinTM(L, s2v(ra), rb, result, tm));
        vmbreak;
      }
      vmcase(OP_MMBINI) {
        StkId ra = RA(i);
        Instruction pi = *(pc - 2);  /* original arith. expression */
        int imm = GETARG_sB(i);
        TMS tm = (TMS)GETARG_C(i);
        int flip = GETARG_k(i);
        StkId result = RA(pi);
        Protect(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm));
        vmbreak;
      }
      vmcase(OP_MMBINK) {
        StkId ra = RA(i);
        Instruction pi = *(pc - 2);  /* original arith. expression */
        TValue *imm = KB(i);
        TMS tm = (TMS)GETARG_C(i);
        int flip = GETARG_k(i);
        StkId result = RA(pi);
        Protect(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm));
        vmbreak;
      }
      vmcase(OP_UNM) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        lua_Number nb;
        if (ttisinteger(rb)) {
          lua_Integer ib = ivalue(rb);
          setivalue(s2v(ra), intop(-, 0, ib));
        }
        else if (tonumberns(rb, nb)) {
          setfltvalue(s2v(ra), luai_numunm(L, nb));
        }
        else
          Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
        vmbreak;
      }
      vmcase(OP_BNOT) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        lua_Integer ib;
        if (tointegerns(rb, &ib)) {
          setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib));
        }
        else
          Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
        vmbreak;
      }
      vmcase(OP_NOT) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        if (l_isfalse(rb))
          setbtvalue(s2v(ra));
        else
          setbfvalue(s2v(ra));
        vmbreak;
      }
      vmcase(OP_LEN) {
        StkId ra = RA(i);
        Protect(luaV_objlen(L, ra, vRB(i)));
        vmbreak;
      }
      vmcase(OP_CONCAT) {
        StkId ra = RA(i);
        int n = GETARG_B(i);  /* number of elements to concatenate */
        L->top.p = ra + n;  /* mark the end of concat operands */
        ProtectNT(luaV_concat(L, n));
        checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */
        vmbreak;
      }
      vmcase(OP_CLOSE) {
        StkId ra = RA(i);
        Protect(luaF_close(L, ra, LUA_OK, 1));
        vmbreak;
      }
      vmcase(OP_TBC) {
        StkId ra = RA(i);
        /* create new to-be-closed upvalue */
        halfProtect(luaF_newtbcupval(L, ra));
        vmbreak;
      }
      vmcase(OP_JMP) {
        dojump(ci, i, 0);
        vmbreak;
      }
      vmcase(OP_EQ) {
        StkId ra = RA(i);
        int cond;
        TValue *rb = vRB(i);
        Protect(cond = luaV_equalobj(L, s2v(ra), rb));
        docondjump();
        vmbreak;
      }
      vmcase(OP_LT) {
        op_order(L, l_lti, LTnum, lessthanothers);
        vmbreak;
      }
      vmcase(OP_LE) {
        op_order(L, l_lei, LEnum, lessequalothers);
        vmbreak;
      }
      vmcase(OP_EQK) {
        StkId ra = RA(i);
        TValue *rb = KB(i);
        /* basic types do not use '__eq'; we can use raw equality */
        int cond = luaV_rawequalobj(s2v(ra), rb);
        docondjump();
        vmbreak;
      }
      vmcase(OP_EQI) {
        StkId ra = RA(i);
        int cond;
        int im = GETARG_sB(i);
        if (ttisinteger(s2v(ra)))
          cond = (ivalue(s2v(ra)) == im);
        else if (ttisfloat(s2v(ra)))
          cond = luai_numeq(fltvalue(s2v(ra)), cast_num(im));
        else
          cond = 0;  /* other types cannot be equal to a number */
        docondjump();
        vmbreak;
      }
      vmcase(OP_LTI) {
        op_orderI(L, l_lti, luai_numlt, 0, TM_LT);
        vmbreak;
      }
      vmcase(OP_LEI) {
        op_orderI(L, l_lei, luai_numle, 0, TM_LE);
        vmbreak;
      }
      vmcase(OP_GTI) {
        op_orderI(L, l_gti, luai_numgt, 1, TM_LT);
        vmbreak;
      }
      vmcase(OP_GEI) {
        op_orderI(L, l_gei, luai_numge, 1, TM_LE);
        vmbreak;
      }
      vmcase(OP_TEST) {
        StkId ra = RA(i);
        int cond = !l_isfalse(s2v(ra));
        docondjump();
        vmbreak;
      }
      vmcase(OP_TESTSET) {
        StkId ra = RA(i);
        TValue *rb = vRB(i);
        if (l_isfalse(rb) == GETARG_k(i))
          pc++;
        else {
          setobj2s(L, ra, rb);
          donextjump(ci);
        }
        vmbreak;
      }
      vmcase(OP_CALL) {
        StkId ra = RA(i);
        CallInfo *newci;
        int b = GETARG_B(i);
        int nresults = GETARG_C(i) - 1;
        if (b != 0)  /* fixed number of arguments? */
          L->top.p = ra + b;  /* top signals number of arguments */
        /* else previous instruction set top */
        savepc(L);  /* in case of errors */
        if ((newci = luaD_precall(L, ra, nresults)) == NULL)
          updatetrap(ci);  /* C call; nothing else to be done */
        else {  /* Lua call: run function in this same C frame */
          ci = newci;
          goto startfunc;
        }
        vmbreak;
      }
      vmcase(OP_TAILCALL) {
        StkId ra = RA(i);
        int b = GETARG_B(i);  /* number of arguments + 1 (function) */
        int n;  /* number of results when calling a C function */
        int nparams1 = GETARG_C(i);
        /* delta is virtual 'func' - real 'func' (vararg functions) */
        int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
        if (b != 0)
          L->top.p = ra + b;
        else  /* previous instruction set top */
          b = cast_int(L->top.p - ra);
        savepc(ci);  /* several calls here can raise errors */
        if (TESTARG_k(i)) {
          luaF_closeupval(L, base);  /* close upvalues from current call */
          lua_assert(L->tbclist.p < base);  /* no pending tbc variables */
          lua_assert(base == ci->func.p + 1);
        }
        if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0)  /* Lua function? */
          goto startfunc;  /* execute the callee */
        else {  /* C function? */
          ci->func.p -= delta;  /* restore 'func' (if vararg) */
          luaD_poscall(L, ci, n);  /* finish caller */
          updatetrap(ci);  /* 'luaD_poscall' can change hooks */
          goto ret;  /* caller returns after the tail call */
        }
      }
      vmcase(OP_RETURN) {
        StkId ra = RA(i);
        int n = GETARG_B(i) - 1;  /* number of results */
        int nparams1 = GETARG_C(i);
        if (n < 0)  /* not fixed? */
          n = cast_int(L->top.p - ra);  /* get what is available */
        savepc(ci);
        if (TESTARG_k(i)) {  /* may there be open upvalues? */
          ci->u2.nres = n;  /* save number of returns */
          if (L->top.p < ci->top.p)
            L->top.p = ci->top.p;
          luaF_close(L, base, CLOSEKTOP, 1);
          updatetrap(ci);
          updatestack(ci);
        }
        if (nparams1)  /* vararg function? */
          ci->func.p -= ci->u.l.nextraargs + nparams1;
        L->top.p = ra + n;  /* set call for 'luaD_poscall' */
        luaD_poscall(L, ci, n);
        updatetrap(ci);  /* 'luaD_poscall' can change hooks */
        goto ret;
      }
      vmcase(OP_RETURN0) {
        if (l_unlikely(L->hookmask)) {
          StkId ra = RA(i);
          L->top.p = ra;
          savepc(ci);
          luaD_poscall(L, ci, 0);  /* no hurry... */
          trap = 1;
        }
        else {  /* do the 'poscall' here */
          int nres;
          L->ci = ci->previous;  /* back to caller */
          L->top.p = base - 1;
          for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
            setnilvalue(s2v(L->top.p++));  /* all results are nil */
        }
        goto ret;
      }
      vmcase(OP_RETURN1) {
        if (l_unlikely(L->hookmask)) {
          StkId ra = RA(i);
          L->top.p = ra + 1;
          savepc(ci);
          luaD_poscall(L, ci, 1);  /* no hurry... */
          trap = 1;
        }
        else {  /* do the 'poscall' here */
          int nres = ci->nresults;
          L->ci = ci->previous;  /* back to caller */
          if (nres == 0)
            L->top.p = base - 1;  /* asked for no results */
          else {
            StkId ra = RA(i);
            setobjs2s(L, base - 1, ra);  /* at least this result */
            L->top.p = base;
            for (; l_unlikely(nres > 1); nres--)
              setnilvalue(s2v(L->top.p++));  /* complete missing results */
          }
        }
       ret:  /* return from a Lua function */
        if (ci->callstatus & CIST_FRESH)
          return;  /* end this frame */
        else {
          ci = ci->previous;
          goto returning;  /* continue running caller in this frame */
        }
      }
      vmcase(OP_FORLOOP) {
        StkId ra = RA(i);
        if (ttisinteger(s2v(ra + 2))) {  /* integer loop? */
          lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
          if (count > 0) {  /* still more iterations? */
            lua_Integer step = ivalue(s2v(ra + 2));
            lua_Integer idx = ivalue(s2v(ra));  /* internal index */
            chgivalue(s2v(ra + 1), count - 1);  /* update counter */
            idx = intop(+, idx, step);  /* add step to index */
            chgivalue(s2v(ra), idx);  /* update internal index */
            setivalue(s2v(ra + 3), idx);  /* and control variable */
            pc -= GETARG_Bx(i);  /* jump back */
          }
        }
        else if (floatforloop(ra))  /* float loop */
          pc -= GETARG_Bx(i);  /* jump back */
        updatetrap(ci);  /* allows a signal to break the loop */
        vmbreak;
      }
      vmcase(OP_FORPREP) {
        StkId ra = RA(i);
        savestate(L, ci);  /* in case of errors */
        if (forprep(L, ra))
          pc += GETARG_Bx(i) + 1;  /* skip the loop */
        vmbreak;
      }
      vmcase(OP_TFORPREP) {
       StkId ra = RA(i);
        /* create to-be-closed upvalue (if needed) */
        halfProtect(luaF_newtbcupval(L, ra + 3));
        pc += GETARG_Bx(i);
        i = *(pc++);  /* go to next instruction */
        lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i));
        goto l_tforcall;
      }
      vmcase(OP_TFORCALL) {
       l_tforcall: {
        StkId ra = RA(i);
        /* 'ra' has the iterator function, 'ra + 1' has the state,
           'ra + 2' has the control variable, and 'ra + 3' has the
           to-be-closed variable. The call will use the stack after
           these values (starting at 'ra + 4')
        */
        /* push function, state, and control variable */
        memcpy(ra + 4, ra, 3 * sizeof(*ra));
        L->top.p = ra + 4 + 3;
        ProtectNT(luaD_call(L, ra + 4, GETARG_C(i)));  /* do the call */
        updatestack(ci);  /* stack may have changed */
        i = *(pc++);  /* go to next instruction */
        lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
        goto l_tforloop;
      }}
      vmcase(OP_TFORLOOP) {
       l_tforloop: {
        StkId ra = RA(i);
        if (!ttisnil(s2v(ra + 4))) {  /* continue loop? */
          setobjs2s(L, ra + 2, ra + 4);  /* save control variable */
          pc -= GETARG_Bx(i);  /* jump back */
        }
        vmbreak;
      }}
      vmcase(OP_SETLIST) {
        StkId ra = RA(i);
        int n = GETARG_B(i);
        unsigned int last = GETARG_C(i);
        Table *h = hvalue(s2v(ra));
        if (n == 0)
          n = cast_int(L->top.p - ra) - 1;  /* get up to the top */
        else
          L->top.p = ci->top.p;  /* correct top in case of emergency GC */
        last += n;
        if (TESTARG_k(i)) {
          last += GETARG_Ax(*pc) * (MAXARG_C + 1);
          pc++;
        }
        if (last > luaH_realasize(h))  /* needs more space? */
          luaH_resizearray(L, h, last);  /* preallocate it at once */
        for (; n > 0; n--) {
          TValue *val = s2v(ra + n);
          setobj2t(L, &h->array[last - 1], val);
          last--;
          luaC_barrierback(L, obj2gco(h), val);
        }
        vmbreak;
      }
      vmcase(OP_CLOSURE) {
        StkId ra = RA(i);
        Proto *p = cl->p->p[GETARG_Bx(i)];
        halfProtect(pushclosure(L, p, cl->upvals, base, ra));
        checkGC(L, ra + 1);
        vmbreak;
      }
      vmcase(OP_VARARG) {
        StkId ra = RA(i);
        int n = GETARG_C(i) - 1;  /* required results */
        Protect(luaT_getvarargs(L, ci, ra, n));
        vmbreak;
      }
      vmcase(OP_VARARGPREP) {
        ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
        if (l_unlikely(trap)) {  /* previous "Protect" updated trap */
          luaD_hookcall(L, ci);
          L->oldpc = 1;  /* next opcode will be seen as a "new" line */
        }
        updatebase(ci);  /* function has new base after adjustment */
        vmbreak;
      }
      vmcase(OP_EXTRAARG) {
        lua_assert(0);
        vmbreak;
      }
    }
  }
}

В чём преимущество OnInit
 
Самый бестолковый колбек это OnTrade.
------------------------------------
Нет смысла тратить на него вообще какое-нибудь время,
так как совершение сделки отражается в заявках и в портфеле.
примеры колбеков
 
Владимир,
Кто о чем а вшивый о бане.
Судя по твоим постоянным попыткам узнать кто меня считает учителем, тебе очень хочется быть им.
Но тебя учить поздно. .
примеры колбеков
 
Цитата
Владимир написал:
nikolz, Лапуль, ну хватит корчить из себя программиста. Уши вянут смотреть на эту бредятину. Вас ХОТЬ КТО-НИБУДЬ принимает за учителя?
Не смотри. И хватит корчить из себя мудака .Давно все понятно.
примеры колбеков
 
пояснение:
-----------------
во всех примерах колбеков есть блок с вызовом функции  SearchItems
он исполняется для каждого инструмента лишь один раз.
---------------------
Это блок нужен, чтобы обработать те сделки и заявки , которые были исполнены или выставлены до запуска скрипта.
Так как эти блоки исполняются один раз, то их время исполнение практически не влияет скорость исполнения колбеков.
примеры колбеков
 
Написал  изучающим Lua примеры вариантов колбеков сделок, заявок и стоп-заявок.
----------------------
Примеры написаны специально для форума и не тестировались, а лишь проверены на синтаксис.
---------------------------
Поэтому, если есть желающие тестить и найдете ошибки, то пишите, исправим вместе.
--------------
В этих колбеках сделки, активные заявки и активные стоп заявки размещаются в соответствующие инструментам рабочие таблицы.
--------------------------------
Код
--таблицы
TRADE={}; -- индексы сделок по инструментам
ORDER={}; -- индексы активных заявок по инструментам
STOP={}; -- индексы активных стоп-заявок по инструментам

function OnTrade(tr)
  local n,m;local sec=tr.sec_code;
  local t=TRADE[sec]; --таблица номеров строк сделок в таблице QUIK инструмента sec
  if t then
   m=TRADE[0]; n=t[0];
 else                --создание таблицы инструмента
   m=getNumberOf("trades"); n=0;
   t=SearchItems("trades",n,m-1, function(p1) if p1==sec then return true;end return false; end,"sec_code")
   TRADE[sec]=t;
end
 if m>t[n] then n=n+1; t[n]=m;  t[0]=n; TRADE[0]=m+1; end
end

local function fOrder(tr,T,s)  --функция обработки для колбеков orders и stop_orders
  local n,m,x;local sec=tr.sec_code; local t=T[sec];  --таблица номеров строк в таблице QUIK активных ордеров или стоп_ордеров инструмента sec
  local flag=tr.flags&1; local num=tr.order_num;
  if t then
    m=T[0]; n=t[0];
   for i=1,n do x=getItem(s,i-1);
      if x.num_order==num then
         if flag==0 then n=n-1;if n>0 then t[i]=t[n]; end break; else return; end
      end
   end
 else                --создание таблицы инструмента
   m=getNumberOf(s); n=0;
   t=SearchItems(s,n,m-1, function(p1,p2) if p1==sec and p2&1==1 then return true;end return false; end,"sec_code,flags")
   T[sec]=t;
end
   if flags==1 then n=n+1; t[0]=n; t[n]=m; T[0]=m+1; end
end

function OnOrder(t)   fOrder(t,ORDER,"orders");  end
function OnStopOrder(t) fOrder(t,ORDER,"stop_orders"); end
 
В чём преимущество OnInit
 
Цитата
VPM написал:
Но все ругают колбеки чего ждать от них не понятно,
Так как не только использую все колбеки QLua, но и пишу свои дополнительные колбеки для скриптов Lua,
то попробую объяснить что это за зверь.
-------------------
колбек - это обычная глобальная функция на Lua (можно и на C), но с конкретным именем.
---------------------
В терминале QUIK , при обработке полученных данных с сервера, перед тем как отправить данные в таблицы терминала,
делается вызов функции Lua с именем колбека и ей передаются данные.
--------------------------
Если такой функции нет, то ее нет в глобальном стеке Lua и ее вызов пропускается.
===================
Резюме:   Если Вы ругаете колбеки, то Вы ругаете "чистое" Lua, так как колбек -это функция на чистом луа.
-------------
Колбеки обычно ругают те, кто  луа не изучил толком и в функциях QLUA не разобрался.
---------------
Но зеркало не виновато, в том ...
Заявки.
 
это Вы про метатрейдер намекаете?
В чём преимущество OnInit
 
пардон опечатка
Вот вам пример преимущества перед чистым LUA
В чём преимущество OnInit
 
относительно не использования библиотек C..
==================
Вот вам пример преимущества перед чистым СИ
---------------------
Вы в срипте как курица с яйцом носитесь с sleep в main,  Много поставите - раздуете  стек или очередь
мало поставите - лишняя пустая загрузка ядра процессора.
-----------------
Делаем библиотеку на си для работы с событиями.
В итоге поток main вызывается максимально быстро (примерно за 0.000001 сек) если надо и не вызывается никогда, если не надо.
sleep вообще не нужен.
-------------
И много чего еще можно сделать на СИ, например библиотека QLUA - вся исключительно на СИ или C++.
В чём преимущество OnInit
 
Цитата
TGB написал:
Цитата
    Не надо бегать по таблице сделок. Достаточно сохранять ее размер и только если он изменился, читать только новые записи.
колбек дает сигнал, когда размер таблицы изменится.
Поэтому с колбеком даже не надо проверять размер таблицы.
--------------------------------
Более того, можно в колбеке не разбирать таблицу на составляющие , а запоминать последний номер.
В итоге в колбеке все будет очень просто и при этом не будет проблем с уборщиком мусора.
Как запустить скрипт qlua из командной строки?
 
технически сделать так можно.
--------------------
Но поясню что не так в вашем понимании.
-------------------------
скрипт луа выполняет виртуальная машина луа ,если знаете есть виртуальная машина джава и еще куча виртуальных машин для других языков программирования.
виртуальная машина - это программная реализация некоторого вычислительного устройства.
У него своя система команд, свои регистры и свой процессор, не такой как тот, на котором исполняется эта программа.  
----------------
В программе КВИК запущена программа VMLua.
VMLua работает сама по себе, исполняя загружаемые в нее скрипты.
Т е разработчики КВИК не разрабатывали VMLua,
а взяли готовый код и запустили его внутри своей программы.
---
В нее можно грузить любой скрипт на луа и она будет его исполнять.
-------------
Чтобы передать VMLua данные из терминала QUIK, разработчики написали библиотеку QLUA на СИ и таким образом организовали обмен информацией между двумя процессами , один из которых на VMLua.
------------
Запуск скрипта для исполнения в VMLua осуществляем в соответствующем окне терминала QUIK.
==============
Ччтобы делать это автоматом надо  написать соответствующий скрипт для виртуальной машины либо для планировщика задач с использованием библиотеки функций манипуляции с экраном. В скриптах это делается хуками.  Я делал это на AutoIt.
===============
Но прикол в том, что разработчики встроили блокировку в новые версии QUIK,
которая  не позволяет работать с отладчиками.
Индикатор MACD настройки оформления и отображения графика, Две скользящие средние в индикаторе MACD отображаются не как две линии, а как одна линия и гистограмма в место второй линии
 
Вот так у Вас?

а надо так?

делается так:

 
В чём преимущество OnInit
 
Прикольно, буря в стакане.
Казалось бы все просто.
Сам вопрос темы не корректный
спросили " в чем преимущество OnInit" , но забыли указать с чем сравнивать.
Написал три возможных варианта
Касалось бы все ясно.
Если ты чайник в программировании, то делай как рекомендуют разработчики КВИК и спи спокойно.
Нет, начинается треп а зачем, а мне насрать, а че это за такие преимущества и бла-бла бла.
В чём преимущество OnInit
 
Цитата
swerg написал:
Цитата
Но вот чтобы узнать какие callback-функции в скрипте определены - QUIK (да и  вообще Lua) вынужден весь скрипт полностью выполнить, это определит для Lua имеющиеся в скрипте функции, про них станет известно.
Вы уверены в тот, что для нахождения всех колбек надо выполнить скрипт.
---------------
Не знаю как реализовали разработчики, но полагаю, что это не обязательно делать.
Определение существующих колбеков можно делать либо один раз после загрузки скрипта и формировать специальную таблицу указателей (давно это тестил и вроде бы пришел к такой схеме)
Но можно это делать налету при приходе соответствующих данных в терминал.
----------------
Относительно Вашего замечание "делайте как нравится"
Я привел ранее аналогию перекрестка. Можно ходить на зеленый, а можно - как нравиться - с закрытыми глазами.  Если потом откроите и поймете, что в больнице, ну тогда будете ходить по правилам. Но может Вам и повезет.  
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Применительно к скриптам в которых ставите в main sleep(500)
либо создаете очередь,
либо пропускаете данные и потом хвалитесь на форуме,
что вы самый лучший алгоритмист, та как Вам на все на...ть.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Очередь не связана с передачей данных потокам или еще куда-нибудь.
-----------------------
Очередь связана лишь с обработкой данных в реальном времени.
------------------------
Реальное время - это время за которое Вы обрабатываете очередную порцию данных.
-----------------
И если Вы не успеваете обработать эту порцию до прихода новой, то возникает очередь.
------------------
Поэтому и имеет значение как быстро Вы можете обрабатывать данные.
===============
И если кто-то говорит что он может обрабатывать тысячи данных, и при этом обрабатывает их по таймеру через 0.5 секунды,
то это значит , что тысячный элемент он обработает лишь через 9 минут ,
следовательно интервал обработки нового значения первого элемента будет не 0.5 сек, а 500 секунд,
так как все элементы будут стоить в очереди.
 
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Владимир,  Добрый день!

Системная математика  видимо имеется в виду QUIK, но основную лепту вносит биржа.
ARQA Technologies декларирует что дают то и передаем.

Согласен с Вами реализация мягко говоря не "кудышняя", одно пустое обновление версий чего стоит (windows уже отстал).
Но  QUIK старая система писалась еще для сибирской биржи, вот и латают как могут.

Язык бессмысленно ругать другого нет. Я люблю луа - чтоб делал без него (Qpile).

Какие из торговых алгоритмов применять дело индивидуальное. Я люблю солянку.

Событие не включать имеет мин. риск.

Но мы ведь обсуждаем Вкл. Чтоб сделку совершил, вел ее по установленным правилам RM MM  и желательно закрыл в +.
Да еще при всем этом желательно чтоб терминал не падал  ::

Ну а если серьезно посмотрите TradingVieW современная более серьезная разработка со своим языком, да и профи привлекают.
Правда брокер на ММВБ один Алор.

с уважением, VPM
Напоминает басню Эзопа "Лиса и виноград"
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
изначально этот код выложен здесь:
http://www.lua.org/pil/11.4.html
Ему в обед 20 лет.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
этому коду в обед 12 лет
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Цитата
VPM написал:
Всем Добрый день!

Уж коль тема называется  Программирование на языке Lua , обращусь к профи за пояснениями.

Взят Пример из книги Р.Е.

------ Очереди и двойные очереди

"Простейшим способом реализации очередей в Lua является использование функций ins ert и remove из библиотеки table.
Эти функции вставляют и удаляют элементы из произвольной позиции массива, сдвигая остальные элементы для согласования действий.
Однако, подобные перемещения могут быть дорогими для больших структур.

Более эффективная реализация использует две индекса, один для первого элемента и один для последнего:

function ListNew () return {first = 0, last = -1} end

Во избежание загрязнения глобального пространства имен мы
определим все операции со списком внутри таблицы, которую мы соответственно назовем List
(таким образом, мы создадим модуль)."

Код
      local  List  =  {};
 function   List.new ()
     return  {first  =   0 , last  =   -  1 }
 end 
 --Теперь мы можем вставлять и удалять элементы с обоих концов за постоянное время: 
 function  List.pushfirst (list, value)
    local  first  =  list.first  -   1 
   list.first  =  first
   list[first]  =  value
 end 
 function  List.pushlast (list, value)
    local  last  =  list.last  +   1 ;
   list.last  =  last;
   list[last]  =  value;
    --message('List.pushlast: ' ..'; '..tostring(last)..'; '.. tostring(value.price)..'; '.. tostring(value.qty)) 
 end 
 function  List.popfirst (list)
    local  first  =  list.first;
    if  first  >  list.last  then  
    --error("list is empty")  
    return   nil 
    end 
    local  value  =  list[first]
   list[first]  =   nil   -- чтобы разрешить сборку мусора 
   list.first  =  first  +   1 
    return  value
 end 
 function  List.poplast (list)
    local  last  =  list.last
    if  list.first  >  last  then  error( "list is empty" )  end 
    local  value  =  list[last]
   list[last]  =   nil   -- чтобы разрешить сборку мусора 
   list.last  =  last  -   1 
    return  val ue
 end 
 
  
Если вы будете использовать эту структуру для обслуживания в порядке поступления, вызывая только pushlast и popfirst,
то и first, и last будут постоянно расти.

Однако, так как мы представляем массивы в Lua при помощи таблиц,
вы можете индексировать их как с 1 до 20, так и с 16 777 216 до 16 777 236.

Поскольку Lua использует для представления чисел двойную точность, ваша программа можем
выполняться на протяжении двухсот лет, делая по миллиону вставок в секунду,
прежде чем возникнет проблема с переполнением.

-----------------------------------------------------------------------

Реализовал у себя для обработки  OnAllTrade:

Создаем т.  list
local list=List.new()

Получаю, сохраняю list и уматываю.
function OnAllTrade(at)
   if is_run and at and at.sec_code==symbol and at.class_code==class then
   List.pushlast(list, at);
end

Получаю из  list строку для обработки.
function AllTrade()
   at = List.popfirst(list);
end

Все инструмента нормально для обработки одного инструмента,  но в процессе работы скрипт накапливает память.

Вопрос к Профи, как нужно сделать чтоб максимально быстро обрабатывалась и очищалась очередь?
Кто то может пример показать.
Вы забыли дать ссылку, откуда Вы скопировали этот код.
https://stackoverflow.com/questions/18843610/fast-implementation-of-queues-in-lua

,
В чём преимущество OnInit
 
Цитата
VPM написал:
Оказывается nil запускает сборщик.
Вы где это прочитали?
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
пардон, опечатка
1) запись X в стек:     t[#t+1]=X
2) выталкивание из стека:   X=t[#t],  t[#t]=nil
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Применительно к скриптам на луа стек реализуется гораздо проще, чем Вы написали.
Алгоритм такой
1) запись X в стек:     t[#t+1]=X
2) выталкивание из стека:   X=t[#t],  #t=nil
-----------------
Для указатель стека можно использовать значение таблицы с индексом 0.
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Возможно ошибаюсь,
но Вы реализовали очередь по принципу LIFO - это стек,
но классическая очередь ( "кто последний", не "последний", а "крайний")  это принцип FIFO, на пример которой Вы сослались   Программирование на языке Lua,
-----------------
Т е Вы просто вместо очереди из книги делаете стек - совершенно другую организацию очереди.
Ваша реализация - это тоже классика реализации стека.
Некорректность вывода по DDE, При выводе по DDE не совпадают данные в таблице ТТС и в таблице вывода - почему?
 
Цитата
sandyman написал:
Добрый день,

При выводе по DDE не совпадают данные в таблице ТТС и в таблице вывода - почему?
Причём это не похоже на какую-то задержку - данные постоянно не совпадают...

[img]data:image/png;base64, *[/img]
Попробуйте отключить все фильтры в таблице. Фильтры таблицы не действуют на вывод по DDE  
В чём преимущество OnInit
 
QUIK создает 7 потоков.  
Скрипты  -запускают  main в следующих по очереди потоки.
В чём преимущество OnInit
 
Объясняю, тем кто не понял.
--------------
Если у Вас скрипт запускается одновременно с запуском QUIK,
то нет особой разницы, где Вы устанавливаете и загружаете
начальные параметры  скрипта.  
-------------------------
Но если Вы запускаете скрипт при работающем QUIK, т е в реальном времени торговли,
то возможны следующие последствия в зависимости
от места , где вы устанавливаете переменные.
Рассмотрим эти варианты:
------------------
1) В начале скрипта присваиваем значения.
В этом случае присвоение происходит до полной загрузки скрипта и запуска функции main.
присвоение произойдет лишь при загрузке скрипта.
При этом могут быть еще не определены Ваши функции, которые Вы используете для назначения параметров.
-------------------
2) В начале функции main
В этом случае весь скрипт уже загружен и все функции определены.
Но так как main - это отдельный поток, то при длительной процедуре инициализации переменных могут поступить данные по колбекам
и эти данные могут оказать влияние на установку переменных.
Вот пример  теста main c установкой параметров:
Код
local beg=os.clock();
local x={}
local function sig(i)   return i end
function main()
      Log:write("main начинаем устанавливать начальные значения"..os.clock()-beg.."\n"); --Log:flush();
   for i=1,10000 do x[i]=math.sin(i); Log2:write("X="..x[i].."\n"); Log2:flush();
   end;
         Log:write("закончили установку нач значений\n"); Log:flush();
    while true do
--       nkevent.wait(event); --ждем события
      Log:write("main основной цикл="..os.clock()-beg.."\n"); Log:flush();
      sleep(10);
   end
end
а вот результат работы этого скрипта с колбеками
Код
OnI nit=0.0
main начинаем устанавливать начальные значения0.0010000000002037
On All=0.0020000000004075
On All=0.0020000000004075
On All=0.0020000000004075
...
On All=0.0060000000003129
On All=0.0060000000003129
On All=0.0060000000003129
...
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
закончили установку нач значений
main основной цикл=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
Внутри цикла установки параметров в функции main вызывается колбек OnAllTrade в основном потоке .
----------------------
3) Установка параметров в колбеке OnInit()
это самый безопасный и предсказуемый способ установки.
OnInit вызывается ,когда весь скрипт загружен и определены все наши функции.
OnInit  вызывается в основном потоке, когда поток main еще не запущен.
Так как все колбеки вызываются в основном потоке, то они не могут быть вызваны пока OnInit не завершит работу.
===================
Т е все переменные будут определены и загружены без каких-либо неожиданностей.
====================
Приведу для наглядности аналогию.
На перекрестке есть светофор.
Особо буйные могут ходить через перекресток не взирая на сигналы светофора.
Особо продвинутые могут даже ходить с закрытыми глазами.
Особо осторожные будут ходить лишь на зеленый.
---------------------
Выбор за Вами.
В чём преимущество OnInit
 
Код
OnI nit=0.0
main=0.0
OnPa ram=0.072999999999979
OnPa ram=0.072999999999979
OnPa ram=0.072999999999979
OnPa ram=0.072999999999979
OnPa ram=0.073999999999984
OnQu ote=0.074999999999989
OnPa ram=0.074999999999989
OnPa ram=0.074999999999989
OnPa ram=0.074999999999989
OnPa ram=0.074999999999989
main=0.114
OnPa ram=0.17699999999999
OnPa ram=0.17699999999999
main=0.22299999999998
OnPa ram=0.31699999999998
main=0.333
OnPa ram=0.41199999999998
main=0.441
OnPa ram=0.517
OnPa ram=0.517
OnPa ram=0.517
main=0.54999999999998
OnQu ote=0.61199999999999
OnPa ram=0.61199999999999
OnPa ram=0.61199999999999
OnPa ram=0.61199999999999
main=0.65899999999999
main=0.76899999999998
OnPa ram=0.81699999999998
OnPa ram=0.81699999999998
OnPa ram=0.81699999999998
Страницы: Пред. 1 ... 8 9 10 11 12 13 14 15 16 17 18 ... 72 След.
Наверх