0

I am trying to write customized code within Interactive Brokers' Java API. There are a bunch of methods that get sent to TWS via the eClientSocket object. Two examples are reqIds() and reqMktData(). These are both void methods, so they do not return anything. Instead, they 'activate' methods written within the class that invokes them (in this case, SampleFrame). These methods are also void, in that they don't return any data. Instead, code is written within these methods (nextValidId() and tickPrice() respectively) to handle the data that is sent back from TWS (trader workstation).

I am having trouble creating a modified version of the nextValidId() and tickPrice() methods because reqIds() and reqMktData() don't actually specify these method names in their own code. I therefore cannot write a method called "tickPriceBlackBox()" which is called from within reqMktData(), or from within a copy of reqMktData() called reqMktDataBlackBox(). Again, there is no specific code within reqMktData() that can be modified to call a specific tickPriceBlackBox() method. It's as if code within TWS itself is hardwired to call the tickPrice() method, making it impossible for me to create a new method for returning price information.

Can anyone explain what is going on, or how to create a solution?

Here's some code:


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 ); }

4

2 回答 2

2

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

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

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

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

然后编写自己的handleTick方法

于 2015-05-11T22:24:00.740 回答
0

终于可能找到答案了。我是 Java 新手……这些似乎是回调方法。回调方法从其他来源接收信息。因为该方法是 OOP 中对象的一部分,所以返回的信息(本例中为股票信息)将返回到回调方法中。回调方法中包含的任何其他代码都会在该方法得到回复时执行。

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

于 2015-04-28T20:09:20.363 回答