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

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

Страницы: Пред. 1 ... 68 69 70 71 72 73 74 75 76 77 78 След.
Поле count
 
Цитата
Серж пишет:
Цитата
Sergey Gorokhov пишет:
Расскажите, как по Вашему, что изменило бы в диагностике, если бы проблему воспроизводили на боевом потоке?
Если бы воспроизводили проблемы на боевом Квике, то этот вопрос уже решили бы.
А теперь расскажите как проблема с индикатором связанна с проблемой описанной на этой ветке форума
Поле count
 
Цитата
sam063rus пишет:
честно говоря, ответ на троечку бо как тестируя обращения и пожелания, т.е. выявленные баги от пользователей на, как вы говорите, тестовых серверах, которые не ведут себя, как боевые - вы тем самым потом нам же и пишете, что мол де данная проблема, у вас не воспроизводится.
Расскажите, как по Вашему, что изменило бы в диагностике, если бы проблему воспроизводили на боевом потоке?
Поле count
 
Цитата
sam063rus пишет:
мой вопрос #21 всё ещё в силе.
У нас есть тестовые сервера и на них информация не обязана совпадать с боевой.
Поле count
 
Цитата
sam063rus пишет:
и ещё: с радостью от вас выслушаю Вашу версию того, что вы считаете плагином... ))
Все просто, то что в меню Справка - Версии компонентов, имеет возможность установить галку - то плагин, все остальное служебные составляющие
Поле count
 
Цитата
PFelix пишет:
чтобы сервер QUIK передавал в поле Count номер строки таблицы изменения параметра по инструменту (если она на сервере хранится).
Не хранится
Цитата
PFelix пишет:
Если эти предложения не выход, можете изложить в каком виде эти данные на сервере хранятся? Спасибо.
Они хранятся в том виде как приехали.
И на рабочее место они приезжают в том же виде.
Проблема возникает при попытке воспроизвести ту хронологию в которой эти данные приехали.
И как сказал Михаил, сейчас мы УЖЕ работаем над тем чтобы эту проблему преодолеть.
В виду сказанного не считаю разумным вести диалог дальше.
Изменение цвета фона, Как изменить цвет фона по событию
 
Цитата
Максим Федоров пишет:
Фоновый цвет графика, на котором отображаются эти две EMA.
Цвет фона графика менять нельзя.
Можно менять цвет линии индикатора.
В текущей версии это можно сделать если создать несколько линий, с заранее заданными цветами, и передавать значения только на одну из них, в зависимости от условия, а на остальные nil
6.17.0.58 bugs collection, разработчикам на заметку. (все остальные - прошу проходить мимо и не засорять топик)
 
Здравствуйте!

Ваше письмо получено, проблема изучается. Постараемся в ближайшее время дать ответ.
Status в OnTransReply
 
Цитата
Серж пишет:
При отсутствии связи сервера с торговой системой клиенту ничего не приходит в ответ на транзакцию?
А что со стоп-заявками? Для них ведь связь сервера с торговой системой биржи не нужна? (Мой случай был именно со стоп-заявками)
Не надо делать правила из возможной вероятности.
То что у брокера были проблемы, уже говорит о том, что последствия этих проблем могут быть самыми разнообразными.
В том числе и отсутствие ответа на транзакцию.
Действительно, стоп заявки относятся к серверу брокера, а не к бирже.
Однако, так как точно не известно, какие именно были проблемы у брокера, нельзя назвать причины по которым ответ на транзакцию выставления стоп заявки не был получен.
Например, если Вы работали через сервер доступа, а основной сервер был недоступен.
В любом случае, дальше играть в догадки не вижу смысла.
Status в OnTransReply
 
Цитата
Серж пишет:
Спорное утверждение
Не вижу противоречий. Вы сами сказали что были проблемы на стороне брокера.
Я же точно указал как важнейшее условие "при наличии связи сервера с торговой системой"
Если сможете пример когда ответ на транзакцию не пришел, но при этом у брокера и у Вас со связью было все хорошо, то это повод разбираться отдельно.
Status в OnTransReply
 
Цитата
Viktor MMM пишет:
1. Всегда ли должен прийти ответ на транзакцию при наличии связи с сервером? Другими словами, значит ли отсутствие ответа в течение какого-то времени (какого?) что связи с сервером нет?
При наличии связи клиента с сервером и при наличии связи сервера с торговой системой, ответ на транзакцию приходит всегда.
Цитата
Viktor MMM пишет:
2. Верна ли логика, что если статус не 3, то значит она отвергнута?
Пользователь решает, вредна она или нет. Кому то, она может оказаться достаточной для решения поставленных задач а кому-то нет.
Цитата
Viktor MMM пишет:
3. Наличие статусов 0 и 1 говорит о том, что заявка подвисла и не обработана, но получена и, теоретически, может быть принята. Значит ли это, что надо просто подождать, получив эти статусы? Сколько ждать?
Пользователь сам должен решать сколько ждать. при синхронной подаче транзакций для этого даже есть специальный отдельный  параметр.
Цитата
Viktor MMM пишет:
4. И, как результат, сообщите алгоритм, по которому можно 100% выяснить, что заявка прошла или не прошла.
Не понятно что значит "прошла" и "не прошла"
Если Вы говорите про то сработала заявка (были сделки) или нет, извините по транзакции понять это не представляется возможным.

