Вопрос к разработчикам по mtapi.dll

 
Вопрос к разработчикам по mtapi.dll
Уважаемые разработчики!
В текстовике есть такое предложение "Если инструмент, по которому запрашиваются цены,
находится в режиме Instant Execution, то обращения к серверу не произойдёт,
и функция вернет ошибку RET_INSTANTEXECUTION." Я так понял режим Instant Execution - это поле ConSecurity.exemode. Сейчас 11 инструментов находятся в EXE_MARKET, и 4 - в EXE_REQUEST. Дальше что-то непонятно. Ошибка RET_INSTANTEXECUTION вообще нигде не описана. Если клиента переводим в режим подкачки данных, то про историю котировок вообще можно забыть (с данным сокетом), так что-ли? Извините, но это не совсем понятно.
 
Instant Execution
да, действительно ошибка RET_INSTANTEXECUTION не описана, тем не менее функция MtGetErrorDescription с числовым кодом этой ошибки 24 в качестве параметра возвращаеи описание "symbol is in instant execution mode but not selected". если вы уже выяснили, что запрашиваемый инструмент находится в режиме EXE_MARKET, то можно не запрашивать цену при помощи функции MtGetPrices, а использовать текущие котировки. если клиент переведён в режим подкачки данных, то это - те самые котировки, которые приходят по событию UPDATE_BIDASK и уже хранятся внутри объекта сокета. попробуйте по такому инструменту обратиться к сокету, переведённому в режим подкачки, при помощи функции MtGetPrices(как вы процитировали, "обращения к серверу не произойдёт" и вы не нарушите режим подкачки данных) и вы получите не код ошибки, а интересующую вас цену!
непонятен вопрос "Если клиента переводим в режим подкачки данных, то про историю котировок вообще можно забыть". хранение истории котировок в необходимом для вас формате вы должны обеспечивать сами.
 
подкачка истории котировок и работа с API
Подкачка истории котировок производится через отдельный коннект. Обычно, подкачка истории - это разовая функция и используется при открытии нового графика.
Рекомендуем не злоупотреблять вызовом этой функции - она очень затратна по трафику(хотя данные и сжимаются) и ресурсам сервера.
Не нужно каждый раз требовать загрузки всей истории(несколько тысяч баров) с сервера, а загружайте последние 100-200 баров.

Желательно руководствоваться правилами:
- экономное использование вызовов функций, не загружайте сервер
- не создавайте массу лишних соединений
- не пробуйте совершать сделки по неверным ценам - не получится и все это фиксируется в логах сервера
- если есть вопрос - желательно спросить у разработчиков(по емайлу или в форуме).


Как не нужно обновлять исторические данные:

while( программа не закрыта )
{
RateInfo *buff=GetRates(symbol,period,lasttime,&total);
.... обновляем чарты
.... ждем пару секунд или больше
}


Что получается в этом случае? Бесконечная подгрузка данных с сервера, огромный трафик и вероятность запрета использования API с сервера.

Как нужно работать с историческими данными:


if( нужно подкачать данные )
{
RateInfo *buff=GetRates(symbol,period,lasttime,&total);
.... обновляем чарты
}
// чарты обновлены глобально
....

// в другом месте программы где получаем
// уведомления о приходе тиков
case UPDATE_BIDASK:
... обновляем маркет вотч
... чего-либо еще
AddTickToHistory(...); // добавляем вновь пришедший тик в базу истории, выстраивая новые бары.
break;



