Восстановление online-функций Microsoft Money. Котировки

в 14:56, , рубрики: microsoft, microsoft money, money, money 2004, реверс-инжиниринг

Microsoft Money имеет давнюю историю.
Начиная с первой версии вышедшей в 1991 году Windows 3.0 и заканчивая версией Plus 2007 года Money была удобным инструментом для управления личными финансами.

Помимо обычного ведения счетов Money предлагала и развитые online-сервисы.
Их можно разделить на три составляющие:

1) Получение данных о котировках и конвертации валют.
2) Синхронизация данных о счетах, как теперь модно говорить, с облаком.
3) Работа с online-банкингом, в том числе оплата счетов через протокол OFX.

К сожалению, в 2011 году Microsoft поддержав моду на закрытие сервисов, закрыла online-сервис MSN Money, и первые две функции перестали работать.
А вышедшая в 2010 году бесплатная версия Money Plus Sunset уже не содержала поддержку online-функций став простым инструментом для offline-ведения счетов.

Я пользуюсь Microsoft Money 2004 Standard начиная с 2006 года.
За это время были и попытки уйти на другие программы или online-сервисы, но тем не менее Money оказывалась удобней. Но вот не работающие функции откровенно расстраивали. И если online-банкинг в нашей стране бесполезен, т.к. насколько мне известно, даже ни один из крупных банков не поддерживает работу через OFX для частных лиц, то данных о обменных курсах очень не хватало. А уж online-синхронизация после работы с одним online-сервисом вообще была мечтой.

Сообществом было создано несколько инструментов разной степени костыльности, но они имеют один фатальный недостаток: они не интегрируются в Money и требуют ручного труда для получения результатов.

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

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

Задачу по возвращению online-функций можно разбить на два больших этапа:
1) Получение данных о котировках и обменных курсах.
2) Синхронизация с online-сервисом.

URLом по-умолчанию, по которому Money пытается получить котировки является

http://moneycentral.msn.com/Scripts/invisapi.dll

Microsoft Money имеет сложную и гибкую структуру. На вид монолитная программа
состоит из множества компонентов связанных через OLE. Большинство компонентов имеют настройки либо в ini-файлах, либо в реестре, и это прекрасная возможность изменить поведение программы без вмешательства в ее файлы.

Поэтому есть возможность изменить URL запроса, указав в реестре свое строковое значение параметра
HKLMSoftware\Microsoft\Investor\StockQuotes\QuoteServerURL
Тогда мы сможем перенаправить запросы от серверов Microsoft к собственному серверу.

Money отправляет запрос по указанному URL посредством команды HTTP GET включая список требуемых данных как параметры адреса.
Пример:

http://moneycentral.msn.com/Scripts/invisapi.dll?V=5&S=$US:INDU,/RUBUS,/ECUUS,/ATSUS,/BECUS,/DEMUS,/FIMUS,/FRFUS,/GRDUS,/IEPUS,/ITLUS,/LUFUS,/NLGUS,/PTEUS,/ESPUS&Q=19,15,32,0,3,5,1,2,10,4,17,18,8C,E9,EA,1E,8,9,A2,104,3A,3B,3C,3D,7F,7D,7,13,14,14E,14F,EB,21,192,16A&N=8,15&H=15,5,20002+20201+20170916+20180316,20006+20201+20170916+20180316,20000+20201+20170916+20180316,20001+20201+20170916+20180316,20004+20201+20170916+20180316

Здесь закодирован запрос на получения данных об индексе биржевом INDU, его исторических данных за год, а также данных о обменных курсах валют.
Интересно что вместо современного кода валюты USD используется US, а код рубля в запросе используется правильный: RUB.

В ответ Money ожидает данные в бинарном виде. К сожалению протокол InvAPI очень запутан и его восстановление очень трудоемко.

К счастью для нас Money умеет работать еще с двумя форматами: QWB и WebQUOTE.
Поэтому не очень понятно зачем в Microsoft перешли на использование бинарного InvAPI отказавшись от прилично структурированного WebQUOTE, основанного на XML, учитывая то, что XML в Money используется очень широко.

Для использования альтернативных протоколов нужно создать раздел в ветке реестра HKEY_LOCAL_MACHINESOFTWAREMicrosoftMoney12.0OnlineWebQuoteServers.
Подраздел может иметь произвольное имя и должен содержать следующие параметры:
WebQTSrvrURL — основной параметр, содержит URL по которому будет отправлен запрос
ServerType — Если сервер работает по протоколу QWB, то значение параметра должно быть равно QWB. Если используется WebQUOTE, этот параметр должен отсутствовать.

Следующие параметры должны содержать список стран, через запятую, индексы которых поддерживает сервер:
FundCountries — фондовый рынок
MnyMktCountries — Рынок денежных средств, акции
StockCountries — акции
TBillCountries — неизвестно

Предназначение следующих параметров осталось неизвестно:
LookUpURL
XRateFrom
XRateTo

Есть нюанс с порядком описания серверов: если первым в сортировке идет описание WebQUOTE-сервера, а за ним QWB, то запрос будет осуществлен к обоим. Если наоборот, то только к серверу QWB.

Не удалось выяснить начиная с какой версии Money появилась поддержка протокола QWB (Quotes Write Back).
Но по всем признакам это был самый первый протокол использовавшийся для получения данных.
Money 2000 умела импортировать файлы в этом формате. А вот версия 2004 такой возможностью уже не обладает.

При использовании QWB Money формирует URL с параметрами запроса и отправляет через HTTP методом GET.
К примеру:

http://example.com/msmoney/webqt.qwb?N=INDU

где

http://example.com/msmoney/webqt.qwb?N=

— это значение параметра WebQTSrvrURL.

Формат ответа прост: заголовок формата, дата/время и перечисление данных по индексам.

Пример:

<FORMAT>QWB2.0
<DATE>20180311105300
US:INDU@179.98@0@0@0@0@0@0@0@0@0@0@USD@

Формат даты — YYYYMMDDHHmmSS
Значение полей:
0 — WKN с информацией о стране, а фактически имя индекса из запроса
1 — Last (Курс в указанное время) (double)
2 — High (Самая высокая цена на торгах в этот день) (double)
3 — Low (Самая низкая цена на торгах в этот день) (double)
4 — Open (Цена открытия) (double)
5 — 52 week max (Диапазон за 52 недели, от DATE) (double)
6 — 52 week min (Диапазон за 52 недели, от DATE) (double)
7 — P/E Ratio (EPS) (Цена/прибыль (P/E)) (double)
8 — Volume (long) Объем торгов
9 — ? 1/0 (bool)
10 — Shares Outstanding (Акции в обращении) (double)
11 — Market Capitalization (Рыночная капитализация) (double)
12 — Код валюты (US,RUR...)

Данный формат предназначен для получения данных об акциях и индексах (securities), получить через него обменный курс не получится.

WebQUOTE является следующим шагом в развитии протокола получения данных.
Его использование позволяет получать более подробные данные.

Money формирует запрос в виде XML документа и отправляет методом POST на сервер. Тело запроса и выглядит так:

<?xml version="1.0" encoding="windows-1251"?>
<WEBQUOTE Version="1.0" Source="Money2K">
    <QUOTERQ Symbol="$INDU" Type="INDEX" Country="US"/>
    <HISTQUOTERQ Symbol="$INDU" Type="INDEX" Country="US" StartDate="20170918" EndDate="20180318"/>
</WEBQUOTE>

Формат ответа следующий:

<WEBQUOTE>
    <EXRATERS CurrFrom="" CurrTo="" datetime="" rate=""/>
    <QUOTERS  Symbol="" Country="" Type="STOCK|INDEX|MUTUAL|OTHER" Currency="string" DateTime="YYYYmmDD"
        Price="double" Low="double" High="double" Open="double" PrevClose="double" YearHigh="double" YearLow="double"
        Pe="double" Vol="dword" Out="double" Cap="double" NewsURL="string" Ask="double" Bid="double" Beta="double"
        DividendYield="double" AmtEPS="double" Size="long" LastUpdate="YYYYmmDD" FYI="YYYYmmDD" News="YYYYmmDD"
        PercentCash="double" PercentOther="double" PercentSmall="double" PercentLarge="double" PercentMedium="double"
        BaseUnit="long"/>
    <HISTQUOTERS Symbol="" Country="" Type="STOCK|INDEX|MUTUAL|OTHER" Currency="string" DateTime="YYYYmmDD"
        Price="double" Low="double" High="double" Open="double" PrevClose="double" YearHigh="double" YearLow="double"
        Pe="double" Vol="dword" Out="double" Cap="double" NewsURL="string" Ask="double" Bid="double" Beta="double"
        DividendYield="double" AmtEPS="double" Size="long" LastUpdate="YYYYmmDD" FYI="YYYYmmDD" News="YYYYmmDD"
        PercentCash="double" PercentOther="double" PercentSmall="double" PercentLarge="double" PercentMedium="double"
        BaseUnit="long"/>
</WEBQUOTE>

где
EXRATERS — данные о конвертации валют.
QUOTERS — данные о котировках на момент запроса.
HISTQUOTERS — исторические данные о котировках.

Набор возвращаемых данных намного расширен по сравнению с QWB. Из названия атрибутов вполне понятно какие данные они должны содержать.
Что интересно, Money никогда не запрашивает данные о конвертации валют, но если в ответ содержит эти данные, то прекрасно их обрабатывает и сохраняет.

При формировании ответа по любому протоколу следует учитывать коды валют, хранящихся в БД. К примеру, код рубля в Money записан как RUR, и если написать RUB, то разбор завершится с ошибкой.

Есть еще и третий вариант: использование протокола OFX. Данные в этом формате можно импортировать файлом, к примеру сформированном одной из утилит, либо полученным online
от подключенного к Money банка. Но этот метод является вторичным по отношению к QWB и WebQUOTE и требует ручного вмешательства.

Автор: aunoor

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js