无法在 IB API C++ 中获取历史数据

Cant get historical data in IB API C++

我正在尝试获取外汇合约的历史数据(不需要任何订阅)并在

获取std::bad_alloc

m_pClient->reqHistoricalData(4001, contract, queryTime, "1 M", "1 day", "TRADES", 1, 1, false, TagValueListSPtr());

完整代码如下:

#include "stdafx.h"

#include <Contract.h>
#include <Order.h>
#include <OrderState.h>
#include <Execution.h>
#include <CommissionReport.h>
#include <ScannerSubscription.h>
#include <executioncondition.h>
#include <PriceCondition.h>
#include <MarginCondition.h>
#include <PercentChangeCondition.h>
#include <TimeCondition.h>
#include <VolumeCondition.h>
#include <CommonDefs.h>
#include <EWrapper.h>
#include <EReaderOSSignal.h>
#include <EReader.h>
#include <EClientSocket.h>
#include <EClient.h>

#include <stdio.h>
#include <chrono>
#include <iostream>
#include <thread>
#include <ctime>
#include <fstream>
#include <cstdint>

using namespace std;
class TestSample : public EWrapper
{
public:
    TestSample();
    ~TestSample();
    void historicalDataRequests(Contract &contract);
    bool connect(const char * host, int port, int clientId = 0);
    void tickPrice(TickerId tickerId, TickType field, double price, const TickAttrib& attrib) {}
    void tickSize(TickerId tickerId, TickType field, int size) {}
    void tickOptionComputation(TickerId tickerId, TickType tickType, double impliedVol, double delta,
        double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) {}
    void tickGeneric(TickerId tickerId, TickType tickType, double value) {}
    void tickString(TickerId tickerId, TickType tickType, const std::string& value) {}
    void tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const std::string& formattedBasisPoints,
        double totalDividends, int holdDays, const std::string& futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate) {}
    void orderStatus(OrderId orderId, const std::string& status, double filled,
        double remaining, double avgFillPrice, int permId, int parentId,
        double lastFillPrice, int clientId, const std::string& whyHeld, double mktCapPrice) {}
    void openOrder(OrderId orderId, const Contract&, const Order&, const OrderState&) {}
    void openOrderEnd() {}
    void winError(const std::string& str, int lastError) {}
    void connectionClosed() {}
    void updateAccountValue(const std::string& key, const std::string& val,
        const std::string& currency, const std::string& accountName) {}
    void updatePortfolio(const Contract& contract, double position,
        double marketPrice, double marketValue, double averageCost,
        double unrealizedPNL, double realizedPNL, const std::string& accountName) {}
    void updateAccountTime(const std::string& timeStamp) {}
    void accountDownloadEnd(const std::string& accountName) {}
    void nextValidId(OrderId orderId) {}
    void contractDetails(int reqId, const ContractDetails& contractDetails) {}
    void bondContractDetails(int reqId, const ContractDetails& contractDetails) {}
    void contractDetailsEnd(int reqId) {}
    void execDetails(int reqId, const Contract& contract, const Execution& execution) {}
    void execDetailsEnd(int reqId) {}
    void error(int id, int errorCode, const std::string& errorString) {}
    void updateMktDepth(TickerId id, int position, int operation, int side,
        double price, int size) {}
    void updateMktDepthL2(TickerId id, int position, const std::string& marketMaker, int operation,
        int side, double price, int size, bool isSmartDepth) {}
    void updateNewsBulletin(int msgId, int msgType, const std::string& newsMessage, const std::string& originExch) {}
    void managedAccounts(const std::string& accountsList) {}
    void receiveFA(faDataType pFaDataType, const std::string& cxml) {}
    void historicalData(TickerId reqId, const Bar& bar);
    void historicalDataEnd(int reqId, const std::string& startDateStr, const std::string& endDateStr) {}
    void scannerParameters(const std::string& xml) {}
    void scannerData(int reqId, int rank, const ContractDetails& contractDetails,
        const std::string& distance, const std::string& benchmark, const std::string& projection,
        const std::string& legsStr) {}
    void scannerDataEnd(int reqId) {}
    void realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
        long volume, double wap, int count) {}
    void currentTime(long time) {}
    void fundamentalData(TickerId reqId, const std::string& data) {}
    void deltaNeutralValidation(int reqId, const DeltaNeutralContract& deltaNeutralContract) {}
    void tickSnapshotEnd(int reqId) {}
    void marketDataType(TickerId reqId, int marketDataType) {}
    void commissionReport(const CommissionReport& commissionReport) {}
    void position(const std::string& account, const Contract& contract, double position, double avgCost) {}
    void positionEnd() {}
    void accountSummary(int reqId, const std::string& account, const std::string& tag, const std::string& value, const std::string& curency) {}
    void accountSummaryEnd(int reqId) {}
    void verifyMessageAPI(const std::string& apiData) {}
    void verifyCompleted(bool isSuccessful, const std::string& errorText) {}
    void displayGroupList(int reqId, const std::string& groups) {}
    void displayGroupUpdated(int reqId, const std::string& contractInfo) {}
    void verifyAndAuthMessageAPI(const std::string& apiData, const std::string& xyzChallange) {}
    void verifyAndAuthCompleted(bool isSuccessful, const std::string& errorText) {}
    void connectAck() {}
    void positionMulti(int reqId, const std::string& account, const std::string& modelCode, const Contract& contract, double pos, double avgCost) {}
    void positionMultiEnd(int reqId) {}
    void accountUpdateMulti(int reqId, const std::string& account, const std::string& modelCode, const std::string& key, const std::string& value, const std::string& currency) {}
    void accountUpdateMultiEnd(int reqId) {}
    void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass,
        const std::string& multiplier, const std::set<std::string>& expirations, const std::set<double>& strikes) {}
    void securityDefinitionOptionalParameterEnd(int reqId) {}
    void softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers) {}
    void familyCodes(const std::vector<FamilyCode> &familyCodes) {}
    void symbolSamples(int reqId, const std::vector<ContractDescription> &contractDescriptions) {}
    void mktDepthExchanges(const std::vector<DepthMktDataDescription> &depthMktDataDescriptions) {}
    void tickNews(int tickerId, time_t timeStamp, const std::string& providerCode, const std::string& articleId, const std::string& headline, const std::string& extraData) {}
    void smartComponents(int reqId, const SmartComponentsMap& theMap) {}
    void tickReqParams(int tickerId, double minTick, const std::string& bboExchange, int snapshotPermissions) {}
    void newsProviders(const std::vector<NewsProvider> &newsProviders) {}
    void newsArticle(int requestId, int articleType, const std::string& articleText) {}
    void historicalNews(int requestId, const std::string& time, const std::string& providerCode, const std::string& articleId, const std::string& headline) {}
    void historicalNewsEnd(int requestId, bool hasMore) {}
    void headTimestamp(int reqId, const std::string& headTimestamp) {}
    void histogramData(int reqId, const HistogramDataVector& data) {}
    void historicalDataUpdate(TickerId reqId, const Bar& bar) {}
    void rerouteMktDataReq(int reqId, int conid, const std::string& exchange) {}
    void rerouteMktDepthReq(int reqId, int conid, const std::string& exchange) {}
    void marketRule(int marketRuleId, const std::vector<PriceIncrement> &priceIncrements) {}
    void pnl(int reqId, double dailyPnL, double unrealizedPnL, double realizedPnL) {}
    void pnlSingle(int reqId, int pos, double dailyPnL, double unrealizedPnL, double realizedPnL, double value) {}
    void historicalTicks(int reqId, const std::vector<HistoricalTick> &ticks, bool done) {}
    void historicalTicksBidAsk(int reqId, const std::vector<HistoricalTickBidAsk> &ticks, bool done) {}
    void historicalTicksLast(int reqId, const std::vector<HistoricalTickLast> &ticks, bool done) {}
    void tickByTickAllLast(int reqId, int tickType, time_t time, double price, int size, const TickAttribLast& tickAttribLast, const std::string& exchange, const std::string& specialConditions) {}
    void tickByTickBidAsk(int reqId, time_t time, double bidPrice, double askPrice, int bidSize, int askSize, const TickAttribBidAsk& tickAttribBidAsk) {}
    void tickByTickMidPoint(int reqId, time_t time, double midPoint) {}
    void orderBound(long long orderId, int apiClientId, int apiOrderId) {}
    void completedOrder(const Contract& contract, const Order& order, const OrderState& orderState) {}
    void tickOptionComputation(TickerId tickerId, TickType tickType, int tickAttrib, double impliedVol, double delta,
    double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) {}
    void replaceFAEnd(int reqId, const std::string& text) {}
    void completedOrdersEnd() {};
    //! [socket_declare]
    private:
    EReaderOSSignal m_osSignal;
    EClientSocket * const m_pClient;
    EReader *m_pReader;

};
TestSample::TestSample() :
    m_osSignal(2000)//2-seconds timeout
    , m_pClient(new EClientSocket(this, &m_osSignal))
{
}
TestSample::~TestSample()
{
    if (m_pReader)
        delete m_pReader;

    delete m_pClient;
}
Bar Return_Bar_Data(TickerId reqId, const Bar& bar)
{
    cout << bar.close << " " << bar.open << " " << endl;
    return bar;
}
void TestSample::historicalData(TickerId reqId, const Bar& bar) {
    printf("HistoricalData. ReqId: %ld - Date: %s, Open: %g, High: %g, Low: %g, Close: %g, Volume: %lld, Count: %d, WAP: %g\n", reqId, bar.time.c_str(), bar.open, bar.high, bar.low, bar.close, bar.volume, bar.count, bar.wap);
    //Return_Bar_Data(reqId, bar);
}

void TestSample::historicalDataRequests(Contract &contract)
{
    /*** Requesting historical data ***/
    //! [reqhistoricaldata]
    std::time_t rawtime;
    std::tm* timeinfo;
    char queryTime[80];

    std::time(&rawtime);
    timeinfo = std::localtime(&rawtime);
    std::strftime(queryTime, 80, "%Y%m%d %H:%M:%S", timeinfo);

    m_pClient->reqHistoricalData(4001, contract, queryTime, "1 M", "1 day", "TRADES", 1, 1, false, TagValueListSPtr());
    //m_pClient->reqMktData(1, contract, "1 min",false, false, TagValueListSPtr());
}

bool TestSample::connect(const char *host, int port, int clientId)
{
    // trying to connect
    printf("Connecting to %s:%d clientId:%d\n", !(host && *host) ? "127.0.0.1" : host, port, clientId);

    //! [connect]
    bool bRes = m_pClient->eConnect(host, port, clientId);
    //! [connect]

    if (bRes) {
        //printf("Connected to %s:%d clientId:%d\n", m_pClient->host().c_str(), m_pClient->port(), clientId);
        cout << "Connected!" << endl;
        //! [ereader]
        m_pReader = new EReader(m_pClient, &m_osSignal);
        m_pReader->start();
        //! [ereader]
    }
    else
        cout << "Cannot connect!" << endl;

    return bRes;
}

const unsigned MAX_ATTEMPTS = 50;
const unsigned SLEEP_TIME = 10;

int main()
{
    unsigned attempt = 0;
    printf("Start of C++ Socket Client Test %u\n", attempt);
    TestSample client;

    Contract contract;
    contract.symbol = "EUR";
    contract.secType = "CASH";
    contract.currency = "USD";
    contract.exchange = "IDEALPRO";

    for (;;) {
        ++attempt;
        std::cout << "Attemt No: " << attempt << " of " << MAX_ATTEMPTS;

        if (client.connect("", 7497, 271727))
            break;

        if (attempt >= MAX_ATTEMPTS) {
            break;
        }
        printf("Sleeping %u seconds before next attempt\n", SLEEP_TIME);
        std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME));
    }
    client.historicalDataRequests(contract);
    printf("End of C++ Socket Client Test\n");

    return 0;
}


经过一些实验,我弄清楚了如何连接和获取历史数据。这是整个代码。也许对某人有用。

#include "stdafx.h"

#include <Contract.h>
#include <Order.h>
#include <OrderState.h>
#include <Execution.h>
#include <CommissionReport.h>
#include <ScannerSubscription.h>
#include <executioncondition.h>
#include <PriceCondition.h>
#include <MarginCondition.h>
#include <PercentChangeCondition.h>
#include <TimeCondition.h>
#include <VolumeCondition.h>
#include <CommonDefs.h>
#include <EWrapper.h>
#include <EReaderOSSignal.h>
#include <EReader.h>
#include <EClientSocket.h>
#include <EClient.h>

#include <stdio.h>
#include <chrono>
#include <iostream>
#include <thread>
#include <ctime>
#include <fstream>
#include <cstdint>

using namespace std;

class MyEwrapper : public EWrapper
{
public:
    void tickPrice(TickerId tickerId, TickType field, double price, const TickAttrib& attrib) {}
    void tickSize(TickerId tickerId, TickType field, int size) {}
    void tickOptionComputation(TickerId tickerId, TickType tickType, int tickAttrib, double impliedVol, double delta,
        double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) {}
    void tickGeneric(TickerId tickerId, TickType tickType, double value) {}
    void tickString(TickerId tickerId, TickType tickType, const std::string& value) {}
    void tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const std::string& formattedBasisPoints,
        double totalDividends, int holdDays, const std::string& futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate) {}
    void orderStatus(OrderId orderId, const std::string& status, double filled,
        double remaining, double avgFillPrice, int permId, int parentId,
        double lastFillPrice, int clientId, const std::string& whyHeld, double mktCapPrice) {}
    void openOrder(OrderId orderId, const Contract&, const Order&, const OrderState&) {}
    void openOrderEnd() {}
    void winError(const std::string& str, int lastError) {}
    void connectionClosed() {}
    void updateAccountValue(const std::string& key, const std::string& val,
        const std::string& currency, const std::string& accountName) {}
    void updatePortfolio(const Contract& contract, double position,
        double marketPrice, double marketValue, double averageCost,
        double unrealizedPNL, double realizedPNL, const std::string& accountName) {}
    void updateAccountTime(const std::string& timeStamp) {}
    void accountDownloadEnd(const std::string& accountName) {}
    void nextValidId(OrderId orderId) {}
    void contractDetails(int reqId, const ContractDetails& contractDetails) {}
    void bondContractDetails(int reqId, const ContractDetails& contractDetails) {}
    void contractDetailsEnd(int reqId) {}
    void execDetails(int reqId, const Contract& contract, const Execution& execution) {}
    void execDetailsEnd(int reqId) {}
    void error(int id, int errorCode, const std::string& errorString) {}
    void updateMktDepth(TickerId id, int position, int operation, int side,
        double price, int size) {}
    void updateMktDepthL2(TickerId id, int position, const std::string& marketMaker, int operation,
        int side, double price, int size, bool isSmartDepth) {}
    void updateNewsBulletin(int msgId, int msgType, const std::string& newsMessage, const std::string& originExch) {}
    void managedAccounts(const std::string& accountsList) {}
    void receiveFA(faDataType pFaDataType, const std::string& cxml) {}
    void historicalData(TickerId reqId, const Bar& bar);
    void historicalDataEnd(int reqId, const std::string& startDateStr, const std::string& endDateStr) {}
    void scannerParameters(const std::string& xml) {}
    void scannerData(int reqId, int rank, const ContractDetails& contractDetails,
        const std::string& distance, const std::string& benchmark, const std::string& projection,
        const std::string& legsStr) {}
    void scannerDataEnd(int reqId) {}
    void realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
        long volume, double wap, int count) {}
    void currentTime(long time) {}
    void fundamentalData(TickerId reqId, const std::string& data) {}
    void deltaNeutralValidation(int reqId, const DeltaNeutralContract& deltaNeutralContract) {}
    void tickSnapshotEnd(int reqId) {}
    void marketDataType(TickerId reqId, int marketDataType) {}
    void commissionReport(const CommissionReport& commissionReport) {}
    void position(const std::string& account, const Contract& contract, double position, double avgCost) {}
    void positionEnd() {}
    void accountSummary(int reqId, const std::string& account, const std::string& tag, const std::string& value, const std::string& curency) {}
    void accountSummaryEnd(int reqId) {}
    void verifyMessageAPI(const std::string& apiData) {}
    void verifyCompleted(bool isSuccessful, const std::string& errorText) {}
    void displayGroupList(int reqId, const std::string& groups) {}
    void displayGroupUpdated(int reqId, const std::string& contractInfo) {}
    void verifyAndAuthMessageAPI(const std::string& apiData, const std::string& xyzChallange) {}
    void verifyAndAuthCompleted(bool isSuccessful, const std::string& errorText) {}
    void connectAck() {}
    void positionMulti(int reqId, const std::string& account, const std::string& modelCode, const Contract& contract, double pos, double avgCost) {}
    void positionMultiEnd(int reqId) {}
    void accountUpdateMulti(int reqId, const std::string& account, const std::string& modelCode, const std::string& key, const std::string& value, const std::string& currency) {}
    void accountUpdateMultiEnd(int reqId) {}
    void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass,
        const std::string& multiplier, const std::set<std::string>& expirations, const std::set<double>& strikes) {}
    void securityDefinitionOptionalParameterEnd(int reqId) {}
    void softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers) {}
    void familyCodes(const std::vector<FamilyCode> &familyCodes) {}
    void symbolSamples(int reqId, const std::vector<ContractDescription> &contractDescriptions) {}
    void mktDepthExchanges(const std::vector<DepthMktDataDescription> &depthMktDataDescriptions) {}
    void tickNews(int tickerId, time_t timeStamp, const std::string& providerCode, const std::string& articleId, const std::string& headline, const std::string& extraData) {}
    void smartComponents(int reqId, const SmartComponentsMap& theMap) {}
    void tickReqParams(int tickerId, double minTick, const std::string& bboExchange, int snapshotPermissions) {}
    void newsProviders(const std::vector<NewsProvider> &newsProviders) {}
    void newsArticle(int requestId, int articleType, const std::string& articleText) {}
    void historicalNews(int requestId, const std::string& time, const std::string& providerCode, const std::string& articleId, const std::string& headline) {}
    void historicalNewsEnd(int requestId, bool hasMore) {}
    void headTimestamp(int reqId, const std::string& headTimestamp) {}
    void histogramData(int reqId, const HistogramDataVector& data) {}
    void historicalDataUpdate(TickerId reqId, const Bar& bar) {}
    void rerouteMktDataReq(int reqId, int conid, const std::string& exchange) {}
    void rerouteMktDepthReq(int reqId, int conid, const std::string& exchange) {}
    void marketRule(int marketRuleId, const std::vector<PriceIncrement> &priceIncrements) {}
    void pnl(int reqId, double dailyPnL, double unrealizedPnL, double realizedPnL) {}
    void pnlSingle(int reqId, int pos, double dailyPnL, double unrealizedPnL, double realizedPnL, double value) {}
    void historicalTicks(int reqId, const std::vector<HistoricalTick> &ticks, bool done) {}
    void historicalTicksBidAsk(int reqId, const std::vector<HistoricalTickBidAsk> &ticks, bool done) {}
    void historicalTicksLast(int reqId, const std::vector<HistoricalTickLast> &ticks, bool done) {}
    void tickByTickAllLast(int reqId, int tickType, time_t time, double price, int size, const TickAttribLast& tickAttribLast, const std::string& exchange, const std::string& specialConditions) {}
    void tickByTickBidAsk(int reqId, time_t time, double bidPrice, double askPrice, int bidSize, int askSize, const TickAttribBidAsk& tickAttribBidAsk) {}
    void tickByTickMidPoint(int reqId, time_t time, double midPoint) {}
    void orderBound(long long orderId, int apiClientId, int apiOrderId) {}
    void completedOrder(const Contract& contract, const Order& order, const OrderState& orderState) {}
    void completedOrdersEnd() {}
    void replaceFAEnd(int reqId, const std::string& text) {}
};

void MyEwrapper::historicalData(TickerId reqId, const Bar& bar)
{
    cout << "Open: " << bar.open << " Close: " << bar.close << endl;
}

int main()
{
    MyEwrapper MV;
    EReaderOSSignal Esignal(2000);
    EClientSocket* EC = new EClientSocket(&MV, &Esignal);
    
    Contract contract;
    contract.symbol = "EUR";
    contract.secType = "CASH";
    contract.currency = "USD";
    contract.exchange = "IDEALPRO";

    if (EC->eConnect("127.0.0.1", 7497, 271726))
    {
        cout << "Connected" << endl;
        this_thread::sleep_for(chrono::seconds(3));
        EC->startApi();
        EReader *m_pReader = new EReader(EC, &Esignal);
        m_pReader->start();
        
        EC->reqHistoricalData(101, contract, "", "2 D", "1 hour", "MIDPOINT", 1, 1, false, TagValueListSPtr());
        this_thread::sleep_for(chrono::seconds(3)); // needs some time to get signal. without sllep it won't work
        Esignal.waitForSignal();
        m_pReader->processMsgs();
    
    }
    else
        cout << "Not Connected" << endl;
    
    system("pause");
    return 0;
}