Если Вы имеете в виду, транзакция привела к выставлению заявки или нет, то если есть ответ на транзакцию и в этом ответе есть номер заявки, значит что на 100% эта транзакция была выполнена и привела к появлению заявки.
доступ к строкам таблицы изменений параметров, почему его нет?
 
Дмитрий,
Отсутствие функционала не является ошибкой.
Ошибкой, можно считать любое девиантное поведение софта.
А то, что поставленная Вами задача не решается из за отсутствия технической возможности, это не ошибка.
В связи с чем, переквалифицировать мы ничего в этом месте не будем.
Добавить в функцию getQuoteLevel2() дополнительный возвращаемый параметр datetime, Вызывая функцию getQuoteLevel2() хотелось бы точно знать время когда произошли изменения в стакане, не привязываясь к локальному времени на клиенте.
 
Здравствуйте!

Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Status в OnTransReply
 
Цитата
Серж пишет:
В Отчёте по транзакциям фиксируется локальное время сервера QUIK?
Время шлюза.
Цитата
Серж пишет:
Т.е., возможна такая ситуация, когда "Время получения на сервере QUIK" и "Время получения ответа торговой системы" больше, чем время заявки в таблице заявок?
Ситуация, когда заявка приходит раньше чем ответ на транзакцию вполне возможна.
К стати, именно из за таких ситуаций, на одну заявку может придти повторный колбэк.
Почему умерает корутина?
 
Здравствуйте,
К сожалению, затруднюсь назвать причины.
Возможно что то делаете не так.
В соседней ветке, Вам рекомендовали для ознакомления статьи по теме корутинов.
Простой код по созданию файла с ценами из all_trades таблички, файл создаётся, но пустой, табличку получаем.
 
и уберите message слишком частое их использование приводит к тормозам. Используйте для диагностики PrintDbgStr
Простой код по созданию файла с ценами из all_trades таблички, файл создаётся, но пустой, табличку получаем.
 
Цитата
Николай Бехтерев пишет:
ЧО НЕ ТАК ТО?
Николай,Вам уже объяснили что информация в файле появится только после выполнения close() или flush()
В Вашем коде нету flush()  есть только close() который сработает в лучшем случае при остановке скрипта.
Рекомендация остается прежней, добавьте команду file:flush()  сразу после file:write
Зависание QLUA
 
Цитата
Роман пишет:
Еще косяк getInfoParam("SERVERTIME")- а что за формат, что за время такое 25:09:51 - там разве не 24 часовое исчесление
Здравствуйте
В одной из прошлых версий была такая проблема. Сообщите точно какая версия терминала у Вас установлена.
Использовать поле COMMENT из условных заявок, созданных в QLua
 
Поле "COMMENT" служит для того чтобы снимать заявки по условию, а не для того чтобы задать комментарий.
Комментарий задается в параметре CLIENT_CODE после кода клиента, нужно указать знак "/" или "//" (зависит от настроек брокера) а потом уже указывать комментарий.
Создание таблицы текущая прибыль/убыток и высчитывать по позициям в терминале, Сегодня невозможно понять текущее состояние счета, пересчет происходит с долгими задержкам, что добавляет еще большего психологического давления
 
Интервал расчета вар маржи настраивается на стороне биржи. Для каждого подключения индивидуально.
К сожалению, у нас нет возможности повлиять на решение уменьшить интервал расчета.
Мы можем только рекомендовать брокеру обратиться на биржу с этим вопросом.
Далее уже брокер, совместно со специалистами биржи, решает следовать рекомендациям или нет.
Еще, можем предложить пример расчета вариационки:

Цитата
Вариационная маржа (ВМ) по фьючерсу на Индекс РТС рассчитывается по следующим формулам:

В ходе дневной клиринговой сессии:

В случае, если расчет вариационной маржи по контракту ранее не осуществлялся:
ВМ1 = (РЦ1 – ЦО) x W1 : R

В случае, если расчет ВМ осуществлялся ранее:
ВМ1 = (РЦ1 – РЦП) x W1 : R

В ходе вечерней клиринговой сессии:

В случае, если расчет вариационной маржи по контракту ранее не осуществлялся:
ВМ2 = (РЦ2 – ЦO) x W2 : R

В случае, если расчет ВМ осуществлялся ранее:
ВМ2 = ВМ – ВМ1

При этом величина ВМ рассчитывается по следующим формулам (и округляется
с точностью до копеек по правилам математического округления):

В случае, если расчет вариационной маржи по контракту до дневной клиринговой
сессии текущего торгового дня не осуществлялся:
ВМ = (РЦ2 – ЦO) x W2 : R

В случае, если расчет ВМ в ходе дневной клиринговой сессии текущего торгового
дня осуществлялся:
ВМ = (РЦ2– РЦП) x W2 : R

Где:
ВМ1 — вариационная маржа по контракту, рассчитанная в ходе дневной клиринговой
сессии текущего торгового дня,

