Вопрос с повторными расчетами добавляемого индикатора или индикатора, у которого меняют параметры, имеет давнюю историю и разумно решен, похоже, не будет.
Напомню, что в QUIK версии 6.17 при редактировании параметров индикатора пересчитывался только он один, остальные индикаторы на диаграмме не пересчитывались ("1+0"). В одной из последующих версий сделали улучшение - "2+1". На просьбу вернуть "1+0" Разработчик откликнулся доведением до абсурда в версии 7.2.15 - при редактировании параметров какого-либо индикатора он пересчитывался 3 раза, а все остальные на диаграмме - по 2 ("3+2"). Это он шутил так. Чтоб пользователю жизнь раем не казалась.
Так что, нынешние "2+1" (при изменении параметров индикатора) или "3+1" (при добавлении), очень нужные Разработчику, опасно беспокоить, может получиться, как тогда. А пользователь перебьется как-нибудь на нынешних.
"Как определить, какой расчет окончательный?" Они близнецы, все окончательные.
Совет - со временем переходите от индикаторов к скриптам-роботов. Там этого вопроса не будет.
Сбор за неэффективные транзакции взимается, если участник торгов или его клиент совершает большое количество транзакций, но заключает мало сделок. Под транзакцией понимается подача заявки (AddOrder), удаление заявки (DelOrder) или изменение заявки (MoveOrder)
Imersio Arrigo, у меня, как Вы догадываетесь, и терпение есть и набор костылей, и обходные варианты.
Взгляните еще раз: - шаг цены - это не онлайновый параметр, для VTBR он менялся 8 лет назад; - в таблице текущих торгов он виден до сессии; - левой рукой (getSecurityInfo) его выдают в offlne; - правой рукой (getParamEx) его из той же таблицы текущих торгов, где он виден до сессии, его в offline не выдают.
Мне интересно, что все-таки по этому конкретному поводу думает уважаемый Разработчик.
Для проверки одной гипотезы мне и была нужна именно автономная работа индикатора на исторических данных для статистической обработки, без соединения с сервером, но попал в засаду.
В выходной и без интернета можете запустить любой свой скрипт.
Можем, но и он тоже может - не заработать.
Понадобилось мне в индикаторе использовать минимальный шаг цены и точность инструмента (в скриптах я их тоже использую). Как многие здесь делают, использовал для получения шага цены
При этом в Таблице текущих торгов показываются правильные значения. Шаг цены и точность - величины очень стабильные, меняются крайне редко, скрывать их нет необходимости..
Год назад я поднимал вопрос, близкий к данной теме. Получить контроль над количеством свечек без нехороших излишеств. Не всем нужны 65000 свечек, многим и 300 избыточны.
А пока что, чтоб получить даже "старые автоматические" 3000 свечек, приходится удалять руками файлы в archive и перезаказывать данные. Сделайте нормальное управление, без танцев с файлами. Ведь могли же когда-то ограничивать фиксированным начальным размером.
Есть разные варианты нарезки данных на свечки: по времени (штатный в QUIK), по объему, по высоте, ... Многие Вы можете реализовать, если у Вас в руках SetUpdateCallback, даже по времени можно разнообразить, например, через 17.5 секунд. Для меня, например, важнее не завершение свечки, а достижение ценой определенного значения, причем это значение само меняется во времени. Достижение этого значения не связано с Close штатной свечки, да и вообще, Open и Close менее надежны, чем High и Low. Дожидаясь Close, Вы теряете драгоценное время.
Свечки нужны только для компактного хранения истории, хранить тики и пользоваться ими очень неудобно. Гораздо важнее временные задержки и особенности в доставке данных от биржи через брокера и QUIK до Вашего скрипта.
Павел Bosco написал: может надо создать какой-нибудь глобальный именной event в квике и взводить его, когда изменяется свечка только в updateCallBack, а в другом процессе его ловить.
Я так и делаю, только событий у меня много, поэтому
2. При Ваших допущениях. А зачем Вам копировать в Сишный массив? Не возникало мысли работать с данными прямо по месту их нахождения? Есть, правда, некоторые трудности и даже опасности. Как минимум придется разобраться с устройством памяти в LUA, с ее динамикой и инфрастуктурой. Но оно стоит того. На моих таблицах и алгоритмах заработало примерно в 30 раз быстрее. Для меня это было жизненно необходимо. .
Boris Litvinov, возможно, Вы не учитываете некоторые нюансы Таблицы позиций по клиентским счетам (фьючерсы) -- futures_client_holding. Когда в ней возникают строки по инструменту, когда исчезают?
Чтобы строка с нужным фьючерсом появилась в этой таблице (если ее не было), я выдаю вспомогательную заявку по дальней цене (строка появилась) и снимаю заявку. Далее могу работать с этой строкой. Но если я закрываю позицию, то строка держится в таблице не бесконечно, а день-два, как карты лягут.
Андрей Пахомов, Вы же писали индикаторы (с Ваших слов). Они вызываются асинхронно, в рамках основного потока, обычно много-много раз для ликвидных инструментов при изменении текущей свечки, можете оценить - это не сложно, Возможно, Вас устроит частота вызовов и отрисовки линий (или еще чего) по тем данным, что насчитал Ваш LUA-скрипт. Да, будет асинхронность и некоторое отставание от момента выставления признаков и данных в Вашем LUA-скрипте для отрисовки индикатором, но Вы же не HFT решение хотите реализовать.
Ваш LUA-скрипт выполняется в другом потоке, Вам не надо вызывать индикатор (это делает QUIK), но Вам надо из LUA-скрипта передать ему данные. Найдите вариант передачи данных между потоками, который соответствует Вашей квалификации, например, через файлы, через MMF (Memory Mapped File), ... Если обсчет для отрисовки не занимает много времени, то можно вынести его в индикатор, я так делал и много чего рисовал и перерисовывал.
В этом вопросе можно и дальше углубляться.
Imho, требовать и ждать чего-то от разработчиков - потеря времени.
Андрей Пахомов, заготавливайте данные для отрисовки в LUA-скрипте, а рисуйте в индикаторе ТА, который эти данных заметит при очередном вызове. Можно? Да. Плохо? Конечно.
Imersio Arrigo, ... сквозь слезы. Скорее всего, так у них получилось. Если бы это было осознанное действие, то и разбить одну линию индикатора на участки с разной раскраской/видимостью тоже смогли бы (может, уже и сделали, давно не слежу).
По возможности стараюсь уйти от зависимости от многих возможностей QLUA, от особенностей и сроков их реализации. Иногда реализация пожеланий имеет характер какой-то шутки, пару-тройку раз на собственном опыте убеждался.
Отдал дань индикаторам на этапе исследования свойств рынка. Доступ к данным есть (разные варианты), торговые приказы можно отдавать, миллисекундные штампы - есть, ордерлоги для анализа нюансов можно найти, асинхронные выходы - есть, DLL подключается, массивы передаются и обсчитываются, нарезать свечки по вкусу - можно, быстрая связь между потоками - есть, хорошие алгоритмы - есть. Для полного счастья только времени не хватает.
Но есть и опасение, что QUIK могут перегрузить каким-нибудь бантиком, типа историей на 65000 свечек. Появляются тормоза. Хорошо еще, что пока можно обрезать историю до 3000 свечек.
Андрей Пахомов, легко, в программе индикатора. Идея - определим только начало и конец отрезка. Пока еще работает, но разработчики, думаю, искоренят этот эффект.
Settings = { Name = "!!!line", line = { { Name = "line1", Color = RGB(0,128,64), Type = TYPE_LINE, Width =3 } } }
Init = function() return 1 end
function OnCalculate(index) if index == 1917 then return 99 end if index == 2420 then return 121 end return nil end
Anastasia Gordienko, речь идет о том, что результаты послеторгового аукциона то попадают в Close последней свечки дня, то не попадают, в зависимости от того, как лягут карты (фильтр и таймфрейм). Это доставляет естественные неудобства и даже может создать проблемы. И не все могут приспособиться к такой реализации фильтра.
Индикатор "сломается", как только попадет на свечку с нулевой высотой (H(i) равно L(i)). Будете делить на 0. Изредка такие свечки бывают. Добавьте проверку на этот случай. Оставьте на диаграмме несколько заведомо "хороших" свечек и Вы увидите Вашу гистограмму.
Когда-то меня интересовал вопрос - какого размера таблицы я смогу создать в скрипте робота.
QUIK - 32-разрядное приложению (не уверен, может уже сделали 64?). Есть ограничение на размер памяти, доступной приложению. Обычно это 2GB, но через некоторые манипуляции можно добраться до 3GB и даже до 4GB, зависит от версии Windows. У меня - Windows XP, особо упорствовать в ее ломке не стал, но к границе в 2GB подобрался близко. Контролировал по Диспетчеру задач (info.exe, виртуальная память).
Есть особенности LUA в распределении памяти под таблицы. Изначально выделяется какой-то минимум. Как только выходим за этот предел, выделяется память в 2 раза большего размера, старые данные копируются в новую память, старая память уходит в мусор. Превысили новый предел - процедура повторяется, опять удвоение, опять мусор.
Может наступить момент, когда свободного непрерывного участка памяти двойного размера может не оказаться. Получим not enough memory. В лучших попытках я получал возможность разместить таблицы суммарно за сотню миллионов элементов, выбрав почти все 2GB доступной виртуальной памяти. Меня этот результат устроил.
Теперь - почему "в лучших попытках". Я запускал скрипт сразу после загрузки QUIK, еще было несколько графиков и с десяток индикаторов.
Скрипт сначала распределял большие таблицы, типа на 64 миллиона элементов (на попытке добавить еще элемент - not enough memory), все элементы в цикле заполнял каким-то одним значением. То есть, нарастить таблицу до 128 миллионов элементов я не мог, но мог создать еще одну размера в 64 миллиона. Потом создавал таблицы по 32 миллиона элементов, потом по 16 и т. д., пока не нарывался на нехватку памяти, отступал назад и переходил на половинный размер.
Процесс распределения памяти при загрузке QUIK оказался недетерминированным, новые ли свечки или что другое влияло - мне было несущественно. Налицо было явление фрагментации памяти, я мог распределить очень много мелких таблиц, но для крупной могло не найтись непрерывного участка нужного размера.
Отсюда и естественный рецепт - разбить гигантскую таблицу на более мелкие.
Штатная уборка мусора почему-то дремала, использовал collectgarbage явным образом.
P.S. Пишу по памяти в походных условиях, основную идею передал, числа могут отличаться.
Время изменения стакана получаемого через OnQuotes, OnQuotes - есть ли возможность параллельно с чтением стакана, получить точное время торгового сервера, когда он возник/изменился
Борис Гудылин написал: Очень многие заявки (90%) отменяются и переустанавливаются заново.
... Как это можно объяснить теоретически? (код не прошу, это конечно деньги и он секретный в коммерческом плане) Но должна ведь быть какая то теория для возможности построения таких роботов? Теория вероятности, которая построена 50 на 50, тут видимо не работает?
Цитата
и переустанавливаются заново
и кем переустанавливаются? Роботами пользователей? (Если транзакция не прошла, и в колбеке пришло соответствующее сообщение по транзакции)
Андрей, теория вероятностей это вовсе не 50 на 50, а рынок вовсе не случайное блуждание.
Есть в теорвере старая задачка на случайное блуждание - про пьяницу, который выходит из кабака и на каждом перекрестке поворачивает случайным образом (0.25-0.25-0.25-0.25) в одну из четырех сторон (планировка - как на листке в клеточку, скорость - постоянна). На какое расстояние в среднем удалится пьяница от кабака за время T? Ответ - расстояние растет по корню квадратному из Т.
А теперь к рынку. Как меняется средняя высота свечек в зависимости от таймфрейма? Первая ловушка - она меняется по тому же закону. Как бы, начинается новая свечка и растет она в течение времени ТФ. Можете проверить по индикатору ATR. Правда скорость (волатильность) непостоянна, но в первом приближении этим результатом можно пользоваться. Из него, кстати, следует и относительная "гладкость" движения цены на больших ТФ. Кто-то называет это "шумом".
Практическое соображение - на каком ТФ надо работать, если торговая система работает в плюс, масштабируется по ТФ и можно отвлечься от ограничений физиологии трейдера, ликвидности, комиссий, ...? Ответ - чем меньше ТФ, тем лучше.
Сравним часовики и минутки. Свечек на минутках - в 60 раз больше, сделок можно сделать в 60 раз больше (масштабируемость), но высота свечек (наш потенциал прибыли) примерно в 8 раз меньше (корень квадратный из 60). Соответственно - прибыль в 8 раз больше (работы, повторюсь, в 60 раз больше). Начиная с какого-то ТФ вниз роботы начинают иметь бесспорное преимущество.
Ловушка 3. ЦПТ (центральная предельная теорема). Если замешать много-много случайных величин с разными характеристиками распределений, то получим нормальное распределение.
Очень велик соблазн воспользоваться близостью рынка к случайному блужданию и отработанным аппаратом математической статистики. Для кого-то гипотеза эффективного рынка (EMH) уже умерла, кто-то про нее еще не знает, но псевдонобелей она наплодить успела.
Но есть и альтернатива - строить исследование устройства рынка на отличиях от случайного блуждания, развивать гипотезу фрактального рынка (FMH). Но путь это вовсе не прост, для энтузиастов.
На многие Ваши вопросы есть ответы, есть чисто аналитические, еще есть опыт, есть результаты изучения и измерений. Ордерлоги биржи еще можно найти и посмотреть, много интересного можно найти в измерении полноты и временных характеристик получения данных для разных таблиц.
А частные вопросы - заявки снимаются трейдером (руками или роботом) сообразно постоянно меняющейся ситуации и переустанавливаются точно так же.
Время изменения стакана получаемого через OnQuotes, OnQuotes - есть ли возможность параллельно с чтением стакана, получить точное время торгового сервера, когда он возник/изменился
Вполне возможно, что Вам не хватит возможностей скрипта main и придется задействовать callback'и.
Термин "поток" я использую для обозначения архитектурной единицы ОС Windows, которая претендует на время процессора и другие ресурсы и может выполняться параллельно с аналогичными единицами. При определенных условиях они могут "подраться" за некоторые Ваши таблицы, которые Вы захотите ввести и обрабатывать (модифицировать) сразу в двух потоках. Для предотвращения таких коллизий (организация последовательного доступа) и были введены функции sinsert и sremove (там еще несколько подобных по назначению есть, посмотрите). Не повезло QUIKу, многие термины перегружены разными смысловыми нагрузками, а некоторые объекты обзываются по-разному, это мешает.
В Вашем примере вы неявно находитесь в рамках потока main скрипта и имеете непосредственный доступ к данным источника, без задействования функций обратного вызова (те, что выполняются в основном ;) потоке).
Зачем роботу графики - я не понимаю, Вы же сами все расчеты должны делать и чувствовать, где находятся Ваши кривые на текущий момент (втемную). Для визуализации или отладки можно использовать штатные графики QUIK и штатные МАшки, если Ваши с ними совпадают по алгоритмам. Если не совпадают - напишите для них свои индикаторы, это просто, и поместите их на нужные графики.
Для отслеживания и визуализации состояния робота постройте таблицу и отображайте ее средствами QUIK.
С трудом представляю, как без знания решений проблем работы с разделяемыми ресурсами в мультизадачных средах (не суть важно, задачи, процессы, потоки, ...) в условиях асинхронного поступления данных и событий через интернет, когда нормой считается потеря, дублирование, искажение и опережение ранних данных более поздними, когда разработчики пропускают на пользователя часть своих проблем, когда документация оставляет желать лучшего - как в этих условиях новичку быстро и корректно написать робота. У меня нет претензий к разработчикам, "не стреляйте в пианиста, он играет как умеет". Пока еще можно адаптироваться.
Для начала Вам, как программисту, лучше было бы разобраться хотя бы по минимуму с архитектурой QUIK, после этого с архитектурой Вашего робота, обращая внимание на потоки, в которых будут выполняться его функции. Какой-то минимум есть в документации (файл "Использование Lua в Рабочем месте QUIK.pdf").
Вы можете попробовать не использовать асинхронные выходы (callback), которые выполняются в специально выделенном так называемом "основном" потоке QUIK, ограничившись только потоками main (тут определенно есть злой умысел, main - можно перевести тоже как "основной"). Будет Ваш робот периодически просыпаться, пробегать по таблицам QUIK и Вашим собственным и принимать какие-то решения.
Захотите большей эффективности и сложности, задействуйте функции обратного вызова (callback'и). Одно дело, если в OnStop Вы просто взведете признак, который при очередном просыпании заметит Ваш поток main. Если в callback'е Вы получите более емкие данные (пока поток main спит по sleep() их может накопиться много) и захотите их накопить и передать роботу в поток main, то посмотрите потокобезопасные функции sinsert и sremove. Разработчики иногда реагируют на замечания и закрывают очередную дыру в межпоточном взаимодействии, но они все равно остаются и лучше изначально строить робота так, чтобы он не бросал монетку - повезет - не повезет.
Определитесь с вариантом доступа к источнику данных, в частности, будете ли Вы работать только по закрытии текущей свечи или Вам важна ее динамика. Много вариантов есть: можно "монтекарлить" по срезам таблицы текущих торгов (OnParam - last) с риском пропустить экстремум, можно привязаться к графику по идентификатору, можно пропускать через себя все сделки (OnAllTrade), про варианты с CreateDataSource Вы уже знаете. У них у всех есть свои достоинства и недостатки, иногда даже опасности, свои временные характеристики.
Потом стоило бы смотреть на прикладную сторону - на торговые операции, получился бы движок робота. И только потом на его основе реализовывать собственно Ваши стратегии.
На многие вопросы Вам придется отвечать самому, пишите и выполняйте Ваши программы, не бойтесь использовать отладочные выдачи по message или в файл, скорость отладки в LUA очень велика. Если Вы исследователь, то пробьетесь.
Существенная разница при использовании CreateDataSource в том, что в первом случае все свечи от первой до текущей и изменения к текущей вбрасываются в указанную Вами в SetUpdateCallback программу принудительно и настолько быстро, насколько это может QUIK. Эта программа выполняется в основном потоке QUIK, там, где QUIK последовательно вызывает все функции обратных вызовов (OnCalculate - это индикаторы, OnStop, OnParam, OnTrade, OnOrder, ... много их). Преимущество - скорость и возможность предварительной фильтрации и обработки получаемых данных, неудобство - необходима аккуратная передача данных в скрипт(ы) Вашего робота (ов) (main), которые выполняются в отдельных потоках, независимо и параллельно с основным потоком и друг с другом, насколько это возможно. Номер свечи подается на входе, сначала все свечи истории, начиная с первой, а затем текущая и ее изменения.
Во втором случае Вы более сосредоточены в скрипте робота, у Вас не будет принудительного вброса свечек, но Вам придется самому периодически обращаться к свечкам, ориентируясь на текущий Size и другие поля таблицы полученного источника.
В обоих случаях к данным уже имеющихся свечек (O,H,L,C,V,T, Size) полученного по CreateDataSource источника можно обращаться по номеру (индексу) свечи от 1 до текущего Size.
Если новичок - советую написать простенький индикатор, вставить в него выдачу (message()) номера получаемой свечи и ее параметров. Прочувствуете суть обратного вызова для SetUpdateCallback.
А нюансов будет много. И альтернатив может быть несколько. Например, кто-то обращается к данным свечей через идентификатор графика, без CreateDataSource.
Когда-то я вносил предложение: значение ограничения количества свечей по умолчанию (3000) вывести как параметр в настройках QUIK. Далеко не всем нужны даже 3000 свечей, не говоря уже о 65000. Лично меня устроили бы и 300 свечей. Экономия памяти, трафика и времени процессора - очевидны, а для меня просто необходимы. Работаю исключительно на малых ТФ, свечи копятся быстро, с какого-то момента QUIK начинает деградировать. Временно вынужден периодически делать обрезку через перезаказ данных.
Это предложение даже приняли к реализации, наряду с несколькими другими моими предложениями. Есть предположение, что его даже реализовали. В "Редактирование настроек графика" появился параметр "Диапазон" данных - "последние xxxxx интервалов". Он относится к графику, а не к источнику данных. На графике я стал видеть заданное количество свечей, но начальный размер источника при этом, естественно, не поменялся. А на график из скрипта я вообще не смотрю. Я недоумеваю - неужели я не был понят правильно? Извините, если это не реализация моего предложения и до него еще не дошла очередь, просто хотел определенности.
На всякий случай еще раз вношу свое предложение. Значение ограничения начального количества свечей для источника данных (по умолчанию 3000) вывести как параметр в настройках QUIK.
Для определения в обычном скрипте функции обратного вызова (callback) для обработки события - изменения свечи в источнике данных, который запросили по CreateDataSource. Ее аналогом в скрипте индикатора является функция OnCalculate.
Suntor написал: Цитата Борис Гудылин написал: Публично обсуждать ключевые моменты своей (и не только своей) защиты - просто невероятный абсурд! Обсуждаем технические моменты, методы, инструменты... никто не просит вываливать свой код в готовом виде. Всё же разные вещи.
Обеспечение защиты и ее преодоление, оценка стойкости и трудоемкости - две стороны одного процесса. Хотите научить всех преодолевать защиту? Асимметричность, "ломать - не строить". Здесь не то, что код в готовом виде, но даже намек или просто привлечение внимания может иметь фатальные последствия для защиты. Лучше перестраховаться и закруглить дискуссию.
Всё. "Бабушка приехала". Согласен - "Детский сад какой-то". Публично обсуждать ключевые моменты своей (и не только своей) защиты - просто невероятный абсурд! Михаилы согласованно поработали в паре. Нарочно не придумаешь.
P.S. Как только софт попадает в чужие руки - он обречен. От специалиста нет защиты. Недавно заметил (кажется, у команды Герчика) одно старое решение. Индикатор разбивается на две части, клиентская отдается пользователю, секретная (собственно алгоритм) остается и работает у автора на его сервере.
P.P.S. Есть несправедливая несимметричность - красивая изощренная защита, на которую потратили много времени и сил, часто преодолевается быстро и совершенно смешными приемами.
Можно увидеть живьем Ваш DataSource. Добавьте к Вашему графику в отдельном окне график истории значений параметра по такой последовательности:
Добавить график - Новый - Изменить - История значений параметра - Количество сделок за сегодня.
Если есть возможность, то на меньших ТФ. См. прилагаемые картинки. Фрагменты для ТФ M1 и M3 (реал) и М1 (демо).
Для части параметров история ведется только за текущий день. Для дневок будет 1 (одна) свечка. Разработчики обоснуют - почему. Для фьючерсов есть еще нюанс - жизнь начинается с вечерки.
Чисто формально. Если приведенный код имеет какое-то отношение к теме "Учебный бот на спредах для quik" (https://github.com/AndSemenoff/spread_bot_quik), то там есть опечатки в function OnTransReply(repl).
В подаваемой на вход таблице repl нет поля R,выдается диагностика TrRepl NO LAST TRAN, которую можно вольно интерпретировать как "OnTransreply получил реакцию не на последнюю транзакцию".
Фрагмент из учебного бота. if (uniq_trans_id ~= repl.R) then l_file:write(os.date().." TrRepl NO LAST TRAN\n") return end
О нюансах. У меня старенький ПК, 2 ядра, Windows XP. Запускаю 3 скрипта-близнеца, имена только разные. Подобрал параметры цикла, чтоб каждый в одиночку на не очень нагруженном ПК исполнялся около 1 минуты.
function main() message("00c-start",2) s=0 for i=0, 580000000 do s = s+1 end message("00c-finish",2) return end
Я запускаю их поочередно, жду завершения, а затем запускаю все три одномоментно. При последовательном запуске каждый выполняется около минуты. Вполне ожидаемо.
При параллельном выполнении какому-то ядру достался один скрипт, какому-то - два. Наблюдаю загрузку процессора в Диспетчере задач Windows - оба ядра по 100%. Через минуту завершается один скрипт - тоже ожидаемо. Была одна из вспомогательных гипотез, что те скрипты, что попали в одну воронку, завершатся еще через минуту. По факту они завершились через полминуты. Эти полминуты оба ядра были загружены полностью. При полной загрузке ядер вся работа трех скриптов была выполнена за полторы минуты.
Приятный нюанс - произошло перераспределение нагрузки, освободившееся ядро стало выполнять один из двух отставших скриптов. Два ядра, у каждого свой скрипт, осталось выполнить половину работы каждого, по полминуты. Итого: 3 минуты/2(ядра) = 1.5 минуты. Прямо задачка про трубы.
Неприятный нюанс. Все знают что основной поток QUIK, в котором последовательно обрабатываются асинхронные выходы, в частности - индикаторы, нельзя грузить долгой работой, можно многое притормозить и даже заблокировать. Три (даже два) "тяжелых" скрипта в соседних потоках при двух ядрах тоже справляются с такой задачей - на полторы минуты практически блокируют работу QUIK. Вероятная причина - приоритеты всех потоков одинаковы.
Разработчикам - оцените, пожалуйста, целесообразность и возможность повышения приоритета основного потока QUIK. Не думаю, что только у меня ресурсоемкие алгоритмы. Оптимизировал алгоритмы, "тяжесть" унес в DLL(C++), использовал особенности внутреннего устройства LUA, межпоточную сихронизацию, уйду (ушел) из индикаторов, перейду на многоядерный ПК, но мину за спиной оставлять не хочется, как не хочется и жить на костылях.
На днях была похожая ситуация, тоже с демо-биржей и с той же диагностикой. Перестали приниматься лимитки, ни купить, ни продать. Поддержка брокера объяснила, что были проблемы на демо-бирже. Через некоторое время лимиты восстановили. Попробуйте пообщаться с брокером.
Кстати, демо-биржа конкурса InvestTrial оказалась удобна для тестирования роботов - участники близки по финансовым возможностям, безумных действий совершить особо не могут, трафик удерживается близко к реальному, но из-за особенностей его реализации результаты получаются завышенные.
Проверьте, не пытаетесь ли Вы с помощью li+ 1 заглянуть в будущее. Простейший прием - вставить временную отладочную выдачу li+ 1 и H(li+ 1) с помощью Message перед ее использованием. Сравните с фактическими границами доступных индексов..
Для одного инструмента (типа VTBR, где цена болтается близ 0.05) 100 может оказаться невозможно большим, для другого - слишком мало. Вместо H(Out1)+100 и L(Out2)-100 лучше использовать H(Out1)*1.0007 и L(Out2)*0.9993 (процентный перелет-недолет, подберете по вкусу), автоматом сработает на любой размер цены.
Подсказка разработчикам - можно сначала попробовать ответить на вопрос "Почему CreateDataSource не выдает ошибки при заведомо ошибочном sec_code – код бумаги?". Или ситуация не воспроизводится?