Игорь Б написал: Myfilefile = "\\MyData.txt"; i = 0; while i == 0 do Myfile = io.open(getScriptPath()..Myfilefile,"r+"); -- Если файл занят if Myfile == nil then sleep(100); else i = 1; end; end;
у вас просто неправильно сделана реакция на if Myfile == nil then если Myfile == nil это означает что файл не открыт т е вам надо проверять на ni и если не открыт то делать его открытие, а не спать.
Боюсь те, кто этим смог бы грамотно воспользоваться, могут это сами и сделать, как автор идеи, в частности. Всем остальным буратинам это не нужно и вредно.
с Вами не согласен по трем причинам: 1) Если это решение будет официальное, то не надо отслеживать новые версии и исправлять то, что перестает работать . Как это есть сейчас. 2) Буратинам будет еще легче писать свои хотелки так как нет надобности одно и тоже программировать в множестве роботов Все будет существенно проще 3) если это реализуют, то размещу следующее пожелание, в котором создание роботов превращается в написание лишь алгоритма, а все или почти функции QLUA скрываются в обертке Т е буратинам даже не надо изучать луа. Просто пишут почти на естественном языке что хотят и все работает.
Добрый день, Прошу разработчиков рассмотреть следующее предложение по развитию QLUA. ---------------- Суть проблемы. При создании нескольких скриптов приходится дублировать внешнюю среду функции main в каждом скрипте Т е все колбеки и все глобальные переменные Но так как все это исполняется в одном потоке создается существенное торможение работы терминала при большом числе скриптов. -------------------- Решение - предложение. Решить проблему можно двумя путями. Вариант1 Реализовать возможность создание в одном скрипте множество функций main Т е реализовать механизм запуска нескольких потоков в одном скрипте Ввариант2 Реализовать возможность работы множеству скриптов с одной глобальной областью Этот вариант реализуется, например, путем подмены указателя глобальной таблицы скрипта на указатель общей глобальной области Этот вариант я реализовал лет восемь назад для win32 и LUA 5.1, Теперь надо все переделывать на 64 и 5.3 ------------------- Поэтому предлагаю это сделать для всех буратин.
Nikolay написал: Это, конечно, похвально написать свой RabbitMQ, но, в результате, получится схема не меньшей сложности. Т.е. мы пишем свой терминал. Он будет собирать события терминала, исполнять команды скриптов и читать их ответы, передавать им поток данных.
При этом мы итак находимся внутри такого окружения... Что мешает написать скрипт исполняющий сразу несколько алгоритмов, по многим инструментам. Будет один скрипт, одно окружение. А колбеки Квика слишком ненадежная конструкция. Проще без них. Хотя, конечно, от части из них отказаться сложно, как, например, OnTransReply.
вообще-то я написал о том, что сделал сам лет ...надцать назад, т е фактически сразу как внедрили VMlua в квик. А перед этим примерно года за два я сам в переписке с руководством разработчика предлагал внедрить вместо QPILE LUA. не утверждаю, что они меня послушались, но в результате появился луа в квике. --------------------- Тот механизм, о котором я написал, позволяет очень просто делать много роботов по различным алгоритмом для одного инструмента. Колбеки не дублируются в скриптах Каждый колбек существует в своем скрипте и вызывается всего один раз квиком для получения данных вне зависимости от числа роботов. Роботы получают требуемые данные от этого скрипта. т е потоки синхронизируются и обмениваются данными , а также чтобы не дублировать код, могут запускать функции других скриптов через механизм колбеков между скриптами. Сравнительно просто в этом варианте отдавать данные совершенно независимым процессам. ----------------------- Но если не мечтать о вечном, то проще всего делать роботов как индикаторы.
nikolz написал: Каждый скрипт условно можно разделить на три части1) действия вне колбеков и функции main - это отдельный поток и VM Lua2) функция main каждого скрипта - это отдельный поток и VMLua3) вызов и исполнение функций колбек осуществляется в одном основном потоке термина.
Не совсем оно так, стейт для тела скрипта и колбеков один и выполняется в основном потоке квика, стейт для мейна второй и выполняется в специально для него созданном потоке. То есть ваш п.1 лишний, нет отдельного стейта для тела.
Ваши мысли насчет 128 ядер это из разряда давайте загрузим проц бесполезной работой, чо он простаивает-то. В любом случае ваши 100500 потоков будут сериализоваться на доступе к общим ресурсам, т.е. в основном (в таком количестве) они будут крутить спинлок. Для примера предлагаю прогу из directx sdk, где можно отрисовать одно и то же либо одним потоком, либо многими. Запустите и убедитесь, что проц оно жрет в N раз больше, а fps растет процентов на 5.
Я вам предлагаю для примера посмотреть алгоритм БПФ либо нейронной сети
Иван Ру написал: Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Признаться, все более склоняюсь в сторону такой модели, в первую очередь из-за разрастания скрипта и усложнения его логики из-за чего работа и модификация скрипта становится все более затруднительной... Полагаю можно использовать такую структуру: - базовый скрипт, который определяет статус сессии и агрегирует информацию из коллбэков - описание классов (стратегия, позиция и т.п.) - типовые универсальные модули, например, удаление устаревшей части данных таблиц (цены, бид аск и т.п.), ежедневное определение ключевых временных точек сессии в формате posix, визуализация и логгирование информации и т.п. - собственно скрипты с описанием стратегий, логики определение сигналов на вход и выход и сопутствующих действий...
Если кто-то поделится своим видением организационной структуры - буду признателен
Поясню свое прежнее беспокойство - у меня большинство скриптов работает одновременно с большим числом инструментов, предполагается большой объем расчетов, опасаюсь, что в тех случаях когда они осуществляются не в теле основного потока (main), а путем многократного вызова функции, это может негативно сказаться на быстродействии скрипта.
Проблема усложняется тем, что разработчики не утруждают себя документацией по API к их библиотеке, нигде не описывают интерфейс взаимодействия скриптов с терминалом на уровне API C for LUA. На основе ответов основного разработчика QLUA(не будем показывать пальцем) , по-моему мнению, схема взаимодействия скриптов с терминалом следующая: ------------------------------- Каждый скрипт условно можно разделить на три части 1) действия вне колбеков и функции main - это отдельный поток и VM Lua 2) функция main каждого скрипта - это отдельный поток и VMLua 3) вызов и исполнение функций колбек осуществляется в одном основном потоке термина. --------------------------- В итоге получаем следующее. Если Вы не профессионал , то скорее всего будете много делать в колбеках - так проще . Все колбеки будете вызывать в каждом из скриптов. ------------------------------- Получается прикольно. Даже если у Вас суперкомпьютер с 128 ядрами , то все колбеки будут тупо работать на одном ядре и в одном потоке, в котором крутится еще и основное ядро терминала КВИК. ------------------ Сейчас версию 7 заменяют на версию 8 В итоге XP с одним ядром не работает вообще. Но зато у Вас теперь win10 64 бита и ядер хоть 128. А что реально в сухом остатке? -------------------------- Представим что на телегу прикрутить двигатель от болида формулы 1, а впереди телеги все та же лошадь . Вопрос, насколько быстрее эта телега теперь довезет Вас из пункта А в пункт В? ----------------------------------------- Конечно есть решение костыльное - ничего не делать в колбеках, а делать все в main. Но резонно спросить разработчиков, а о чем думали они когда разрабатывали концепцию встраиваемой виртуальной машины? -------------------------------- Да и это костыльное решение не решает проблему многократного дублирования кода в различных скриптах. --------------------------------- На самом деле все могло быть существенно проще и исполняться существенно быстрее, но именно это никому не требуется. -------------------------- На рынке всегда решается лишь одна задача, за разработку инструмента для решения которой платят разработчикам, - как у буратины отобрать пять золотых. ----------------------------------- В итоге для целей конструирование игрушечных роботов, чем занимаются посетители данного форума, все сделано просто замечательно. ==================================================================================== "Теперь попросим на трибуну начальника транспортного цеха. Пусть доложит об изыскании внутренних резервов. "
Иван Ру написал: Интересно мнение форумчан - как предпочитаете писать скрипты - все в одном файле или в виде конструктора - с подгрузкой отдельных файлов: 1. Отдельных функций/процедур (выставление заявки, считывание определенных данных и т.п.) 2. Отдельных классов (стратегия, позиция и т.п.)
Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Иван Ру написал: Вот так ругается на строку кода в цикле расположенном в пределах main, где пытаюсь считать статус соединения... while is_run do sleep (50) if isConnected() == 1 then .. -- не могу понять, что тут написал не так, ругается на эту строку ... end
jonny1960 написал: Подскажите, как правильно получить значения цены закрытия для N последних свечей и умножить на их порядковый номер по счету (P1 * 5) + (P2 * 4) + (P3 * 3)
И не совсем понимаю, что делает функция Squeeze и зачем она нужна?
if CandleExist(I,ds) then
if it.l >= P then local MD = 0 for i = it.l-P+1, it.l do MD = MD + (GetValueEX(it[Squeeze(i,P)], VT, ds)) * i end return MD end end
http://www.kamynin.ru/ пример индикатора для произвольных параметров. по его подобию можете сделать любой свой.
На самом деле посылать письма из квика на смартфон или оповещать через приложение, работающие через интернет, которое установлено на смартфоне - это какой-то мазохизм. --------------------- У вас терминал квика в режиме торгов постоянно включен в интернет и смартфон тоже в интернете. Ну так что же вам мешает передать сообщение по схеме pоint to point, а не гонять письма и сообщения через сторонние сервера? Скорость передачи будет раз в сто выше, а накладные расходы раз в сто меньше. Делал такое, давно это было. -------------------------- Подумайте на досуге.
Незнайка написал: Для фьючерсного контракта на акцию есть конкретная ценная бумага, которая торгуется на бирже и поставляется при экспирации. Как из квика получить код этой бумаги, например для GZU0?
начну с анекдота: ----------------------- Мужик вечером что-то ищет у фонаря. Прохожий спрашивает - что потерял? Да вон там у забора 100 рублей. А почему здесь ищешь? Так тут светлее. -------------------------------- Вы очевидно как этот мужик. Вместо того, чтобы искать коды фьючерсов на бирже , которая их и придумала, задаете вопрос на форуме. --------------------------- В будущем ищите там, где потеряли. ===================== Ваш ответ на бирже называется: ------------------- Спецификации коротких кодов фьючерсных и опционных контрактов на срочном рынке --------------------- https://www.moex.com/a214
Nikolay написал: Начались торги в вечернюю сессию на фондовой секции. Я уже задавал вопрос про трансляцию времени сессии, но вот сейчас она идет и можно посмотреть на реальный поток данных.
Что мы видим:
Вот утро. Начало торгов. По фьючерсу все ожидаемо и понятно. Есть и времена и статус. По акции я вижу только статус, а время заполнилось только утренним аукционом.
Вот данные пор акции внутри дня. Время утреннего акциона. Это как понимать? Уже сессия к концу идет, а время старое. [INFO 2020-06-23 17:33:32] : SBER TRADINGSTATUS {param_image = "открыта", param_type = "4", param_value = "1.000000", result = "1"} [INFO 2020-06-23 17:33:32] : SBER STARTTIME {param_image = "9:50:00", param_type = "5", param_value = "95000.000000", result = "1"} [INFO 2020-06-23 17:33:32] : SBER ENDTIME {param_image = "9:59:34", param_type = "5", param_value = "95934.000000", result = "1"}
Вечер. По фьючерсам все адекватно, а вот по акциям:
Времена аукциона я еще могу понять. А вот что это такое при старте вечерней сессии уже с трудом. И опять - времена то где? Почему нельзя заполнить времена прямо при подключению к серверу, как это делается для фьючерсов и менять их, если они меняются внутри дня? Поля же есть.
Часть акций торгуется, часть нет. А информации о времени сессии нет. Раньше можно было хотя бы определить константы, когда времена были фиксированными (хоть это было и спорное решение), но сейчас то как.
На первом этапе на вечерней сессии торгуются 25 ликвидных акций из списка индекса МосБиржи, а до конца года в список торгуемых инструментов войдут все акции из индекса МосБиржи (38 акций), а также 50 наиболее ликвидных иностранных акций из американского индекса S&P 500.
Николай написал: В Lua загружаю библиотеку написанную мной на C++ (я предварительно переписал и скомпилировал C++ код под Lua5.3)require("luacdll") Файлы luacdll.dll и файл lua положил в папку с quik. При загрузке dll выдает ошибку error loading module 'luacdll' fr om file '.\luacdll.lua': .\luacdll.lua:1: too many C levels (lim it is 200) in main function near '"luacdll"' Компилировал библиотеку на C++ под Win64 Relise в Visual Studio 2017 регистрировал внешние функции так extern "C" LUALIB_API int luaopen_luacdll(lua_State *L) { // эта функция выполнится в момент вызова require() в Lua-коде // регистрируем реализованные в dll функций, чтобы они стали дуступны для Lua #if LUA_VERSION_NUM >= 502 lua_newtable(L); luaL_setfuncs(L, ls_lib, 0); lua_setglobal(L, "luacdll"); #else luaL_openlib(L, "luacdll", ls_lib, 0); #endif return 0; } Если указать в коде Lua перед загрузкой модуля dll package.cpath = "C:\\Open_Broker_QUIK_AGromazin\\luacdll.dll" Ничего не меняется
Внимательно читаем сообщение об ошибке: too many C levels (lim it is 200) in main function near '"luacdll"' Усе понятно?
Михаил В написал: Если выставить sleep < 100 например 10 или 1, то обновление в таблице происходят очень медленно, раз в 10 секунд примерно или по нажатию мышкой в любую ячейку таблицы. Торговые операции при этом проходят нормально. Можно ли как-то побороть? Пример: function main() CreateTable() while IsRun do SetCell(t_id, 8, 1, tostring(math.random(1,9999))) sleep(10) end end
1) вообще-то минимальный квант времени для задачи в винде без танцев с бубном составляет не менее 10 мс. sleep останавливает вашу задачу и отдает оставшееся время ее кванта другой задачи. если Вы установите 10 или меньше, то вы ничего не отдадите в реальности, т к это и есть минимум для вашей задачи. В квике все еще хуже. Поэтому ставить в sleep значения меньше 10 - не имеет смысла. Надо ставить больше. ----------------------- 2) в документации на QLUA указано, что если установлен sleep , нет обработки событий терминала в функции main. ------------------------------------------- Поэтому не следует ждать чудо от QUIK, подобно тому как не следует пытаться на самокате выжать 100 км в час. -------------------------------- Будьте реалистом.
в документации указанной выше Вы узнаете что ГО зависит от направления сделки: Эффекты: • Асимметричное ГО на покупку и продажу • Увеличение ГО по однонаправленным позициям из-за учета процентного риска • Снижение изменений из-за влияния IR с увеличением срока • Снижение ГО по позициям в ММС и по «Календарным спредам» ---------------------
_sk_ написал: Не ломай голову, в явном виде пропиши дату, когда надо переходить на новый фьючерс.
С календариком посмотреть когда какой фъючерс заканчивается и в какой день лучше менять с учетом праздников и выходных? Особенно это неудобно у нефти. Хотелось бы автоматизировать
ну так введите в начале года в программу календарь и считывайте автоматически. в чем проблема?
Кто может написать простой скрипт на Lua для индивидуального графика-индикатора?, написать простой скрипт на Lua для индивидуального графика-индикатора
Кто может написать простой скрипт на Lua для индивидуального графика-индикатора?, написать простой скрипт на Lua для индивидуального графика-индикатора
правильно понял : вывести на экран сумму= "количество заявок на покупку" + "на продажу" + обьем (???) ------------------------ В таблице нет параметра "объем" есть "оборот в деньгах" --------------- что такое "объем" и откуда его брать?
Сергей написал: Освежу темку. 1. Если фирма для брокера это группа счетов, то зачем в вызовах getDepoEx, getMoneyEx, getFuturesLimit, ... кроме номера счета указывать еще и фирму? Кажется, эта информация избыточна. 2. Практически всегда, номер счета фондового рынка МБ имеет код "L01~00000F00", получается это не счет клиента, и даже не брокера, а .... счет чего?
на бирже торгуют фирмы(брокеры) а не их клиенты поэтому информация о фирме нужна бирже. кроме того в сделке на бирже есть и идентификатор клиента, но идентификатор клиента(счет) нужен реально лишь брокеру для разнесения сделок по клиентам во внутренней "амбарной книге"
just написал: Здравствуйте, подскажите, пожалуйста можно ли программно получить базовый актив по фьючерсу или наоборот найти есть ли фьючерсы к заданному активу. Например, getParamEx("SPBFUT", "SiM0", "OPTIONBASE").param_image возвращает значение "Si", а актив, который, я так понял, лучше всего подходит в качестве базового я нахожу по коду USD000UTSTOM. Ну и по другим фьючерсам аналогично... Вычислить конкретный базовый актив, который можно использовать в коде я не вижу как...
Si - фьючерсный контракт на курс доллара США/ российского рубля, обращающийся на бирже РТС FORTS. Для фьючерса Si базовым активом является официальный курс доллара и рос. рубля Центральным Банком РФ. Участники сделки (покупатель и продавец) фьючерса торгуются только за цену, и несут ответственность перед РТС до момента исполнения (даты погашения). Исполнение фьючерса происходит по расчетной цене, которая зафиксируется в день погашения.
вместо: if tblAsk==nil then Ask=0 else Ask=tonumber(tblAsk.param_value) end -------------- пишите проще: if tblAsk then Ask=tonumber(tblAsk.param_value) end ---------------------------------- где используете Ask тоже пишите if Ask then .... end ----------------- В итоге вы не будете тратить время на расчеты если Ask=nil , а в Вашем случает Вы тратите время на расчеты, если Ask=0, либо ставите такое же условие для нуля
Простейший вариант: Получаем точное время. три варианта: 1) синхронизируем компьютер по серверу точного времени 2) читаем время сервера брокера из параметров соединения квик 3) читаем в скрипте время с сервера точного времени ------------- сравниваем текущее точное время с ожидаемым (временем перерыва) ================== достижимая погрешность 0.01 сек точнее лишь в дата центре
Александр написал: Спасибо. А если рассчитать значения в скрмпте, можно как-нибудь отрисовать их на графике?
например так 1) делаете индикатор (test.lua) на вывод содержимого из файла (test.log) ----------------- 2) в скрипте считаете индикатор test и пишите в файл test.log --------------------- пускаем скрипт пускаем индикатор если файла нет то при пуске индикатора ничего отображаться не будет -------------- таким образом можете считать и отображать любое количество индикаторов ------------------------------ например так создаю индикатор отношения числа заявок на покупку к числу заявок на продажу
вот вариант учитывающий вроде бы ваши желания. nk_com_v1.lua ----------------- -- удаляем комментарии и лишние пробелы --пример вызова для файла C:\NK\nk_bot.lua: --lua nk_com_v1.lua C:\NK\nk_bot -------------------- if arg[1] then out=io.open(arg[1].."_.lua","w") ---------------- for s1 in io.lines(arg[1]..".lua") do len=string.len(s1); s=""; x1=0; m=1; while len>=m do x=string.byte(s1,m) if x==59 then x=32 end if x==32 and x==x1 then x1=x; x=0 else if f==nil then if n==nil then if x==34 or x==39 then n=x end else if x==n then n=nil end end end if n==nil then z0=string.byte(s1,m+1); if x==45 and z0==x then z=string.byte(s1,m+2); z1=string.byte(s1,m+3); if f then if f==1 then if z==93 and z==z1 then f=nil m=m+3; x=0; end end else if z==91 and z==z1 then f=1 end break;end end if f then x=0; end end x1=x; end if x and x>=32 then s=s..string.char(x);x=x1; end m=m+1; end if s and s~="" then out:write(s.."\n") end end out:close(); end -------------------------------------------- если что-то не учитывает то напишите это тест:
Archie_ написал: nikolz, А теперь обработайте все эти примеры вот этой функцией
Код
local function DeleteAll_Comments (text);
----
text = text .. '\n';
local t,t2,t3,one,two,cmt,x,Rem = {},{},{}, 0 , 0 , 0 , 1 , nil ;
local boxOpens,box Close ,RemStr = 0 , 0 , nil ;
local SingleLine,boxActiv = nil , nil ;
local LineCom,LineComM,LineComRemove = 0 , nil , nil ;
----
for val in text:gmatch( ".-\n" ) do ;
t3[ # t3 + 1 ] = val:gsub( '\n' ,( ' ' ):rep( 2 ) .. '\n');
end ;
text = table.concat (t3);
----
for val in text:gmatch( "." ) do ;
t[ # t + 1 ] = val;
end ;
----
for i = 1 , # t do ;
--------------------
if Rem then ;
local Cls = RemStr:match( '.' ,x);
if Cls = = t[i] and x = = # RemStr then RemStr = nil Rem = nil Cls = nil end ;
if Cls = = t[i] then x = x + 1 end ;
if Cls ~ = t[i] then x = 1 end ;
t[i] = "" ;
end ;
--------------------
--------------------
if LineComRemove then ;
if t[i] ~ = '\n' then ;
t[i] = "" ;
else ;
LineComRemove = nil ;
end ;
end ;
--------------------
if LineCom = = 1 and t[i] ~ = "-" then LineCom = 0 end ;
if one = = 0 and two = = 0 and not boxActiv and not Rem and not LineComRemove then ;
if LineCom > = 3 then ; --4 simb>=
if t[i] = = "[" or t[i] = = "=" and LineComM = = 1 then ;
if t[i] = = "[" then ;
LineCom = 0 ;
LineComM = nil ;
end ;
else ;
t[i - 0 ],t[i - 1 ],t[i - 2 ],t[i - 3 ] = '' ,'','','';
LineComRemove = true ;
LineCom,LineComM = 0 , nil ;
boxOpens,box Close ,SingleLine,cmt,t2 = 0 , 0 , nil , 0 ,{};
end ;
end ;
if LineCom = = 2 then ;
LineCom = LineCom + 1 ;
if t[i] = = "[" then LineComM = 1 end ;
end ;
if t[i] = = "-" and LineCom < 2 and not LineComRemove then ;
LineCom = LineCom + 1 ;
end ;
end ;
if not LineComRemove then ;
--------------------------------------------------
--------------------------------------------------
if t[i] = = "'" and two = = 0 and not boxActiv then ;
if one > 0 then one = 0 else one = 1 end ;
end ;
---
if t[i] = = '"' and one = = 0 and not boxActiv then ;
if two > 0 then two = 0 else two = 1 end ;
end ;
---
if t[i] ~ = '[' then boxOpens = 0 end ;
if t[i] ~ = ']' then box Close = 0 end ;
if t[i] ~ = "-" then cmt = 0 end ;
---
if t[i] = = '[' and one = = 0 and two = = 0 and not boxActiv and # t2 < 2 then ;
boxOpens = boxOpens + 1 ;
if boxOpens > = 2 then ;
boxOpens = 0 ;
boxActiv = true ;
end ;
end ;
---
if t[i] = = ']' and one = = 0 and two = = 0 and boxActiv then ;
box Close = box Close + 1 ;
if box Close > = 2 then ;
box Close = 0 ;
boxActiv = nil ;
end ;
end ;
---
if SingleLine then t2[ 1 ],t2[ 2 ] = '-' ,' - ' end ;
if one = = 0 and two = = 0 and not boxActiv and t[i] = = '-' then ;
cmt = cmt + 1 ;
if cmt > = 2 then ; SingleLine = true ; cmt = 0 end ;
end ;
---
if SingleLine and # t2 > = 2 then ;
if (t[i] = = '[' or t[i] = = '=' ) and # t2 > = 3 then ;
t2[ # t2 + 1 ] = t[i];
elseif t[i] ~ = '[' and t[i] ~ = '=' and # t2 > = 3 then ;
t2 = {};
SingleLine = nil ;
end ;
---
if t[i] = = '[' and # t2 = = 2 then ;
t2[ 3 ] = t[i];
elseif # t2 = = 2 and t[i] ~ = '[' then ;
t2 = {};
SingleLine = nil ;
end ;
---
if # t2 > 3 and t[i] = = '[' then ;
Rem = true ;
for ii = 1 , # t2 do ;
t[i - (ii - 1 )] = '' ;
end ;
RemStr = table.concat (t2):gsub( '%s' ,''):gsub( '%-' ,''):gsub( '%[' ,']');
t2 = {};
SingleLine = nil ;
if not RemStr or RemStr = = '' then Rem = nil end ;
end ;
end ;
-------
end ; --LineComRemove
end ; --End for #t
text = table.concat (t);
----
t3 = {};
for val in text:gmatch( ".-\n" ) do ;
t3[ # t3 + 1 ] = val:gsub( '%s%s\n' ,'\n');
end ;
----
return table.concat (t3);
end ;
--===================================
--filename = [[C:\\...]]
local file = io.open (filename .. '.lua','r');
if not file then return end ;
local text = file:read( 'a' );
file:close();
-----
text = DeleteAll_Comments(text);
-----
file = io.open (filename .. '_.lua','w');
file:write(text)
file:close();
--===================================
начнем по порядку Зачем так агрессивно вести беседу? Я Вам ничего не должен. -------------------- теперь по существу. Сравните размер кода вашего и моего. ------------------ Я написал его за 20 минут на основе своих привычек размещать коммент -------------------------- Выше я привел как я ставлю многострочный Ставить закрытие в конце строки как у Вас по-моему мнению это не красиво и не наглядно. поэтому у меня даже мысли не возникало так ставить ------------------------- Но если такие чудики есть, то это легко исправить Вариант с тестом, содержащим символы выделения, тоже решается просто, Так как никогда не было такой надобности в таких кусках текста, то об этом не заморачивался ----------------
одно замечание я выделяю многострочные коммент и так именно обрабатывается коммент в данной программе: --[[ ...... ....... ...... --]] т е символы выделения всегда в начале строки у Вас в первом примере завершающий символ в конце строки
могу выложить скрипт до и после объем скрипта 1000 операторов -------------------------- напишите конкретно что у вас не работает или выложите свой файл я вам его обработаю и опубликую. если есть у вас потребность в таком скрипте. --------------------- если не умеете запускать то могу выложить скомпилированный или exe файл например для Luajit.
Нет, такой возможности нет - MA привязан к текущему интервалу графика, который может быть только один для одного окна графика.
Наиболее вероятно, Вашу задачу можно решить пользовательским индикатором на LUA. Необходимую информацию и примеры для написания собственных индикаторов Вы можете найти по следующей ссылке .
Вопрос немного в другом. 1) Можно ли на принципах индикатора нарисовать линию и после двигать ее мышкой на графике. 2) Можно ли запомнить ее ID что бы не отрисовывать дважды?
Archie_ написал: Привет всем! Ребят подскажите пожалуйста, как удалить все комментарии из файла lua, может быть есть у кого уже написанная функция. Поиск в Google не дал результатов. Попытался написать сам, на первый взгляд вроде бы просто, но оказалось не все так просто, потому как в середине строки может встретится что то типа того *** или еще чего и это оказалось выше моих сил. Спасибо!
***
Код
if bla then bla = '--' end - - коммент
if bla then bla = 'D --' end - - коммент
или
--[[ bla bla bla bla bla --[==[ bla bla bla
bla bla bla bla -- bla bla bla -- bla bla --]=] bla
bla bla bla bla --]]
выкладываю скрипт (nk_com.lua):
Код
-- удаляем комментарии и лишние пробелы
--пример вызова для файла C:\NK\nk_bot.lua: nk_com.lua C:\NK\nk_bot
--результат в C:\NK\nk_bot_.lua:
--------------------
if arg[1] then
out=io.open(arg[1].."_.lua","w")
----------------
for s1 in io.lines(arg[1]..".lua") do
local len=string.len(s1); local s="";
for m=1,len do
local x=string.byte(s1,m)
if x==59 then x=32 end
if x==32 then
if s~="" and m~=len then
if f==nil then s=s..string.char(x) f=1 end
end
else if x>=32 then s=s..string.char(x); f=nil; end end
end
if e then s=nil;end
if s2=="--]]" then e=nil; else if s2=="--[[" then e=1; s=nil; end end --многострочный комментарий
if s then
local m=string.find(s,"%-%-")
if m then
if m==1 then s=nil else s=string.sub(s,1,m-1)
end end
if s and s~="" then out:write(s.."\n") end
end
end
out:close();
end
Sergey Gorokhov написал: Здравствуйте, Такой возможности не предусмотрено.
А можно как-то проверить существует такой идентификатор или нет?
Можно сделать так: перечень встроенных индикаторов не меняется. поэтому его можно записать в текстовый файл ------------------------ все самопальные индикаторы размещаются в папке LuaIndicators. Читаем имена файлов в этой папке.
просьба пояснить, Вы знаете алгоритм работы сервера или это ваше предположение? ---------------------------------- Я тоже так полагал, Но, предлагаю вам посмотреть в стакан. Там можно наблюдать как маркет-мейкер ставит заявки по одной акции. Если поставить туда же свои заявки то при исполнении число заявок на этой позиции увеличится и свои исполнятся не второй а гораздо позже. ---------------- Знаю, что такой прием раньше использовался на форексе.
Иван написал: Не совсем понял при чем здесь HFT роботы (высокочастотники как понимаю)?
Сейчас у меня стоп выставляется через функцию OnTrade(). Прошла сделка объемом 7 = выставился стоп объемом 7.
Сложность начинается тогда, когда мне нужно сделать закрытие частями. К примеру хочу закрыть 30% сделки - это будет 3 контракта.
Соответственно сделка прошла и OnTrade() вижу что мне нужно изменить стоп на 7 контрактов. И здесь начинаются сложности - удали стоп 7, выставь стоп 4. Это хорошо сработает если исполнится 3 контракта сразу. А если они исполнятся по 1, 1 и 1. Т.е. мне нужно удалить стоп 7, выставить стоп 6. Удалить стоп 6 (которого возможно еще нет в живых), поставить стоп 5, удалить стоп 5 (которого также еще нет), поставь стоп 4. Сложность в этом.
поясню Проблема в скорости поступления в терминал(ваш комп) информации с сервера биржи и в скорости исполнения сервером квика поручений с терминала В HFT задержки составят десятки микросекунд а в квике сотни миллисекунд. Поэтому пока вы снимаете старый стоп и выставляете новый - это все будет исполнять сервер квика, сервер биржи уже продаст следующую часть в вашей заявке. ----------------- Поэтому для высоколиквидного инструмента квик не обеспечит нужной скорости исполнения ------------------ поэтому для конкретного ответа надо рассматривать конкретный алгоритм конкретный инструмент иначе это лишь теория. Программу можете написать, но реально это не всегда будет работать как хочется.
Добрый день, вопрос к разработчикам. ---------------------- Рассмотрим такую ситуацию. На сервере есть очередь заявок длинною 100 первой стоит заявка клиента1 в текущий момент этот клиент подает точно такую же заявку, но с другим количеством ----------------------- Внимание вопросы: 1) как данную ситуацию обработает сервер квика 2) как данную ситуацию обработает сервер биржи --------------------- Варианты ответов 1) поместит заявку в очередь с номером 101 2) добавит заявку в очередь с номером 1 ------------ Спасибо
Николай Камынин написал: текст в любой кодировке - это массив байт
Вообще все в компьютере это массив байт. Остальное все неверно. Ноль в конце это чисто сишная фишка, в паскале их нет например. Строка это не байты, а codepoints, каждая из которых может быть больше байта (до четырех например в utf8). Если вы разрежете строку посреди codepoint, обе половины уже не будут строками или, в лучшем случае, будут битыми строками. Отображение это вообще отдельная тема, там не только codepoints действуют, композиция включается, а еще куча параметров конкретного шрифта. Знание кодировки нужно для любых действий со строкой, отличных от простого копирования. Это если говорить о строках, а не о кучке мусора с приделанным ноликом. Прежде чем пояснять, стоит все же хоть немного тему изучить.
ну почитайте хотя бы документацию: цитата: ------------------------------------ lua_tolstring[-0, +0, e]const char *lua_tolstring (lua_State *L, int index, size_t *len);Конвертирует Lua значение по заданному индексу в C строку. Если len не является NULL, она также устанавливает указатель *len с длиной строки. Lua значение должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение является числом, то lua_tolstring также изменяет действительное значение в стеке на строку. (Такое изменение дезориентирует функцию lua_next, когда lua_tolstring применяется для ключей во время обхода таблицы.)
lua_tolstring возвращает полностью согласованный, внутри Lua состояния, указатель на строку. В этой строке всегда имеется нуль ('\0'), после последнего символа (как в C).
Иван написал: Обычно выставление стоп-лосса затачивается на то какой объем был куплен или продан. Продали 100 контрактов = 1 стоп на 100 контрактов Учитывая то что продажа 100 контрактов может происходить частями по 45 по 5 и по 50 контрактов, то соответственно можно и стопы также выставить по 45 по 5 и по 50. И здесь при закрытии позиции начинаются сложности - закрытие также может произойти частями по 30, по 20 и по 50. И сложно пересчитать каждый из ордеров.
Другое дело если каждый ордер это 1 контракт. Продалось 30 контрактов - сняли 30 стопов. Продалось еще 20 - сняли 20 и т.д. Насколько вообще в принципе жизнеспособна идея купив к примеру 100 контрактов выставить не 1 стоп, а 100 стопов по 1 контракту.
При торговле на 10 контрактов по инструменту допускаю что все это допустимо 10 продано = 10 ордеров. А вот когда число контрактов 100, 500?
теоретически можно сколько душе угодно. практически - трудно придумать смысл этому. ---------------- Надо учитывать следующее: ----------------- стопы хранятся в очереди стопов на сервере брокера и отсылаются им на биржу, если условие true ------------------ ордер находится на бирже ----------------- Если вы хотите выставить ордер на продажу на 100, а стопы выставлять по мере исполнения ордера, то надо делать HFT робот и ставить максимально близко к бирже. --------------- на квике - как на велосипеде обгонять самолет. Упаритесь.
поясняю для тех кто в танке -------------------------- текст в любой кодировке - это массив байт конец массива обозначается нулевым байтом, поэтому в массивах с текстом запрещен нулевой байт но если в массиве байтов нет нуля то это может быть массив не текста --------------------- знание кодировки требуется лишь генератору символов на устройстве отображения ------------------ поэтому если отображения нет , то кодировка не имеет значение, если все строки текста в программе имеют одинаковую кодировку то с ними можно работать как с массивами байт ---------------------- оператору tostring вообще не требуется знать кодировки так как его задача заменить хеш указателем на массив байт с нулем в конце