Большая часть истории строится на клиенте, а не подкачивается бесконечно с сервера.
Просьба использовать именно этот метод, а не качать данные с сервера каждую секунду.

 
есть еще некоторые мелочи
Ну вобщем-то так примерно я и догадывался. Хотя до начала разбирательства с API у меня были совершенно другие мысли. Можете их воспринимать за мои пожелания. Может и узрите в них что-нибудь ценное. Итак,
MtSetWorkingDirectory, по моему мнению, должен был указать на директорию, в которой потом создалась бы структура каталогов и данных, аналогичная MetaTrader.
По MtSetPumpingMode и MtAddSymbol, я надеялся, что начнут автоматически обновляться файлы истории выбранных инструментов в MetaTrader\bases\ (при установке этой директории рабочей). И действительно, зачем хранить два набора одних и тех же данных (MetaTrader и мое приложение)?
Естественно, все это должно работать в отдельном потоке, дабы мое приложение отвечало на сообщения. Но... не тут-то было.
Поэтому, сейчас буду пытаться переписать класс MTAPI, чтобы функции отрабатывали в отдельном потоке. Далее внедряю в него новый класс для работы с историей МетаТрейдера. В связи с этим возникает вопрос, насколько свежими являются данные в файлах истории MetaTrader при его работе, и не возникнет ли неразберихи потом при сбросе Метатрейдером кеша на диск? Или все же файловый кеш сбрасывается на каждом тике? (Это скорее всего не так, для того и придуман кеш, чтобы не насиловать железки). Скорее всего в этом случае придется не допускать одновременной работы этих программ.
Этот момент мне понравилось, как сделали в Метастоке, хотя очень многое совсем не понравилось, как они сделали, как-будто руки у них не оттуда растут, или мозги... Да простят меня буржуи! Так вот, доступ к данным осуществляется через msfl7(0 или 2).dll, независимо от того, кто их затребовал: MetaStock, DownLoader или мое приложение. Соответственно эта dll и ведает всеми кешами и т.д. С Метатрейдером и API, я изначально думал, происходит то же самое. Но вижу, ошибался.
Теперь вопрос по формированию баров в realtime по Bid/Ask. C Low & High все понятно, а как Вы вычисляете Open и Close? Если бы спред был 4 или 6 пунктов, тут ясно - дели пополам. А на 5 пунктах сколько не смотрел, так ничего и не высмотрел. То от Bid/Ask последняя цена на 2 и 3 пункта, а то на 3 и 2. Вроде ерунда, а неприятно, когда непонятно.

Кроме того, думаю, была бы не лишней функция типа MtGetVersion, хотя, конечно, версию dll можно и сейчас добыть, но более затратным способом.

И еще пожелание по форуму. Пожалуйста, сделайте окошко для набора сообщения поболее! Ширину можно сделать со страницу, а высоту тоже можно раза в три-четыре увеличить.
 
использование mtapi.dll
Правило - не используйте MetaTrader и mtapi.dll в одном каталоге!
MetaTrader API для того и выпущен, чтобы не использовать обычный клиентский терминал.
MetaTrader API - это набор функций прямого доступа к возможностям сервера и для них абсолютно не нужен клиентский терминал.

Базы данных истории терминала сбрасываются на диск изредка(только в некоторых случаях), вся работа ведется с кешами в памяти. Поэтому ориентироваться на работу с файлами истории не стоит.

Формирование баров:
Low - минимум из бидов
High - максимум из асков
Open=Close=Normalize((bid+ask)/2,digits);
Нормализация цен используется для урезания лишних знаков, вместо 1.456788301 получится 1.4568

GetVersion добавим, поля ввода увеличим.
 
А вот с Normalize похоже у MtGetRates проблемы
MtGetRates возвращает как раз ненормализованные цены. Проверял на йене получалось типа 118.920000024, а посмотрев это дело в шестнадцатиричном виде в памяти, заподозрил, как-будто float к double преобразован. Первые 4 байта почти полностью нулевые. Отсюда и хвосты. Посмотрите пожалуйста.
Или на самом деле Bid/Ask должны быть с хвостами? Только отображается в нормализованном виде.
С остальным все понятно, спасибо.
 
передача котировок и нормализация
При передаче истории котировок они переводятся из double во float, пакуются аналогом зипа и передаются по сети. Далее данные расжимаются и преобразуются из float в double. Но автоматическая нормализация в MetaTrader API не производится. Но в клиенте MetaTrader такая нормализация происходит.
В следующей версии MetaTrader API добавим автоматическую нормализацию истории котировок чтобы не было хвостов.
Причина обращения: