Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?
Ноября 08, 2024, 05:01:44 pm
Начало Помощь Поиск Войти Регистрация
Новости:

Transaq  |  СБО "Transaq"  |  Подсистема ATF  |  Topic: Глюк с выставлением заявки по рынку « предыдущая тема следующая тема »
Страниц: 1 [2] 3 4 Печать
Автор Тема: Глюк с выставлением заявки по рынку  (Прочитано 29296 раз)
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #15 : Декабря 26, 2012, 01:49:31 pm »

onOrder вызовется, если сервер Transaq вначале примет заявку, а затем что-то с ней пойдет не так. Если же заявка будет сразу же отклонена, то onOrder не будет вызван, но гарантированно позовётся onATFOrderErr.
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #16 : Декабря 27, 2012, 09:45:47 am »

Ну если концепция такая, то текущая работа сервера в моем случае ей не соответствует. Ведь, если я правильно понимаю результаты раскопок по глюку, с которого стартовала эта тема: терминал послал рыночную заявку, сервер подставил в нее, известную ему на тот момент планку цены и !послал заявку на биржу. Но планка оказалась устаревшей и сервер биржи отказал. В этой ситуации сервер тразака должен был вернуть в статусе какой-нить статус связанный с отказом биржи, а он получается даже заявку с trid не создал, раз onATFOrder не вызвался.
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #17 : Декабря 27, 2012, 09:57:54 am »

P.S. плюсом onATFOrderErr является более подробное чем в статусе заявки описание ошибки. Но допустим при работе нескольких скриптов на одной бумаге сущемтвенно более ценной является возможность привязать ошибку к конкретному скрипту/попытке послать заявку - в этом случае лучше получать вызов onOrder с соотв. статусом.- тогда хоть как-то можно будет узнать (с использованием будущего поля комментарий или более извратно анализируя другие поля хэша заявки), чья заявка не прошла при одновременном их посыле двумя скриптами (здесь onATFOrderErr будет бесполезен, т.к. например в терминах выщеупоминаемых примеров не может обеспечить 2В).
« Последнее редактирование: Декабря 27, 2012, 10:10:52 am от ddd323 » Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #18 : Декабря 28, 2012, 03:04:20 pm »

В общем в ATF 1.18 обработка ошибок будет расширена следующим образом:

1) В onATFOrderErr будет добавлен еще один необязательный параметр - идентификатор заявки (правда это значение будет не всегда - если сервер немедленно заявку отклонит, то идентификатора никакого присвоено не будет; будет передано значение 0).

2) В струтуре заявки и стоп-заявки будет добавлено поле message - сообщение от сервера Transaq или биржи, если оно есть (это далеко не всегда так), с описанием ошибки.
Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #19 : Января 10, 2013, 07:44:27 pm »

Работа на ATF 1.18 закончена, работа с заявками и сделками переделана теперь следующим образом:

1. Операции trade_action:: а так же функции снятия заявок теперь работают в синхронном режиме и сразу возвращают либо номер транзакции, либо значение 0, и тогда ошибку можно считать функцией getLastErrorMessage().  Примерно это может выглядеть так:

Code: [Select]
var trnid = trade_action::buy(1, ::lots);

if (not trnid) {
   signal::output("Заявка не выставлена: " + getLastErrorMessage());
}

if (not cancelAllOrders()) {
  signal::output("Не удалось снять заявки: " + getLastErrorMessage);
}

И в случае с message:

Code: [Select]
function onOrder(var id) {
  var order = getOrder(id);
  if (order["message"]) {
    signal::output("Ошибка выставления заявки: " + order["message"]);
  }
}

Событие onATFOrderErr теперь вообще более не существует.
« Последнее редактирование: Января 10, 2013, 07:46:07 pm от Heller » Записан
nxz
Full Member
***
Сообщений: 241


Просмотр профиля Email
« Ответ #20 : Января 10, 2013, 08:52:40 pm »

А в Интре когда будет обновление ATF до версии 1.18?
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #21 : Января 11, 2013, 01:07:57 am »

