Wednesday, February 11, 2009

Proof Of Concept 8 of 8 : Yeah!

If you keep at it long enough, something's bound to work. I had success today with requesting market quote. Building on my prior experience (ignoring the fake 'error' messages), code was added to instantiate Contract object and request quote for SPY ETF.


package ibjava;

import com.ib.client.*;


public class StockBot implements EWrapper {

public StockBot() throws InterruptedException {
int i = 0;
EClientSocket m_client = new EClientSocket(this);
m_client.eConnect("127.0.0.1",7496, 0);
System.out.println("Connected.");

// preparing to quote SPY
Contract contract;
contract = new Contract();

contract.m_symbol = "SPY";
contract.m_secType = "STK";
contract.m_expiry = "";
contract.m_right = "";
contract.m_multiplier = "";
contract.m_exchange = "SMART";
contract.m_primaryExch = "";
contract.m_currency = "USD";
contract.m_localSymbol = "";
// submit quote for SPY. results will come in through
// tickPrice() and tickSize() methods
m_client.reqMktData(1,contract,null , true);

Thread.sleep(4000); // sleep for 4 seconds

m_client.eDisconnect();
System.out.println("Disconnected.");
}

public static void main(String[] args) throws InterruptedException {

System.out.println("Hello");
StockBot myBot= new StockBot();
}

// ---------------------------------------------------
// -- methods from EWrapper -- must be declared
// ---------------------------------------------------
public void tickPrice( int tickerId, int field, double price, int canAutoExecute){
System.out.println("Price Update: Id: "+tickerId+" Type: "+field+" Price: "+price);
}
public void tickSize( int tickerId, int field, int size){
System.out.println("Volume Update: Id: "+tickerId+" Type: "+field+" Size: "+size);
}
public void tickOptionComputation( int tickerId, int field, double impliedVol, double delta, double modelPrice, double pvDividend){}
public void tickGeneric(int tickerId, int tickType, double value){}
public void tickString(int tickerId, int tickType, String value){}
public void tickEFP(int tickerId, int tickType, double basisPoints, String formattedBasisPoints, double impliedFuture, int holdDays, String futureExpiry, double dividendImpact, double dividendsToExpiry){}
public void orderStatus( int orderId, String status, int filled, int remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, String whyHeld){}
public void openOrder( int orderId, Contract contract, Order order, OrderState orderState){}

public void updateAccountValue(String key, String value, String currency, String accountName){}
public void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue, double averageCost, double unrealizedPNL, double realizedPNL, String accountName){}
public void updateAccountTime(String timeStamp){}
public void nextValidId( int orderId){}
public void contractDetails(int reqId, ContractDetails contractDetails){}
public void bondContractDetails(int reqId, ContractDetails contractDetails){}
public void contractDetailsEnd(int reqId){}
public void execDetails( int orderId, Contract contract, Execution execution){}
public void updateMktDepth( int tickerId, int position, int operation, int side, double price, int size){}
public void updateMktDepthL2( int tickerId, int position, String marketMaker, int operation, int side, double price, int size){}
public void updateNewsBulletin( int msgId, int msgType, String message, String origExchange){}
public void managedAccounts( String accountsList){}
public void receiveFA(int faDataType, String xml){}
public void historicalData(int reqId, String date, double open, double high, double low, double close, int volume, int count, double WAP, boolean hasGaps){}
public void scannerParameters(String xml){}
public void scannerData(int reqId, int rank, ContractDetails contractDetails, String distance, String benchmark, String projection, String legsStr){}
public void scannerDataEnd(int reqId){}
public void realtimeBar(int reqId, long time, double open, double high, double low, double close, long volume, double wap, int count){}
public void currentTime(long time){}
public void fundamentalData(int reqId, String data){}

// ---------------------------------------------------
// -- methods from AnyWrapper -- must be declared
// ---------------------------------------------------

public void connectionClosed() {
System.out.println(" [API.connectionClosed] Closed connection with TWS");
}
public void error(String str) {
System.out.println(" [API.msg1] " + str);
}

public void error(int one, int two, String str) {
System.out.println(" [API.msg2] " + str + " {" + one + ", " + two + "}");
}

public void error(Exception e) {
System.out.println(" [API.msg3] " + e.getMessage());
}

}


Running the code above with 'Incoming Connection' dialog ON and OFF works the same way. The output is:


Hello
Server Version:43
TWS Time at connection:20090211 22:58:59 EST
Connected.
[API.msg2] Market data farm connection is OK:usopt {-1, 2104}
[API.msg2] Market data farm connection is OK:usfarm {-1, 2104}
Price Update: Id: 1 Type: 1 Price: 83.6
Volume Update: Id: 1 Type: 0 Size: 5
Price Update: Id: 1 Type: 2 Price: 83.62
Volume Update: Id: 1 Type: 3 Size: 9
Price Update: Id: 1 Type: 4 Price: 83.61
Volume Update: Id: 1 Type: 5 Size: 1
Volume Update: Id: 1 Type: 8 Size: 3213164
Price Update: Id: 1 Type: 6 Price: 84.05
Price Update: Id: 1 Type: 7 Price: 82.4
Price Update: Id: 1 Type: 9 Price: 83.11
Price Update: Id: 1 Type: 14 Price: 83.45
Disconnected.
BUILD SUCCESSFUL (total time: 13 seconds)



So I have proven that Java code works. What was missing from JRuby code were the methods from AnyWrapper. Adding them in will be the next step.

No comments: