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

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

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 След.
Последняя доступная версия QUIK
 
Терминал 8.0.3:ftp://ftp.quik.ru/public/updates/8.0/quik_8.0.3_upd.zip
64-битная версия QUIK
 
Проверил, что будет после обновления до версии 8.0.2.3. Визуально ничего не изменилось, lua-скрипты работают (за исключением тех, что были скомпилированы lua -> luac через Lua For Windows x86; внешние библиотеки я не использую). Заметных ускорений/замедлений или повышенных требований к памяти не вижу. Через некоторое время обновлю боевой торговый компьютер, если на тестовом будет "нормальный полёт" в течение нескольких дней.
Ужасно тормозит КВИК, при вводе заявок отклик достигает пару минут (CQ02392709) (CQ02396085) (CQ02447240)
 
Если перезагрузить компьютер и не запускать никаких программ, какая будет загрузка процессора?

У меня был случай, когда из-за какого-то обновления драйвера видеокарты процессор стал грузиться примерно на 20%. При этом было несколько процессов, которые отжирали по 3%-5% CPU и делали какие-то RPC-вызовы. После замены драйвера на старый это ушло, даже после обновления драйвера в Windows Update проблема больше не появлялась. Не исключаю, что возможна аналогичная ситуация, в которой обращение к видеокарте в Windows идёт совсем неоптимально и торговый терминал тормозит. Косвенно об этом может свидетельствовать загрузка GPU в диспетчере задач на Вашем скриншоте.

Возможно, я не прав, но проверить стоит.
Последняя доступная версия QUIK
 
Терминал 8.0.2: ftp://ftp.quik.ru/public/updates/8.0/quik_8.0.2_upd.zip
64-битная версия QUIK
 
Вышла 64-битная версия. Кто сможет протестировать у своего брокера -- напишите, как оно.
Последняя доступная версия QUIK
 
Терминал 8.0.1: ftp://ftp.quik.ru/public/updates/8.0/quik_8.0.1_upd.zip
Формат чисел для стоп-заявок
 
Код
local function priceString(price, step, scale)
    price = math.floor(0.5 + price / step) * step
    return string.format("%." .. scale .. "f", price)
end

local scale = getSecurityInfo(classCode, secCode).scale
local step = getPar("SEC_PRICE_STEP", classCode, secCode)
Исторические данные торгов spbexchange - какого брокера выбрать, Можно ли получить исторические данные торгов Санкт-Петербургской биржи через CreateDataSource
 
Я через Best Efforts Bank из терминала QUIK получал рыночные данные с Санкт-Петербургской биржи по американским акциям. Время у свечек московское, приходилось к американскому времени специально приводить с учётом переходов на летнее и зимнее время. Не знаю как там сейчас, но раньше не всё гладко было с ценами. Во время американской сессии котировки были адекватные, в остальное время могли быть странные цены.
64-битная версия QUIK
 
Цитата
Imersio Arrigo написал:
Цитата
_sk_ написал:
Ходят слухи, что в середине лета появится 64-битная версия терминала QUIK.
Откуда дровишки?
Вот отсюда:
Цитата
Уважаемые коллеги!

В начале июля 2019 года компания ARQA Technologies планирует выпустить Рабочее место QUIK версии 8.0, поддерживающее только 64-разрядные ОС Windows. Уведомляем Вас, в связи с этим, о следующем:

Версии РМ QUIK для 32-разрядных ОС Windows выпускаться более не будут. Текущие версии (x32 6.x, 7.x) будут продолжать работать и смогут подключаться к новым версиям сервера QUIK, но обновлений для этих версий не будет.
Прекращается поддержка операционной системы Window XP.
Если Ваши сотрудники и/или клиенты используют Window XP или x32-релизы других ОС Windows -
рекомендуем донести до них информацию о необходимости обновления в случае, если они
заинтересованы получать обновления РМ QUIK.

Актуальные требования к системному ПО для Рабочего места QUIK доступны по ссылке -
https://arqatech.com/ru/products/quik/terminals/user-applications/quik-workstation/


Best regards,
QUIK clients support
ARQA Technologies
quiksupport@arqatech.com
+7 383 219 16 06 (RU)
www.arqatech.com
64-битная версия QUIK
 
Ходят слухи, что в середине лета появится 64-битная версия терминала QUIK. Возможно, не сразу всё заработает, как надо, но это, скорее, хорошие слухи.
доступ к большим таблицам
 
Имеет смысл завести по одной таблице, индексируемой с 1, для каждого из параметров свечи:
open, high, low, close, stdev.
Все эти таблицы должны иметь одинаковую длину; забота об этом лежит на программисте. Такой подход приведёт к лучшему использованию памяти по сравнению с одной таблицей candles, в каждой ячейке которой записана таблица с описанием свечи:
candles[i] = { open = ..., high = ..., low = ..., close = ..., stdev = ...}
В первом случае lua обходится массивами примитивов, а во втором случае в каждой ячейке таблицы candles записывается некий объект, что для большого количества индексов приводит к большим расходам памяти и медленной скорости работы.

Как всегда в программировании: наблюдаем trade-off между удобством и производительностью.
Последняя доступная версия QUIK
 
Терминал 7.27.1: ftp://ftp.quik.ru/public/updates/7.27/quik_7.27.1_upd.zip
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
1. "Желаемые позиции" - это чисто алгоритмическая вещь ТС? Например, как  вторую ногу поставить при парном трейдинге или арбитраже.
2. Это  проверка текущей расчетной позиции в роботе с реальной позицией?  Например, в лишний раз куда-то в табличку терминала заглянуть и  проверить, правильно ли робот держит позу или он пропустил какие-то  сделки, в результате чего его расчетная позиция не совпадает с  фактической. Почему тогда много строк кода?