ВМ2 — вариационная маржа по контракту, рассчитанная в ходе вечерней
клиринговой сессии за вечерний расчетный период текущего торгового дня,

ВМ — вариационная маржа по контракту, рассчитанная в ходе вечерней
клиринговой сессии за текущий торговый день,

ЦО — цена заключения контракта,

РЦ1, РЦ2 — текущая (последняя) расчетная цена контракта,

РЦП — расчетная цена контракта, определенная по итогам вечернего расчетного
периода предыдущего торгового дня,

W1 — стоимость минимального шага цены, используемая в ходе дневной
клиринговой сессии,

W2 — стоимость минимального шага цены, используемая в ходе вечерней
клиринговой сессии,

R — минимальный шаг цены.

В приведенных выше формулах расчета вариационной маржи можно заменить блок,
отвечающий за перевод фьючерсных пунктов в рубли, на более привычный долларовый
эквивалент:
W : R = 0,02 x курс USD/RUR, рассчитанный согласно Методике ФБ РТС (fs.rts.ru/files/5307).

Рассмотрим пример расчета вариационной маржи при проведении операций с фьючерсом на Индекс РТС.

Пример 1
Участник торгов в 14:45 купил 1 фьючерс на Индекс РТС по цене 132 700 пунктов.
В 18:45 МСК, перед началом клиринга, расчетная цена (fs.rts.ru/files/2892) (цена
последней сделки) инструмента составила 135 200 пунктов. Курс доллара США
к российскому рублю, рассчитанный согласно упомянутой выше Методике .
(fs.rts.ru/files/5307), на 16:30 МСК составил 30,2765 рубля. По итогам клиринга
участник получит следующий финансовый результат:
(135 200 – 132 700) x 0,02 x 30,2765 = 1 513,82 рубля.
При этом размер гарантийного обеспечения на следующий торговый период (с 19:00
до 14:00 МСК) будет установлен исходя из расчетной цены, определенной по итогам
завершившейся сессии (в 18:45 МСК), и будет равен:
135 200 x 0,02 x 30,2765 x 7,5% = 6 140,07 рубля.
Поскольку фьючерс на Индекс РТС является расчетным, его исполнение происходит
в вечернем клиринговом сеансе в последний день обращения путем перечисления/
списания денежных средств. Это означает, что в день исполнения участники торгов,
не закрывшие позиции противоположными (офсетными) сделками перед вечерним
клиринговым сеансом, получают положительную или отрицательную вариационную
маржу за последний день торгов на основе расчетной цены контракта в этот день.

Пример 2
Участник торгов в 14:30 МСК последнего дня обращения контракта, 11 июня
2010 года, купил фьючерс на Индекс РТС по цене 135 050 пунктов и удерживал
позицию до закрытия сессии.
Среднее значение Индекса РТС с 15:00 до 16:00 МСК в этот день составило
1 355,10 пункта. Соответственно, расчетная цена была зафиксирована на уровне:
1 355,10 x 100 = 135 510 пунктов.
В этом случае вариационная маржа, начисленная участнику торгов в итоговом
клиринге, составила:
(135 510 – 135 050) x 0,02 x 30,7246 = 282,67 рубля.
Универсальный дистрибутив квика
 
Здравствуйте,
В одной из старых версий была такая беда, наблюдалась в основном на больших мониторах.
Для решения проблемы, обновите терминал до последней версии. На текущий момент это 6.17
Набор функций Qlua для автозаполнения, нужны функции Qlua
 
Здравствуйте,
У нас такого набора нет. Можно использовать стандартный набор для обычного LUA.
Да там нет функций QUIK но тем не менее он подойдет
коды событий поворотов колеса мыши SetTableNotificationCallback
 
Цитата
Вячеслав пишет:
И клавишу Esc, для отмены убыточной сделки. )))
Esc работает. при этом par2 будет равен 27
Обмен с сервером DDE - что не так?, Не идет обмен QUIK с сервером DDE, хотя Excel с ним(сервером) работает.
 
Здравствуйте,
К сожалению, мы не можем дать консультацию по данному вопросу. Попробуйте поискать ответ на каком-либо форуме посвященному написанию DDE серверов
Создание таблицы текущая прибыль/убыток и высчитывать по позициям в терминале, Сегодня невозможно понять текущее состояние счета, пересчет происходит с долгими задержкам, что добавляет еще большего психологического давления
 
Цитата
Вячеслав пишет:
Finrise (Инстройинвест), Открытие - также ссылаются на разработчиков ПО.
Открытие даже обновление QUIK делают с задержкой 2-3 версии. У них до сих пор 6.16(42)
Вопрос был адресован другому пользователю.
Или у Вас тоже задержки в трансляции маржи?
Создание таблицы текущая прибыль/убыток и высчитывать по позициям в терминале, Сегодня невозможно понять текущее состояние счета, пересчет происходит с долгими задержкам, что добавляет еще большего психологического давления
 
Цитата
rozmin пишет:
Брокер говорит - обратитесь к разработчику ПО. Замкнутый круг))))

