Цепочка опционов на акции Bloomberg через API

В настоящее время я работаю над проектом, который должен помочь мне создать поверхность подразумеваемой волатильности для данной акции. Для этого я пишу скрипт, который будет загружать все доступные варианты для этой конкретной акции — из того, что я собрал, это возможно, отправив запрос через Bloomberg API с использованием полей/переопределений масс. Вот мой текущий код:

d_host = "localhost";
d_port = 8194;
SessionOptions sessionOptions;
sessionOptions.setServerHost(d_host.c_str());
sessionOptions.setServerPort(d_port);
Session session(sessionOptions);
Service refDataService = session.getService("//blp/refdata");
Request request = refDataService.createRequest("ReferenceDataRequest");

request.append("securities", "MSFT US EQUITY");
request.append("fields", "CHAIN_TICKERS");

// add overrides
Element overrides = request.getElement("overrides");
Element override1 = overrides.appendElement();
override1.setElement("fieldId", "CHAIN_PUT_CALL_TYPE_OVRD");
override1.setElement("value", "C");

Element override2 = overrides.appendElement();
override2.setElement("fieldId", "CHAIN_POINTS_OVRD");
override2.setElement("value", 100);

Element override3 = overrides.appendElement();
override3.setElement("fieldId", "CHAIN_EXP_DT_OVRD");
override3.setElement("value", "20250203");

std::cout << "Sending Request: " << request << std::endl;
CorrelationId cid(this);
session.sendRequest(request, cid);

(followed by event handling)

Теперь у меня есть несколько проблем/вопросов:

  1. Код компилируется без проблем, но при запуске на терминале Bloomberg выводится следующая ошибка: bloomberg errorКак бы мне заняться устранением этой проблемы? Я предполагаю, что где-то ошибся в полях переопределения.

  2. Как мне нужно настроить свой код для загрузки всех доступных вариантов с учетом определенного срока действия, т. Е. Я хочу получить список всех вариантов до сегодняшнего дня + 15 лет.

  3. Как мне тогда загрузить подразумеваемую волатильность для каждого опциона? Нужно ли мне хранить тикеры в массиве, а затем отправлять запрос на поле «IVOL_MID» для каждого варианта, или есть какой-то способ получить все волатильности сразу?

Изменить: вот код моего обработчика событий, так как это кажется проблемой.

    session.sendRequest(request, cid);

    while (true)
    {
        Event event = session.nextEvent();
        MessageIterator msgIter(event);
        while (msgIter.next()) {
            Message msg = msgIter.message();
            if (msg.correlationId() == cid) {
                processMessage(msg);
            }
        }
        if (event.eventType() == Event::RESPONSE) {
            break;
        }
    }




 void processMessage(Message &msg)
{
    Element securityDataArray = msg.getElement(SECURITY_DATA);
    int numSecurities = securityDataArray.numValues();
    for (int i = 0; i < numSecurities; ++i) {
        Element securityData = securityDataArray.getValueAsElement(i);
        std::cout << securityData.getElementAsString(SECURITY)
            << std::endl;
        const Element fieldData = securityData.getElement(FIELD_DATA);
        for (size_t j = 0; j < fieldData.numElements(); ++j) {
            Element field = fieldData.getElement(j);
            if (!field.isValid()) {
                std::cout << field.name() << " is NULL." << std::endl;
            }
            else {
                std::cout << field.name() << " = "
                    << field.getValueAsString() << std::endl;
            }
        }

        Element fieldExceptionArray =
            securityData.getElement(FIELD_EXCEPTIONS);
        for (size_t k = 0; k < fieldExceptionArray.numValues(); ++k) {
            Element fieldException =
                fieldExceptionArray.getValueAsElement(k);
            std::cout <<
                fieldException.getElement(ERROR_INFO).getElementAsString(
                "category")
                << ": " << fieldException.getElementAsString(FIELD_ID);
        }
        std::cout << std::endl;
    }

person Olorun    schedule 04.02.2015    source источник
comment
Как насчет того, чтобы обратиться в службу поддержки клиентов Bloomberg? Вы уже платите им (прямо или косвенно) за ответы на подобные вопросы.   -  person John Zwinck    schedule 04.02.2015
comment
Я нахожусь в стране, где службе поддержки клиентов Bloomberg требуется несколько дней, чтобы ответить, и я надеялся на что-то более быстрое... но я думаю, что это имеет смысл - я опубликую их решение здесь, когда они ответят.   -  person Olorun    schedule 04.02.2015
comment
Если у вас есть доступ к терминалу Bloomberg, вы можете воспользоваться помощью онлайн-чата. Если нет, вы можете позвонить в службу поддержки, набрав любой из номеров на этой странице в любое время дня и ночи: bloomberg.com/professional/systems-support/customer-support   -  person John Zwinck    schedule 04.02.2015
comment
Ну, я использую терминал Bloomberg моего университета, поэтому я не могу легко получить к нему доступ (придется идти в библиотеку за 20 минут), и я не уверен в поддержке по телефону в этом случае.   -  person Olorun    schedule 04.02.2015
comment
Мой опыт показывает, что сотрудники службы поддержки по телефону мотивированы помочь любому законному пользователю их системы и могут направить вас к внутренним экспертам, если они не знают ответа.   -  person John Zwinck    schedule 04.02.2015
comment
Смогу ли я позвонить в службу поддержки по телефону, даже если терминал есть только в моем университете? У меня нет доступа к какой-либо конкретной информации для входа в терминал, так как они вводятся сотрудниками библиотеки университета.   -  person Olorun    schedule 04.02.2015
comment
Я не знаю, почему бы вам не спросить их?   -  person John Zwinck    schedule 04.02.2015


Ответы (2)


Проблема в коде обработки событий, который вы не показываете. Вы, вероятно, неправильно анализируете его.

Выполняя ваш запрос, я получаю следующий результат:

MSFT US 01/20/17 C23
MSFT US 01/20/17 C25
MSFT US 01/20/17 C30
MSFT US 01/20/17 C33
MSFT US 01/20/17 C35
MSFT US 01/20/17 C38
MSFT US 01/20/17 C40
MSFT US 01/20/17 C43
MSFT US 01/20/17 C45
MSFT US 01/20/17 C47
MSFT US 01/20/17 C50
MSFT US 01/20/17 C52.5
MSFT US 01/20/17 C55
MSFT US 01/20/17 C57.5
MSFT US 01/20/17 C60
MSFT US 01/20/17 C65
MSFT US 01/20/17 C70

Примечание. Я использую Java API, но по сути это то же самое.


ОБНОВИТЬ:

ваш код неправильно анализирует элемент массива данных поля: возвращаемые данные содержат массив последовательностей, поэтому вам нужно проанализировать его в два этапа. Вместо field.getValueAsString() у вас должен быть такой код (он на Java и не тестировался):

//...
for (int i = 0; i < field.numValues(); i++) {
  Element sequence = field.getValueAsElement(i);
  ElementIterator it = sequence.elementIterator();
  while (it.hasNext()) {
    Element e = it.next();
    System.out.println(e.getValueAsString());
  }

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

Для получения более подробной информации см. руководство разработчика. , в частности А.2.3.

person assylias    schedule 04.02.2015
comment
Обновил свой пост, обратите внимание, что я также обновил скриншот (в моей предыдущей программе была небольшая опечатка, поэтому API Bloomberg вернул эту ошибку). - person Olorun; 04.02.2015
comment
@Olorun, посмотри мое обновление. Я не уверен в вашем втором вопросе, вы можете задать его Bloomberg. Что касается вашего третьего вопроса, ваш подход звучит правильно. - person assylias; 04.02.2015
comment
В моем скрипте C++ ElementIterator не определен в API - я что-то делаю не так или где вы его определяете? - person Olorun; 04.02.2015
comment
@Olorun, вы правы, это API Java, а не API C++. В документах они показывают эквивалент: const char* city = address.getElementAsString("city"); - в моем код, вероятно, будет const char* ticker = sequence.getElementAsString("Ticker");. - person assylias; 04.02.2015

Как видно из другого ответа, проблема заключается в обработке событий, поэтому я переписал эту часть, используя несколько примеров из Bloomberg API. эмулятор.

session.sendRequest(request, cid);
bool continueToLoop = true;
while (continueToLoop)
{
    Event evt = session.nextEvent();
    switch (evt.eventType())
    {
        case Event::RESPONSE:
            continueToLoop = false; //fall through
        case Event::PARTIAL_RESPONSE:
            ProcessReferenceDataEvent(evt);
        break;
     }
}

void ProcessReferenceDataEvent(Event evt)
{
    const string level1 = "";
    const string level2 = "\t";
    const string level3 = "\t\t";
    const string level4 = "\t\t\t";

    std::cout << endl << endl;
    std::cout << level1 << "EventType = " << evt.eventType();

    MessageIterator iter(evt);
    while (iter.next())
    {
        Message msg = iter.message();

        std::cout << endl << endl;
        std::cout << level1 << "correlationID = " << msg.correlationId().asInteger() << endl;
        std::cout << level1 << "messageType = " << msg.messageType().string() << endl;
        std::cout << endl << endl;
        Element SecurityDataArray = msg.getElement(SECURITY_DATA);
        int numSecurities = SecurityDataArray.numValues();
        for (int valueIndex = 0; valueIndex < numSecurities; valueIndex++)
        {
            Element SecurityData = SecurityDataArray.getValueAsElement(valueIndex);

            string Security = SecurityData.getElementAsString(SECURITY);
            std::cout << level2 << Security << endl;

            bool hasFieldErrors = SecurityData.hasElement("fieldExceptions", true);
            if (hasFieldErrors)
            {
                Element FieldErrors = SecurityData.getElement(FIELD_EXCEPTIONS);
                for (size_t errorIndex = 0; errorIndex < FieldErrors.numValues(); errorIndex++)
                {
                    Element fieldError = FieldErrors.getValueAsElement(errorIndex);
                    string fieldId = fieldError.getElementAsString(FIELD_ID);

                    Element errorInfo = fieldError.getElement(ERROR_INFO);
                    string source = errorInfo.getElementAsString("source");
                    int code = errorInfo.getElementAsInt32("code");
                    string category = errorInfo.getElementAsString("category");
                    string strMessage = errorInfo.getElementAsString("message");
                    string subCategory = errorInfo.getElementAsString("subcategory");

                    cerr << level3 << "field error:" << endl;
                    cerr << level4 << "fieldId = " << fieldId << endl;
                    cerr << level4 << "source = " << source << endl;
                    cerr << level4 << "code = " << code << endl;
                    cerr << level4 << "category = " << category << endl;
                    cerr << level4 << "errorMessage = " << strMessage << endl;
                    cerr << level4 << "subCategory = " << subCategory << endl;
                }
            }

            bool isSecurityError = SecurityData.hasElement("securityError", true);
            if (isSecurityError)
            {
                Element secError = SecurityData.getElement("securityError");
                string source = secError.getElementAsString("source");
                int code = secError.getElementAsInt32("code");
                string category = secError.getElementAsString("category");
                string errorMessage = secError.getElementAsString("message");
                string subCategory = secError.getElementAsString("subcategory");

                cerr << level3 << "security error:" << endl;
                cerr << level4 << "source = " << source << endl;
                cerr << level4 << "code = " << code << endl;
                cerr << level4 << "category = " << category << endl;
                cerr << level4 << "errorMessage = " << errorMessage << endl;
                cerr << level4 << "subCategory = " << subCategory << endl;
            }
            else
            {
                Element FieldData = SecurityData.getElement(FIELD_DATA);


                double pxLast = FieldData.getElementAsFloat64("PX_LAST");
                double bid = FieldData.getElementAsFloat64("BID");
                double ask = FieldData.getElementAsFloat64("ASK");
                string ticker = FieldData.getElementAsString("TICKER");

                std::cout << level3 << "fields: " << endl;
                std::cout << level4 << "PX_LAST = " << pxLast << endl;
                std::cout << level4 << "BID = " << bid << endl;
                std::cout << level4 << "ASK = " << ask << endl;
                std::cout << level4 << "TICKER = " << ticker << endl;

                bool excludeNullElements = true;
                if (FieldData.hasElement("CHAIN_TICKERS", excludeNullElements))
                {
                    Element chainTickers = FieldData.getElement("CHAIN_TICKERS");
                    for (size_t chainTickerValueIndex = 0; chainTickerValueIndex < chainTickers.numValues(); chainTickerValueIndex++)
                    {
                        Element chainTicker = chainTickers.getValueAsElement(chainTickerValueIndex);
                        string strChainTicker = chainTicker.getElementAsString("Ticker");

                        std::cout << level4 << "CHAIN_TICKER = " << strChainTicker << endl;
                    }
                }
                else
                {
                    std::cout << level4 << "NO CHAIN_TICKER information" << endl;
                }
            }
        }
    }
}

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

override2.setElement("fieldId", "CHAIN_POINTS_OVRD");
override2.setElement("value", 50000);

Для третьего вопроса можно загрузить тикеры цепочки для всех сроков погашения, установив переопределение «CHAIN_EXP_DT_OVRD» на «ВСЕ» (эта часть в настоящее время не проверена):

    Element override3 = overrides.appendElement();
    override3.setElement("fieldId", "CHAIN_EXP_DT_OVRD");
    override3.setElement("value", 'ALL');
person Olorun    schedule 04.02.2015