Например, сейчас у робота куплено 200 контрактов (текущая позиция). Закончилась очередная 15-минутная свеча и логика торговой системы говорит, что теперь хочется иметь 300 контрактов (желаемая позиция). В работу вступает модуль исполнения, который, скажем, раз в 5 секунд:
- выставляет по цене бид 10 контрактов,
- ждёт сделок, если они будут;
- снимает заявку, если там что-то осталось;
- снова выставляет в бид 10 контрактов (или сколько там осталось, чтобы получилась желаемая позиция).
Таким образом, сведение позиций занимает довольно много времени, зато меньше проскальзывание и влияние на рынок. Кроме того, логика расчёта желаемых позиций отделена от логики их достижения.
Цитата
Учитываете ли вы заявки или сделки только на основании OnTransReply() и до срабатывания OnOrder() или OnTrade()?

Информация о заявке берётся из OnTransReply() в обязательном порядке. Список сделок пишется только на основании OnTrade(). Если что-то где-то пропало, выдаются предупреждения. Если у неактивной заявки долго не сходится сумма объёмов по сделкам и разность между объёмом и остатком, выдаётся ошибка.


Цитата
Программирую я редко и кривовато

Учиться -- всегда полезно.
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
Сергей написал:
Цитата
_sk_ написал:
Биржа работает быстро, у нескольких сделок могут микросекунды совпадать.

OnTransReply() лучше использовать. В принципе, можно и без него обойтись, но тогда исполнение заметно замедлится.

Если программируете свой исполнитель заявок, то лучше делайте его корректно работающим, а не компактным.
Вас хотелось бы расспросить больше, чем кого бы то ни было :)
1. что есть такого критичного и необходимого в OnTransReply(), чего нельзя поймать через OnOrder() и OnTrade()?

2. нет ли у вас шаблона робота, который можно просто купить и вставить туда логику? :) Сколько стоит?
1) Детали уже не помню, давно дело было. При программировании мне хотелось:
а) использовать как можно больше источников информации, чтобы повысить надёжность системы;
б) реализовать быструю систему работы с заявками.
В результате получилась хоть и непростая система, зато с коррекцией всякого рода редких ошибок и нетипичных ситуаций, которая работает на полном автомате.

2) Шаблона робота нет. На моей практике кроме менеджера заявок нужен ещё и модуль сведения позиций, который приводит текущие позиции робота к желаемым. Это ещё примерно столько же строк кода. Таких модулей у меня три, каждый со своей спецификой работы с заявками. Продать что-то из кода нет возможности.
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Биржа работает быстро, у нескольких сделок могут микросекунды совпадать.

OnTransReply() лучше использовать. В принципе, можно и без него обойтись, но тогда исполнение заметно замедлится.

Если программируете свой исполнитель заявок, то лучше делайте его корректно работающим, а не компактным.
Как рассчитывается объем в таблице обезличенных сделок?
 
Это сколько стоят 2 нефтяных контракта в рублях. Цена нефти при этом указана в долларах. Как эта цифра получается описано в спецификации на сайте МосБиржи.

https://www.moex.com/ru/contract.aspx?code=BRJ9
https://fs.moex.com/files/3243/21741
Последняя доступная версия QUIK
 
Вижу сообщения от пользователей, которые утверждают, что используют терминал версии 7.26.0.26. При этом вот тут
ftp://ftp.quik.ru/public/updates
только версия 7.25 есть. В новостях про 7.26 тоже ничего нет.

Правда ли, что терминал 7.26.0.26 был выпущен "ограниченным тиражом" для отдельных брокеров?
Оптимизация быстродействия
 
Мне кажется, что проблема производительности решается. Если у вас есть DataSource, и вам надо обратиться к последним 100 свечкам, пишите цикл от ds:Size() - 100 до ds:Size(), чтобы пропустить всё ненужное далёкое прошлое.

Используемый индикатор можно запрограммировать самостоятельно. Это далеко не самое сложное в торговом роботе. Если, к примеру, надо рассчитать какой-нибудь EMA для последних 100 свечей, достаточно начать рассчитывать этот индикатор, скажем, для последних 300 свечей (отступ зависит от периода EMA), т.к. влияние далёкого прошлого мало.

Практика разработки роботов для трейдинга показывает, что расчёты типичных однопроходных индикаторов можно организовать так, чтобы на это тратилось порядка 100-500 мс. Этого вполне достаточно.
Не запускается Квик
 
Установите обновление 7.25.1. Возможно, поможет.
Последняя доступная версия QUIK
 
Терминал 7.25.1: ftp://ftp.quik.ru/public/updates/7.25/quik_7.25.1_upd.zip
Обновился до 7.23, Некоторые проблемы
 
Цитата
Zoya Skvorcova написал:
Дмитрий, Добрый день,
     
      Данная проблема вызвана ошибкой в ПО терминала QUIK и будет       исправлена в одной из ближайших версий программы. Приносим       извинения за причиненные неудобства.
      В качестве временной меры рекомендуем воспользоваться специальным       функционалом экспорта в Excel (Ctrl + L или пункт контекстного       меню таблицы "вывод через DDE сервер". Укажите книгу, лист, а так       же прочие необходимые параметры вывода и нажмите кнопку "Вывести       сейчас".
Я правильно понимаю, что в версии 7.24.1.15 проблема решена, т.е. можно поставить в настройках галочку "Формальное представление данных" и пробелы в числах уйдут?

При этом заголовки столбцов станут английскими. Так и должно быть?
Последняя доступная версия QUIK
 
Терминал 7.24.1: ftp://ftp.quik.ru/public/updates/7.24/quik_7.24.1_upd.zip
Уведомление, когда скрипт перестал работать/не запустился
 
Если есть критичные ошибки либо падения/запуск скриптов за последние 30 секунд, отправляется письмо со списком этих ошибок и смс на телефон, что есть проблемы и надо читать почту. Обычно такие ошибки возникают блоками (несколько писем с интервалами по 30 секунд между ними) по несколько раз в месяц в среднем.

На всякий случай, два раза в день приходят письма со списком работающих скриптов.

Несколько раз в день приходит письмо с оценками P&L портфеля с начала дня для каждого из скриптов.

Письма про проблемы с электропитанием пишет приложение UPS, которое вместе с этим UPS поставляется. Питания хватает на 20-30 минут. Случаев, когда питания не хватало, бывает пару раз в год.
Уведомление, когда скрипт перестал работать/не запустился
 
Для отслеживания, что скрипт живой/сдох, можно поступить так:
1) скрипт периодически даёт знать, что он жив;
2) имеется внешний наблюдатель, который просигнализирует о том, что скрипт не дал о себе знать в течение некоторого времени.

Варианты реализации пунктов 1 и 2 могут быть разными. Например, скрипт раз в 5 секунд записывает в некоторый файл текущее время, а наблюдатель раз в 10 секунд читает этот файл и, если записанное в файле время отличается от текущего времени более чем на 60 секунд или не удалось прочитать файл 5 раз подряд, то наблюдатель считает, что скрипт умер и сигнализирует куда-нибудь об этом, например по электронной почте. Вместо файлов и электронной почты можно применять сокеты и смс или ещё что-нибудь.

У нас применяется вариант с файлами и электронной почтой. Наблюдатель реализован в виде консольного java-приложения. Туда же до кучи приделано оповещение об ошибках, возникающих в скрипте: дисконнекты терминала и сервера QUIK, непонятные изменения статусов заявок (например, если заявку выставил робот, а сняли руками), невозможность выставить заявку из-за нехватки средств и др. С какими-то ошибками скрипт справляется сам, но уведомляет об этом, а какие-то ошибки требуют уже ручного вмешательства.

Наблюдателя надо делать как можно более надёжным (внешнее приложение по отношению к терминалу или даже на другом устройстве).

Возможно, что надо ещё наблюдать за наблюдателем, а то ошибки повалятся, а мы не в курсе, поскольку наблюдатель сам сдох.

В дополнение на торгующем компьютере стоит UPS, который шлёт по электронной почте предупреждения об отключении и включении электричества.

В целом, такой самодельный комплекс у нас более-менее работает.
Обновился до 7.23, Некоторые проблемы
 
Версия терминала 7.23.2.5 с несколькими запущенными lua-скриптами после нескольких дней непрерывной работы иногда внезапно аварийно закрывается перед началом торговой сессии. Кажется, что это происходит в момент подключения информации по срочному рынку. В папке dmp, куда терминал обычно пишет аварийный дамп, пусто. Вопрос: как, всё-таки, получить дамп? Запускать терминал с каким-то ключом или использовать внешние утилиты от Microsoft? Просьба к разработчикам подсказать решение.
Обучение или заказ робота?, Нужен совет: стоит ли обучаться написанию роботов или лучше сразу готовый заказать?
 
Жаль, что Вы не программист. Если Вы готовы выделять средства сторонним программистам, можете попробовать заказать робота, но я бы посоветовал в любом случае самому изучить QLua, чтобы Вы могли хотя бы разобраться, что понаписали программисты на заказ и как это доделать до нужного Вам состояния.

Примеров роботов, действительно, мало. Такова реальность на настоящий момент.
Последняя доступная версия QUIK
 
Терминал 7.23.2.5: ftp://ftp.quik.ru/public/updates/7.23/quik_7.23.2_upd.zip
Единицы измерения волатильности
 
Про историческую волатильность с формулой расчёта: https://utmagazine.ru/posts/11364-istoricheskaya-volatilnost

Цитата оттуда:
Цитата
Нормальная историческая волатильность акций, к примеру, должна  находиться в пределах 10-15%. Если же данный параметр превышает 100%, то  активы обладают повышенной волатильностью.
Вот вопрос на stackexchange.com и ответ на него (англ.):

https://quant.stackexchange.com/questions/16705/why-an-option-has-sometimes-and-implied-volatility-g...

Наконец, вот примеры implied-волатильности для опционов на RI и SR с нашего рынка во время девальвации в декабре 2014 года. Данные из терминала на 2014-12-16.
Код
Время    Инструмент    Спрос    Кол. спрос    Предл.    Кол. предл.    Теор. цена    Волатильность
10:01:24    SR003750BF5    0    0    0    0    3004    110.556
10:01:24    SR003750BR5    0    0    0    0    552    110.556
10:01:24    SR004000BF5    0    0    0    0    2815    106.73
10:01:24    SR004000BR5    0    0    0    0    613    106.73
10:01:24    SR004250BF5    10    100    0    0    2631    103.226
10:01:24    SR004250BR5    0    0    0    0    679    103.226
10:01:24    SR004500BF5    10    100    500000    1    2454    100.016
10:01:24    SR004500BR5    0    0    500000    1    752    100.016
10:01:24    SR004750BF5    10    100    500000    1    2283    97.072
10:01:24    SR004750BR5    0    0    500000    1    831    97.072
10:01:24    SR005000BF5    10    100    500000    1    2119    94.373
10:01:24    SR005000BR5    0    0    500000    1    917    94.373
10:01:24    SR005250BF5    0    0    500000    1    1961    91.894
10:01:24    SR005250BR5    0    0    500000    1    1009    91.894
10:01:24    SR005500BF5    0    0    500000    1    1811    89.617
10:01:24    SR005500BR5    0    0    500000    1    1109    89.617
10:01:24    SR005750BF5    0    0    500000    1    1669    87.523
10:01:24    SR005750BR5    0    0    500000    1    1217    87.523
10:01:24    SR006000BF5    0    0    500000    1    1534    85.595
10:01:24    SR006000BR5    0    0    500000    1    1332    85.595
10:01:24    SR006250BF5    0    0    500000    1    1407    83.818
10:01:24    SR006250BR5    0    0    500000    1    1455    83.818
10:01:24    SR006500BF5    0    0    500000    1    1288    82.178
10:01:24    SR006500BR5    0    0    500000    1    1586    82.178
10:01:24    SR006750BF5    0    0    500000    1    1176    80.66
10:01:24    SR006750BR5    0    0    500000    1    1724    80.66
10:01:24    SR007000BF5    0    0    500000    1    1071    79.254
10:01:24    SR007000BR5    0    0    500000    1    1869    79.254
10:01:24    SR007250BF5    0    0    500000    1    974    77.947
10:01:24    SR007250BR5    0    0    500000    1    2022    77.947
10:01:24    SR007500BF5    0    0    500000    1    883    76.73
10:01:24    SR007500BR5    0    0    500000    1    2181    76.73
10:01:24    SR007750BF5    0    0    500000    1    800    75.594
10:01:24    SR007750BR5    0    0    500000    1    2348    75.594
10:01:24    SR008000BF5    0    0    500000    1    723    74.529
10:01:24    SR008000BR5    100    10    500000    1    2521    74.529
10:01:24    SR008250BF5    0    0    500000    1    652    73.528
10:01:24    SR008250BR5    10    100    500000    1    2700    73.528
10:01:24    SR008500BF5    0    0    500000    1    587    72.586
10:01:24    SR008500BR5    100    10    500000    1    2885    72.586
10:01:24    SR008750BF5    0    0    500000    1    527    71.696
10:01:24    SR008750BR5    10    100    500000    1    3075    71.696
10:01:24    SR010750BF5    0    0    500000    1    212    66.286
10:01:24    SR010750BR5    10    500    500000    1    4760    66.286
10:01:24    SR011000BF5    0    0    500000    1    189    65.835
10:01:24    SR011000BR5    10    500    500000    1    4987    65.835
10:01:24    RI020000BI5    1020    396    750000    1    43660    105.233
10:01:24    RI020000BU5    0    0    800000    1    1530    105.233
10:01:24    RI025000BI5    1020    396    0    0    39200    94.972
10:01:24    RI025000BU5    0    0    0    0    2070    94.972
10:01:24    RI030000BI5    1020    396    0    0    34860    86.667
10:01:24    RI030000BU5    0    0    0    0    2730    86.667
10:01:24    RI035000BI5    1020    396    0    0    30670    79.859
10:01:24    RI035000BU5    0    0    0    0    3540    79.859
10:01:24    RI040000BI5    500    550    0    0    26680    74.22
10:01:24    RI040000BU5    0    0    0    0    4550    74.22
10:01:24    RI045000BI5    200    700    0    0    22940    69.511
10:01:24    RI045000BU5    0    0    0    0    5810    69.511
10:01:24    RI050000BI5    200    700    0    0    19460    65.551
10:01:24    RI050000BU5    3200    1    0    0    7330    65.551
10:01:24    RI055000BI5    100    300    0    0    16300    62.201
10:01:24    RI055000BU5    0    0    0    0    9170    62.201
10:01:24    RI060000BI5    100    300    0    0    13470    59.351
10:01:24    RI060000BU5    0    0    0    0    11340    59.351
10:01:24    RI065000BI5    100    300    0    0    10980    56.915
10:01:24    RI065000BU5    0    0    0    0    13850    56.915
10:01:24    RI070000BI5    100    300    0    0    8830    54.821
10:01:24    RI070000BU5    30    3000    0    0    16700    54.821
10:01:24    RI075000BI5    50    300    0    0    7020    53.01
10:01:24    RI075000BU5    50    3000    0    0    19890    53.01
10:01:24    RI080000BI5    50    300    0    0    5500    51.431
10:01:24    RI080000BU5    50    3000    0    0    23370    51.431
10:01:24    RI085000BI5    50    300    0    0    4260    50.041
10:01:24    RI085000BU5    60    3000    0    0    27130    50.041
10:01:24    RI090000BI5    30    250    0    0    3260    48.803
10:01:24    RI090000BU5    120    3000    0    0    31130    48.803
10:01:24    RI095000BI5    350    15    4000    5    2460    47.685
10:01:24    RI095000BU5    120    3000    0    0    35330    47.685
10:01:24    RI100000BI5    0    0    0    0    1840    46.661
10:01:24    RI100000BU5    200    700    0    0    39710    46.661
10:01:24    RI105000BI5    0    0    0    0    1360    45.71
10:01:24    RI105000BU5    200    700    0    0    44230    45.71
10:01:24    RI110000BI5    0    0    0    0    990    44.824
10:01:24    RI110000BU5    320    800    0    0    48860    44.824
10:01:24    RI115000BI5    0    0    0    0    710    44
10:01:24    RI115000BU5    320    800    0    0    53580    44
10:01:24    RI120000BI5    0    0    810    5    500    43.248
10:01:24    RI120000BU5    1020    396    0    0    58370    43.248
10:01:24    RI125000BI5    0    0    0    0    360    42.58
10:01:24    RI125000BU5    1020    396    0    0    63230    42.58
10:01:24    RI130000BI5    150    1    0    0    250    42.012
10:01:24    RI130000BU5    1020    396    0    0    68120    42.012
10:01:24    RI135000BI5    0    0    0    0    180    41.552
10:01:24    RI135000BU5    1020    396    0    0    73050    41.552
10:01:24    RI140000BI5    0    0    0    0    130    41.204
10:01:24    RI140000BU5    1020    396    0    0    78000    41.204
10:01:24    RI145000BI5    0    0    0    0    90    40.963
10:01:24    RI145000BU5    1020    396    0    0    82960    40.963
10:01:24    RI150000BI5    0    0    0    0    70    40.822
10:01:24    RI150000BU5    1020    396    0    0    87940    40.822
10:01:24    RI155000BI5    0    0    0    0    50    40.771
10:01:24    RI155000BU5    1020    396    0    0    92920    40.771
10:01:24    RI160000BI5    0    0    0    0    40    40.8
10:01:24    RI160000BU5    1020    396    0    0    97910    40.8
10:01:24    RI165000BI5    0    0    0    0    30    40.898
10:01:24    RI165000BU5    1020    396    0    0    102900    40.898
10:01:24    RI170000BI5    0    0    0    0    20    41.057
10:01:24    RI170000BU5    1020    396    0    0    107890    41.057
10:01:24    RI175000BI5    0    0    0    0    20    41.269
10:01:24    RI175000BU5    1020    396    0    0    112890    41.269
10:01:24    RI180000BI5    0    0    0    0    20    41.526
10:01:24    RI180000BU5    1020    396    0    0    117890    41.526
10:01:24    RI020000BL5    1020    396    700000    1    48440    101.077
10:01:24    RI020000BX5    0    0    800000    1    1940    101.077
10:01:24    RI025000BL5    1020    396    0    0    44030    91.427
10:01:24    RI025000BX5    0    0    0    0    2530    91.427
10:01:24    RI030000BL5    1020    396    0    0    39730    83.712
10:01:24    RI030000BX5    0    0    0    0    3230    83.712
10:01:24    RI035000BL5    1020    396    0    0    35570    77.419
10:01:24    RI035000BX5    0    0    0    0    4070    77.419
10:01:24    RI040000BL5    500    550    0    0    31590    72.207
10:01:24    RI040000BX5    0    0    0    0    5090    72.207
10:01:24    RI045000BL5    200    700    0    0    27800    67.836
10:01:24    RI045000BX5    0    0    0    0    6300    67.836
10:01:24    RI050000BL5    200    700    0    0    24260    64.132
10:01:24    RI050000BX5    0    0    0    0    7760    64.132
10:01:24    RI055000BL5    100    300    0    0    20960    60.964
10:01:24    RI055000BX5    450    10    0    0    9460    60.964
10:01:24    RI060000BL5    60    300    0    0    17950    58.234
10:01:24    RI060000BX5    550    10    0    0    11450    58.234
10:01:24    RI065000BL5    50    400    0    0    15210    55.863
10:01:24    RI065000BX5    0    0    0    0    13710    55.863
10:01:24    RI070000BL5    50    300    0    0    12770    53.79
10:01:24    RI070000BX5    30    3000    0    0    16270    53.79
10:01:24    RI075000BL5    50    300    0    0    10620    51.963
10:01:24    RI075000BX5    30    3000    0    0    19120    51.963
10:01:24    RI080000BL5    50    300    0    0    8740    50.343
10:01:24    RI080000BX5    50    3000    0    0    22240    50.343
10:01:24    RI085000BL5    500    50    0    0    7130    48.897
10:01:24    RI085000BX5    60    3000    0    0    25630    48.897
10:01:24    RI090000BL5    30    250    0    0    5760    47.596
10:01:24    RI090000BX5    120    3000    0    0    29260    47.596
10:01:24    RI095000BL5    400    5    0    0    4610    46.419
10:01:24    RI095000BX5    120    3000    0    0    33110    46.419
10:01:24    RI100000BL5    1000    10    0    0    3650    45.348
10:01:24    RI100000BX5    200    700    0    0    37150    45.348
10:01:24    RI105000BL5    500    5    3000    5    2870    44.37
10:01:24    RI105000BX5    200    700    0    0    41370    44.37
10:01:24    RI110000BL5    0    0    0    0    2230    43.474
10:01:24    RI110000BX5    320    800    0    0    45730    43.474
10:01:24    RI115000BL5    0    0    0    0    1720    42.652
10:01:24    RI115000BX5    320    800    0    0    50220    42.652
10:01:24    RI120000BL5    0    0    0    0    1320    41.902
10:01:24    RI120000BX5    1020    396    0    0    54820    41.902
10:01:24    RI125000BL5    0    0    0    0    1010    41.221
10:01:24    RI125000BX5    1020    396    0    0    59510    41.221
10:01:24    RI130000BL5    0    0    0    0    760    40.606
10:01:24    RI130000BX5    1020    396    0    0    64260    40.606
10:01:24    RI135000BL5    0    0    0    0    580    40.059
10:01:24    RI135000BX5    1020    396    0    0    69080    40.059
10:01:24    RI140000BL5    0    0    0    0    430    39.579
10:01:24    RI140000BX5    1020    396    0    0    73930    39.579
10:01:24    RI145000BL5    0    0    0    0    330    39.165
10:01:24    RI145000BX5    1020    396    0    0    78830    39.165
10:01:24    RI150000BL5    0    0    0    0    250    38.815
10:01:24    RI150000BX5    1020    396    0    0    83750    38.815
10:01:24    RI155000BL5    0    0    0    0    190    38.527
10:01:24    RI155000BX5    1020    396    0    0    88690    38.527
10:01:24    RI160000BL5    0    0    0    0    140    38.3
10:01:24    RI160000BX5    1020    396    0    0    93640    38.3
10:01:24    RI165000BL5    0    0    0    0    110    38.128
10:01:24    RI165000BX5    1020    396    0    0    98610    38.128
10:01:24    RI170000BL5    0    0    0    0    90    38.01
10:01:24    RI170000BX5    1020    396    0    0    103590    38.01
10:01:24    RI175000BL5    0    0    0    0    70    37.94
10:01:24    RI175000BX5    1020    396    0    0    108570    37.94
10:01:24    RI180000BL5    0    0    0    0    50    37.916
10:01:24    RI180000BX5    1020    396    0    0    113550    37.916
Интерфейс в Lua, Диалог из Lua
 