Думаю, все всё понимают.
Хотя бы сообщите кто брокер, чтобы мы могли с ними поговорить
Создание таблицы текущая прибыль/убыток и высчитывать по позициям в терминале, Сегодня невозможно понять текущее состояние счета, пересчет происходит с долгими задержкам, что добавляет еще большего психологического давления
 
Цитата
rozmin пишет:
Sergey: не помогает.

Вариационная маржа, судя по всему, считается на сервере, поэтому и задержки, надо чтобы отдельный скрипт непосредственно в клиентском терминале рассчитывал разницу пунктов с ценой открытия и выводил в таблицу клиентский портфель, например. Можно назвать "оперативная вар. маржа"
Вы не говорили что речь про ФОРТС. Указанная настройка в этом случае и не должна была помочь.
Так как она влияет только на клиентский портфель в котором считаются показатели фондовой секции.
Вар маржа считается не на сервере, а на бирже.
Никаких задержек с расчетом Вар маржи не должно быть, если они имеются это может говорить о проблемах на стороне брокера.
Уточните Вы обращались к брокеру? Что он ответил?
Создание таблицы текущая прибыль/убыток и высчитывать по позициям в терминале, Сегодня невозможно понять текущее состояние счета, пересчет происходит с долгими задержкам, что добавляет еще большего психологического давления
 
Цитата
rozmin пишет:
На сегодняшний день расчет происходит раз в n-ое количество времени, что так-же вносит путаницу в реалиях. Спасибо.
Здравствуйте,
Попробуйте в меню Настройки - Основные - Торговля - Клиентский портфель поставить галку "Пересчитывать при изменении позиций"
И в поле "Обновлять через каждые … секунд" укажите 0
Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Цитата
Андрей пишет:
Это здорово! Т.е. можно будет обновить терминал, и он обновленный сможет работать с игровым сервером моего брокера и проблем совместимости не возникнет?
с демо сервером не возникнет. а вот с боевым, есть риски что какой-нибудь плагин перестанет работать.
по CALLBACK, алгоритм работы
 
Цитата
Viktor MMM пишет:
Спасибо! а работать они будут тоже с версии 6.17?
Эти функции были и раньше, то есть на 6.16 тоже работать будут
по CALLBACK, алгоритм работы
 
Цитата
Серж пишет:
Пардон, не видел: здесь об этих функциях ни слова, в quik_6_17_1_upd.zip вообще отсутствует WhatsNew.
Эти функции были и раньше, d 6.17 просто добавили их описание.
Поэтому это НЕ новый функционал. соответственно в список он не попал
по CALLBACK, алгоритм работы
 
Цитата
Viktor MMM пишет:
Квик6,16,0,42 только что обновил.
Эти функции описаны начиная с версии 6.17
Также актуальная документация есть по ссылке:
http://www.quik.ru/depot/quik_lua.zip
Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Цитата
Андрей пишет:
Я, так понимаю, что у брокера нет обновления Junior, только до версии 6.12.4.11...
Тогда можете отправить нам запрос на адрес 911@quik.ru с просьбой выслать обновление и мы отправим.
Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Цитата
Андрей пишет:
Обновлений нет . Плохо мое дело.
Как нет? У нас на Junior нет? или у брокера нет?
по CALLBACK, алгоритм работы
 
Цитата
Серж пишет:
Sergey Gorokhov , отметьте также об отсутствии потокобезопасности предложенного вами способа. А то ведь ещё один человек по этим "граблям пройдётся".
да ладно, а как же
Потокобезопасные функции для работы с таблицами Lua
Цитата

Одновременная работа с таблицами из функций обратного вызова скрипта и функции main() может приводить к неопределенным ситуациям. Для решения этой проблемы qlua.dll предоставляет потокобезопасные аналоги стандартных функций Lua.

Формат вызова потокобезопасной функции совпадает с форматом вызова аналогичной стандартной функции Lua.

В таблице представлены стандартные функции Lua и соответствующие им потокобезопасные аналоги:

Стандартная функция Lua  
concat  
remove  
insert  
sort  

Потокобезопасная функция
sconcat  
sremove  
sinsert  
ssort  

взято из документации QLUA.chm
Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Цитата
Андрей пишет:
Он работает при открытом стакане. Куда нужно писать Subscribe_Level_II_Quotes(CLASS, SEC) ? Там, где я закомментировал выдает ошибку.
Скорее всего просто версия терминала старая. Эта функция появилась относительно недавно.
Попробуйте обновить версию через меню Связь - "Обновить версии программы"
по CALLBACK, алгоритм работы
 
Цитата
Viktor MMM пишет:
Не могли бы Вы натолкнуть на способ такого складывания?
Имеется в виду создать таблице t={} и добавлять в нее элементы которые не успели обработать.
А после обработки очищать ее.
Отображение нужного параметра в заголовке Quik, Зачем мне постоянно видеть своё Ф.И.О. или UID в заголовке? Я хочу видеть там последнюю цену.
 
Еще задачу можно решить через скрипт LUA.
Полученную таблицу вынести за пределы главного окна и свернуть

Код
--НАСТРОЙКИ:
CLASS="TQBR"   --код класса
SECUR="LKOH"   --код инструмента
PARAM="last"   --параметр из ТТП


--ТО ЧТО НИЖЕ ТРОГАТЬ НЕ НАДО
not_stopped = nil
t_id=0
ds=nil
lRow=nil

function OnStop(stop_flag)
   ds:Close()
   DestroyTable(t_id)
   not_stopped = false
end

function OnInit(script_path)
   t_id=AllocTable()
   AddColumn(t_id,1,PARAM,true,QTABLE_STRING_TYPE,30)
   CreateWindow(t_id)
   lRow = InsertRow(t_id, 1)
   SetSelectedRow(t_id, lRow)
   not_stopped = true
   top, left, bottom, right = GetWindowRect(t_id)
   width=227
   height=68
   SetWindowPos(t_id, left, top, width, height)
   ds,err = CreateDataSource(CLASS, SECUR, INTERVAL_TICK, PARAM)
   if ds==nil then
      message("Ошибка при получении параметра "..PARAM..":\n"..err, 3)
   else
      ds: SetUpdateCallback(cb)
   end
end

function cb(index)
if index==ds:Size() then
      SetWindowCaption(t_id,SECUR.."="..tostring(ds:C(index)))
      SetCell(t_id, lRow, 1, tostring(ds:C(index)))
end
end

function main()
  while not_stopped do
   if IsWindowClosed(t_id) then
      OnStop()
   end
  end
end

Отображение нужного параметра в заголовке Quik, Зачем мне постоянно видеть своё Ф.И.О. или UID в заголовке? Я хочу видеть там последнюю цену.
 
Цитата
Иван Кешиков пишет:
Это абсолютно не то, что нужно. Вот открыт у меня к примеру браузер на весь экран, или фотошоп - квик не видно, а панель задач всегда на виду.
Если задача стоит смотреть какой-то один параметр, можно вынести таблицу с ним за пределы терминала и сделать поверх всех окон. тогда он будет виден поверх панели задач или браузера.
Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Что делает:
  По Таблице текущих параметров строит таблицу опционов с расcчитанными греками
  Формулы взяты отсюда:
  http://en.wikipedia.org/wiki/Black%96Scholes
  http://en.wikipedia.org/wiki/Greeks_%28finance%29
 
Как использовать:
  откройте Таблицу Текущих Параметров (меню Таблицы -> Текущая Таблица)
  Укажите настройки, после чего, запустите скрипт (меню Таблицы - Lua - Доступные скрипты)
  чтобы сохранить в CSV файл, текущее состояние таблицы, нужно нажать комбинацию клавиш Ctrl+S файл сохраняется в папку со скриптом, с именем HHHMMDD.csv

Код
-------------------------------НАСТРОЙКИ-------------------------------
RiskFree=0/100 --безрисковая ставка %, Указывается вручную

BaseClassCode = "SPBFUT" --Класс базового актива
ClassCode = "SPBOPT" --Класс опционов

--Список базовых активов, через запятую, по которым отображать опционы:
BaseSecList = "RIZ4" --getClassSecurities(BaseClassCode) --все сразу
 
--Список опционов через запятую:
SecList = getClassSecurities(ClassCode) --все сразу

INTERVAL = 1000 --Интервал обновления таблицы

doLogging=false --включает запись в файл, формата csv. 
log_file=getScriptPath() .. "\\Greek.csv" --путь к csv файлу 

-----------------------------------------------------------------------

-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
--Параметры таблицы
tbl = {
["caption"]="Greek",
[1]="Название",
[2]="Код опциона",
[3]="Тип опциона",
[4]="Баз. актив",
[5]="Расчетная цена",
[6]="Страйк",
[7]="Волатильность",
[8]="До исполнения",
[9]="Дельта",
[10]="Гамма(%)",
[11]="Тэта",
[12]="Вега",
[13]="Ро",
["t_id"]=0
}

abTable = {}
BaseCol = {}
Sec2row = {}
file = nil
Sep = ";"
YearLen=365.0 --Число дней в году
WORK = true
CALC = false
G_ROW = -1
if (BaseSecList == "") or (BaseSecList == nil) then
   BaseSecList = getClassSecurities(BaseClassCode)
end

if (SecList == "") or (SecList == nil) then
   SecList = getClassSecurities(ClassCode)
end

-------------------------------ФУНКЦИИ------------------------------------------------------------------
function Logging(str) --Пишет лог
   if file~=nil and doLogging then
      file:write(str .. "\n")
      file:flush()
   end
end

function N(x) --Нормальное среднее
    if (x > 10) then
      return 1
   elseif (x < -10) then
      return 0
   else
      local t = 1 / (1 + 0.2316419 * math.abs(x))
      local p = 0.3989423 * math.exp(-0.5 * x * x) * t * ((((1.330274 * t - 1.821256) * t + 1.781478) * t - 0.3565638) * t + 0.3193815)
      if x > 0 then
         p=1-p
      end 
      return p   
   end
end

function pN(x) --производная от функции нормального среднего
   return math.exp(-0.5 * x * x) / math.sqrt(2 * math.pi) 
end

function Greek(tmpParam)
   local b = tmpParam.volatility / 100 --"b" волатильность доходности (квадратный корень из дисперсии) базисной акции.
   local S = tmpParam.settleprice --"S" текущая цена базисной акции;
   local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
   local K =  tmpParam.strike --"K" цена исполнения опциона;
   local r = RiskFree --"r" безрисковая процентная ставка;
   local d1 = (math.log(S / K) + (r + b * b * 0.5) * Tt) / (b * math.sqrt(Tt))
   local d2 = d1-(b * math.sqrt(Tt))
   
local Delta = 0
local Gamma = 0
local Theta = 0
local Vega = 0
local Rho = 0 

local e = math.exp(-1 * r * Tt)
   
   Gamma = pN(d1) / (S * b * math.sqrt(Tt))
   Vega = S * e * pN(d1) * math.sqrt(Tt)
   
   Theta = (-1 * S * b * e * pN(d1)) / (2 * math.sqrt(Tt))

   
   if tmpParam.Optiontype == "Call" then
      Delta = e * N(d1)
      Theta = Theta - (r * K * e * N(d2)) + r * S * e * N(d1)
      ----Theta = Theta - (r * K * e * N(d2))
      Rho = K * Tt * e * N(d2)
   else
      Delta = -1 * e * N(-1*d1)
      Theta = Theta + (r * K * e * N(-1 * d2)) - r * S * e * N(-1 * d1)
      ----Theta = Theta + (r * K * e * N(-1 * d2))
      Rho = -1 * K * Tt * e * N(-1 * d2)
   end
   

   return {
   ["Delta"] = Delta,
   ["Gamma"] = 100 * Gamma,
   ["Theta"] = Theta / YearLen,
   ["Vega"] = Vega / 100,
   ["Rho"] = Rho / 100
   }
end

function GetRow(ID,row) --возвращает строку таблицы
local rows, col = GetTableSize(ID)
local result = ""
if rows~=nil and row<=rows then
   for i=1,col do
      result=result..GetCell(ID,row,i).image .. Sep
   end
end
   return result
end

function CSV(T) --пишет таблицу в csv файл
   function FTEXT(V) --ПРОВЕРЯЕМ КОРРЕКТНОСТЬ КОЛИЧЕСТВА СИМОЛОВ ПЕРЕМЕННОЙ
      V=tostring(V)
      if (string.len(V)==1) or (string.len(V)==5) then
         V="0".. V
      end
      return V  
   end
local temp = os.date("*t")
local Fname =getScriptPath() .. "\\" .. FTEXT(temp.year) .. FTEXT(temp.month) .. FTEXT(temp.day) .. ".csv"
   CSVFile = io.open(Fname, "w+")
   if CSVFile~=nil then
      local rows, col = GetTableSize(T.t_id)
      for i=1,col do --расставляем заголовки
         CSVFile:write(T[i] .. Sep)
      end
      CSVFile:write("\n")
      for i=1,rows do --пишем таблицу
         CSVFile:write(GetRow(T.t_id,i).."\n")
      end      
      CSVFile:flush()
      CSVFile:close()
      message("Файл успешно сохранен:\n"..Fname, 1)
   else 
      message("Ошибка при сохранении файла:\n"..Fname, 3)
   end   
end

function round(num, idp) --округляет до указанного количества знаков
   local mult = 10^(idp or 0)
   return math.floor(num * mult + 0.5) / mult
end 

function comma_value(n) --ставит разделители в числах
   local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
   return left..(num:reverse():gsub('(%d%d%d)','%1 '):reverse())..right
end

function getParamValue(Class,Sec,Par)
local result={}
--делаем предварительный заказ данных
   local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
   if ds==nil then
      message("Ошибка при получении параметра "..Par..":\n"..err, 3)
      return 0
   else
      ds:SetUpdateCallback(function() end)
      result=getParamEx(Class,Sec,Par)
      ds:Close()
      return result.param_value+0
   end
end

function Stop()
   if doLogging then 
      file:close() 
   end
   WORK = false
end

function Calculate(row,do_calc)
if (row~=nil) and (row>=0) and (do_calc) then
         local T=BaseCol[row]
         local tmpParam ={
            ["Optiontype"] = T.Optiontype,
            ["settleprice"] = getParamValue(BaseClassCode,T.Optionbase,"settleprice"),
            ["strike"] = getParamValue(ClassCode,T.SecCode,"strike"),
            ["volatility"] = getParamValue(ClassCode,T.SecCode,"volatility"),
            ["DAYS_TO_MAT_DATE"] = T.DAYS_TO_MAT_DATE
         }
         local tmpGreek = Greek(tmpParam)
         SetCell(tbl.t_id, row, 5, comma_value(tmpParam.settleprice), tmpParam.settleprice) -- "Расчетная цена",
         SetCell(tbl.t_id, row, 6, comma_value(tmpParam.strike), tmpParam.strike) --"Страйк",
         SetCell(tbl.t_id, row, 7, tostring(tmpParam.volatility), tmpParam.volatility) -- "Волатильность",
         SetCell(tbl.t_id, row, 8, tostring(tmpParam.DAYS_TO_MAT_DATE), tmpParam.DAYS_TO_MAT_DATE) --"До исполнения",
         SetCell(tbl.t_id, row, 9, tostring(round(tmpGreek.Delta,2)), tmpGreek.Delta) --"Дельта",
         SetCell(tbl.t_id, row, 10, tostring(round(tmpGreek.Gamma,4)), tmpGreek.Gamma) -- "Гамма(%)",
         SetCell(tbl.t_id, row, 11, tostring(round(tmpGreek.Theta,2)), tmpGreek.Theta) -- "Тэта",
         SetCell(tbl.t_id, row, 12, tostring(round(tmpGreek.Vega,2)), tmpGreek.Vega) -- "Вега",
         SetCell(tbl.t_id, row, 13, tostring(round(tmpGreek.Rho,2)), tmpGreek.Rho) -- "Ро",
         Logging(os.date().. Sep .. GetRow(tbl.t_id,row))
end
return false
end

-------------------------------Колбэки------------------------------------------------------------------
function f_cb(t_id,msg,par1,par2) --событие на нажатие клавиш
   if (msg==QTABLE_CHAR) and (par2==19) then --сохранить в CSV файл текущее состояние таблицы нужно нажать комбинацию клавиш Ctrl+S
      CSV(t_id)
   end
   if (msg==QTABLE_CLOSE) then --закрытие окна
      Stop()
   end
end

function OnStop()
   Stop()
   DestroyTable(tbl.t_id)
end

function OnInit()
local STR = ""
   
   if doLogging then 
      file = io.open(log_file, "w+") 
   end
   tbl.t_id = AllocTable()
   for i=1,table.maxn(tbl) do --добавляем колонки
      if i<=4 then
         AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_CACHED_STRING_TYPE, string.len(tbl[i])*2)
      else
         AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_DOUBLE_TYPE, 10)
      end
      if doLogging then
         STR=STR..tbl[i]..Sep
      end
   end
   Logging("Дата Время".. Sep .. STR)
   CreateWindow(tbl.t_id)
   SetWindowCaption(tbl.t_id,tbl.caption)
   SetTableNotificationCallback(tbl.t_id, f_cb)
end

function OnParam(class, sec)
if (class==ClassCode) and (WORK) and (string.find(SecList,sec)~=nil) then
   G_ROW = Sec2row[sec]
   if (G_ROW~=nil) and (G_ROW>=0) then
      Highlight(tbl.t_id, G_ROW, QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
      CALC=true
   end
end
end

function main()

WORK = false
CALC=true
   for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
            local Optionbase=getParamEx(ClassCode,SecCode,"optionbase").param_image
            local Optiontype=getParamEx(ClassCode,SecCode,"optiontype").param_image
            if (string.find(BaseSecList,Optionbase)~=nil) then
               local row = InsertRow(tbl.t_id,-1)
               local T={
                  ["Name"] = getSecurityInfo(ClassCode,SecCode).name,
                  ["SecCode"] = SecCode,
                  ["Optiontype"] = Optiontype,
                  ["Optionbase"] = Optionbase,
                  ["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value+0
                  }
               BaseCol[row]=T
               --заполняем статичные параметры
               Sec2row[SecCode]=row
               SetCell(tbl.t_id, row, 1, BaseCol[row].Name) -- "Название опциона",
               SetCell(tbl.t_id, row, 2, BaseCol[row].SecCode) --"Код опциона",
               SetCell(tbl.t_id, row, 3, BaseCol[row].Optiontype) -- "Тип опциона",
               SetCell(tbl.t_id, row, 4, BaseCol[row].Optionbase) --"Баз. актив",
               --заполняем динамичные параметры
               CALC=Calculate(row,CALC) 
            end
   end
WORK = true
while WORK do
   CALC=Calculate(G_ROW,CALC)
   sleep(INTERVAL)
end
end

Вопросы по совместной работе, quik junior и доске опционов., Два пользователя за одним терминалом. Программный доступ к доске опционов ...
 
Цитата
Андрей пишет:
1. Как правильно настроить последовательную работу двух человек на одном терминале quik на одном компьютере в среде Windows7?
Если брокер один, можно объединить ключи доступа от двух учетных записей (просто добавить информацию из одного файла secring.txk в другой) эти файлы открываются обычным блокнотом. При этом логины должны быть разными. После этого, сменить учетную запись можно будет путем смены логина при подключении. Если брокера разные то там немного сложнее, нужно будет дополнительно объединить файлы ip.cfg и pubring.txk
Цитата
Андрей пишет:
2. Subscribe_Level_II_Quotes работает в quik junior на опционах?
Использование функций не зависит от конкретного класса и сервера. Однако, если класс отключен, то работать функции по этому классу не будут.
Цитата
Андрей пишет:
3. Как программно(на qlua) можно получить доступ к доске опционов?
Программного доступа к этой таблице нет. Если интересует расчет греков, могу предложить пример расчета выполненный на LUA
Баг с валютой шага
 
Цитата
Reshpekt Fund Russia пишет:
Пользователь нашёл баг и теперь как попка бегает между биржей и аркой, пытаясь достучаться. Мне не важно, из-за кого, мне важно, чтобы пришло в норму.
Мы отправили данное обращение специалистам биржи.
по CALLBACK, алгоритм работы
 
Виктор,
На Ваш вопрос, можно ли застопроприть событие так, чтобы накопиться очередь, а потом она продолжилась, то ответ можно, включив бесконечный цикл в событии. Но это приведет к зависанию всего терминала.
Если Вам нужно обрабатывать данные которые поступили за время работы функции main без зависаний, используйте стороннее хранилище поступающих данных
по CALLBACK, алгоритм работы
 
Цитата
Viktor MMM пишет:
Происходит событие. Вы говорите, что терминал подвисает и начинает его обрабатывать.
Мне же надо, чтобы при возникновении события сначала доработала какая -то моя функция, а потом уже пошла обработка события. Причем по моему выбору. В каких-то для меня критичных местах. То есть не код в событии продолжал работать, а, например, тот же main. Доработал бы до какого-то места, а потом бы разрешил обработать событие. Это возможно?
Вы можете установить на входе и выходе своей функции какую-нибудь переменную флаг, и пропускать обработку событий пока флаг не примет нужного значение.
Цитата
Viktor MMM пишет:
я мог бы конечно отсечь влияние событий глобальным флагом, но хотелось бы, чтоб событие не терялось а в очередь вставало и отработало в итоге.
Это нельзя сделать, так как появление очереди приведет к полному отказу в работе терминала.
по CALLBACK, алгоритм работы
 
Здравствуйте,
Цитата
Viktor MMM пишет:
Работает скрипт, происходит событие.
Скрипт прерывается и включается обработка? А потом скрипт продолжает работу?
Все события работают в основном потоке терминала. таким образом пока что-то делается в каком-то событии, в терминале ничего не происходит. Он даже может повиснуть.
Цитата
Viktor MMM пишет:
Как сделать так, чтобы пока, например, функция не выполнится, обработка не выполнялась? В тех случаях, когда мне так надо.
Этот вопрос совершенно не понятен.
Вы имеете в виду, чтобы "пока код в событии работает, функция main останавливала работу"?
Отображение нужного параметра в заголовке Quik, Зачем мне постоянно видеть своё Ф.И.О. или UID в заголовке? Я хочу видеть там последнюю цену.
 
Здравствуйте,
Вы можете вынести нужные окна за пределы главного окна терминала и назвать их как угодно
В руководстве:
-Раздел 2. Основные принципы работы с программой
--Работа с окнами
---Вынесенные окна
Использование Subscribe_Level_II_Quotes, получение данных стакана без открытия стакана
 
Цитата
Eldar пишет:
и вопрос про функцию Subscribe_Level_II_Quotes по моему мнению тоже резонный.
На вопрос где лучше использовать Subscribe_Level_II_Quotes у нас нет и не может быть ответа.
Так как этот вопрос зависит от Вашего видения работы программы.
Можно даже сказать от Вашего вкуса.
Использование Subscribe_Level_II_Quotes, получение данных стакана без открытия стакана
 
Цитата
Eldar пишет:
но тогда все еще не понятен вопрос, как именно ОСТАНОВИТЬ выполнение скрипта. вот как через меню "Доступные скрипты" - Остановить.
Чтобы остановить работу скрипта, нужно остановить работу всех функций и циклов этого скрипта.
Пример уже был дан.
Использование Subscribe_Level_II_Quotes, получение данных стакана без открытия стакана
 
Цитата
Eldar пишет:
Спасибо. что-то проясняется.
например найден BREAK. но так как документация скудная, появился следующий вопрос.
По поводу документации объясняю.
Язык LUA придумали НЕ мы.
Мы взяли готовый язык и добавили в него несколько наших функций.
Поэтому в НАШЕЙ документации только НАШИ функции.
Все функции которые являются стандартными для языка LUA описаны в документации на язык LUA, которая есть в интернете:
http://www.lua.org/docs.html

BREAK приводит к выходу из цикла. Подробнее в документации на LUA
Использование Subscribe_Level_II_Quotes, получение данных стакана без открытия стакана
 
Цитата
Eldar пишет:
может мне проще Subscribe_Level_II_Quotes использовать в функции OnInit()?
На Ваше усмотрение
Использование Subscribe_Level_II_Quotes, получение данных стакана без открытия стакана
 
Цитата
Eldar пишет:
дело в том, что не понятно как работает функция Subscribe_Level_II_Quotes:
вызов Subscribe_Level_II_Quotes аналогичен открытию стакана в терминале QUIK.
Без открытия стакана данные в него не поступают. Соответственно OnQuote и getQuoteLevel2 работать не будут
Цитата
Eldar пишет:
в этой функции я могу пометить is_run как false и не обрабатывать в main, но скрипт все еще будет запущен.
Это значит что Вы не понимаете как работает IsWindowClosed
Напишите в функции Quotes так:

Код
function Quotes(code)
   sleep(150)
   for i=1, shares_count do
    if IsWindowClosed(t) then 
      is_run=false
      break 
    end
--остальной код
 
Страницы: Пред. 1 ... 68 69 70 71 72 73 74 75 76 77 78 След.
Наверх