Search code examples
javaapialgorithmic-tradinginteractive-brokers

java interactive brokers api historical data and tick


brian was able to get a working example of this on 9.72 and with slight modification it can probably run in 9.73. The question was simple: look at current price and compare to previous day session high and low. If price is above it prints out buy, and if below low of historical previous session it would print out sell. At first I struggled due to my weak knowledge of Java, but brian displayed in his answer selected as best, how to use the current and historical prices for comparison. Very rudimentary, but important.

This is the current code that is supposed to take current price and compare it to prior session and if above high give a buy print out and if below low give a sell print out. In the 9.72 API this code did nothing because it did not properly connect data types.

    package apidemo;

    import java.io.IOException;
    import java.util.Set;
    import ib.client.TickType;
    import ib.client.CommissionReport;
    import ib.client.Contract;
    import ib.client.ContractDetails;
    import ib.client.DeltaNeutralContract;
    import ib.client.EClientSocket;
    import ib.client.EJavaSignal;
    import ib.client.EReader;
    import ib.client.EWrapper;
    import ib.client.Execution;
    import ib.client.Order;
    import ib.client.OrderState;
    import ib.client.SoftDollarTier;
    import ib.client.TagValue;
    import java.util.Vector;
    import com.ib.client.*;
    import com.ib.contracts.StkContract;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Set;

  public class xxx implements EWrapper {
    EJavaSignal m_signal = new EJavaSignal();
    EClientSocket m_s = new EClientSocket(this, m_signal);
    // Keep track of the next ID
    private int nextOrderID = 0;
    // The IB API Client Socket object
    private EClientSocket client = null;
  private double high = Double.MAX_VALUE;
    private double low = -Double.MAX_VALUE;
    public static void main(String[] args) {
        new xxx().run();

    }






    private void run() {
        m_s.eConnect("localhost", 7497, 0);

        final EReader reader = new EReader(m_s, m_signal);

        reader.start();

        new Thread() {
            public void run() {
                while (m_s.isConnected()) {
                    m_signal.waitForSignal();
                    try {
                        javax.swing.SwingUtilities
                                .invokeAndWait(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            reader.processMsgs();
                                        } catch (IOException e) {
                                            error(e);
                                        }
                                    }
                                });
                    } catch (Exception e) {
                        error(e);
                    }
                }
            }
        }.start();
        Contract contract = new Contract ();
                 Order order = new Order();
                  m_s.reqMarketDataType(3);
                  //contract.m_localSymbol = "ESM7";

    }


    @Override public void nextValidId(int orderId) {
             System.out.println("id "+orderId);
        nextOrderID = orderId;
        Contract c = new Contract ();
          //contract.m_localSymbol = "ESM7";
        c.m_symbol = "EUR";
        c.m_exchange = "IDEALPRO";

        c.m_secType = "CASH";
        c.m_currency = "USD";
        m_s.reqHistoricalData(1, c, 
                LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE)+ " 16:00:00",
                "2 D", "1 day", "MIDPOINT", 1, 1, null);
        m_s.reqMktData(1, c, "", false, null);

    }
   public void historicalData(int reqId, String date, double open, double high, double low, double close, int volume, int count, double WAP, boolean hasGaps) {
      System.out.println("date xxx"+date);
        this.high = high;
        this.low = low;
        System.out.println(high);
         System.out.println(low);
          System.out.println("xxx");
        }
 public void tickPrice(int orderId, int field, double price,
            int canAutoExecute)
    {
        System.out.println(high);
         System.out.println(low);
         System.out.println("idx: "+orderId + " " + TickType.getField(field) + " pricex: "+price);
       if (field == TickType.LAST.index()){
            if (price > high) {
                System.out.println("buy");
            }
            if (price < low){
                System.out.println("sell");
            }
        }   
    }
        @Override public void connectionClosed() {
        }


    }

This code currently has out put like the following:

id 1836254
date xxx20170328
1.08727
1.079905
xxx
date xxx20170329
1.08267
1.073995
xxx
date xxxfinished-20170327  16:00:00-20170329  16:00:00
-1.0
-1.0
xxx
-1.0
-1.0
idx: 1 bidPrice pricex: 1.07658
-1.0
-1.0
idx: 1 askPrice pricex: 1.07659
-1.0
-1.0

Notice the high and low daily are showed for two sessions, that is truly amazing. But when trying to use those high and lows in tickprice it is not being remembered and returns -1.


Solution

  • I removed a bunch of stuff from your code and added the parts needed. After connecting wait for nextValidId to start requesting stuff. Get the history and set highs and lows. Get mktData and check the last price, buy/sell as needed.

    import com.ib.client.*;
    import com.ib.contracts.StkContract;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Set;
    
    public class Test implements EWrapper {
        EJavaSignal m_signal = new EJavaSignal();
        EClientSocket m_client = new EClientSocket(this, m_signal);
    
        private int nextOrderID = 0;
        private double high = Double.MAX_VALUE;
        private double low = -Double.MAX_VALUE;
    
        public static void main(String[] args) {
            new Test.run();
        }
    
        private void run() {
            m_client.eConnect("localhost", 7497, 123);
            final EReader reader = new EReader(m_client, m_signal);
            reader.start();
            new Thread() {
                @Override
                public void run() {
                    while (m_client.isConnected()) {
                        m_signal.waitForSignal();
                        try {
                            reader.processMsgs();
                        } catch (Exception e) {
                            System.out.println("Exception: " + e.getMessage());
                        }
                    }
                }
            }.start();
        }
    
        @Override
        public void nextValidId(int orderId) {
            System.out.println("id "+orderId);
            nextOrderID = orderId;
            Contract c = new StkContract("IBKR");
            m_client.reqHistoricalData(1, c, 
                    LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE)+ " 16:00:00",
                    "2 D", "1 day", "TRADES", 1, 1, null);
            m_client.reqMktData(1, c, "", false, null);
        }
    
        @Override
        public void error(int id, int errorCode, String errorMsg) {
            System.out.println(id + " " + errorCode + " " + errorMsg);
        }
    
        @Override
        public void historicalData(int reqId, String date, double open, double high, double low, double close, int volume, int count, double WAP, boolean hasGaps) {
            //if being run on the next calendar day, this works
            if (LocalDate.now().minusDays(1).format(DateTimeFormatter.BASIC_ISO_DATE).equals(date)){
                this.high = high;
                this.low = low;
                System.out.println(date + " h: " + high + " l: " +low);
            }
        }
    
        @Override
            public void tickPrice(int tickerId, int field, double price, int canAutoExecute) {
    
            System.out.println("id: "+tickerId + " " + TickType.getField(field) + " price: "+price);
            if (field == TickType.LAST.index()){
                if (price > high) {
                    System.out.println("buy");
                }
                if (price < low){
                    System.out.println("sell");
                }
            }
    
        }
     //impl rest of EWrapper
    }
    

    output

    id 130002
    -1 2104 Market data farm connection is OK:usfuture
    -1 2104 Market data farm connection is OK:cashfarm
    -1 2104 Market data farm connection is OK:cafarm
    -1 2104 Market data farm connection is OK:usfarm
    -1 2106 HMDS data farm connection is OK:ushmds
    date 20170328
    date 20170329
    date finished-20170327  16:00:00-20170329  16:00:00
    id: 1 bidPrice price: 34.74
    id: 1 askPrice price: 34.82
    id: 1 lastPrice price: 34.73
    buy
    id: 1 high price: 34.87
    id: 1 low price: 34.56