Примеры можно увидеть в "Руководстве пользователя QLua". Там в приложении 3 приводятся примеры обработки событий для таблиц. Дальше всё зависит только от вашей фантазии.

Конкретно мы у себя сделали интерактивное изменение размера капитала, выделяемого торговой системе. Двойной щелчок левой кнопкой мыши на ячейке таблицы уменьшает капитал на 10%, а то же самое правой кнопкой мыши -- увеличивает на 10%.
Код
--
-- Таблица для управления долей капитала, которую разрешается использовать торговой системе.
--

local AmountPercentTable = {}

--- Конструктор.
-- @param self объект
-- @param accountSecurityPositions объект, хранящий данные о позициях
-- @param step шаг изменения величины, задающей процент использования капитала
local function new(self, accountSecurityPositions, step)
    local tableId = AllocTable()
    local table = {
        tableId = tableId,
        accountSecurityPositions = accountSecurityPositions,
        step = step,
    }
    setmetatable(table, self)
    self.__index = self

    AddColumn(tableId, 1, "Счёт", true, QTABLE_CACHED_STRING_TYPE, 15)
    AddColumn(tableId, 2, "Объём", true, QTABLE_DOUBLE_TYPE, 15)
    AddColumn(tableId, 3, "Процент", true, QTABLE_DOUBLE_TYPE, 10)

    SetTableNotificationCallback(tableId, function(tId, msg, rowId, colId)
        if tableId ~= tId then
            return
        end
        if msg == QTABLE_LBUTTONDBLCLK and colId == 3 then
            local account = GetCell(tableId, rowId, 1).image
            local percent = table.accountSecurityPositions[account].percent
            percent = percent - step
            if percent < 0 then
                percent = 0
            end
            table.accountSecurityPositions[account].percent = percent
            SetCell(tableId, rowId, colId, tostring(percent), percent)
        end
        if msg == QTABLE_RBUTTONDBLCLK and colId == 3 then
            local account = GetCell(tableId, rowId, 1).image
            local percent = table.accountSecurityPositions[account].percent
            percent = percent + step
            if percent > 100 then
                percent = 100
            end
            table.accountSecurityPositions[account].percent = percent
            SetCell(tableId, rowId, colId, tostring(percent), percent)
        end
    end)

    return table
