Старатель, в предыдущих версиях возвращался рабочий DataSource. В коде который разгребает открытые источники там как раз есть ожидание по длине данных, раньше работало.
local classes = {
'TQBR',
'SPBXM',
}
local intervals = {
INTERVAL_M1,
INTERVAL_M2,
}
function main ( )
while isConnected ( ) == 0 do sleep ( 10000 ) end
local list = { }
for _, int in ipairs ( intervals ) do
for _, class in ipairs ( classes ) do
for sec in getClassSecurities ( class ):gmatch ( "([^,]+)") do
table.insert ( list, { class = class, sec = sec, int = int } )
end
end
end
local sources = { }
for _, entry in pairs ( list ) do
local source, error = CreateDataSource ( entry.class, entry.sec, intervals[ entry.int ] )
if source then
source:SetEmptyCallback ( )
table.insert ( sources, source )
else
message ( string.format ( "Failed to create data source: %s\n%s %s %s" , error, entry.class, entry.sec, entry.int ) )
end
end
for _, source in ipairs ( sources ) do
...
end
end
Скрипт висит запущеный. При подключении сыпет ошибки что не указанный инструмент не существует. При перезапуске скрипта, работает как положено.
if isConnected ( ) == 1 and do_cycle then
do_cycle = false
for class in getClasses ( ):gmatch ( "," ) do for sec in getClassSecurities ( ):gmatch ( "," ) do ds, err = CreateDataSource ( class, sec, INTERVAL_M1 )
В предыдущей версии работало, сейчас сыпет ошибки. Начинает работать только после перезапуска скрипта.
Владимир, близок к идеальному на перфокартах. Но благо дело современные текстовые файлы вполне себе резиновые и можно без зазрений совести использовать большое количество вспомогательных символов для разметки и длинные имена переменных. Вы тут вручную пишете минимизированный код по сути дела, вполне естественно что он нечитабелен даже для вас самого и вам гораздо труднее уловить логические ошибки в коде.
Евгений, думаю тут всё проще: случайно поменяли какие-то константы, и теперь рекурсивный поиск индикаторов останавливается на первой итерации т.е. самой верхней папке.
Скачайте MSVC. Скачайте исходный код нужной версии Lua. Откройте нативный терминал разработки MSVC х64, в нем откройте папку с исходниками. Скомпилируйте Lua с помощью такого кода:
Код
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua54.lib /OUT:lua54.dll *.obj
link /OUT:lua.exe lua.o lua54.lib
lib /OUT:lua54-static.lib *.obj
link /OUT:luac.exe luac.o lua54-static.lib
замените "54" на "53" если у вас эта версия. Скопируйте все файлы в системную папку для Lua, например C:\Lua54. Добавьте эту папку в переенную %PATH%.
Скачайте исходный код luarocks. Перейдите в терминале папку с исходниками, установите систему с помощью такой коанды:
Код
install /LV 5.4 /MSVC /P C:\Lua54\luarocks
тоже поменяйте номер версии при надобности. Перейдите в папку luarocks и установите luasocket
Код
luarocks install luasocket
полученные файлы библиотеки можно скопировать из C:\Lua54\luarocks\systree\lib\lua\5.4 в корень QUIK, либо в нужное место если у вас есть соответствующая запись в package.cpath.
Все операции по компиляции и установке надо проводить в нативном терминале х64 (в нем инициализированы нужные настройки).
Отсутствие автологина это мера безопасности, так как тут вопрос стоит посерьёзней чем утечка личных файлов.
Однако для роботов на базе QUIK требуется какой-то механизм установления связи без ввода пароля вручную, т.к. во-первых работают они без непрерывного присмотра, а во-вторых серверы брокеров могут разрывать связь по всевозможным причинам в случайные моменты времени, что парализует работу робота в отсутствии безпользовательского способа подключения.
Евгений написал: Тоже не понятно как это работает, какая то неведомая логика.
Логика очень простая на самом деле: берется самое большое и самое малое значение из всех свечек и линий которые видно на экране, и подбирается масштаб чтобы эти величины были в самой верхней и самой нижней части графика соответственно.
К разработчикам просьба добавить минимальное масштабирование в шагах цены, по умолчанию 20 например - чтобы вертикальный масштаб был не менее 20 шагов цены. Неплохо бы еще добавить минимум масштаба в процентах от исторического максимума.
Владимир, свечи минутные потому что я так выбрал. А индикатор минутный потому что выбраны минутные свечи. Будут часовые свечи, будет отдельно и часовой индикатор. Насчет идеального таймфрейма можно спорить конечно, но мое личное мнение - тиковый. Графики на разных таймфреймах имеют фрактальную структуру, чем короче фрейм тем больше локальных максимумов и минимумов на нём видно. Максимальный объем прибыли можно ивзлечь, собрав все локальные максимумы и минимумы (с поправкой на комиссию разумеется), так как если в более коротком фрейме есть не только монотонный подъем но и локальный спуск, то суммарная высота подъёмов в нём больше, чем на более длинном фрейме. Это значит, что максимальная суммарная высота подъемов лежит в самом коротком фрейме, то есть в тиковом. Практически конечно это зависит от способности алгоритма делать верные решения на коротких фреймах, и не исключены ситуации когда в силу более низкой предсказательной способности, короткий индикатор имеет меньшую прибыльность чем более длинный несмотря на то что имеет более высокий потенциал к прибыли.
Владимир, свечи минутные - в заголовке написано же.
Про отсутсвие логики и здравого смысла в параметрах индикатора я уже говорил. Здравого смысла и логики в поведениии живых торговцев тоже в районе нуля. Надо тумберы щёлкать и ресотаты крутить пока заработает.
A: средневзвешенное среднее от разницы между верхней и нижней ценой за 4 свечки
B: минимальная цена закрытия за 5 свечек
C: максимальная средняя реальная цена за 3 свечки
покупка если A на 10%+ ближе к B чем к Cпродажа если A на 20%+ дальше от B чем от C
От себя могу добавить то, что пытаться применять такие методы анализа как полосы боллингера я считаю нерезонным. Индикаторы, имеющие хорошую предсказательную силу, представляют собой "чёрный ящик" в котором, несмотря на открытость данных и настроек, невозможно разглядеть какую-либо логику и здравый смысл.
Тангенс ниже нуля = просадка. Осталось только выбрать ширину окна и настроить нелинейность. Можно еще вторую кривую бахнуть чтобы короткие тренды ловить. Более простой метод это фракталы посчитать. Но это речь идет о "поймать просадку", найти идеальный момент для покупки это отдельная история и в целом оно вычислению не поддаётся вообще, в силу того что ценовая динамика зависит от психологии торговцев или, по простому говоря, от веления их левой пятки - тут можно максимум сделать статистически благоприятную результативность. Еще конечно можно пытаться эксплуатировать алгоритмические уязвимости в системах конкурирующих алготрейдеров, но вероятность такого сценария такова, что можно смело жопу ставить.
Юрий Волошин, проверить в цикле все 100 акций на предмет просадки цены. Обычно будет целый список а не один отдельный инструмент, так что для вывода результата целесообразно использовать массив вместо одной переменной.
Напоминаю, что каждое "ядро" это отдельный физический процессор. В домашних компьютерах как правило имеется всего 1 сокет и все процессоры монтируются на одном куске кремния, так что принято думать будто плата, на которой смонтировано десяток процессоров, это монолитный "процессор", а "ядра" это так, эфемерное понятие. На рабочих станциях и серверах распространены платы с 2, 4 и более сокетами под процессоры, и каждый процессор зачастую состоит из нескольких раздельных чипов, это проливает некоторый свет на идею многоядерности.
Владимир, не вижу связи с предметом разговора. Специально описывается система, которая работает последовательно на одном процессоре, без какой-либо параллельности. А у нас тут наоборот, проблема в том, что люди пытаются натянуть сову на глобус и заставить однопоточный Lua работать сразу на несколько процессоров, с ожидаемым результатом (вылеты скриптов на пустом месте).
Владимир, как товарищ Эйнштейн завещал: в теории, теория и практика это одно и тоже, но на практике, практика и теория сильно различаются. Так что то, что способ хорошо реализовать многопроцессность на Lua существует, еще не значит что кто-то его сможет найти в обозримом будущем. Ни один интерпретируемый язык не поддерживает работу на нескольких физических процессорах и изменения на этом фронте не предвидятся.
Roman Azarov, Lua принципиально не поддерживает многопоточность, нативных средств реализации нет. В силу чего многопоточность Lua реализуют запуском отдельной виртуальной машины на каждый тред, и реализацией отправки данных между виртуальными машинами через C++, и вам тоже советую использовать такой-же метод. Один из простых методов реализации колбеков в однопоточном Lua заключается в том, чтобы писать колбеки в стек и сделать так, чтобы функция sleep вызывала колбеки и только после этого останавливала выполнение на оставшееся количество времени. Реализовывать можно прямо в Lua а не в C++.
Код
function sleep(ms)
local t1 = os.clock()
for cb, ... in _cplusplus_pollCallbacks() do
if type(_G[cb]) == 'function' then cb(...) end
end
_cpusplus_sleep(math.max(0, (os.clock() - t1) * 1000 - ms))
end
У вас тут повреждение стека виртуальной машины в случайные моменты времени, налицо наличие каких-то неочевидных ошибок в реализации многопоточности, и врядли у вас в команде есть программист С++ у которого IQ выше 180 чтобы этот баг можно было отловить и починить. Надо признать что интеллект до уровня Богов Олимпа всё-таки не дотягивает и решать проблему методами, которые под силу простому человеку.
Старатель, я как-то библиотеку написал для обработки ввода. Биндинги там, фильтрование, все дела. Одна из центральных функций там isKeyPressed, которая возвращает, нажата ли указанная кнопка в текущий момент. Точнее, центральные функции это колбеки onKeyPress и onKeyReleease, но людям нравится писать поллинг вместо обработки колбеков. И я много где в аналогичных библиотеках видел просьбы юзеров добавить wasKeyPressed, которая возвращает была ли кнопка нажата "в предыдущий момент". Тут даже сама формулировка страдает от неопределённости - это примерно как "покажите число, следующее после 0.999", нет такого определённого числа - так что у меня такой функции не было. Но в итоге и ко мне добрались желающие иметь такой функционал. Как было говорено, юз-кейсы обсуждать это не моя задача, моя задача это делать так чтобы они были покрыты, так что я просто взял и сделал, и меня поблагодарили за добавление нужного функционала. То что лично я считаю что пользоваться такого рода функцией это тупо и что сама идея это просто каша - тут не влияет ни на что. Юзеры просят - берешь и делаешь, по мере возможностей.
Старатель,Я ничего не собираюсь - обдумывать юз-кейсы это не моя задача, я должен только обеспечить их покрытие. У вас тут идея наоборот - сидеть и выдумывать причины по которым те или иные фичи НИНУЖНЫ.
Старатель написал: Но QUIK всё одно преобразует аргумент в строку по своему усмотрению. А считает он, что надо 6 знаков после запятой, не меньше. И плевать он хотел на точность шага.
tostring ( ) это стандартная функция Lua и она в свою очередь вызывает стандартную функцию C. В инструкции sprintf():
Цитата
.precision: For a, A, e, E, f and F specifiers: this is the number of digits to be printed after the decimal point (by default, this is 6).
Ну ви таки понели, да? Чтобы вывести число нужным форматом надо использовать форматирование строки.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Такие вещи как бы должны быть либо строковые либо BIGINT. Я может слепой но я не вижу причин по которым для клиента эти данные должны быть числовые а не строковые.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Владимир, IEEE 64-битные флоаты поддерживают целочисленные операции до 53 бит. В языке версии 5.3 добавили 64-битные целочисленные структуры и операторы вывод которых только целочисленный.
Сделайте раскладку окон "для новичков" которая создаётся по-умолчанию при установке QUIK. Включить туда только состояние счёта, таблицу котировок, график тренда и окно заявок. В таблицах данные поставить самые минимальные, например в таблице котировок поставить только последнюю цену, %изменения и объем торгов.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Родина дала ему хеш-таблицы с оптимизацией для целочисленных индексов - нет не хочу, хочу жрать гомно. Ну что поделаешь если в голове тараканы вместо нервных клеток.
В инструкции написано о довольно странной многопоточности. Действительно ли то, что многопоточность реализована путём патча виртуальной машины Lua в котором треды в любой момент времени могут очистить стек виртуальной машины и заполнить другими данными для начала исполнение колбека? Если это так, и если момент перехвата управления точно совпадает с моментом передачи аргументов в функцию, то возможна потеря аргументов если стек не был восстановлен корректно при завершении работы колбека.
Старатель, попробуйте запустить этот же код без колбеков.
Андрей написал: Тут собственно говоря проблема была даже не в том, что запятая пропущена, а в том, что клиент не способен корректно пересылать данные на сервер. обратите внимание на строку ниже: она напрямую запрашивает данные с сервера
А потом просто ретранслирует их обратно через переменную
Код
[ "PRICE" ] = PRCStr
В этом и состоял вопрос: почему клиент не умеет корректно работать с данными сервера. А это уже вопрос к разработчикам. Хотя swerg тоже прав: почему они до сих пор все переводится в строковый вариант)))))) Времена ДОС прям-таки)))))
Смею предположить что PRCStr у вас содержит число вида "123.50000000002" в силу особенностей IEEE 64-битных чисел с плавающей запятой. Опытным путём установлено, что даже просто наличие большего количества нулей чем точность цены тоже отвергает транзакцию. Я выше уже написал функцию которая правильно составляет строковое выражение цены.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Владимир написал: Артем, Так документация-то глупая! Язык паршивый, и документация соответствующая.
Язык отличный и документация исчерпывающая - всё верно. Кому-то не нравятся 1-индексируемые таблицы, кому-то отвратительны begin-end вместо скобок, кто-то жалуется на отсутствие += и ++, кому-то свербит от того что - как в С - классов не предусмотрено и если очень хочется то надо свою реализацию делать. Но того факта что это, можно смело сказать, самый лучший встраиваемый скриптовый язык - не отменяет. Можно даже спорить что Lua это вообще самый лучший скриптовый язык, лучше даже чем Python (т.к. выигрывает он главным образом в размере экосистемы).
Строки в Lua это "непрозрачные" (opaque) объекты для которых определены строковые функции и тип "string". Внутренне каждый раз когда создаётся строка, проводится проверка существует ли уже эта строка, и в таком случае память не выделяется а просто выдается указатель на существующую строку. Указатель потом трансформируется в Lua-объект. В результате чего кстати сравнение строк такое же быстрое как сравнение чисел, хотя это больше для LuaJIT релевантно т.к. оверхед у него ниже. По этой технической причине, изменять строки нельзя, можно только создавать новые, хотя тут конечно "курица или яйцо" - может решили так сделать потому что строки иммутабельные, а может объявили строки иммутабельными потому что так сделали. Сами строки внутренне обрабатываются как набор байтов фиксированной длины а не как текст, что упрощает/ускоряет обработку под капотом и развязывает руки программистам, при этом ни на что не влияя если собственно обрабатывать как текст.
Чтобы можно было строки индексировать как таблицы, можно сделать вот такой финт ушами:
Код
do
local smt = getmetatable ( "" )
local __index = smt.__index
smt.__index = function ( s, k )
if type ( k ) == 'number' then
return s:sub ( k, k )
else
return __index[ k ]
end
end
smt.__len = function ( s )
return s:len ( )
end
end
Код
local s = "foo bar"for i = 1, #s do print ( i, s[ i ] ) end
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Владимир написал: TGB, А ХОТЬ КАКОЙ-НИБУДЬ - считается? Если нет, то это не строка, а именно массив.
Тут действительно вопрос семанткии: в классических языках программирования различие между строкой и массивом основано на содержимом - произвольные данные или валидный текст - причём строки это подмножество массивов в любом случае. Так что спорить что ABC это строка а XYZ это массив это онанизм. В языке Lua строки определены как иммутабельные уникальные объекты абстрактного характера для которых существуют функции работы с ASCII-текстом, а массивов в Lua вообще не предусмотрено, так что тут спорить что ABC это строка а XYZ это массив это не только онанизм но еще и тупость т.к. про всё это прямо в документации написано.
Старатель, ветка о колбеках, вот контекст. Вы несёте сюда поллер с претензией на то что и так хорошо будет. То есть вы предлагаете поллить "новой" функцией внутри "старого" колбека, будто такой вариант не хуже а то и лучше. При том что в предлагаемом колбеке вся эта информация будет содержаться в аргументах вызова. В таком контексте, такое предложение это дурость.
AlexanderKk, криптовалюта уже одной стопой вне закона, так что влошиться в это не советую. Да и как бы торговля без какого-либо контроля со стороны закона позволяет нечестным игрокам использовать какие вздумается манёвры, от простых биржевых манипуляций до таких абсурдных вещей как "пропажа" всех монет с биржи в пользу неизвестных лиц. Уж не буду разжёвывать про то, что функционирует криптовалюта как частично распределённая схема Понци, так что само по себе участие в этом деле подразумевает либо криминальный умысел либо отсутствие серого вещества.
Дмитрий, запускается та которая в настройках указана же. Какую надо такую и поставьте. С байткодом работать не рекомендую по ряду причин, но главным образом потому что байткод не определён и ни о какой совместимости даже речь не идёт.