0

Interactive Brokers の Java API 内でカスタマイズされたコードを作成しようとしています。eClientSocket オブジェクトを介して TWS に送信される一連のメソッドがあります。2 つの例は、reqIds() と reqMktData() です。これらはどちらも void メソッドであるため、何も返しません。代わりに、それらを呼び出すクラス (この場合は SampleFrame) 内に記述されたメソッドを「アクティブ化」します。これらのメソッドは、データを返さないという点でも無効です。代わりに、コードはこれらのメソッド (それぞれ nextValidId() および tickPrice()) 内に記述され、TWS (トレーダー ワークステーション) から送り返されたデータを処理します。

reqIds() および reqMktData() は実際にはこれらのメソッド名を独自のコードで指定していないため、nextValidId() および tickPrice() メソッドの修正バージョンを作成する際に問題が発生しています。したがって、reqMktData() 内から、または reqMktDataBlackBox() と呼ばれる reqMktData() のコピー内から呼び出される「tickPriceBlackBox()」というメソッドを作成することはできません。ここでも、特定の tickPriceBlackBox() メソッドを呼び出すように変更できる reqMktData() 内の特定のコードはありません。あたかも 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 ); }

4

2 に答える 2

0

最後に答えを見つけたかもしれません。私はJavaが初めてです...これらはコールバックメソッドのようです。コールバック メソッドは、他のソースから情報を受け取ります。このメソッドは OOP のオブジェクトの一部であるため、返された情報 (この場合は株式情報) はコールバック メソッドに返されます。コールバック メソッド内に含まれるその他のコードは、メソッドが応答されたときに実行されます。

私のマシンのコードで具体的に実行されていない場合、これらのメソッドがどのようにアクティブ化されるかはまだ明確ではありません。Interactive Broker は、Java プログラム内のこのメソッドに情報をフィードバックすることを知っていますか? 論理的に思えます。

于 2015-04-28T20:09:20.363 に答える