end

AmountPercentTable.new = new

--- Закрыть окно монитора позиций и удалить все его данные.
-- @param self объект
local function delete(self)
    DestroyTable(self.tableId)
    self.tableId = nil
    self.accountSecurityPositions = nil
    self.step = nil
end

AmountPercentTable.delete = delete

local function show(self, caption, windowPosition)
    local tId = self.tableId
    if IsWindowClosed(tId) then
        CreateWindow(tId)
        if type(windowPosition) == "table" then
            local x, y, dx, dy = windowPosition.x, windowPosition.y, windowPosition.dx, windowPosition.dy
            if x and y and dx and dy then
                SetWindowPos(tId, x, y, dx, dy)
            end
        end
    end
    SetWindowCaption(tId, caption)
    local rows = {}
    local rowCount = 0
    for account, securityPositions in pairs(self.accountSecurityPositions) do
        rowCount = rowCount + 1
        rows[rowCount] = {
            account = account,
            amount = securityPositions.amount,
            percent = securityPositions.percent,
        }
    end
    table.sort(rows, function(row1, row2) return row1.account < row2.account end)
    local tableRows = GetTableSize(tId) or 0
    local shouldAddRows = false
    if tableRows ~= rowCount then
        for i = tableRows, 1, -1 do
            DeleteRow(tId, i)
        end
        shouldAddRows = true
    end
    for i = 1, rowCount do
        if shouldAddRows then
            InsertRow(tId, -1)
        end
        local row = rows[i]
        SetCell(tId, i, 1, row.account)
        SetCell(tId, i, 2, tostring(row.amount), row.amount)
        SetCell(tId, i, 3, tostring(row.percent), row.percent)
    end
end

AmountPercentTable.show = show

return AmountPercentTable
Единицы измерения волатильности
 
В модели Блэка-Шоулса есть время до экспирации, обозначаемое буквой T. Так уж повелось, что T = 1 означает экспирацию через год, т.е. единица шкалы T -- год.


Кроме того, есть волатильность доходности базисного актива sigma, являющаяся безразмерной величиной. Так уж повелось, что опционщики привыкли оперировать с величиной sigma * 100%. С этой точки зрения волатильность, вроде бы, указана в процентах, но при этом вполне может быть больше 100%, если исходное значение sigma > 1.

Не надо переживать, что если волатильность больше 100%, то цена через год станет отрицательной. Этого не допустит модель геометрического случайного блуждания.
Данные из стакана котировок
 
Возможно, кто-то отправил рыночную заявку большого объёма и собрал значительную часть стакана.
Интерфейс в Lua, Диалог из Lua
 
Для реализации диалогов и окон мы пробовали использовать библиотеку iplua. Только интерфейс при этом тормозит из-за особенностей многопоточности в QLua в нашей конкретной реализации.

Ещё можно использовать обычные таблицы терминала совместно с событиями нажатия на кнопки мыши. Костыльный вариант, но иногда подходит.

Возможно, кто-нибудь ещё что посоветует.
Единицы измерения волатильности
 
Волатильность измеряется в процентах, приведённых к промежутку в один год. То, что встречаются значения более 100, не приводят к противоречию, т.к. в основе модели Блэка-Шоулса лежит не обычное случайное блуждание, а геометрическое (логарифм цены считается случайным блужданием). Более детально разобраться с нюансами, на мой взгляд, можно только непосредственно изучая модель Блэка-Шоулса. Можно, например, вот это пособие почитать:
А. Н. Балабушкин «Опционы и фьючерсы»
http://studentam.net/download/opciony_i_fyuchersy_balabushkin.zip

Это и для общего понимания сути дела хорошо подойдёт.
Последняя доступная версия QUIK
 
Терминал 7.23.1: ftp://ftp.quik.ru/public/updates/7.23/quik_7.23.1_upd.zip
Последняя доступная версия QUIK
 
Терминал 7.23.0: ftp://ftp.quik.ru/public/updates/7.23/quik_7.23.0_upd.zip
Последняя доступная версия QUIK
 
Терминал 7.19.0: ftp://ftp.quik.ru/public/updates/7.19/quik_7.19.0_upd.zip
Очищение памяти
 
Если в таблице относительно немного колонок, но много строк, то есть способ сильно сэкономить, если хранить таблицу в виде набора колонок. В Вашем примере будет 6 колонок, которые можно реализовать через массив чисел с индексацией с 1. Конечно, надо беспокоиться о том, чтобы в колонках было одинаковое количество элементов. В результате экономия будет существенной, т.к. не будет создаваться хэш-таблица на каждую строку.
Последняя доступная версия QUIK
 
Терминал 7.18.1: ftp://ftp.quik.ru/public/updates/7.18.1/quik_7.18.1_upd.zip
Как закрыть файл?
 
Есть гипотеза для объяснения проблем с "битыми" строчками: вы пишете в один физический файл, используя несколько разных дескрипторов на уровне lua.
Код
local f1 = io.open("filename.txt", "a+")
local f2 = io.open("filename.txt", "a+")
f1:write("Some text")
f2:write("Another text")
f1:close()
f2:close()
Фильтрация транзакций "своего" робота
 
Чтобы при рестарте терминала счётчик не сбрасывался, я у себя реализовал такую схему:
1) для значений счётчика выделяется достаточно широкий диапазон чисел от a до b: [a, b);
2) периодически, скажем, раз в минуту, значение счётчика сохраняется на диск в файл;
3) при запросе номера транзакции в скрипте текущее значение счётчика увеличивается на 1 и, если оно становится равно b, то оно приравнивается a;
4) при старте скрипта значение счётчика считывается из файла и увеличивается достаточно большую на величину c и аналогичным образом приводится в диапазон [a, b), чтобы не было пересечений номеров транзакций, которые были посланы после того, как значение счётчика сохранялось в файл.

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

Типичные значения в моих скриптах: a = 123 000 000, b = 124 000 000, c = 1000.

Поскольку сейчас планируется сделать номера глобальными для копии терминала, то описанная выше схема потребует выделения всего одного диапазона. Значение c и периодичность записи на диск имеет смысл вынести в конфигурационный файл.
в каких случаях order_date_time == nil в таблице orders
 
Потому, что вместо order_date_time надо писать datetime. В документации QLua об этом сказано.
order_num == nil и status == 3 в ответ на NEW_ORDER
 
Подтверждаю, что OnTransReply может не придти. Хотя это бывает очень редко, при сетевых проблемах, но проектировать логику отслеживания статусов заявок надо с учётом этого.

Порядок прихода коллбэков может быть любым. Это тоже надо учитывать.
Расчет стоимости фьючерсов, Как определить программно стоимость позиции или лота "сложных" фьючерсов на индексы и биржевые товары (Ri, BR и др.)
 
Цитата
Иван Ру написал:

Правда на метод InfoSecurities.isFuturesClass у меня квик что-то ругается : attempt to index global 'InfoSecurities' (a nil value)
Это моя собственная разработка для отделения фьючерсов от всего остального. Можно написать просто classCode == "SPBFUT".
Расчет стоимости фьючерсов, Как определить программно стоимость позиции или лота "сложных" фьючерсов на индексы и биржевые товары (Ri, BR и др.)
 
Может, я что-то не так понял, но у меня используется код такого типа:
Код
local NaN = 0 / 0

local function getPointsToRublesMultiplier(classCode, secCode)
    if InfoSecurities.isFuturesClass(classCode) then
        local stepPrice = getParamEx(classCode, secCode, "STEPPRICE")
        local secPriceStep = getParamEx(classCode, secCode, "SEC_PRICE_STEP")
        if type(stepPrice) ~= "table" or type(secPriceStep) ~= "table" then
            return NaN
        end
        stepPrice = stepPrice.param_value
        secPriceStep = secPriceStep.param_value
        if stepPrice == nil or secPriceStep == nil then
            return NaN
        end
        local stepPriceInRub = tonumber(stepPrice)
        local priceStepInPts = tonumber(secPriceStep)
        if stepPriceInRub > 0 and priceStepInPts > 0 then
            return stepPriceInRub / priceStepInPts
        else
            return NaN
        end
    else
        return 1
    end
