自定义Interactive Brokers的reqIds()和reqMktData()Java方法

时间:2015-04-23 19:44:27

标签: java interactive-brokers

我正在尝试在Interactive Brokers的Java API中编写自定义代码。有许多方法通过eClientSocket对象发送到TWS。两个例子是reqIds()和reqMktData()。这些都是void方法,因此它们不会返回任何内容。相反,它们“激活”在调用它们的类中编写的方法(在本例中为SampleFrame)。这些方法也是无效的,因为它们不返回任何数据。相反,代码在这些方法中编写(nextValidId()和tickPrice())以处理从TWS(交易者工作站)发回的数据。

我在创建nextValidId()和tickPrice()方法的修改版本时遇到问题,因为reqIds()和reqMktData()实际上并没有在自己的代码中指定这些方法名称。因此,我无法编写一个名为“tickPriceBlackBox()”的方法,该方法在reqMktData()中调用,或者从reqMktData()调用reqMktDataBlackBox()中复制。同样,reqMktData()中没有特定的代码可以修改为调用特定的tickPriceBlackBox()方法。就好像TWS本身的代码是硬连线来调用tickPrice()方法一样,这使我无法创建一个返回价格信息的新方法。

任何人都可以解释发生了什么,或者如何创建解决方案?

以下是一些代码:


void onReqMktData() {//requests market data from TWS / Interactive Brokers
        // run m_orderDlg
        m_orderDlg.init("Mkt Data Options", true, "Market Data Options", m_mktDataOptions);
        m_orderDlg.show();
if( !m_orderDlg.m_rc ) { return; } m_mktDataOptions = m_orderDlg.getOptions();

    // req mkt data
    m_client.reqMktData( m_orderDlg.m_id, m_orderDlg.m_contract,
            m_orderDlg.m_genericTicks, m_orderDlg.m_snapshotMktData, m_mktDataOptions);
}

//Here is the reqMktData() method public synchronized void reqMktData(int tickerId, Contract contract, String genericTickList, boolean snapshot, List mktDataOptions) { if (!m_connected) { error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, ""); return; }

    if (m_serverVersion < MIN_SERVER_VER_SNAPSHOT_MKT_DATA && snapshot) {
        error(tickerId, EClientErrors.UPDATE_TWS,
                "  It does not support snapshot market data requests.");
        return;
    }

    if (m_serverVersion < MIN_SERVER_VER_UNDER_COMP) {
        if (contract.m_underComp != null) {
            error(tickerId, EClientErrors.UPDATE_TWS,
                "  It does not support delta-neutral orders.");
            return;
        }
    }

    if (m_serverVersion < MIN_SERVER_VER_REQ_MKT_DATA_CONID) {
        if (contract.m_conId > 0) {
            error(tickerId, EClientErrors.UPDATE_TWS,
                "  It does not support conId parameter.");
            return;
        }
    }

    if (m_serverVersion < MIN_SERVER_VER_TRADING_CLASS) {
        if (!IsEmpty(contract.m_tradingClass)) {
            error(tickerId, EClientErrors.UPDATE_TWS,
                "  It does not support tradingClass parameter in reqMarketData.");
            return;
        }
    }

    final int VERSION = 11;

    try {
        // send req mkt data msg
        send(REQ_MKT_DATA);
        send(VERSION);
        send(tickerId);

        // send contract fields
        if (m_serverVersion >= MIN_SERVER_VER_REQ_MKT_DATA_CONID) {
            send(contract.m_conId);
        }
        send(contract.m_symbol);
        send(contract.m_secType);
        send(contract.m_expiry);
        send(contract.m_strike);
        send(contract.m_right);
        if (m_serverVersion >= 15) {
            send(contract.m_multiplier);
        }
        send(contract.m_exchange);
        if (m_serverVersion >= 14) {
            send(contract.m_primaryExch);
        }
        send(contract.m_currency);
        if(m_serverVersion >= 2) {
            send( contract.m_localSymbol);
        }
        if(m_serverVersion >= MIN_SERVER_VER_TRADING_CLASS) {
            send( contract.m_tradingClass);
        }
        if(m_serverVersion >= 8 && BAG_SEC_TYPE.equalsIgnoreCase(contract.m_secType)) {
            if ( contract.m_comboLegs == null ) {
                send( 0);
            }
            else {
                send( contract.m_comboLegs.size());

                ComboLeg comboLeg;
                for (int i=0; i < contract.m_comboLegs.size(); i ++) {
                    comboLeg = contract.m_comboLegs.get(i);
                    send( comboLeg.m_conId);
                    send( comboLeg.m_ratio);
                    send( comboLeg.m_action);
                    send( comboLeg.m_exchange);
                }
            }
        }

        if (m_serverVersion >= MIN_SERVER_VER_UNDER_COMP) {
           if (contract.m_underComp != null) {
               UnderComp underComp = contract.m_underComp;
               send( true);
               send( underComp.m_conId);
               send( underComp.m_delta);
               send( underComp.m_price);
           }
           else {
               send( false);
           }
        }

        if (m_serverVersion >= 31) {
            /*
             * Note: Even though SHORTABLE tick type supported only
             *       starting server version 33 it would be relatively
             *       expensive to expose this restriction here.
             *
             *       Therefore we are relying on TWS doing validation.
             */
            send( genericTickList);
        }
        if (m_serverVersion >= MIN_SERVER_VER_SNAPSHOT_MKT_DATA) {
            send (snapshot);
        }

        // send mktDataOptions parameter
        if(m_serverVersion >= MIN_SERVER_VER_LINKING) {
            StringBuilder mktDataOptionsStr = new StringBuilder();
            int mktDataOptionsCount = mktDataOptions == null ? 0 : mktDataOptions.size();
            if( mktDataOptionsCount > 0) {
                for( int i = 0; i < mktDataOptionsCount; ++i) {
                    TagValue tagValue = (TagValue)mktDataOptions.get(i);
                    mktDataOptionsStr.append( tagValue.m_tag);
                    mktDataOptionsStr.append( "=");
                    mktDataOptionsStr.append( tagValue.m_value);
                    mktDataOptionsStr.append( ";");
                }
            }
            send( mktDataOptionsStr.toString());
        }

    }
    catch( Exception e) {
        error( tickerId, EClientErrors.FAIL_SEND_REQMKT, "" + e);
        close();
    }
}

//The key piece of this code, REQ_MKT_DATA, leads to a final int variable within the EClientSocket.java object, equal to 1. tickPrice() is not mentioned anywhere.

//This method provides stock price, but doesn't return a value. You have to put executable code within this one method. I cannot duplicate and change the name of this method (tickprice();) because none of my accessible code calls it, to my knowledge. It feels as if TWS is calling tickPrice from its end.

public void tickPrice( int tickerId, int field, double price, int canAutoExecute) { // received price tick String msg = EWrapperMsgGenerator.tickPrice( tickerId, field, price, canAutoExecute); m_tickers.add( msg ); }

2 个答案:

答案 0 :(得分:2)

从EReader调用tickPrice方法,该方法在EClientSocket中创建,后者知道EWrapper实现。

基本上你调用套接字reqMktData方法,它会将它发送给TWS。 EReader会将套接字上的响应看作tickPrice消息,并将其发送给Wrapper实现。

如果您想自己处理它,那么您可以在tickPrice方法中执行此操作。它可以像将数据传递给您定义的方法一样简单。

public void tickPrice( int tickerId, int field, double price, int canAutoExecute) {
    handleTick(tickerId,field,price);
}

然后编写自己的handleTick方法

答案 1 :(得分:0)

最后可能已经找到了答案。我是Java新手......这些似乎是回调方法。回调方法从其他来源接收信息。因为该方法是OOP中对象的一部分,所以返回的信息(在这种情况下为股票信息)将返回到回调方法中。回复方法时,将执行回调方法中包含的任何其他代码。

如果这些方法没有在我的机器上的代码中专门执行,我仍然不清楚这些方法是如何被激活的。 Interactive Broker是否知道在Java程序中将信息反馈给此方法?似乎合乎逻辑。