Ну Вы быстрые ребята! Исправляя неудобство с обработкой ошибок глобально поменяли идеологию работы с заявками :o Вы же где-то на форуме писали, что собираетесь делать по выбору пользователя - синхронная (для тех кому скорость не важна) или асинхронная обработка... Теперь пока trnid/ошибку не получишь от сервера дальнейшее выполнение кода (вызов калков) останавливается  (при быстрых движениях на рынке их пройдет несколько сотен и цена уйдет заметно в то время пока скрипт никак не может это обрабатывать) - правильно я понимаю? Надеюсь только в текущем скрипте?
А код старый теперь срочно переписывать придется или можно по прежнему просто вызывать функцию ничему не присваивая ее результат?
« Последнее редактирование: Января 11, 2013, 01:29:59 am от ddd323 » Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #22 : Января 11, 2013, 11:32:27 am »

Понимаю ваши опасения, попробую объяснить почему мы пошли на такой шаг.

Идея с асинхронным выставлением заявок, как мы выяснили, была не особо оправдана. Если интересны детали, то раньше алгоритм выставления заявок из ATF выглядел так:

1. Transaq посылает запрос к серверу, в котором получает порцию обновлений по всем необходимым ему данным (заявки, сделки, стаканы, статистика и прочее что использует клиент в данный момент).
2. Сразу после получения ответа от сервера синхронно и последовательно все эти данные раздаются во все открытые окна, в том числе в окна графиков и находящиеся там скрипты ATF.
3. Если пользователь выставляет заявку из скрипта ATF, то она не выставляется сразу, а откладывается в очередь.
4. Только после того как будут обработаны все данные во всех окнах, происходит последовательная отправка всех заявок на сервер Transaq.
5. Когда все заявки будут отправлены, Transaq отправляет серверу запрос на новые обновления и процесс начинается сначала.

Единственное, что сейчас поменялось - мы выкинули очередь и отправляем теперь заявки немедленно как того затребовал клиент. Задержки появиться сейчас действительно могут, но это будут лишь задержки интерфейсные - пока из скрипта ATF заявка не будет отправлена на сервер, не начнут обрабатываться новые данные в других окнах. Однако если говорить о скорости выставления заявок, то это на самом деле никак не влияет - всё равно пока не будет отправлена одна заявка, не могут начать отправляться другие заявки.

Ну то есть изначальное решение с асинхронной отправкой заявок на сервер казалось хорошим, но оно таким казалось лишь из-за того, что я ATF писал на высоком уровне, не вникая как это всё будет работать на уровне взаимодействия клиента и сервера. В ходе расследования ошибок, которые возникали с выставлением заявок и в основном при подробном анализе как работает onATFOrderErr на уровне взаимодействия клиент-сервер, стало понятно, что асинхронный подход на самом деле никак не помогает вообще, а лишь создаёт иллюзию какой-то эффективности.

onATFOrderErr был выкинут по причине того, что он всё равно работал из рук вон плохо и был неудовлетворителен: если вникать совсем в детали, то он закладывался на уже несколько версий как выкинутый механизм разграничения заявок и сделок робота и пользователя и тащил за собой кучу ненужного старого кода. При этом по факту полноценно использовать его было нельзя - при выставлении сразу многих заявок было невозможно понять в асинхронном режиме какая именно заявка не прошла, плюс, как выяснилось, о целом ряде ошибок onATFOrderErr вообще мог не сообщать. Закладываться на правильность его работы было явно опасно для клиентов, однако из примеров тех скриптов, которые присылали пользователи и которые я имел возможность посмотреть, стало понятно, что в таком виде этим событием всё равно никто не пользуется.

Собственно что касается изменения идеологии и обратной совместимости, то единственное действительно существенное изменение, которое может быть заметно для клиента - это отсутствие функции onATFOrderErr. Единственное, что придётся заменить в коде, чтобы вернуть старое поведение - это сделать замену

trade_action::...

на

if (not trade_action::...) {onATFOrderErr(getLastErrorMessage());}

и дописать в начало функции onOrder(var id) строчки

var order = getOrder(id);
if (order["message"]) {onATFOrderErr(order["message"]);}

Ну то есть если вы действительно интенсивно использовали функцию onATFOrderErr, то вам придётся немного изменить старый код, однако незначительно. Зато теперь при необходимости можно гораздо более эффективно контролировать возникающие ошибки и сразу иметь идентификатор выставляемых заявок и вообще использовать все эти новшества довольно удобным образом.

Присваивать результат выполнения trade_action::... куда-либо не обязательно - это по желанию только.
« Последнее редактирование: Января 11, 2013, 11:39:42 am от Heller » Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #23 : Января 14, 2013, 01:20:28 am »

Спасибо большое за подробные разъяснения. Т.е. получается, что и раньше на шаге 4 - пока не получен ответ от сервера (или ок/trnid, или ошибка) по первой отправленной заявке, вторая заявка из очереди даже не отправлялась на сервер?
Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #24 : Января 14, 2013, 10:13:34 am »

Да, именно так.
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #25 : Января 14, 2013, 10:37:30 am »

Понятно, спасибо.  Действительно, получение trnid сразу - позволяет упростить очень многие вещи в коде, в частности, например, теперь можно легко, даже не используя поле brokerref, игнорировать в onOrder/onTrade чужие (не данного скрипта) заявки/сделки при работе нескольких скриптов по одной бумаге. (По крайней мере это относится к рыночным заявкам, для которых можно пренебречь вероятностью смены trnid на сервере за время их исполнения)

P.S. Раньше никто onATFOrderErr эффективно не использовал и в будущем поле message не будет, т.к. это почти невозможно делать без функций работы со строками. Может это и к brokerref относится, если кто-то будет туда текст писать, пытаясь максимально сохранить структуру кода из WealthLab например.
« Последнее редактирование: Января 14, 2013, 10:54:03 am от ddd323 » Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #26 : Января 14, 2013, 01:04:51 pm »

Я честно говоря плохо понимаю что вы имеете ввиду, когда говорите "без функций работы со строками". ATF имеет функции substr, strlen и конкатенацию, с помощью которых в общем-то можно реализовать всё что угодно (пусть и синтаксически это вероятно будет не очень удобно, но всё необходимое можно вынести в отдельные функции). Какие конкретно функции вам требуются ещё для удобной работы?
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #27 : Января 15, 2013, 01:26:20 am »

Да, каюсь. Извините. Просто существование/появление substr я и не заметил. Действительно с этим набором можно все что угодно сделать, но для удобства неплохо бы иметь еще функцию поиска подстроки в строке. От двух аргументов - чтобы возвращала номер позиции начала подстроки или ноль, если подстрока в строке не найдена (тогда эту функцию можно будет и в if'ах использовать как аналог str.Contains())
Может не обязательно даже в атф, а в виде кода в раздел примеры. Конечно это несложный цикл, но с учетом того, что break появится лишь в 1.18, и того что возможно не всем его будет легко написать - полезно было бы иметь оптимальный по быстродействию код от разработчиков
« Последнее редактирование: Января 15, 2013, 02:06:39 am от ddd323 » Записан
Heller
Разработчики
Hero Member
*****
Сообщений: 1277


Просмотр профиля Email
« Ответ #28 : Января 15, 2013, 10:29:22 am »

Ок, в 1.19 сделаем.
Записан
ddd323
Sr. Member
****
Сообщений: 257


Просмотр профиля Email
« Ответ #29 : Января 29, 2013, 09:47:47 pm »

А в чем смысл возвращать в strfind(str1, str2) "-1", если не найдено? Ведь "-1" не воспринимается как false... Лучше возвращать 0, хоть это может и менее традиционно. 0-й позиции все равно не существует, и можно будет без лишних действий и весьма интуитивно использовать в виде if(strfind(str1, str2)) в смысле if(str1.Contains(str2)).
Записан
Страниц: 1 [2] 3 4 Печать 
Transaq  |  СБО "Transaq"  |  Подсистема ATF  |  Topic: Глюк с выставлением заявки по рынку « предыдущая тема следующая тема »
Перейти в:  


Войти

Powered by MySQL Powered by PHP Powered by SMF 2.0.10 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!