end
Внешний вид диаграмм и настройки шрифтов
 
Я имел в виду, что настройки шрифта ПО УМОЛЧАНИЮ для диаграмм можно дать в диалоге "Настройки клиентского места". Например, хочет пользователь, чтобы все НОВЫЕ диаграммы были с шрифтом Segoe UI размера 10, а у него каждый раз вылезает Arial 8 и непонятно, где установить такую настройку. Придётся КАЖДЫЙ РАЗ редактировать КАЖДЫЙ новый график.
Как узнать приостановленны ли торги по инструемнту ?
 
По нормальному и надёжно -- никак. У МосБиржи и есть параметр, транслируемый в ТТП в колонке "Статус" ("status"), где пишется "торгуется" или "приостановлено", бывает (при авариях на бирже), что этот статус остаётся "торгуется", хотя реально всё встало. И биржа особенно не заботится об этом. Если вы влетите на штраф за ошибочные транзакции -- это уже ваши проблемы.

Если инструмент ликвидный и сделки идут часто, можно смотреть, сколько прошло времени с момента последней сделки. Если более, скажем, 60 секунд, значит при выставлении своей заявки надо задуматься, а стоит ли.

В случаях аварий на бирже можно вести аналогичные измерения для классов инструментов. Скажем, если по SPBFUT более минуты нет сделок, а должны быть, то это либо клиринг, либо авария какая-то.

У меня в скриптах отслеживаются как статус, так и таймауты. Отлажено на реальных событиях :)
Внешний вид диаграмм и настройки шрифтов
 
Берём терминал 7.16.3.14, нажимаем F9 и получаем окно с настройками клиентского места. Там есть пункты Программа -> шрифты, где можно указать шрифты для заголовков столбцов, строк, числовых данных и текстовых данных, а также для окон диалогов. Кнопка "Стандартные" устанавливает везде шрифт Segoe UI.

Однако, тут нет пункта для установки шрифта для диаграмм. У меня диаграммы создаются со шрифтом Arial, который потом можно заменить на Segoe UI.

Кажется, что здесь некоторая недоделка. По-хорошему, шрифт диаграмм также должен быть в настройках клиентского места.
Горячие клавиши
 
Раз уж QPILE больше не развивается и его всё больше заменяет QLua, давайте перенесём комбинацию Ctrl+F11 с пункта меню "QPILE скрипты" на пункт меню "Lua скрипты". Полагаю, что пользователей, довольных этим нововведением, будет больше, чем недовольных, а реализация от разработчиков терминала практически не потребует усилий.
Один компьютер и несколько брокеров
 
Создаёте несколько папок типа
Код
D:\QUIK_BROKER1
D:\QUIK_BROKER2
D:\QUIK_BROKER3
В каждую из папок устанавливаете соответствующий дистрибутив программы, рекомендованный каждым из брокеров (версии могут быть разными в зависимости от брокера).

Пользуетесь терминалами независимо друг от друга, возможно одновременно.

Для старта этого достаточно. Если хочется одинаковые настройки в каждом из терминалов, придётся делать дополнительные действия и рисковать несовместимостью wnd-файлов настроек из-за разных версий терминалов.
Размеры окон, создаваемых скриптом
 
Это не сообщение о какой-то ошибке или проблеме, наоборот, это сообщение, которое может помочь программирующим на qlua скрипты роботов.

Допустим, что Ваш скрипт создаёт одно или несколько окон на своей вкладке. Если не прилагать усилий и просто создавать окна через CreateWindow, эти окна получают некоторый размер и местоположение, определяемые автоматически. Не всегда это удобно. Можно после создания указать конкретное местоположение и размеры окна с помощью функции SetWindowPos(tableId, x, y, dx, dy). Однако, откуда взять значения x, y, dx, dy? Их можно подбирать методом последовательных приближений, но ведь это неудобно!

Предлагается следующий подход. Сначала Вы располагаете графики, окна Вашего скрипта и прочие элементы так, чтобы было удобно. Потом запускаете предлагаемый ниже код. Он создаёт пустое окно, которое можно перемещать и изменять его размер с помощью мышки, накладывая это окно ровно поверх каждого окна Вашего скрипта. При этом в заголовке накладываемого окна динамически обновляются параметры x, y, dx, dy, которые нужно будет подставить в функцию SetWindowPos(tableId, x, y, dx, dy) в Вашем скрипте. При этом подбор параметров можно осуществить сразу, а не методом последовательных приближений.

Вот такой вот калибровщик положения и размеров окон получается.

Если я изобрёл велосипед, а все нормальные программисты пользуются подобными штуками, отнесусь к этому с пониманием.
Код
--
-- Подгонка размеров окна.
--

local interrupted = false

function OnStop()
    interrupted = true
end

function main()
    local tId = AllocTable()
    CreateWindow(tId)

    local topPrev, leftPrev, bottomPrev, rightPrev = 0, 0, 0, 0
    while not interrupted do
        if IsWindowClosed(tId) then
            break
        end
        local top, left, bottom, right = GetWindowRect(tId)
        if top == nil or left == nil or bottom == nil or right == nil then
            break
        end
        if topPrev ~= top or leftPrev ~= left or bottomPrev ~= bottom or rightPrev ~= right then
            SetWindowCaption(tId, "x=" .. tostring(left)
                    .. ",y=" .. tostring(top)
                    .. ",dx=" .. tostring(right - left)
                    .. ",dy=" .. tostring(bottom - top))
            topPrev = top
            leftPrev = left
            bottomPrev = bottom
            rightPrev = right
        else
            sleep(50)
        end
    end
end
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 След.
Наверх