Космонавт написал: Ведь при каждом новом таймф-фрейме таблицу придётся таки обновлять и запихивать в её поля новый набор свечек. То есть раз в таймфрейм полный пересчёт делать всё же придётся.
А кто мешает сохранять свечи и индикатор в таблицу в зависимости от таймфрейма? Как-то так:
Код
ds[SecCode][Interval] = CreateDataSource(ClassCode, SecCode, Interval)
local function GetPrice(index)
Candles[SecCode][Interval] = ds[SecCode][Interval]
Indicator[SecCode][Interval][index] = func( ... )
end
for i = 1, ds:Size() do GetPrice(i) end
ds:SetUpdateCallback(GetPrice)
Надо делать так, как надо. А как не надо - делать не надо.
Космонавт написал: 3. Рационально ли составлен код?
Нет. Пересчитывать значение индикатора имеет смысл только при обновлении последней свечи. А вы пытаетесь его пересчитывать каждую мс. Какой в этом смысл, если цена не изменилась? Расчёт индикатора лучше вставить в SetUpdateCallback() и сохранять значения в глобальной таблице.
Надо делать так, как надо. А как не надо - делать не надо.
Egor Zaytsev написал: 2. Здесь больше подойдет функция CreateDataSource
CreateDataSource не доступна в индикаторах. Поэтому работать с другим таймфреймом можно только через getCandlesByIndex
Цитата
Виктор Столетов написал: 3. Как отслеживать появление нового бара?
При появлении нового бара в OnCalculate(index) будет увеличиваться индекс свечи
Цитата
Виктор Столетов написал: А что если в какой-то момент самые старые бары будут обрезаны и Size() уменьшится?
Тогда OnCalculate начнётся с первого индекса.
Цитата
Виктор Столетов написал: Вы говорите, что индекс свечи начинается c 0 и в руководстве написано то же самое. Но если в OnCalculate(index) написать PrintDbgStr("index=" .. index), то в окне Debugview выведет index от 1 до Size(). Вроде получается, что самая старая свеча имеет индекс 1.
Да, там у них путаница (видимо разные люди писали куски кода): в OnCalculate в индикаторах индекс начинается с единицы, а в getCandlesByIndex - с нуля.
Надо делать так, как надо. А как не надо - делать не надо.
Вопрос разработчикам: верно ли, что в QUIK, как таковой, многопоточности нет? Да, есть два потока: основной и main. Но в каждый момент времени работают команды только из одного потока. Просто происходит переключение между потоками на уровне ОС. Так?
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov написал: Да, но к сожалению это пожелание было отклонено.
Вобще-то я предложил другое: дать доступ к уже реализованной настройке с клиентского места. Т.е., это другое предложение. Мне оно, как бы, не надо. Дарю идею sav 312, если пропихнёте.
Надо делать так, как надо. А как не надо - делать не надо.
sav 312 написал: Сегодня разговаривал с Брокером (Сбербанк), так вот все, что Вы написали, настроить у него нельзя, полагаю, что чисто технически это сделать реально, но делать они этого не будут.
Возможно, чтобы использовать этот функционал, нужно вносить какие-нибудь правки в регламент. А возиться ради одного клиента они не хотят. Вот если бы на эту услугу был бы спрос...
Цитата
sav 312 написал: Предлагаю вернуться к паролю на скрипты
Ну не будет у вас это работать локально, поймите. То, что вы просите - бессмысленно. Если вы сейчас не можете удержаться, чтобы не остановить скрипт. То завтра вы точно так же запустите QUIK без скриптов, и никакой пароль не поможет.
Цитата
sav 312 написал: или встроенному риск-менеджеру (из 2 пунктов).
А вот это уже разумно. Я вижу это так: изменение настроек риск-менеджера производится локально с рабочего места QUIK самим пользователем (для этого ему надо дать права на эту операцию) и активирует уже давно реализованный на сервере функционал. Но не реалтайм, а после перезагрузки дилерской библиотеки, т.е. на следующий день. sav 312, Sergey Gorokhov, попробуйте договориться
Надо делать так, как надо. А как не надо - делать не надо.
Это не надёжный способ сравнения чисел, т.к. при математических операциях над числами с плавающей точкой появляются разряды, которые tostring не опускает.
В примере стоит изменить шаг и сравнение с tostring перестаёт работать:
Код
function ff1(dp)
for i = -8.8, -0.8, 0.1 do
if tostring(dp) == tostring(i) then print(dp) end
end
end
ff1(-0.8)
Надо делать так, как надо. А как не надо - делать не надо.
function ff1(dp)
for i = -8.8, -0.8 do
if dp == i then print(dp) end
end
end
for param, value in pairs({-8.8, -7.8, -6.8, -5.8, -4.8, -3.8, -2.8, -1.8, -0.8}) do
ff1(value)
end
Надо делать так, как надо. А как не надо - делать не надо.
На ваше усмотрение. Это касается всех функций: когда в функцию передаются параметры, хочется знать их смысл (ну, так, чтобы программирование было более осмысленным). А попробуйте в руководстве найти описание параметров form_id, acc_id, pos_type
Старатель написал: Т.е., на стороне брокера есть настройка, автоматически блокирующая возможность торговли при достижении заданного лимита потерь?
Автоматом блокирует.
Значит такая настройка уже есть. Это настройка самого сервера или нужен дополнительный модуль? Где можно ознакомиться с данной возможностью подробнее? Как она работает?
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov написал: У брокера есть возможность заблокировать торговлю пользователю. Не через CoLibri. Но с помощью нее он может понять что нужно заблокировать. Таким образом она полностью отвечает Вашему запросу.
Как он там может понять, остаётся за скобками...
Цитата
Sergey Gorokhov написал: Нигде не говорилось что Colibri решает задачу контроля дневного лимита потерь (о чем говорит sav 312,)
Тогда не понятно, какую из запрашиваемых задач решает CoLibri, если она и не контролирует и не блокирует?
Цитата
Sergey Gorokhov написал: Задача решается настройками на стороне брокера.
Т.е., на стороне брокера есть настройка, автоматически блокирующая возможность торговли при достижении заданного лимита потерь? Или хотя бы сигнализирующая об этом? А брокер пусть бежит и вручную блокирует клиента. А на завтра надо бы ещё не забыть разблокировать... Тогда эта услуга должна быть очень востребованной, чтобы брокер так напрягался
В любом случае, как само предложение автора топика, так и отмазы тех.поддержки порадовали
Надо делать так, как надо. А как не надо - делать не надо.
sav 312 написал: Дневной лимит потерь (запрет торговли после превышения ранее заданной просадки по счету).
Цитата
Sergey Gorokhov написал: У брокера есть возможность заблокировать торговлю пользователю. Не через CoLibri. Но с помощью нее он может понять что нужно заблокировать.
Мне, конечно, не нужна такая настройка. Но, справедливости ради, хочу уточнить, Colibri разве позволяет отслеживать дневной лимит потерь?
Надо делать так, как надо. А как не надо - делать не надо.
Если рассчитывать среднюю стоимость позиции по прошедшим сделкам, возникает вопрос: Может ли колбэк по сделке прийти позже колбэка OnDepoLimit или OnFuturesClientHolding?
Надо делать так, как надо. А как не надо - делать не надо.
Stanislav Tvorogov, ничего никуда отправлять не нужно. Эффект вполне воспроизводится на любом рабочем месте при подключении как к боевому, так и демо серверу с дефолтными настройками (удалены все dat, log, ini файлы). А проблема заключается в том, что активация кнопок завязана на обновление таблицы котировок после того как отобразится своя заявка в стакане. На следующее обновление таблицы, карл. Поэкспериментируйте на неликвидной бумаге, и вы увидите, что кнопки "Снять выделенную заявку" и "Заменить выделенную заявку" никогда не активируются в стакане. Только если второй раз кликнуть по своей заявке. Более того, после снятия заявки той же кнопкой "Снять выделенную заявку" кнопки не перестают быть активными. Специально для вас: поиграйте с "Химпром ап" на демке. Если же вы будете настаивать, что у вас де не воспроизводится, выложите сюда видео, как вы воспроизводили. Я не верю, что вы что-то делали вообще.
Stanislav Tvorogov, я сделал за вас всю работу! Вам осталось только отправить моё сообщение программистам, чтобы они поправили в коде: сделали активацию/деактивацию кнопок одновременно с отображением/снятием своей заявки в стакане.
Надо делать так, как надо. А как не надо - делать не надо.
В v.7.5 при выставлении заявки из стакана кнопки "Снять выделенную заявку" и "Заменить выделенную заявку" на панели активируются с большим временным лагом.
Надо делать так, как надо. А как не надо - делать не надо.
sav 312 написал: В моем случае, пароль от скрипта после всех настроек, будет находиться не у меня. Тоже самое будет сделано и с учетной записью на винде (квик снести не смогу).
Вам рассказать как запустить QUIK без скриптов и без переустановки квика? Тут правильно написали: в вашем случае поможет только риск-менеджер на сервере. А все эти локальные защиты/блокировки при желании обходятся/отключаются.
Надо делать так, как надо. А как не надо - делать не надо.
тот самый написал: Со своей же стороны - приму к сведению проверять абсолютно ВСЕ данные приходящие с биржи на валидность (к слову..и до этого проверял)
"Абсолютно ВСЕ" данные проверить в QUIK невозможно. Так, в нельзя проверить на наличие пропусков в ТВС или на графиках. Если только сверять с ещё одним источником данных.
Надо делать так, как надо. А как не надо - делать не надо.
swerg написал: Двухпоточность рабатает отлично. Поток main() не мешает основному потоку А время - понятные накладные расходы.
Разве что не мешает... Пока не задействуешь потокобезопасные функции QLua. Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно. А по факту в QUIK накладные расходы слишком высоки.
Надо делать так, как надо. А как не надо - делать не надо.
Мда... Двухпоточность в QLua работает действительно неэффективно: Вот сейчас запустил одновременно три скрипта в QUIK. Общее время работы составило 12.9 сек, что больше, чем при последовательном их запуске через консоль (3.5+3.5+3.6=10.6 сек). Таким образом, выигрыша в производительности от многопоточной схемы работы в QUIK, действительно, не наблюдается. Единственный плюс - то, что интерфейс не зависает при работе длительных циклов в main.
Надо делать так, как надо. А как не надо - делать не надо.
В среде QUIK скрипты выполняются в несколько раз дольше, чем в командной строке. Вот такой скрипт
Код
function main()
print = message or print
local abs = math.abs
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
t = os.clock() - t
print(string.format('%0.1f', t))
end
if not message then main() end
в командной строке выполняется 3.5 сек, в QUIK - 8.8 сек. В 2.5 раза дольше! Почему так?
PS: ЦП: 2 ядра, 4 логических процессора.
Надо делать так, как надо. А как не надо - делать не надо.
Zoya Skvorcova написал: Не было встречного предложения-заявка отверглась. Такая ситуация могла произойти не только, при выставлнии рыночной по исполнению стопа, но и просто с обычной заявкой с признаком рыночная на Срочном рынке.
Zoya Skvorcova, вы не правы. При отсутствии встречного предложения/спроса заявка просто снимается, а не отклоняется ТС.
Надо делать так, как надо. А как не надо - делать не надо.
Есть бумага. Она не принадлежит к конкретному классу TQBR или SMAL: это одна и та же бумага. Поэтому получать количество в depo_limits нужно в штуках. А при необходимости пересчитывать в лоты в зависимости от лотности нужного вам класса.
Надо делать так, как надо. А как не надо - делать не надо.
Не пойму о какой копии идёт речь? У вас в скрипте создаётся только одна таблица. Если вы имели ввиду, что копия создаётся после повторного запуска скрипта, то это буде таблица уже с новым идентификатором. Всё же хотелось бы узнать, в каких случаях таблица может быть не создана, кроме обозначенных мной?
Что касается документации, то неплохо добавить в неё следующую информацию: #1, #2
Надо делать так, как надо. А как не надо - делать не надо.
Stanislav Tvorogov написал: Функция возвращает 0 во всех остальных случаях, в которых таблица не была создана, за исключением указания значений, отличных от NUMBER.
Я как раз хотел от вас услышать, в каких случаях таблица может быть не создана.
Индикаторы все равно рассчитываются так или иначе: в роботе или самим квиком. Но в случае getCandlesByIndex ресурсы тратятся ещё и на отображение графика и индикатора, что более ресурсоёмко, чем просто вычисление.
Надо делать так, как надо. А как не надо - делать не надо.
Теоретическая разница получения данных CreateDataSource+SetUpdateCallback или getNumCandles()+getCandlesByIndex(), В чем разница получения данных 1 способом и 2 способом
Николай Камынин написал: CreateDataSource+SetUpdateCallback - получаем данный в момент прихода их с сервера, т е до помещения в хранилище в терминале.
в этом я сильно сомневаюсь. Всё, что сыпется с сервера - сериализуется на жёстком диске.
Практически было установлено, что сначала вызывается колбэк в момент получения данных, и лишь затем эти данные сбрасываются в хранилище на диске.
Цитата
Владимир Б****ов написал: Т.е если таймфрейм установлен в 3 минуты - то получение данных ~ 1 раз в 3 минуты
Нет, в течение 3-х минут свеча может обновиться несколько раз. В этом вы можете убедиться просто понаблюдав за последней свечой на 3-минутном графике. И на каждое изменение вы будете получать колбэк.
Надо делать так, как надо. А как не надо - делать не надо.