Customize Interactive Brokers' reqIds() and reqMktData() Java methods

旧巷老猫 提交于 2020-01-14 06:17:26

问题


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


回答1:


The tickPrice method is called from EReader which gets created in EClientSocket which knows the EWrapper implementation.

Basically you call the socket reqMktData method and it will send it to TWS. EReader will see the response on the socket as a tickPrice message and will send it to the Wrapper implementation.

If you want to handle it yourself then you do it inside the tickPrice method. It could be just as simple as passing the data to a method you define.

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

And then write your own handleTick method




回答2:


Finally may have found an answer. I'm new to Java...these appear to be callback methods. A callback method receives information from some other source. Because the method is part of an object in OOP, the returned information (stock info in this case) is returned into the callback method. Any other code that is contained within the callback method is executed when the method is replied to.

I am still not clear on how these methods are activated if they haven't been specifically executed in the code on my machine. Does Interactive Broker's know to feed information back to this method inside my Java program? Seems logical.



来源:https://stackoverflow.com/questions/29832911/customize-interactive-brokers-reqids-and-reqmktdata-java-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!