diff --git a/ib/.classpath b/ib/.classpath
new file mode 100644
index 00000000..df370c06
--- /dev/null
+++ b/ib/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/ib/.project b/ib/.project
new file mode 100644
index 00000000..440434d1
--- /dev/null
+++ b/ib/.project
@@ -0,0 +1,23 @@
+
+
+ ib
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.maven.ide.eclipse.maven2Nature
+
+
diff --git a/ib/.settings/org.eclipse.jdt.core.prefs b/ib/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..86260262
--- /dev/null
+++ b/ib/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/ib/.settings/org.maven.ide.eclipse.prefs b/ib/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 00000000..3c757a28
--- /dev/null
+++ b/ib/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,7 @@
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/ib/pom.xml b/ib/pom.xml
new file mode 100644
index 00000000..33d0be56
--- /dev/null
+++ b/ib/pom.xml
@@ -0,0 +1,25 @@
+
+ 4.0.0
+
+ com.uims.bst
+ ib
+ 0.0.1-SNAPSHOT
+ jar
+
+ ib
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
diff --git a/ib/src/main/java/TestJavaClient/AccountDlg.java b/ib/src/main/java/TestJavaClient/AccountDlg.java
new file mode 100644
index 00000000..290b57b1
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/AccountDlg.java
@@ -0,0 +1,372 @@
+/*
+ * AccountDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.AbstractTableModel;
+
+import com.ib.client.Contract;
+import com.ib.client.Util;
+
+public class AccountDlg extends JDialog {
+ private JTextField m_updateTime = new JTextField();
+ private JLabel m_timeLabel = new JLabel("Update time:");
+ private JButton m_close = new JButton( "Close");
+ private PortfolioTable m_portfolioModel = new PortfolioTable();
+ private AcctValueModel m_acctValueModel = new AcctValueModel();
+ private boolean m_rc;
+
+ private String m_accountName;
+ private boolean m_complete;
+
+ boolean rc() { return m_rc; }
+
+ public AccountDlg(JFrame parent) {
+ super(parent, true);
+
+ JScrollPane acctPane = new JScrollPane(new JTable(m_acctValueModel));
+ JScrollPane portPane = new JScrollPane(new JTable(m_portfolioModel));
+
+ acctPane.setBorder(BorderFactory.createTitledBorder( "Key, Value, Currency, and Account") );
+ portPane.setBorder(BorderFactory.createTitledBorder( "Portfolio Entries") );
+
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, acctPane, portPane);
+ splitPane.setOneTouchExpandable(true);
+ splitPane.setDividerLocation(240);
+
+ splitPane.setPreferredSize(new Dimension(600, 350));
+
+ JPanel timePanel = new JPanel();
+ timePanel.add(m_timeLabel);
+ timePanel.add(m_updateTime);
+ timePanel.add(m_close);
+
+ m_updateTime.setEditable(false);
+ m_updateTime.setHorizontalAlignment(JTextField.CENTER);
+ m_updateTime.setPreferredSize(new Dimension(80, 26));
+ m_close.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClose();
+ }
+ });
+
+ getContentPane().add( splitPane, BorderLayout.CENTER);
+ getContentPane().add( timePanel, BorderLayout.SOUTH);
+ setLocation(20, 20);
+ pack();
+ reset();
+ }
+
+ void updateAccountValue(String key, String value, String currency, String accountName) {
+ m_acctValueModel.updateAccountValue(key, value, currency, accountName);
+ }
+
+ void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue,
+ double averageCost, double unrealizedPNL, double realizedPNL, String accountName) {
+ m_portfolioModel.updatePortfolio(contract, position, marketPrice, marketValue,
+ averageCost, unrealizedPNL, realizedPNL, accountName);
+ }
+
+ void reset() {
+ m_acctValueModel.reset();
+ m_portfolioModel.reset();
+ m_updateTime.setText("");
+ }
+
+ void onClose() {
+ setVisible( false);
+ }
+
+ void updateAccountTime(String timeStamp) {
+ m_updateTime.setText(timeStamp);
+ }
+
+ void accountDownloadBegin(String accountName) {
+ m_accountName = accountName;
+ m_complete = false;
+
+ updateTitle();
+ }
+
+
+
+ void accountDownloadEnd(String accountName) {
+
+ if ( !Util.StringIsEmpty( m_accountName) &&
+ !m_accountName.equals( accountName)) {
+ return;
+ }
+
+ m_complete = true;
+ updateTitle();
+ }
+
+ private void updateTitle() {
+
+ String title = new String();
+
+ if (!Util.StringIsEmpty( m_accountName)) {
+ title += m_accountName;
+ }
+ if (m_complete) {
+ if (title.length() != 0) {
+ title += ' ';
+ }
+ title += "[complete]";
+ }
+
+ setTitle(title);
+ }
+}
+
+
+class PortfolioTable extends AbstractTableModel {
+ Vector m_allData = new Vector();
+
+ void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue,
+ double averageCost, double unrealizedPNL, double realizedPNL, String accountName) {
+ PortfolioTableRow newData =
+ new PortfolioTableRow(contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName);
+ int size = m_allData.size();
+ for ( int i = 0; i < size; i++ ) {
+ PortfolioTableRow test = (PortfolioTableRow)m_allData.get(i);
+ if ( test.m_contract.equals(newData.m_contract) ) {
+ if ( newData.m_position == 0 )
+ m_allData.remove(i);
+ else
+ m_allData.set(i, newData);
+
+ fireTableDataChanged();
+ return;
+ }
+ }
+
+ m_allData.add(newData);
+ fireTableDataChanged();
+ }
+
+ void reset() {
+ m_allData.clear();
+ }
+
+ public int getRowCount() {
+ return m_allData.size();
+ }
+
+ public int getColumnCount() {
+ return 13;
+ }
+
+ public Object getValueAt(int r, int c) {
+ return ((PortfolioTableRow) m_allData.get(r)).getValue(c);
+ }
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch(c) {
+ case 0:
+ return "Symbol";
+ case 1:
+ return "SecType";
+ case 2:
+ return "Expiry";
+ case 3:
+ return "Strike";
+ case 4:
+ return "Right";
+ case 5:
+ return "Multiplier";
+ case 6:
+ return "Exchange";
+ case 7:
+ return "Currency";
+ case 8:
+ return "Position";
+ case 9:
+ return "Market Price";
+ case 10:
+ return "Market Value";
+ case 11:
+ return "Average Cost";
+ case 12:
+ return "Unrealized P&L";
+ case 13:
+ return "Realized P&L";
+ case 14:
+ return "Account Name";
+ default:
+ return null;
+ }
+ }
+
+ class PortfolioTableRow {
+ Contract m_contract;
+ int m_position;
+ double m_marketPrice;
+ double m_marketValue;
+ double m_averageCost;
+ double m_unrealizedPNL;
+ double m_realizedPNL;
+ String m_accountName;
+
+ PortfolioTableRow( Contract contract, int position, double marketPrice,
+ double marketValue, double averageCost, double unrealizedPNL,
+ double realizedPNL, String accountName) {
+ m_contract = contract;
+ m_position = position;
+ m_marketPrice = marketPrice;
+ m_marketValue = marketValue;
+ m_averageCost = averageCost;
+ m_unrealizedPNL = unrealizedPNL;
+ m_realizedPNL = realizedPNL;
+ m_accountName = accountName;
+ }
+
+ Object getValue(int c) {
+ switch(c) {
+ case 0:
+ return m_contract.m_symbol;
+ case 1:
+ return m_contract.m_secType;
+ case 2:
+ return m_contract.m_expiry;
+ case 3:
+ return m_contract.m_expiry == null ? null : "" + m_contract.m_strike;
+ case 4:
+ return (m_contract.m_right != null && m_contract.m_right.equals("???")) ? null : m_contract.m_right;
+ case 5:
+ return m_contract.m_multiplier;
+ case 6:
+ return (m_contract.m_primaryExch != null ? m_contract.m_primaryExch : "");
+ case 7:
+ return m_contract.m_currency;
+ case 8:
+ return "" + m_position;
+ case 9:
+ return "" + m_marketPrice;
+ case 10:
+ return "" + m_marketValue;
+ case 11:
+ return "" + m_averageCost;
+ case 12:
+ return "" + m_unrealizedPNL;
+ case 13:
+ return "" + m_realizedPNL;
+ case 14:
+ return m_accountName;
+ default:
+ return null;
+ }
+ }
+ }
+}
+
+class AcctValueModel extends AbstractTableModel {
+ Vector m_allData = new Vector();
+
+ void updateAccountValue(String key, String val, String currency, String accountName) {
+ AccountTableRow newData = new AccountTableRow(key, val, currency, accountName);
+ int size = m_allData.size();
+ for ( int i = 0; i < size; i++ ) {
+ AccountTableRow test = (AccountTableRow)m_allData.get(i);
+ if (test.m_key != null &&
+ test.m_key.equals(newData.m_key) &&
+ test.m_currency != null &&
+ test.m_currency.equals(newData.m_currency)) {
+ test.m_value = newData.m_value;
+ fireTableDataChanged();
+ return;
+ }
+ }
+
+ m_allData.add(newData);
+ fireTableDataChanged();
+ }
+
+ void reset() {
+ m_allData.clear();
+ }
+
+ public int getRowCount() {
+ return m_allData.size();
+ }
+
+ public int getColumnCount() {
+ return 4;
+ }
+
+ public Object getValueAt(int r, int c) {
+ return ((AccountTableRow)m_allData.get(r)).getValue(c);
+ }
+
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch (c) {
+ case 0:
+ return "Key";
+ case 1:
+ return "Value";
+ case 2:
+ return "Currency";
+ case 3:
+ return "Account Name";
+
+ default:
+ return null;
+ }
+ }
+
+ class AccountTableRow {
+ String m_key;
+ String m_value;
+ String m_currency;
+ String m_accountName;
+
+ AccountTableRow(String key, String val, String cur, String accountName) {
+ m_key = key;
+ m_value = val;
+ m_currency = cur;
+ m_accountName = accountName ;
+ }
+
+ Object getValue(int c) {
+ switch (c) {
+ case 0:
+ return m_key;
+ case 1:
+ return m_value;
+ case 2:
+ return m_currency;
+ case 3:
+ return m_accountName ;
+
+ default:
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/AcctUpdatesDlg.java b/ib/src/main/java/TestJavaClient/AcctUpdatesDlg.java
new file mode 100644
index 00000000..a63be920
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/AcctUpdatesDlg.java
@@ -0,0 +1,117 @@
+
+/*
+ * AcctUpdatesDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+public class AcctUpdatesDlg extends JDialog {
+ JTextField m_txtAcctCode = new JTextField(10);
+ JButton m_btnSubscribe = new JButton("Subscribe");
+ JButton m_btnUnSubscribe = new JButton("UnSubscribe");
+ JButton m_btnClose = new JButton( "Close");
+ SampleFrame m_parent;
+ String m_acctCode;
+ boolean m_subscribe = false;
+ boolean m_rc;
+
+ public AcctUpdatesDlg( SampleFrame owner) {
+ super( owner, true);
+
+ m_parent = owner;
+
+ setTitle("Account Updates (FA Customers only)");
+ setSize(200,300);
+
+ m_txtAcctCode.setMaximumSize( m_txtAcctCode.getPreferredSize());
+
+
+ Box row1 = Box.createHorizontalBox();
+ row1.add( new JLabel( " Enter the account code for the FA managed \n account you wish to receive updates for :"));
+
+ Box row2 = Box.createHorizontalBox();
+ row2.add( new JLabel( "Account Code :"));
+ row2.add( Box.createHorizontalStrut(10));
+ row2.add( m_txtAcctCode);
+
+ Box row3 = Box.createHorizontalBox();
+ row3.add( m_btnSubscribe);
+ row3.add( Box.createHorizontalStrut(10));
+ row3.add( m_btnUnSubscribe);
+
+
+ Box vbox = Box.createVerticalBox();
+ vbox.add( Box.createVerticalStrut(10));
+ vbox.add( row1);
+ vbox.add( Box.createVerticalStrut(10));
+ vbox.add( row2);
+ vbox.add( Box.createVerticalStrut(10));
+ vbox.add( row3);
+ vbox.add( Box.createVerticalStrut(10));
+
+ // create accoun chooser panel
+ JPanel acctChooserPanel = new JPanel();
+ acctChooserPanel.setBorder( BorderFactory.createTitledBorder( ""));
+ acctChooserPanel.add(vbox);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_btnClose);
+
+ // create action listeners
+ m_btnSubscribe.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onSubscribe();
+ }
+ });
+ m_btnUnSubscribe.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onUnSubscribe();
+ }
+ });
+ m_btnClose.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClose();
+ }
+ });
+
+ // create dlg box
+ getContentPane().add( acctChooserPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+ pack();
+ }
+
+ void onSubscribe() {
+ m_subscribe = true;
+ m_acctCode = m_txtAcctCode.getText();
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onUnSubscribe() {
+ m_subscribe = false;
+ m_acctCode = m_txtAcctCode.getText();
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onClose() {
+ m_acctCode = "";
+ m_rc = false;
+ setVisible( false);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/AlgoParamsDlg.java b/ib/src/main/java/TestJavaClient/AlgoParamsDlg.java
new file mode 100644
index 00000000..c146ff80
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/AlgoParamsDlg.java
@@ -0,0 +1,248 @@
+/*
+ *
+ * AlgoDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.AbstractTableModel;
+
+import com.ib.client.Order;
+import com.ib.client.TagValue;
+
+public class AlgoParamsDlg extends JDialog {
+
+ private Order m_order;
+
+ private JTextField m_algoStrategy = new JTextField( "");
+
+ private Vector m_algoParams;
+
+ private JTextField m_tag = new JTextField( "");
+ private JTextField m_value = new JTextField( "");
+
+ private JButton m_addParam = new JButton( "Add");
+ private JButton m_removeParam = new JButton( "Remove");
+
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+
+ private AlgoParamModel m_paramModel = new AlgoParamModel();
+ private JTable m_paramTable = new JTable(m_paramModel);
+ private JScrollPane m_paramPane = new JScrollPane(m_paramTable);
+
+ public AlgoParamModel paramModel() { return m_paramModel; }
+
+ public AlgoParamsDlg( Order order, JDialog owner) {
+ super( owner, true);
+
+ m_order = order;
+
+ setTitle( "Algo Order Parameters");
+
+ JPanel pAlgoPanel = new JPanel( new GridLayout( 0, 2, 10, 10) );
+ pAlgoPanel.setBorder( BorderFactory.createTitledBorder( "Algorithm") );
+ pAlgoPanel.add( new JLabel( "Strategy:") );
+ m_algoStrategy.setText(m_order.m_algoStrategy);
+ pAlgoPanel.add(m_algoStrategy);
+
+ // create algo params panel
+ JPanel pParamList = new JPanel( new GridLayout( 0, 1, 10, 10) );
+ pParamList.setBorder( BorderFactory.createTitledBorder( "Parameters") );
+
+ Vector algoParams = m_order.m_algoParams;
+ if (algoParams != null) {
+ m_paramModel.algoParams().addAll(algoParams);
+ }
+ pParamList.add( m_paramPane);
+
+ // create combo details panel
+ JPanel pParamListControl = new JPanel( new GridLayout( 0, 2, 10, 10) );
+ pParamListControl.setBorder( BorderFactory.createTitledBorder( "Add / Remove") );
+ pParamListControl.add( new JLabel( "Param:") );
+ pParamListControl.add( m_tag);
+ pParamListControl.add( new JLabel( "Value:") );
+ pParamListControl.add( m_value);
+ pParamListControl.add( m_addParam);
+ pParamListControl.add( m_removeParam);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create wrapper panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout( new BoxLayout( topPanel, BoxLayout.Y_AXIS) );
+ topPanel.add( pAlgoPanel);
+ topPanel.add( pParamList);
+ topPanel.add( pParamListControl);
+
+ // create dlg box
+ getContentPane().add( topPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ // create action listeners
+ m_addParam.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onAddParam();
+ }
+ });
+ m_removeParam.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onRemoveParam();
+ }
+ });
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ setSize(250, 600);
+ centerOnOwner( this);
+ }
+
+ public void onAddParam() {
+ try {
+ String tag = m_tag.getText();
+ String value = m_value.getText();
+
+ m_paramModel.addParam( new TagValue(tag, value));
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ public void onRemoveParam() {
+ try {
+ if ( m_paramTable.getSelectedRowCount() != 0 ) {
+ int[] rows = m_paramTable.getSelectedRows();
+ for ( int i=rows.length -1; i>=0 ; i-- ) {
+ m_paramModel.removeParam( rows[i]);
+ }
+ }
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ void onOk() {
+
+ m_order.m_algoStrategy = m_algoStrategy.getText();
+
+ Vector algoParams = m_paramModel.algoParams();
+ m_order.m_algoParams = algoParams.isEmpty() ? null : algoParams;
+
+ setVisible( false);
+ }
+
+ void onCancel() {
+ setVisible( false);
+ }
+
+
+ void reportError( String msg, Exception e) {
+ Main.inform( this, msg + " --" + e);
+ }
+
+ private void centerOnOwner( Window window) {
+ Window owner = window.getOwner();
+ if( owner == null) {
+ return;
+ }
+ int x = owner.getX() + ((owner.getWidth() - window.getWidth()) / 2);
+ int y = owner.getY() + ((owner.getHeight() - window.getHeight()) / 2);
+ if( x < 0) x = 0;
+ if( y < 0) y = 0;
+ window.setLocation( x, y);
+ }
+}
+
+class AlgoParamModel extends AbstractTableModel {
+
+ private Vector m_allData = new Vector();
+
+ synchronized public void addParam( TagValue tagValue)
+ {
+ m_allData.add( tagValue);
+ fireTableDataChanged();
+ }
+
+ synchronized public void removeParam( int index)
+ {
+ m_allData.remove( index);
+ fireTableDataChanged();
+ }
+
+ synchronized public void reset() {
+ m_allData.removeAllElements();
+ fireTableDataChanged();
+ }
+
+ synchronized public int getRowCount() {
+ return m_allData.size();
+ }
+
+ synchronized public int getColumnCount() {
+ return 2;
+ }
+
+ synchronized public Object getValueAt(int r, int c) {
+ TagValue tagValue = (TagValue)m_allData.get(r);
+
+ switch (c) {
+ case 0:
+ return tagValue.m_tag;
+ case 1:
+ return tagValue.m_value;
+ default:
+ return "";
+ }
+
+ }
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch (c) {
+ case 0:
+ return "Param";
+ case 1:
+ return "Value";
+ default:
+ return null;
+ }
+ }
+
+ public Vector algoParams() {
+ return m_allData;
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/ComboLegDlg.java b/ib/src/main/java/TestJavaClient/ComboLegDlg.java
new file mode 100644
index 00000000..4fe2f117
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/ComboLegDlg.java
@@ -0,0 +1,292 @@
+/*
+ *
+ * ComboLegDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.AbstractTableModel;
+
+import com.ib.client.ComboLeg;
+import com.ib.client.Contract;
+
+public class ComboLegDlg extends JDialog {
+
+ //private static String BUY = "BUY";
+ //private static String SELL = "SELL";
+ //private static String SSHORT = "SSHORT";
+
+ private Vector m_comboLegs;
+
+ private JTextField m_conId = new JTextField( "0");
+ private JTextField m_ratio = new JTextField( "0");
+ private JTextField m_action = new JTextField( "BUY");
+ private JTextField m_exchange = new JTextField( "");
+ private JTextField m_openClose = new JTextField( "0");
+ private JTextField m_shortSaleSlot = new JTextField( "0");
+ private JTextField m_designatedLocation = new JTextField( "");
+ private JTextField m_exemptCode = new JTextField( "-1");
+
+ private JButton m_addLeg = new JButton( "Add");
+ private JButton m_removeLeg = new JButton( "Remove");
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+
+ private ComboLegModel m_comboLegsModel = new ComboLegModel();
+ private JTable m_comboTable = new JTable(m_comboLegsModel);
+ private JScrollPane m_comboLegsPane = new JScrollPane(m_comboTable);
+
+ public ComboLegModel comboLegModel() { return m_comboLegsModel; }
+
+ public ComboLegDlg( Vector comboLegs, String orderExchange, JDialog owner) {
+ super( owner, true);
+
+ m_comboLegs = comboLegs;
+
+ setTitle( "Combination Legs");
+
+ // create combos list panel
+ JPanel pLegList = new JPanel( new GridLayout( 0, 1, 10, 10) );
+ pLegList.setBorder( BorderFactory.createTitledBorder( "Combination Order legs:") );
+ m_comboLegsModel.comboLegModel().addAll(comboLegs);
+ pLegList.add( m_comboLegsPane);
+
+ if (orderExchange != null && orderExchange.length() > 0) {
+ m_exchange.setText(orderExchange);
+ }
+
+ // create combo details panel
+ JPanel pComboDetails = new JPanel( new GridLayout( 0, 2, 10, 10) );
+ pComboDetails.setBorder( BorderFactory.createTitledBorder( "Combo Leg Details:") );
+ pComboDetails.add( new JLabel( "ConId:") );
+ pComboDetails.add( m_conId);
+ pComboDetails.add( new JLabel( "Ratio:") );
+ pComboDetails.add( m_ratio);
+ pComboDetails.add( new JLabel( "Side:") );
+ pComboDetails.add( m_action);
+ pComboDetails.add( new JLabel( "Exchange:") );
+ pComboDetails.add( m_exchange);
+ pComboDetails.add( new JLabel( "Open/Close:") );
+ pComboDetails.add( m_openClose);
+ pComboDetails.add( new JLabel( "Short Sale Slot:") );
+ pComboDetails.add( m_shortSaleSlot);
+ pComboDetails.add( new JLabel( "Designated Location:") );
+ pComboDetails.add( m_designatedLocation);
+ pComboDetails.add( new JLabel( "Exempt Code:") );
+ pComboDetails.add( m_exemptCode);
+ pComboDetails.add( m_addLeg);
+ pComboDetails.add( m_removeLeg);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create wrapper panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout( new BoxLayout( topPanel, BoxLayout.Y_AXIS) );
+ topPanel.add( pLegList);
+ topPanel.add( pComboDetails);
+
+ // create dlg box
+ getContentPane().add( topPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ // create action listeners
+ m_addLeg.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onAddLeg();
+ }
+ });
+ m_removeLeg.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onRemoveLeg();
+ }
+ });
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ setSize(250, 600);
+ centerOnOwner( this);
+ }
+
+ public void onAddLeg() {
+ try {
+ int conId = Integer.parseInt( m_conId.getText());
+ int ratio = Integer.parseInt( m_ratio.getText());
+ int openClose = Integer.parseInt( m_openClose.getText());
+ int shortSaleSlot = Integer.parseInt(m_shortSaleSlot.getText());
+ int exemptCode = Integer.parseInt(m_exemptCode.getText().length() != 0 ? m_exemptCode.getText() : "-1");
+ m_comboLegsModel.addComboLeg( new ComboLeg(conId, ratio,
+ m_action.getText(), m_exchange.getText(), openClose,
+ shortSaleSlot, m_designatedLocation.getText(), exemptCode) );
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ public void onRemoveLeg() {
+ try {
+ if ( m_comboTable.getSelectedRowCount() != 0 ) {
+ int[] rows = m_comboTable.getSelectedRows();
+ for ( int i=rows.length -1; i>=0 ; i-- ) {
+ m_comboLegsModel.removeComboLeg( rows[i]);
+ }
+ }
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ void onOk() {
+ m_comboLegs.clear();
+ m_comboLegs.addAll( m_comboLegsModel.comboLegModel());
+ setVisible( false);
+ }
+
+ void onCancel() {
+ setVisible( false);
+ }
+
+
+ void reportError( String msg, Exception e) {
+ Main.inform( this, msg + " --" + e);
+ }
+
+ private void centerOnOwner( Window window) {
+ Window owner = window.getOwner();
+ if( owner == null) {
+ return;
+ }
+ int x = owner.getX() + ((owner.getWidth() - window.getWidth()) / 2);
+ int y = owner.getY() + ((owner.getHeight() - window.getHeight()) / 2);
+ if( x < 0) x = 0;
+ if( y < 0) y = 0;
+ window.setLocation( x, y);
+ }
+}
+
+class ComboLegModel extends AbstractTableModel {
+ private Vector m_allData = new Vector();
+
+ synchronized public void addComboLeg( ComboLeg leg)
+ {
+ m_allData.add( leg);
+ fireTableDataChanged();
+ }
+
+ synchronized public void removeComboLeg( int index)
+ {
+ m_allData.remove(index);
+ fireTableDataChanged();
+ }
+
+ synchronized public void removeComboLeg( ComboLeg leg)
+ {
+ for ( int i=0; i < m_allData.size(); i++ ) {
+ if ( leg.equals( (ComboLeg)m_allData.get(i)) ) {
+ m_allData.remove(i);
+ break;
+ }
+ }
+ fireTableDataChanged();
+ }
+
+ synchronized public void reset() {
+ m_allData.removeAllElements();
+ fireTableDataChanged();
+ }
+
+ synchronized public int getRowCount() {
+ return m_allData.size();
+ }
+
+ synchronized public int getColumnCount() {
+ return 8;
+ }
+
+ synchronized public Object getValueAt(int r, int c) {
+ ComboLeg leg = (ComboLeg)m_allData.get(r);
+
+ switch (c) {
+ case 0:
+ return Integer.toString(leg.m_conId);
+ case 1:
+ return Integer.toString(leg.m_ratio);
+ case 2:
+ return leg.m_action;
+ case 3:
+ return leg.m_exchange;
+ case 4:
+ return Integer.toString(leg.m_openClose);
+ case 5:
+ return Integer.toString(leg.m_shortSaleSlot);
+ case 6:
+ return leg.m_designatedLocation;
+ case 7:
+ return Integer.toString(leg.m_exemptCode);
+ default:
+ return "";
+ }
+
+ }
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch (c) {
+ case 0:
+ return "ConId";
+ case 1:
+ return "Ratio";
+ case 2:
+ return "Side";
+ case 3:
+ return "Exchange";
+ case 4:
+ return "Open/Close";
+ case 5:
+ return "Short Sale Slot";
+ case 6:
+ return "Designated Location";
+ case 7:
+ return "Exempt Code";
+ default:
+ return null;
+ }
+ }
+
+ public Vector comboLegModel() {
+ return m_allData;
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/ConnectDlg.java b/ib/src/main/java/TestJavaClient/ConnectDlg.java
new file mode 100644
index 00000000..c8040466
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/ConnectDlg.java
@@ -0,0 +1,95 @@
+/*
+ * ConnectDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+public class ConnectDlg extends JDialog {
+ public static int LAST_CLIENT_ID = 0;
+
+ JTextField m_ipAddress = new JTextField();
+ JTextField m_port = new JTextField( "7496");
+ JTextField m_clientId = new JTextField();
+ JButton m_ok = new JButton( "OK");
+ JButton m_cancel = new JButton( "Cancel");
+ String m_retIpAddress;
+ int m_retPort;
+ int m_retClientId;
+ boolean m_rc;
+
+ public ConnectDlg( Frame owner) {
+ super( owner, true);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ // create mid panel
+ JPanel midPanel = new JPanel();
+ midPanel.setLayout( new GridLayout( 0, 1, 5, 5) );
+ midPanel.add( new JLabel( "IP Address (leave blank for local host)") );
+ midPanel.add( m_ipAddress);
+ midPanel.add( new JLabel( "Port") );
+ midPanel.add( m_port);
+ midPanel.add( new JLabel( "Client ID") );
+ midPanel.add( m_clientId);
+ m_clientId.setText( Integer.toString(LAST_CLIENT_ID) );
+
+ // create dlg box
+ getContentPane().add( midPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+ setTitle( "Connect");
+ pack();
+ }
+
+ void onOk() {
+ m_rc = false;
+
+ try {
+ // set id
+ m_retIpAddress = m_ipAddress.getText();
+ m_retPort = Integer.parseInt( m_port.getText() );
+ m_retClientId = Integer.parseInt( m_clientId.getText() );
+ LAST_CLIENT_ID = m_retClientId;
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ return;
+ }
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onCancel() {
+ LAST_CLIENT_ID = Integer.parseInt( m_clientId.getText() );
+
+ m_rc = false;
+ setVisible( false);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/ExecFilterDlg.java b/ib/src/main/java/TestJavaClient/ExecFilterDlg.java
new file mode 100644
index 00000000..de4772ab
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/ExecFilterDlg.java
@@ -0,0 +1,122 @@
+ /**
+ *
+ * ExtFilterDlg.java
+ *
+ */
+
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import com.ib.client.ExecutionFilter;
+
+public class ExecFilterDlg extends JDialog {
+
+ public int m_reqId;
+ public ExecutionFilter m_execFilter = new ExecutionFilter();
+ public boolean m_rc;
+
+ private JTextField m_reqIdTxt = new JTextField("0");
+ private JTextField m_clientID = new JTextField("0");
+ private JTextField m_acctCode = new JTextField();
+ private JTextField m_time = new JTextField();
+ private JTextField m_symbol = new JTextField();
+ private JTextField m_secType = new JTextField();
+ private JTextField m_exchange = new JTextField();
+ private JTextField m_action = new JTextField();
+
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+
+ public ExecFilterDlg( JFrame owner) {
+ super( owner, true);
+
+ setTitle( "Execution Report Filter");
+
+ // create extended order attributes panel
+ JPanel execRptFilterPanel = new JPanel( new GridLayout( 0, 2, 7, 7) );
+ execRptFilterPanel.setBorder( BorderFactory.createTitledBorder( "Filter Criteria") );
+ execRptFilterPanel.add( new JLabel( "Request ID:") );
+ execRptFilterPanel.add( m_reqIdTxt);
+ execRptFilterPanel.add( new JLabel( "Client ID:") );
+ execRptFilterPanel.add( m_clientID);
+ execRptFilterPanel.add( new JLabel( "Account Code:") );
+ execRptFilterPanel.add( m_acctCode);
+ execRptFilterPanel.add( new JLabel( "Time :") );
+ execRptFilterPanel.add( m_time);
+ execRptFilterPanel.add( new JLabel( "Symbol :") );
+ execRptFilterPanel.add( m_symbol);
+ execRptFilterPanel.add( new JLabel( "SecType :") );
+ execRptFilterPanel.add( m_secType);
+ execRptFilterPanel.add( new JLabel( "Exchange :") );
+ execRptFilterPanel.add( m_exchange);
+ execRptFilterPanel.add( new JLabel( "Action :") );
+ execRptFilterPanel.add( m_action);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ // create dlg box
+ getContentPane().add( execRptFilterPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+ pack();
+ }
+
+ void onOk() {
+ m_rc = false;
+
+ try {
+
+ m_reqId = Integer.parseInt( m_reqIdTxt.getText());
+
+ // set extended order fields
+ String clientId = m_clientID.getText().toString();
+ m_execFilter.m_clientId = clientId != ""
+ ? Integer.parseInt( m_clientID.getText())
+ : 0;
+ m_execFilter.m_acctCode = m_acctCode.getText();
+ m_execFilter.m_time = m_time.getText();
+ m_execFilter.m_symbol = m_symbol.getText();
+ m_execFilter.m_secType = m_secType.getText();
+ m_execFilter.m_exchange = m_exchange.getText();
+ m_execFilter.m_side = m_action.getText();
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ return;
+ }
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onCancel() {
+ m_rc = false;
+ setVisible( false);
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/ExtOrdDlg.java b/ib/src/main/java/TestJavaClient/ExtOrdDlg.java
new file mode 100644
index 00000000..9dcbf41a
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/ExtOrdDlg.java
@@ -0,0 +1,355 @@
+ /**
+ *
+ * ExtOrdDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+
+import com.ib.client.Order;
+
+public class ExtOrdDlg extends JDialog {
+ public Order m_order = new Order();
+ public boolean m_rc;
+
+ private JTextField m_tif = new JTextField( "DAY");
+ private JTextField m_ocaGroup = new JTextField();
+ private JTextField m_ocaType = new JTextField("0");
+
+ private JTextField m_account = new JTextField();
+ private JTextField m_settlingFirm = new JTextField();
+ private JTextField m_clearingAccount = new JTextField();
+ private JTextField m_clearingIntent = new JTextField();
+
+ private JTextField m_openClose = new JTextField( "O");
+ private JTextField m_origin = new JTextField( "1");
+ private JTextField m_orderRef = new JTextField();
+ private JTextField m_parentId = new JTextField( "0");
+ private JTextField m_transmit = new JTextField( "1");
+ private JTextField m_blockOrder = new JTextField( "0");
+ private JTextField m_sweepToFill = new JTextField( "0");
+ private JTextField m_displaySize = new JTextField( "0");
+ private JTextField m_triggerMethod = new JTextField( "0");
+ private JTextField m_outsideRth = new JTextField( "0");
+ private JTextField m_hidden = new JTextField( "0");
+ private JTextField m_discretionaryAmt = new JTextField( "0");
+ private JTextField m_shortSaleSlot = new JTextField( "0");
+ private JTextField m_designatedLocation = new JTextField();
+ private JTextField m_exemptCode = new JTextField( "-1");
+ private JTextField m_rule80A = new JTextField();
+ private JTextField m_allOrNone = new JTextField();
+ private JTextField m_overridePercentageConstraints = new JTextField();
+ private JTextField m_minQty = new JTextField();
+ private JTextField m_percentOffset = new JTextField();
+ private JTextField m_eTradeOnly = new JTextField();
+ private JTextField m_firmQuoteOnly = new JTextField();
+ private JTextField m_nbboPriceCap = new JTextField();
+ private JTextField m_auctionStrategy = new JTextField("0");
+ private JTextField m_startingPrice = new JTextField();
+ private JTextField m_stockRefPrice = new JTextField();
+ private JTextField m_delta = new JTextField();
+ private JTextField m_BOXstockRangeLower = new JTextField();
+ private JTextField m_BOXstockRangeUpper = new JTextField();
+
+ private JTextField m_VOLVolatility = new JTextField();
+ private JTextField m_VOLVolatilityType = new JTextField();
+ private JTextField m_VOLDeltaNeutralOrderType = new JTextField();
+ private JTextField m_VOLDeltaNeutralAuxPrice = new JTextField();
+ private JTextField m_VOLDeltaNeutralConId = new JTextField();
+ private JTextField m_VOLDeltaNeutralSettlingFirm = new JTextField();
+ private JTextField m_VOLDeltaNeutralClearingAccount = new JTextField();
+ private JTextField m_VOLDeltaNeutralClearingIntent = new JTextField();
+ private JTextField m_VOLContinuousUpdate = new JTextField();
+ private JTextField m_VOLReferencePriceType = new JTextField();
+ private JTextField m_trailStopPrice = new JTextField();
+
+ private JTextField m_scaleInitLevelSize = new JTextField();
+ private JTextField m_scaleSubsLevelSize = new JTextField();
+ private JTextField m_scalePriceIncrement = new JTextField();
+
+ private JTextField m_hedgeType = new JTextField();
+ private JTextField m_hedgeParam = new JTextField();
+ private JCheckBox m_optOutSmartRoutingCheckBox = new JCheckBox("Opting out of SMART routing", false);
+
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+
+ public ExtOrdDlg( OrderDlg owner) {
+ super( owner, true);
+
+ setTitle( "Sample");
+
+ // create extended order attributes panel
+ JPanel extOrderDetailsPanel = new JPanel( new GridLayout( 0, 4, 10, 10) );
+ extOrderDetailsPanel.setBorder( BorderFactory.createTitledBorder( "Extended Order Info") );
+ extOrderDetailsPanel.add( new JLabel( "TIF") );
+ extOrderDetailsPanel.add( m_tif);
+ extOrderDetailsPanel.add( new JLabel( "OCA Group") );
+ extOrderDetailsPanel.add( m_ocaGroup);
+ extOrderDetailsPanel.add( new JLabel( "OCA Type") );
+ extOrderDetailsPanel.add( m_ocaType);
+
+ extOrderDetailsPanel.add( new JLabel( "Account") );
+ extOrderDetailsPanel.add( m_account);
+ extOrderDetailsPanel.add(new JLabel("Settling Firm"));
+ extOrderDetailsPanel.add(m_settlingFirm);
+ extOrderDetailsPanel.add(new JLabel("Clearing Account"));
+ extOrderDetailsPanel.add(m_clearingAccount);
+ extOrderDetailsPanel.add(new JLabel("Clearing Intent"));
+ extOrderDetailsPanel.add(m_clearingIntent);
+
+ extOrderDetailsPanel.add( new JLabel( "Open/Close") );
+ extOrderDetailsPanel.add( m_openClose);
+ extOrderDetailsPanel.add( new JLabel( "Origin") );
+ extOrderDetailsPanel.add( m_origin);
+ extOrderDetailsPanel.add( new JLabel( "OrderRef") );
+ extOrderDetailsPanel.add( m_orderRef);
+ extOrderDetailsPanel.add( new JLabel( "Parent Id") );
+ extOrderDetailsPanel.add( m_parentId);
+ extOrderDetailsPanel.add( new JLabel( "Transmit") );
+ extOrderDetailsPanel.add( m_transmit);
+ extOrderDetailsPanel.add( new JLabel( "Block Order") );
+ extOrderDetailsPanel.add( m_blockOrder);
+ extOrderDetailsPanel.add( new JLabel( "Sweep To Fill") );
+ extOrderDetailsPanel.add( m_sweepToFill);
+ extOrderDetailsPanel.add( new JLabel( "Display Size") );
+ extOrderDetailsPanel.add( m_displaySize);
+ extOrderDetailsPanel.add( new JLabel( "Trigger Method") );
+ extOrderDetailsPanel.add( m_triggerMethod);
+ extOrderDetailsPanel.add( new JLabel( "Outside Regular Trading Hours") );
+ extOrderDetailsPanel.add( m_outsideRth);
+ extOrderDetailsPanel.add( new JLabel( "Hidden") );
+ extOrderDetailsPanel.add( m_hidden);
+ extOrderDetailsPanel.add( new JLabel( "Discretionary Amt") );
+ extOrderDetailsPanel.add( m_discretionaryAmt);
+ extOrderDetailsPanel.add( new JLabel( "Trail Stop Price") );
+ extOrderDetailsPanel.add( m_trailStopPrice);
+ extOrderDetailsPanel.add( new JLabel( "Institutional Short Sale Slot") );
+ extOrderDetailsPanel.add( m_shortSaleSlot);
+ extOrderDetailsPanel.add( new JLabel( "Institutional Designated Location") );
+ extOrderDetailsPanel.add( m_designatedLocation);
+ extOrderDetailsPanel.add( new JLabel( "Exempt Code") );
+ extOrderDetailsPanel.add( m_exemptCode);
+ extOrderDetailsPanel.add( new JLabel( "Rule 80 A") );
+ extOrderDetailsPanel.add(m_rule80A);
+
+ extOrderDetailsPanel.add(new JLabel("All or None"));
+ extOrderDetailsPanel.add(m_allOrNone);
+ extOrderDetailsPanel.add(new JLabel("Override Percentage Constraints"));
+ extOrderDetailsPanel.add(m_overridePercentageConstraints);
+ extOrderDetailsPanel.add(new JLabel("Minimum Quantity"));
+ extOrderDetailsPanel.add(m_minQty);
+ extOrderDetailsPanel.add(new JLabel("Percent Offset"));
+ extOrderDetailsPanel.add(m_percentOffset);
+ extOrderDetailsPanel.add(new JLabel("Electronic Exchange Only"));
+ extOrderDetailsPanel.add(m_eTradeOnly);
+ extOrderDetailsPanel.add(new JLabel("Firm Quote Only"));
+ extOrderDetailsPanel.add(m_firmQuoteOnly);
+ extOrderDetailsPanel.add(new JLabel("NBBO Price Cap"));
+ extOrderDetailsPanel.add(m_nbboPriceCap);
+ extOrderDetailsPanel.add( new JLabel( "") );
+ extOrderDetailsPanel.add( new JLabel(""));
+ extOrderDetailsPanel.add(new JLabel("BOX: Auction Strategy"));
+ extOrderDetailsPanel.add(m_auctionStrategy);
+ extOrderDetailsPanel.add(new JLabel("BOX: Starting Price"));
+ extOrderDetailsPanel.add(m_startingPrice);
+ extOrderDetailsPanel.add(new JLabel("BOX: Stock Reference Price"));
+ extOrderDetailsPanel.add(m_stockRefPrice);
+ extOrderDetailsPanel.add(new JLabel("BOX: Delta"));
+ extOrderDetailsPanel.add(m_delta);
+ extOrderDetailsPanel.add(new JLabel("BOX or VOL: Stock Range Lower"));
+ extOrderDetailsPanel.add(m_BOXstockRangeLower);
+ extOrderDetailsPanel.add(new JLabel("BOX or VOL: Stock Range Upper"));
+ extOrderDetailsPanel.add(m_BOXstockRangeUpper);
+
+ extOrderDetailsPanel.add(new JLabel("VOL: Volatility"));
+ extOrderDetailsPanel.add(m_VOLVolatility);
+ extOrderDetailsPanel.add(new JLabel("VOL: Volatility Type (1 or 2)"));
+ extOrderDetailsPanel.add(m_VOLVolatilityType);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Order Type"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralOrderType);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Aux Price"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralAuxPrice);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Contract Id"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralConId);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Settling Firm"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralSettlingFirm);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Clearing Account"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralClearingAccount);
+ extOrderDetailsPanel.add(new JLabel("VOL: Hedge Delta Clearing Intent"));
+ extOrderDetailsPanel.add(m_VOLDeltaNeutralClearingIntent);
+ extOrderDetailsPanel.add(new JLabel("VOL: Continuously Update Price (0 or 1)"));
+ extOrderDetailsPanel.add(m_VOLContinuousUpdate);
+ extOrderDetailsPanel.add(new JLabel("VOL: Reference Price Type (1 or 2)"));
+ extOrderDetailsPanel.add(m_VOLReferencePriceType);
+
+ extOrderDetailsPanel.add(new JLabel("SCALE: Scale Init Level Size"));
+ extOrderDetailsPanel.add(m_scaleInitLevelSize);
+ extOrderDetailsPanel.add(new JLabel("SCALE: Scale Subs Level Size"));
+ extOrderDetailsPanel.add(m_scaleSubsLevelSize);
+ extOrderDetailsPanel.add(new JLabel("SCALE: Scale Price Increment"));
+ extOrderDetailsPanel.add(m_scalePriceIncrement);
+
+ extOrderDetailsPanel.add(new JLabel("HEDGE: Type"));
+ extOrderDetailsPanel.add(m_hedgeType);
+ extOrderDetailsPanel.add(new JLabel("HEDGE: Param"));
+ extOrderDetailsPanel.add(m_hedgeParam);
+ extOrderDetailsPanel.add(m_optOutSmartRoutingCheckBox) ;
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ // create dlg box
+ getContentPane().add( extOrderDetailsPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ JScrollPane scroller = new JScrollPane(extOrderDetailsPanel);
+ this.add( scroller, BorderLayout.CENTER);
+
+ pack();
+ }
+
+ void onOk() {
+ m_rc = false;
+
+ try {
+ // set extended order fields
+ m_order.m_tif = m_tif.getText().trim();
+ m_order.m_ocaGroup = m_ocaGroup.getText().trim();
+ m_order.m_ocaType = parseInt( m_ocaType);
+
+ m_order.m_account = m_account.getText().trim();
+ m_order.m_settlingFirm = m_settlingFirm.getText().trim();
+ m_order.m_clearingAccount = m_clearingAccount.getText().trim();
+ m_order.m_clearingIntent = m_clearingIntent.getText().trim();
+
+ m_order.m_openClose = m_openClose.getText().trim();
+ m_order.m_origin = parseInt( m_origin );
+ m_order.m_orderRef = m_orderRef.getText().trim();
+ m_order.m_parentId = parseInt( m_parentId);
+ m_order.m_transmit = parseInt(m_transmit) != 0;
+ m_order.m_blockOrder = parseInt(m_blockOrder) != 0;
+ m_order.m_sweepToFill = parseInt(m_sweepToFill) != 0;
+ m_order.m_displaySize = parseInt( m_displaySize);
+ m_order.m_triggerMethod = parseInt( m_triggerMethod);
+ m_order.m_outsideRth = parseInt(m_outsideRth) != 0;
+ m_order.m_hidden = parseInt(m_hidden) != 0;
+ m_order.m_discretionaryAmt = parseDouble( m_discretionaryAmt);
+ m_order.m_shortSaleSlot = parseInt( m_shortSaleSlot );
+ m_order.m_designatedLocation = m_designatedLocation.getText().trim();
+ m_order.m_exemptCode = Integer.parseInt(m_exemptCode.getText().length() != 0 ? m_exemptCode.getText() : "-1");
+ m_order.m_rule80A = m_rule80A.getText().trim();
+ m_order.m_allOrNone = parseInt(m_allOrNone) != 0;
+ m_order.m_minQty = parseMaxInt(m_minQty);
+ m_order.m_overridePercentageConstraints =
+ parseInt(m_overridePercentageConstraints) != 0;
+ m_order.m_percentOffset = parseMaxDouble(m_percentOffset);
+ m_order.m_eTradeOnly = parseInt(m_eTradeOnly) != 0;
+ m_order.m_firmQuoteOnly = parseInt(m_firmQuoteOnly) != 0;
+ m_order.m_nbboPriceCap = parseMaxDouble(m_nbboPriceCap);
+ m_order.m_optOutSmartRouting = m_optOutSmartRoutingCheckBox.isSelected();
+ m_order.m_auctionStrategy = parseInt(m_auctionStrategy);
+ m_order.m_startingPrice = parseMaxDouble(m_startingPrice);
+ m_order.m_stockRefPrice = parseMaxDouble(m_stockRefPrice);
+ m_order.m_delta = parseMaxDouble(m_delta);
+ m_order.m_stockRangeLower = parseMaxDouble(m_BOXstockRangeLower);
+ m_order.m_stockRangeUpper = parseMaxDouble(m_BOXstockRangeUpper);
+ m_order.m_volatility = parseMaxDouble(m_VOLVolatility);
+ m_order.m_volatilityType = parseMaxInt(m_VOLVolatilityType);
+ m_order.m_deltaNeutralOrderType = m_VOLDeltaNeutralOrderType.getText().trim();
+ m_order.m_deltaNeutralAuxPrice = parseMaxDouble(m_VOLDeltaNeutralAuxPrice);
+ m_order.m_deltaNeutralConId = parseInt(m_VOLDeltaNeutralConId);
+ m_order.m_deltaNeutralSettlingFirm = m_VOLDeltaNeutralSettlingFirm.getText().trim();
+ m_order.m_deltaNeutralClearingAccount = m_VOLDeltaNeutralClearingAccount.getText().trim();
+ m_order.m_deltaNeutralClearingIntent = m_VOLDeltaNeutralClearingIntent.getText().trim();
+ m_order.m_continuousUpdate = parseInt(m_VOLContinuousUpdate);
+ m_order.m_referencePriceType = parseMaxInt(m_VOLReferencePriceType);
+ m_order.m_trailStopPrice = parseMaxDouble(m_trailStopPrice);
+
+ m_order.m_scaleInitLevelSize = parseMaxInt(m_scaleInitLevelSize);
+ m_order.m_scaleSubsLevelSize = parseMaxInt(m_scaleSubsLevelSize);
+ m_order.m_scalePriceIncrement = parseMaxDouble(m_scalePriceIncrement);
+ m_order.m_hedgeType = m_hedgeType.getText().trim();
+ m_order.m_hedgeParam = m_hedgeParam.getText().trim();
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ return;
+ }
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ private int parseMaxInt(JTextField textField) {
+ String text = textField.getText().trim();
+ if (text.length() == 0) {
+ return Integer.MAX_VALUE;
+ }
+ else {
+ return Integer.parseInt(text);
+ }
+ }
+
+ private double parseMaxDouble(JTextField textField) {
+ String text = textField.getText().trim();
+ if (text.length() == 0) {
+ return Double.MAX_VALUE;
+ }
+ else {
+ return Double.parseDouble(text);
+ }
+ }
+
+ private int parseInt(JTextField textField) {
+ String text = textField.getText().trim();
+ if (text.length() == 0) {
+ return 0;
+ }
+ else {
+ return Integer.parseInt(text);
+ }
+ }
+
+ private double parseDouble(JTextField textField) {
+ String text = textField.getText().trim();
+ if (text.length() == 0) {
+ return 0;
+ }
+ else {
+ return Double.parseDouble(text);
+ }
+ }
+
+ void onCancel() {
+ m_rc = false;
+ setVisible( false);
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/FAAllocationInfoDlg.java b/ib/src/main/java/TestJavaClient/FAAllocationInfoDlg.java
new file mode 100644
index 00000000..105626cd
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/FAAllocationInfoDlg.java
@@ -0,0 +1,104 @@
+/**
+ *
+ * FAAllocationInfoDlg.java
+ *
+ */
+
+package TestJavaClient;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.border.Border;
+import javax.swing.border.TitledBorder;
+
+public class FAAllocationInfoDlg extends JDialog {
+ IBGridBagPanel mainJPanel = new IBGridBagPanel();
+ IBGridBagPanel faGroupJPanel = new IBGridBagPanel();
+ IBGridBagPanel faProfileJPanel = new IBGridBagPanel();
+
+ JLabel m_groupLabel = new JLabel("Group");
+ JLabel m_methodLabel = new JLabel("Method");
+ JLabel m_percentageLabel = new JLabel("Percentage");
+ JLabel m_profileLabel = new JLabel("Profile");
+
+ JTextField m_groupTextField = new JTextField(20);
+ JTextField m_methodTextField = new JTextField(20);
+ JTextField m_percentageTextField = new JTextField(20);
+ JTextField m_profileTextField = new JTextField(20);
+
+ JButton m_okButton = new JButton("OK");
+ JButton m_closeButton = new JButton("Close");
+
+ private OrderDlg m_parent;
+
+ public FAAllocationInfoDlg(OrderDlg dlg) {
+ super(dlg, false);
+ m_parent = dlg;
+ try {
+ jbInit();
+ pack();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ void jbInit() throws Exception {
+ Color etchedColor = new Color(148, 145, 140);
+ Border border1 = BorderFactory.createEtchedBorder(Color.white, etchedColor);
+ Border border2 = BorderFactory.createEtchedBorder(Color.white, etchedColor);
+ TitledBorder titledBorder1 = new TitledBorder(border1, "Group");
+ TitledBorder titledBorder2 = new TitledBorder(border2, "Profile");
+
+ faGroupJPanel.setBorder(titledBorder1);
+ faProfileJPanel.setBorder(titledBorder2);
+
+ faGroupJPanel.SetObjectPlacement(m_groupLabel, 0, 0);
+ faGroupJPanel.SetObjectPlacement(m_groupTextField, 1, 0);
+ faGroupJPanel.SetObjectPlacement(m_methodLabel, 0, 1);
+ faGroupJPanel.SetObjectPlacement(m_methodTextField, 1, 1);
+ faGroupJPanel.SetObjectPlacement(m_percentageLabel, 0, 2);
+ faGroupJPanel.SetObjectPlacement(m_percentageTextField, 1, 2);
+
+ faProfileJPanel.SetObjectPlacement(m_profileLabel, 0, 0);
+ faProfileJPanel.SetObjectPlacement(m_profileTextField, 1, 0);
+
+ mainJPanel.SetObjectPlacement(faProfileJPanel, 0, 0, 4, 1);
+ mainJPanel.SetObjectPlacement(faGroupJPanel, 0, 1, 4, 1);
+ mainJPanel.SetObjectPlacement(m_okButton, 1, 2, 1, 1);
+ mainJPanel.SetObjectPlacement(m_closeButton, 2, 2, 1, 1);
+
+ setTitle("FA Allocation Info");
+ getContentPane().add(mainJPanel);
+ setSize( 600, 300);
+
+
+ m_okButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ onOk();
+ }
+ });
+ m_closeButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ onClose();
+ }
+ });
+ }
+
+ void onOk() {
+ m_parent.faGroup(m_groupTextField.getText().trim());
+ m_parent.faMethod(m_methodTextField.getText().trim());
+ m_parent.faPercentage(m_percentageTextField.getText().trim());
+ m_parent.faProfile(m_profileTextField.getText().trim());
+ dispose();
+ }
+
+ void onClose() {
+ dispose();
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/FinancialAdvisorDlg.java b/ib/src/main/java/TestJavaClient/FinancialAdvisorDlg.java
new file mode 100644
index 00000000..24725f3d
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/FinancialAdvisorDlg.java
@@ -0,0 +1,83 @@
+/*
+ * FinancialAdvisorDlg.java
+ *
+ */
+
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+
+public class FinancialAdvisorDlg extends JDialog {
+ private int DIALOG_WIDTH = 500;
+ private int EDITOR_HEIGHT = 240;
+ private int BUTTON_PANEL_HEIGHT = 60;
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+ private IBTextPanel groupTextEditor = new IBTextPanel("Groups", true) ;
+ private IBTextPanel profileTextEditor = new IBTextPanel("Allocation Profiles", true) ;
+ private IBTextPanel aliasTextEditor = new IBTextPanel("Aliases", true) ;
+ String groupsXML ;
+ String profilesXML ;
+ String aliasesXML ;
+ boolean m_rc = false;
+
+ public FinancialAdvisorDlg( Frame owner) {
+ super( owner, "Financial Advisor", true);
+
+ IBGridBagPanel editPanel = new IBGridBagPanel();
+
+ editPanel.SetObjectPlacement( groupTextEditor, 0, 0 ) ;
+ editPanel.SetObjectPlacement( profileTextEditor, 0, 1 ) ;
+ editPanel.SetObjectPlacement( aliasTextEditor, 0, 2 ) ;
+ Dimension editPanelSizeDimension =
+ new Dimension(DIALOG_WIDTH, 3 * EDITOR_HEIGHT);
+ editPanel.setPreferredSize(editPanelSizeDimension) ;
+
+ IBGridBagPanel buttonPanel = new IBGridBagPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ //setTitle( "Financial Advisor");
+ getContentPane().add( editPanel, BorderLayout.NORTH);
+ getContentPane().add( buttonPanel, BorderLayout.CENTER);
+ pack();
+ }
+
+ void receiveInitialXML(String p_groupsXML, String p_profilesXML, String p_aliasesXML) {
+ groupTextEditor.setTextDetabbed(p_groupsXML);
+ profileTextEditor.setTextDetabbed(p_profilesXML);
+ aliasTextEditor.setTextDetabbed(p_aliasesXML);
+ }
+
+ void onOk() {
+ m_rc = true;
+ groupsXML = groupTextEditor.getText();
+ profilesXML = profileTextEditor.getText();
+ aliasesXML = aliasTextEditor.getText();
+ setVisible( false);
+ }
+
+ void onCancel() {
+ m_rc = false;
+ setVisible( false);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/IBGridBagPanel.java b/ib/src/main/java/TestJavaClient/IBGridBagPanel.java
new file mode 100644
index 00000000..7835e422
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/IBGridBagPanel.java
@@ -0,0 +1,86 @@
+/*
+ * IBGridBagPanel.java
+ *
+ */
+
+package TestJavaClient ;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JPanel;
+
+class IBGridBagPanel extends JPanel {
+ private static final Insets oneInsets = new Insets(1, 1, 1, 1);
+ private GridBagLayout m_layout = new GridBagLayout();
+
+ IBGridBagPanel() {
+ setLayout(m_layout);
+ }
+
+ public void setConstraints(Component comp, GridBagConstraints constraints) {
+ m_layout.setConstraints(comp, constraints);
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y) {
+ addToPane(c, x, y, 1, 1, 100, 100, oneInsets) ;
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y, int w, int h) {
+ addToPane(c, x, y, w, h, 100, 100, oneInsets) ;
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y, int w, int h, int xGrow, int yGrow) {
+ addToPane(c, x, y, w, h, xGrow, yGrow, oneInsets) ;
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y, int w, int h, int xGrow, int yGrow, int fill) {
+ addToPane(c, x, y, w, h, xGrow, yGrow, GridBagConstraints.WEST, fill, oneInsets) ;
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y, int w, int h, int xGrow, int yGrow, int anchor, int fill) {
+ addToPane(c, x, y, w, h, xGrow, yGrow, anchor, fill, oneInsets) ;
+ }
+
+ public void SetObjectPlacement(Component c, int x, int y, int w, int h, int xGrow, int yGrow, Insets insets) {
+ addToPane(c, x, y, w, h, xGrow, yGrow, insets) ;
+ }
+
+ private void addToPane(Component c, int x, int y, int w, int h,
+ int xGrow, int yGrow, Insets insets) {
+ addToPane(c, x, y, w, h, xGrow, yGrow, GridBagConstraints.WEST, GridBagConstraints.BOTH, insets) ;
+ }
+
+ private void addToPane(Component c, int x, int y, int w, int h, int xGrow,
+ int yGrow, int anchor, int fill, Insets insets) {
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ // the coordinates of the cell in the layout that contains
+ // the upper-left corner of the component
+ gbc.gridx = x;
+ gbc.gridy = y;
+
+ // the number of cells that this entry is going to take up
+ gbc.gridwidth = w;
+ gbc.gridheight = h;
+
+ // drive how extra space is distributed among components.
+ gbc.weightx = xGrow;
+ gbc.weighty = yGrow;
+
+ // drive how component is made larger if extra space is available for it
+ gbc.fill = fill;
+
+ // drive where, within the display area, to place the component when it
+ // is larger than its display area.
+ gbc.anchor = anchor;
+
+ // drive the minimum amount of space between the component and the edges
+ // of its display area
+ gbc.insets = insets;
+
+ add(c, gbc);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/IBTextPanel.java b/ib/src/main/java/TestJavaClient/IBTextPanel.java
new file mode 100644
index 00000000..97a775a0
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/IBTextPanel.java
@@ -0,0 +1,112 @@
+/*
+ * IBTextPanel.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import javax.swing.BorderFactory;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.border.Border;
+
+class IBTextPanel extends JPanel {
+ public static final Color textBackgroundColor = new Color(5, 5, 5);
+ public static final Color textForegroundColor = new Color(0, 245, 0);
+ public static final Font textComponentFont = new JList().getFont();
+ public static final Color textCaretColor = Color.WHITE;
+ public static final String lineSeparator = System.getProperty("line.separator");
+
+ private JTextArea m_textArea = new JTextArea();
+ private JScrollPane m_scrollPane = new JScrollPane(m_textArea);
+ private final static String CRLF = "\r\n" ;
+ private final static String LF = "\n" ;
+ private final static String TAB = "\t" ;
+ private final static String EIGHT_SPACES = " ";
+ private final static String EMPTY_STRING = "";
+
+ IBTextPanel() {
+ this(null, false);
+ }
+
+ IBTextPanel(String title, boolean editable) {
+ super(new BorderLayout());
+ if (title != null) {
+ Border border = BorderFactory.createTitledBorder( title);
+ setBorder(border);
+ }
+ m_textArea.setBackground(textBackgroundColor);
+ m_textArea.setForeground(textForegroundColor);
+ m_textArea.setFont(textComponentFont);
+ m_textArea.setCaretColor(textCaretColor);
+ m_textArea.setEditable(editable);
+ add(m_scrollPane);
+ }
+
+ public void clear() {
+ m_textArea.setText(EMPTY_STRING);
+ }
+
+ public void setText(String text) {
+ m_textArea.setText(text);
+ if (m_textArea.isEditable()) {
+ moveCursorToBeginning();
+ } else {
+ moveCursorToEnd();
+ }
+ }
+
+ public void setTextDetabbed(String text) {
+ m_textArea.setText(detabbed(text));
+ }
+
+ public String getText() {
+ return m_textArea.getText();
+ }
+
+ public void add(String line) {
+ m_textArea.append(line + lineSeparator);
+ moveCursorToEnd();
+ }
+
+ public void moveCursorToEnd() {
+ m_textArea.setCaretPosition(m_textArea.getText().length());
+ }
+
+ public void moveCursorToBeginning() {
+ m_textArea.setCaretPosition(0);
+ }
+
+ public void add(Collection lines) {
+ for (Iterator iter = lines.iterator(); iter.hasNext(); ) {
+ add((String)iter.next());
+ }
+ }
+
+ public void addText(String text) {
+ add(tokenizedIntoArrayList(detabbed(text), LF));
+ }
+
+ public static ArrayList tokenizedIntoArrayList(String source, String delimiter) {
+ ArrayList list = new ArrayList();
+ StringTokenizer st = new StringTokenizer(source, delimiter);
+ while (st.hasMoreTokens()) {
+ String temp = st.nextToken();
+ list.add(temp);
+ }
+ return list;
+ }
+
+ private String detabbed(String text) {
+ return text.replaceAll(TAB, EIGHT_SPACES);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/LogConfigDlg.java b/ib/src/main/java/TestJavaClient/LogConfigDlg.java
new file mode 100644
index 00000000..3a6dee26
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/LogConfigDlg.java
@@ -0,0 +1,82 @@
+/*
+ * LogConfigDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+public class LogConfigDlg extends JDialog {
+ public static int SYSTEM_LOG = 1;
+ public static int ERROR_LOG = 2;
+ public static int WARN_LOG = 3;
+ public static int INFO_LOG = 4;
+ public static int DETAIL_LOG = 5;
+
+ JComboBox m_cmbServerLogLevels = new JComboBox();
+ JButton m_ok = new JButton( "OK");
+ JButton m_cancel = new JButton( "Cancel");
+ int m_serverLogLevel;
+ boolean m_rc;
+
+ public LogConfigDlg( Frame owner) {
+ super( owner, true);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ // create mid panel
+ m_cmbServerLogLevels.addItem("System");
+ m_cmbServerLogLevels.addItem("Error");
+ m_cmbServerLogLevels.addItem("Warning");
+ m_cmbServerLogLevels.addItem("Information");
+ m_cmbServerLogLevels.addItem("Detail");
+
+ JPanel midPanel = new JPanel();
+ midPanel.setLayout( new GridLayout( 0, 2, 5, 5) );
+ midPanel.add( new JLabel( "Log Level :") );
+ midPanel.add( m_cmbServerLogLevels);
+
+ // create dlg box
+ getContentPane().add( midPanel, BorderLayout.NORTH);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+ setTitle( "Log Configuration");
+ pack();
+ }
+
+ void onOk() {
+ // set server log Level
+ m_serverLogLevel = m_cmbServerLogLevels.getSelectedIndex() + 1;
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onCancel() {
+ m_rc = false;
+ setVisible( false);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/Main.java b/ib/src/main/java/TestJavaClient/Main.java
new file mode 100644
index 00000000..8a3d68f8
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/Main.java
@@ -0,0 +1,37 @@
+/*
+ * Main.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.Component;
+
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+public class Main {
+
+ // This method is called to start the application
+ public static void main (String args[]) {
+ SampleFrame sampleFrame = new SampleFrame();
+ sampleFrame.setVisible(true);
+ }
+
+ static public void inform( final Component parent, final String str) {
+ if( SwingUtilities.isEventDispatchThread() ) {
+ showMsg( parent, str, JOptionPane.INFORMATION_MESSAGE);
+ }
+ else {
+ SwingUtilities.invokeLater( new Runnable() {
+ public void run() {
+ showMsg( parent, str, JOptionPane.INFORMATION_MESSAGE);
+ }
+ });
+ }
+ }
+
+ static private void showMsg( Component parent, String str, int type) {
+ // this function pops up a dlg box displaying a message
+ JOptionPane.showMessageDialog( parent, str, "IB Java Test Client", type);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/MktDepthDlg.java b/ib/src/main/java/TestJavaClient/MktDepthDlg.java
new file mode 100644
index 00000000..f886956c
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/MktDepthDlg.java
@@ -0,0 +1,276 @@
+/*
+ * MktDepthDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.table.AbstractTableModel;
+
+import com.ib.client.EClientSocket;
+
+public class MktDepthDlg extends JDialog {
+ final static int OPERATION_INSERT = 0;
+ final static int OPERATION_UPDATE = 1;
+ final static int OPERATION_DELETE = 2;
+
+ final static int SIDE_ASK = 0;
+ final static int SIDE_BID = 1;
+ final static int MKT_DEPTH_DATA_RESET = 317;
+
+ private JButton m_close = new JButton( "Close");
+ private MktDepthModel m_bidModel = new MktDepthModel();
+ private MktDepthModel m_askModel = new MktDepthModel();
+ private EClientSocket m_client;
+ private int m_id;
+
+ public MktDepthDlg(String title, JFrame parent) {
+ super(parent, title, false);
+
+ JScrollPane bidPane = new JScrollPane(new JTable(m_bidModel));
+ JScrollPane askPane = new JScrollPane(new JTable(m_askModel));
+
+ bidPane.setBorder(BorderFactory.createTitledBorder( "Bid") );
+ askPane.setBorder(BorderFactory.createTitledBorder( "Ask") );
+
+ JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bidPane, askPane);
+ splitPane.setOneTouchExpandable(true);
+ splitPane.setDividerLocation(300);
+ splitPane.setPreferredSize(new Dimension(600, 380));
+
+ JPanel closePanel = new JPanel();
+ closePanel.add(m_close);
+ m_close.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClose();
+ }
+ });
+
+ this.addWindowListener( new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ onClose();
+ }
+ });
+
+
+ getContentPane().add( splitPane, BorderLayout.CENTER);
+ getContentPane().add( closePanel, BorderLayout.SOUTH);
+ setLocation(20, 20);
+ pack();
+ reset();
+ }
+
+ void setParams( EClientSocket client, int id) {
+ m_client = client;
+ m_id = id;
+ reset();
+ }
+
+ void updateMktDepth( int tickerId, int position, String marketMaker,
+ int operation, int side, double price, int size) {
+ try {
+ MktDepthModel.MktDepthTableRow tmpRow = null;
+
+ if (operation == OPERATION_INSERT )
+ {
+ if ( side == SIDE_BID ) {
+ m_bidModel.addOrderAt(position, marketMaker, price, size);
+ }
+ else {
+ m_askModel.addOrderAt(position, marketMaker, price, size);
+ }
+ }
+ else if (operation == OPERATION_UPDATE )
+ {
+ if ( side == SIDE_BID ) {
+ tmpRow = m_bidModel.getOrderAt(position);
+ if ( tmpRow != null ) {
+ tmpRow.m_marketMaker = marketMaker;
+ tmpRow.m_price = price;
+ tmpRow.m_size = size;
+ }
+ m_bidModel.fireTableRowsUpdated(position, position);
+ }
+ else {
+ tmpRow = m_askModel.getOrderAt(position);
+ if ( tmpRow != null ) {
+ tmpRow.m_marketMaker = marketMaker;
+ tmpRow.m_price = price;
+ tmpRow.m_size = size;
+ }
+ m_askModel.fireTableRowsUpdated(position, position);
+ }
+
+ }
+ else if (operation == OPERATION_DELETE)
+ {
+ if ( side == SIDE_BID ) {
+ m_bidModel.removeOrderAt(position);
+ }
+ else {
+ m_askModel.removeOrderAt(position);
+ }
+ }
+
+ if ( side == SIDE_BID ) {
+ m_bidModel.updateCumSizesAndAvgPrices(position);
+ }
+ else {
+ m_askModel.updateCumSizesAndAvgPrices(position);
+ }
+ }
+ catch( Exception e) {
+ System.out.println("Exception: " + e.getMessage());
+ }
+ }
+
+ void reset() {
+ m_bidModel.reset();
+ m_askModel.reset();
+ }
+
+ void onClose() {
+ m_client.cancelMktDepth( m_id );
+ setVisible( false);
+ }
+}
+
+class MktDepthModel extends AbstractTableModel {
+ private LinkedList m_allData = new LinkedList();
+
+ synchronized public void addOrderAt(int position, String marketMaker, double price, int size)
+ {
+ MktDepthTableRow newData = new MktDepthTableRow(marketMaker, price, size);
+ m_allData.add(position, newData);
+ fireTableRowsInserted(position, position);
+ }
+
+ synchronized public void removeOrderAt(int position)
+ {
+ m_allData.remove(position);
+ fireTableRowsDeleted(position, position);
+ }
+
+ synchronized public MktDepthTableRow getOrderAt(int orderPosition) {
+ return (MktDepthTableRow)getIteratorAt(orderPosition).next();
+ }
+
+ synchronized public ListIterator getIteratorAt(int orderPosition) {
+ return m_allData.listIterator(orderPosition);
+ }
+
+ synchronized public void updateCumSizesAndAvgPrices(int baseRow)
+ {
+ int cumSize = 0;
+ double totalPrice = 0.0;
+ MktDepthTableRow tmpRow = null;
+
+ if (baseRow > 0) {
+ tmpRow = (MktDepthTableRow)m_allData.get(baseRow - 1);
+ cumSize = tmpRow.m_cumSize;
+ totalPrice = tmpRow.m_price * cumSize;
+ }
+
+ for (int ctr = baseRow ; ctr < m_allData.size() ; ctr++)
+ {
+ tmpRow = (MktDepthTableRow) m_allData.get(ctr);
+ cumSize += tmpRow.m_size;
+ totalPrice += (tmpRow.m_price * tmpRow.m_size);
+ tmpRow.m_cumSize = cumSize;
+ tmpRow.m_avgPrice = (totalPrice / cumSize);
+ fireTableCellUpdated(ctr, 3);
+ fireTableCellUpdated(ctr, 4);
+ }
+ }
+
+ synchronized public void reset() {
+ m_allData.clear();
+ fireTableDataChanged();
+ }
+
+ synchronized public int getRowCount() {
+ return m_allData.size();
+ }
+
+ synchronized public int getColumnCount() {
+ return 5;
+ }
+
+ synchronized public Object getValueAt(int r, int c) {
+ if (r >= m_allData.size()) {
+ return null;
+ }
+ return ((MktDepthTableRow)m_allData.get(r)).getValue(c);
+ }
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch (c) {
+ case 0:
+ return "MM";
+ case 1:
+ return "Price";
+ case 2:
+ return "Size";
+ case 3:
+ return "Cum Size";
+ case 4:
+ return "Avg Price";
+ default:
+ return null;
+ }
+ }
+
+ class MktDepthTableRow {
+ public String m_marketMaker;
+ public double m_price;
+ public int m_size;
+ public int m_cumSize;
+ public double m_avgPrice;
+
+ MktDepthTableRow(String marketMaker, double price,int size) {
+ m_marketMaker = marketMaker;
+ m_price = price;
+ m_size = size;
+ m_cumSize = 0;
+ m_avgPrice = 0.0;
+ }
+
+ Object getValue(int c) {
+ switch (c)
+ {
+ case 0:
+ return m_marketMaker;
+ case 1:
+ return "" + m_price;
+ case 2:
+ return "" + m_size;
+ case 3:
+ return "" + m_cumSize;
+ case 4:
+ return "" + m_avgPrice;
+ default:
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/NewsBulletinDlg.java b/ib/src/main/java/TestJavaClient/NewsBulletinDlg.java
new file mode 100644
index 00000000..0991134c
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/NewsBulletinDlg.java
@@ -0,0 +1,92 @@
+/*
+ * NewsBulletinDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JRadioButton;
+
+public class NewsBulletinDlg extends JDialog {
+ private IBGridBagPanel m_subscriptionTypePanel = new IBGridBagPanel();
+ private IBGridBagPanel m_mainPanel = new IBGridBagPanel();
+
+ private JButton m_btnSubscribe = new JButton( "Subscribe");
+ private JButton m_btnUnsubscribe = new JButton( "Unsubscribe");
+ private JButton m_btnClose = new JButton( "Close");
+
+ private ButtonGroup m_btnGroup = new ButtonGroup();
+ private JRadioButton m_btnNewMsgs = new JRadioButton( "receive new messages only.");
+ private JRadioButton m_btnAllMsgs = new JRadioButton( "receive all the current day's messages and any new messages.");
+
+ public boolean m_rc;
+ public boolean m_subscribe;
+ public boolean m_allMsgs;
+
+ public NewsBulletinDlg(SampleFrame parent) {
+ super(parent, "IB News Bulletin Subscription", true);
+
+ m_btnGroup.add( m_btnNewMsgs);
+ m_btnGroup.add( m_btnAllMsgs);
+ m_btnNewMsgs.setSelected( true);
+
+ // register button listeners
+ m_btnSubscribe.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onSubscribe();
+ }
+ });
+ m_btnUnsubscribe.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onUnSubscribe();
+ }
+ });
+ m_btnClose.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClose();
+ }
+ });
+
+ m_subscriptionTypePanel.setBorder( BorderFactory.createLineBorder( Color.BLACK));
+ JLabel optionTypeLabel = new JLabel("When subscribing to IB news bulletins you have 2 options:");
+ m_subscriptionTypePanel.SetObjectPlacement(optionTypeLabel, 0, 0);
+ m_subscriptionTypePanel.SetObjectPlacement(m_btnNewMsgs, 0, 1);
+ m_subscriptionTypePanel.SetObjectPlacement(m_btnAllMsgs, 0, 2);
+
+ m_mainPanel.SetObjectPlacement(m_subscriptionTypePanel, 0, 0, 4, 1);
+ m_mainPanel.SetObjectPlacement(m_btnSubscribe, 0, 1);
+ m_mainPanel.SetObjectPlacement(m_btnUnsubscribe, 1, 1);
+ m_mainPanel.SetObjectPlacement(m_btnClose, 3, 1);
+
+ getContentPane().add(m_mainPanel, BorderLayout.CENTER);
+ setSize( 460, 160);
+ }
+
+ private void onSubscribe() {
+ m_rc = true;
+ m_subscribe = true;
+ m_allMsgs = m_btnAllMsgs.isSelected();
+ setVisible( false);
+ }
+
+ private void onUnSubscribe() {
+ m_rc = true;
+ m_subscribe = false;
+ m_allMsgs = false;
+ setVisible( false);
+ }
+
+ private void onClose() {
+ m_rc = false;
+ setVisible( false);
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/OrderDlg.java b/ib/src/main/java/TestJavaClient/OrderDlg.java
new file mode 100644
index 00000000..6198aa48
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/OrderDlg.java
@@ -0,0 +1,498 @@
+/*
+ * OrderDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.JComboBox;
+
+import com.ib.client.Contract;
+import com.ib.client.Order;
+import com.ib.client.UnderComp;
+import com.ib.client.MarketDataType;
+
+public class OrderDlg extends JDialog {
+ final static String ALL_GENERIC_TICK_TAGS = "100,101,104,105,106,107,165,221,225,233,236,258,293,294,295,318";
+ final static int OPERATION_INSERT = 0;
+ final static int OPERATION_UPDATE = 1;
+ final static int OPERATION_DELETE = 2;
+
+ final static int SIDE_ASK = 0;
+ final static int SIDE_BID = 1;
+
+ public boolean m_rc;
+ public int m_id;
+ public String m_backfillEndTime;
+ public String m_backfillDuration;
+ public String m_barSizeSetting;
+ public int m_useRTH;
+ public int m_formatDate;
+ public int m_marketDepthRows;
+ public String m_whatToShow;
+ public Contract m_contract = new Contract();
+ public Order m_order = new Order();
+ public UnderComp m_underComp = new UnderComp();
+ public int m_exerciseAction;
+ public int m_exerciseQuantity;
+ public int m_override;
+ public int m_marketDataType;
+
+ private JTextField m_Id = new JTextField( "0");
+ private JTextField m_BackfillEndTime = new JTextField(22);
+ private JTextField m_BackfillDuration = new JTextField( "1 M");
+ private JTextField m_BarSizeSetting = new JTextField("1 day");
+ private JTextField m_UseRTH = new JTextField( "1");
+ private JTextField m_FormatDate = new JTextField( "1");
+ private JTextField m_WhatToShow = new JTextField( "TRADES");
+ private JTextField m_conId = new JTextField();
+ private JTextField m_symbol = new JTextField( "QQQQ");
+ private JTextField m_secType = new JTextField( "STK");
+ private JTextField m_expiry = new JTextField();
+ private JTextField m_strike = new JTextField( "0");
+ private JTextField m_right = new JTextField();
+ private JTextField m_multiplier = new JTextField("");
+ private JTextField m_exchange = new JTextField( "SMART");
+ private JTextField m_primaryExch = new JTextField( "ISLAND" );
+ private JTextField m_currency = new JTextField("USD");
+ private JTextField m_localSymbol = new JTextField();
+ private JTextField m_includeExpired = new JTextField("0");
+ private JTextField m_secIdType = new JTextField();
+ private JTextField m_secId = new JTextField();
+ private JTextField m_action = new JTextField( "BUY");
+ private JTextField m_totalQuantity = new JTextField( "10");
+ private JTextField m_orderType = new JTextField( "LMT");
+ private JTextField m_lmtPrice = new JTextField( "40");
+ private JTextField m_auxPrice = new JTextField( "0");
+ private JTextField m_goodAfterTime = new JTextField();
+ private JTextField m_goodTillDate = new JTextField();
+ private JTextField m_marketDepthRowTextField = new JTextField( "20");
+ private JTextField m_genericTicksTextField = new JTextField(ALL_GENERIC_TICK_TAGS);
+ private JCheckBox m_snapshotMktDataTextField = new JCheckBox("Snapshot", false);
+ private JTextField m_exerciseActionTextField = new JTextField("1");
+ private JTextField m_exerciseQuantityTextField = new JTextField("1");
+ private JTextField m_overrideTextField = new JTextField("0");
+ private JComboBox m_marketDataTypeCombo = new JComboBox(MarketDataType.getFields());
+
+ private JButton m_sharesAlloc = new JButton("FA Allocation Info...");
+ private JButton m_comboLegs = new JButton( "Combo Legs");
+ private JButton m_btnUnderComp = new JButton( "Delta Neutral");
+ private JButton m_btnAlgoParams = new JButton( "Algo Params");
+ private JButton m_btnSmartComboRoutingParams = new JButton( "Smart Combo Routing Params");
+
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+ private SampleFrame m_parent;
+
+ private String m_faGroup;
+ private String m_faProfile;
+ private String m_faMethod;
+ private String m_faPercentage;
+ public String m_genericTicks;
+ public boolean m_snapshotMktData;
+
+ private static final int COL1_WIDTH = 30 ;
+ private static final int COL2_WIDTH = 100 - COL1_WIDTH ;
+ public void faGroup(String s) { m_faGroup = s;}
+ public void faProfile(String s) { m_faProfile = s;}
+ public void faMethod(String s) { m_faMethod = s;}
+ public void faPercentage(String s) { m_faPercentage = s; }
+
+ private static void addGBComponent(IBGridBagPanel panel, Component comp,
+ GridBagConstraints gbc, int weightx, int gridwidth)
+ {
+ gbc.weightx = weightx;
+ gbc.gridwidth = gridwidth;
+ panel.setConstraints(comp, gbc);
+ panel.add(comp, gbc);
+ }
+
+ public OrderDlg( SampleFrame owner) {
+ super( owner, true);
+
+ m_parent = owner;
+ setTitle( "Sample");
+
+ java.awt.GridBagConstraints gbc = new java.awt.GridBagConstraints() ;
+ gbc.fill = GridBagConstraints.BOTH ;
+ gbc.anchor = GridBagConstraints.CENTER ;
+ gbc.weighty = 100 ;
+ gbc.fill = GridBagConstraints.BOTH ;
+ gbc.gridheight = 1 ;
+ // create id panel
+ IBGridBagPanel pId = new IBGridBagPanel();
+ pId.setBorder( BorderFactory.createTitledBorder( "Message Id") );
+
+ addGBComponent(pId, new JLabel( "Id"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pId, m_Id, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create contract panel
+ IBGridBagPanel pContractDetails = new IBGridBagPanel();
+ pContractDetails.setBorder( BorderFactory.createTitledBorder( "Contract Info") );
+ addGBComponent(pContractDetails, new JLabel( "Contract Id"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_conId, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Symbol"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_symbol, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Security Type"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_secType, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Expiry"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_expiry, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Strike"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_strike, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Put/Call"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_right, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Option Multiplier"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_multiplier, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Exchange"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_exchange, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Primary Exchange"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_primaryExch, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Currency"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_currency, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Local Symbol"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_localSymbol, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Include Expired"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_includeExpired, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Sec Id Type"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_secIdType, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pContractDetails, new JLabel( "Sec Id"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pContractDetails, m_secId, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+
+ // create order panel
+ IBGridBagPanel pOrderDetails = new IBGridBagPanel();
+ pOrderDetails.setBorder( BorderFactory.createTitledBorder( "Order Info") );
+ addGBComponent(pOrderDetails, new JLabel( "Action"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_action, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Total Order Size"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_totalQuantity, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Order Type"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_orderType, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Lmt Price / Option Price / Volatility"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_lmtPrice, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Aux Price / Underlying Price"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_auxPrice, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Good After Time"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_goodAfterTime, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pOrderDetails, new JLabel( "Good Till Date"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pOrderDetails, m_goodTillDate, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+
+ // create marketDepth panel
+ IBGridBagPanel pMarketDepth = new IBGridBagPanel();
+ pMarketDepth.setBorder( BorderFactory.createTitledBorder( "Market Depth") );
+ addGBComponent(pMarketDepth, new JLabel( "Number of Rows"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pMarketDepth, m_marketDepthRowTextField, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create marketData panel
+ IBGridBagPanel pMarketData = new IBGridBagPanel();
+ pMarketData.setBorder( BorderFactory.createTitledBorder( "Market Data") );
+ addGBComponent(pMarketData, new JLabel( "Generic Tick Tags"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pMarketData, m_genericTicksTextField, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pMarketData, m_snapshotMktDataTextField, gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+
+ // create options exercise panel
+ IBGridBagPanel pOptionsExercise= new IBGridBagPanel();
+ pOptionsExercise.setBorder( BorderFactory.createTitledBorder( "Options Exercise") );
+ addGBComponent(pOptionsExercise, new JLabel( "Action (1 or 2)"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pOptionsExercise, m_exerciseActionTextField, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pOptionsExercise, new JLabel( "Number of Contracts"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pOptionsExercise, m_exerciseQuantityTextField, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pOptionsExercise, new JLabel( "Override (0 or 1)"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pOptionsExercise, m_overrideTextField, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create historical data panel
+ IBGridBagPanel pBackfill = new IBGridBagPanel();
+ pBackfill.setBorder( BorderFactory.createTitledBorder( "Historical Data Query") );
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTimeZone(TimeZone.getTimeZone("GMT"));
+ String dateTime = "" +
+ gc.get(Calendar.YEAR) +
+ pad(gc.get(Calendar.MONTH) + 1) +
+ pad(gc.get(Calendar.DAY_OF_MONTH)) + " " +
+ pad(gc.get(Calendar.HOUR_OF_DAY)) + ":" +
+ pad(gc.get(Calendar.MINUTE)) + ":" +
+ pad(gc.get(Calendar.SECOND)) + " " +
+ gc.getTimeZone().getDisplayName( false, TimeZone.SHORT);
+
+ m_BackfillEndTime.setText(dateTime);
+ addGBComponent(pBackfill, new JLabel( "End Date/Time"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_BackfillEndTime, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pBackfill, new JLabel( "Duration"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_BackfillDuration, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pBackfill, new JLabel( "Bar Size Setting (1 to 11)"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_BarSizeSetting, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pBackfill, new JLabel( "What to Show"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_WhatToShow, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pBackfill, new JLabel( "Regular Trading Hours (1 or 0)"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_UseRTH, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(pBackfill, new JLabel( "Date Format Style (1 or 2)"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pBackfill, m_FormatDate, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create marketDataType panel
+ IBGridBagPanel pMarketDataType = new IBGridBagPanel();
+ pMarketDataType.setBorder( BorderFactory.createTitledBorder( "Market Data Type") );
+ addGBComponent(pMarketDataType, new JLabel( "Market Data Type"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pMarketDataType, m_marketDataTypeCombo, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create mid Panel
+ JPanel pMidPanel = new JPanel();
+ pMidPanel.setLayout( new BoxLayout( pMidPanel, BoxLayout.Y_AXIS) );
+ pMidPanel.add( pContractDetails, BorderLayout.CENTER);
+ pMidPanel.add( pOrderDetails, BorderLayout.CENTER);
+ pMidPanel.add( pMarketDepth, BorderLayout.CENTER);
+ pMidPanel.add( pMarketData, BorderLayout.CENTER);
+ pMidPanel.add( pOptionsExercise, BorderLayout.CENTER);
+ pMidPanel.add( pBackfill, BorderLayout.CENTER);
+ pMidPanel.add( pMarketDataType, BorderLayout.CENTER);
+
+ // create order button panel
+ JPanel pOrderButtonPanel = new JPanel();
+ pOrderButtonPanel.add( m_sharesAlloc);
+ pOrderButtonPanel.add( m_comboLegs);
+ pOrderButtonPanel.add( m_btnUnderComp);
+ pOrderButtonPanel.add( m_btnAlgoParams);
+ pOrderButtonPanel.add( m_btnSmartComboRoutingParams);
+
+ pMidPanel.add( pOrderButtonPanel, BorderLayout.CENTER);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create action listeners
+ m_sharesAlloc.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onSharesAlloc();
+ }
+ });
+
+ m_comboLegs.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onAddComboLegs();
+ }
+ });
+ m_btnUnderComp.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onBtnUnderComp();
+ }
+ });
+ m_btnAlgoParams.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onBtnAlgoParams();
+ }
+ });
+ m_btnSmartComboRoutingParams.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onBtnSmartComboRoutingParams();
+ }
+ });
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ // create top panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout( new BoxLayout( topPanel, BoxLayout.Y_AXIS) );
+ topPanel.add( pId);
+ topPanel.add( pMidPanel);
+
+ // create dlg box
+ getContentPane().add( topPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ JScrollPane scroller = new JScrollPane(topPanel);
+ this.add( scroller, BorderLayout.CENTER);
+
+ pack();
+ }
+
+ private static String pad( int val) {
+ return val < 10 ? "0" + val : "" + val;
+ }
+
+ void onSharesAlloc() {
+ if ( !m_parent.m_bIsFAAccount ) {
+ return;
+ }
+
+ FAAllocationInfoDlg dlg = new FAAllocationInfoDlg(this);
+
+ // show the combo leg dialog
+ dlg.setVisible(true);
+ }
+
+ void onAddComboLegs() {
+
+ ComboLegDlg comboLegDlg = new ComboLegDlg(
+ m_contract.m_comboLegs, m_exchange.getText(), this);
+
+ // show the combo leg dialog
+ comboLegDlg.setVisible( true);
+ }
+
+ void onBtnUnderComp() {
+
+ UnderCompDlg underCompDlg = new UnderCompDlg(m_underComp, this);
+
+ // show delta neutral dialog
+ underCompDlg.setVisible( true);
+ if (underCompDlg.ok()) {
+ m_contract.m_underComp = m_underComp;
+ }
+ else if (underCompDlg.reset()) {
+ m_contract.m_underComp = null;
+ }
+ }
+
+ void onBtnAlgoParams() {
+
+ AlgoParamsDlg algoParamsDlg = new AlgoParamsDlg(m_order, this);
+
+ // show delta neutral dialog
+ algoParamsDlg.setVisible( true);
+ }
+
+ void onBtnSmartComboRoutingParams() {
+
+ SmartComboRoutingParamsDlg smartComboRoutingParamsDlg = new SmartComboRoutingParamsDlg(m_order, this);
+
+ // show smart combo routing params dialog
+ smartComboRoutingParamsDlg.setVisible( true);
+ }
+
+ void onOk() {
+ m_rc = false;
+
+ try {
+ // set id
+ m_id = Integer.parseInt( m_Id.getText() );
+
+ // set contract fields
+ m_contract.m_conId = ParseInt(m_conId.getText(), 0);
+ m_contract.m_symbol = m_symbol.getText();
+ m_contract.m_secType = m_secType.getText();
+ m_contract.m_expiry = m_expiry.getText();
+ m_contract.m_strike = ParseDouble(m_strike.getText(), 0.0);
+ m_contract.m_right = m_right.getText();
+ m_contract.m_multiplier = m_multiplier.getText();
+ m_contract.m_exchange = m_exchange.getText();
+ m_contract.m_primaryExch = m_primaryExch.getText();
+ m_contract.m_currency = m_currency.getText();
+ m_contract.m_localSymbol = m_localSymbol.getText();
+ try {
+ int includeExpired = Integer.parseInt(m_includeExpired.getText());
+ m_contract.m_includeExpired = (includeExpired == 1);
+ }
+ catch (NumberFormatException ex) {
+ m_contract.m_includeExpired = false;
+ }
+ m_contract.m_secIdType = m_secIdType.getText();
+ m_contract.m_secId = m_secId.getText();
+
+ // set order fields
+ m_order.m_action = m_action.getText();
+ m_order.m_totalQuantity = Integer.parseInt( m_totalQuantity.getText() );
+ m_order.m_orderType = m_orderType.getText();
+ m_order.m_lmtPrice = Double.parseDouble( m_lmtPrice.getText() );
+ m_order.m_auxPrice = Double.parseDouble( m_auxPrice.getText() );
+ m_order.m_goodAfterTime = m_goodAfterTime.getText();
+ m_order.m_goodTillDate = m_goodTillDate.getText();
+
+ m_order.m_faGroup = m_faGroup;
+ m_order.m_faProfile = m_faProfile;
+ m_order.m_faMethod = m_faMethod;
+ m_order.m_faPercentage = m_faPercentage;
+
+ // set historical data fields
+ m_backfillEndTime = m_BackfillEndTime.getText();
+ m_backfillDuration = m_BackfillDuration.getText();
+ m_barSizeSetting = m_BarSizeSetting.getText();
+ m_useRTH = Integer.parseInt( m_UseRTH.getText() );
+ m_whatToShow = m_WhatToShow.getText();
+ m_formatDate = Integer.parseInt( m_FormatDate.getText() );
+ m_exerciseAction = Integer.parseInt( m_exerciseActionTextField.getText() );
+ m_exerciseQuantity = Integer.parseInt( m_exerciseQuantityTextField.getText() );
+ m_override = Integer.parseInt( m_overrideTextField.getText() );;
+
+ // set market depth rows
+ m_marketDepthRows = Integer.parseInt( m_marketDepthRowTextField.getText() );
+ m_genericTicks = m_genericTicksTextField.getText();
+ m_snapshotMktData = m_snapshotMktDataTextField.isSelected();
+
+ m_marketDataType = m_marketDataTypeCombo.getSelectedIndex() + 1;
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ return;
+ }
+
+ m_rc = true;
+ setVisible( false);
+ }
+
+ void onCancel() {
+ m_rc = false;
+ setVisible( false);
+ }
+
+ public void show() {
+ m_rc = false;
+ super.show();
+ }
+
+ void setIdAtLeast( int id) {
+ try {
+ // set id field to at least id
+ int curId = Integer.parseInt( m_Id.getText() );
+ if( curId < id) {
+ m_Id.setText( String.valueOf( id) );
+ }
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ }
+ }
+
+ private static int ParseInt(String text, int defValue) {
+ try {
+ return Integer.parseInt(text);
+ }
+ catch (NumberFormatException e) {
+ return defValue;
+ }
+ }
+
+ private static double ParseDouble(String text, double defValue) {
+ try {
+ return Double.parseDouble(text);
+ }
+ catch (NumberFormatException e) {
+ return defValue;
+ }
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/SampleFrame.java b/ib/src/main/java/TestJavaClient/SampleFrame.java
new file mode 100644
index 00000000..e7baa894
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/SampleFrame.java
@@ -0,0 +1,1060 @@
+/*
+ * SampleFrame.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.HashMap;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import com.ib.client.Contract;
+import com.ib.client.ContractDetails;
+import com.ib.client.EClientSocket;
+import com.ib.client.EWrapper;
+import com.ib.client.EWrapperMsgGenerator;
+import com.ib.client.Execution;
+import com.ib.client.Order;
+import com.ib.client.OrderState;
+import com.ib.client.UnderComp;
+import com.ib.client.Util;
+
+class SampleFrame extends JFrame implements EWrapper {
+ private static final int NOT_AN_FA_ACCOUNT_ERROR = 321 ;
+ private int faErrorCodes[] = { 503, 504, 505, 522, 1100, NOT_AN_FA_ACCOUNT_ERROR } ;
+ private boolean faError ;
+
+ private EClientSocket m_client = new EClientSocket( this);
+ private IBTextPanel m_tickers = new IBTextPanel("Market and Historical Data", false);
+ private IBTextPanel m_TWS = new IBTextPanel("TWS Server Responses", false);
+ private IBTextPanel m_errors = new IBTextPanel("Errors and Messages", false);
+ private OrderDlg m_orderDlg = new OrderDlg( this);
+ private ExtOrdDlg m_extOrdDlg = new ExtOrdDlg( m_orderDlg);
+ private AccountDlg m_acctDlg = new AccountDlg(this);
+ private HashMap m_mapRequestToMktDepthDlg = new HashMap();
+ private NewsBulletinDlg m_newsBulletinDlg = new NewsBulletinDlg(this);
+ private ScannerDlg m_scannerDlg = new ScannerDlg(this);
+
+ String faGroupXML ;
+ String faProfilesXML ;
+ String faAliasesXML ;
+ public String m_FAAcctCodes;
+ public boolean m_bIsFAAccount = false;
+
+ private boolean m_disconnectInProgress = false;
+
+ SampleFrame() {
+ JPanel scrollingWindowDisplayPanel = new JPanel( new GridLayout( 0, 1) );
+ scrollingWindowDisplayPanel.add( m_tickers);
+ scrollingWindowDisplayPanel.add( m_TWS);
+ scrollingWindowDisplayPanel.add( m_errors);
+
+ JPanel buttonPanel = createButtonPanel();
+
+ getContentPane().add( scrollingWindowDisplayPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.EAST);
+ setSize( 600, 700);
+ setTitle( "Sample");
+ setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
+ }
+
+ private JPanel createButtonPanel() {
+ JPanel buttonPanel = new JPanel( new GridLayout( 0, 1) );
+ JButton butConnect = new JButton( "Connect");
+ butConnect.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onConnect();
+ }
+ });
+ JButton butDisconnect = new JButton( "Disconnect");
+ butDisconnect.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onDisconnect();
+ }
+ });
+ JButton butMktData = new JButton( "Req Mkt Data");
+ butMktData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqMktData();
+ }
+ });
+ JButton butCancelMktData = new JButton( "Cancel Mkt Data");
+ butCancelMktData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelMktData();
+ }
+ });
+ JButton butMktDepth = new JButton( "Req Mkt Depth");
+ butMktDepth.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqMktDepth();
+ }
+ });
+ JButton butCancelMktDepth = new JButton( "Cancel Mkt Depth");
+ butCancelMktDepth.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelMktDepth();
+ }
+ });
+ JButton butHistoricalData = new JButton( "Historical Data");
+ butHistoricalData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onHistoricalData();
+ }
+ });
+ JButton butCancelHistoricalData = new JButton( "Cancel Hist. Data");
+ butCancelHistoricalData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelHistoricalData();
+ }
+ });
+ JButton butRealTimeBars = new JButton( "Req Real Time Bars");
+ butRealTimeBars.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqRealTimeBars();
+ }
+ });
+ JButton butCancelRealTimeBars = new JButton( "Cancel Real Time Bars");
+ butCancelRealTimeBars.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelRealTimeBars();
+ }
+ });
+ JButton butCurrentTime = new JButton( "Req Current Time");
+ butCurrentTime.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqCurrentTime();
+ }
+ });
+ JButton butScanner = new JButton( "Market Scanner");
+ butScanner.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onScanner();
+ }
+ });
+ JButton butOpenOrders = new JButton( "Req Open Orders");
+ butOpenOrders.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqOpenOrders();
+ }
+ });
+ JButton butCalculateImpliedVolatility = new JButton( "Calculate Implied Volatility");
+ butCalculateImpliedVolatility.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCalculateImpliedVolatility();
+ }
+ });
+ JButton butCancelCalculateImpliedVolatility = new JButton( "Cancel Calc Impl Volatility");
+ butCancelCalculateImpliedVolatility.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelCalculateImpliedVolatility();
+ }
+ });
+ JButton butCalculateOptionPrice = new JButton( "Calculate Option Price");
+ butCalculateOptionPrice.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCalculateOptionPrice();
+ }
+ });
+ JButton butCancelCalculateOptionPrice = new JButton( "Cancel Calc Opt Price");
+ butCancelCalculateOptionPrice.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelCalculateOptionPrice();
+ }
+ });
+ JButton butWhatIfOrder = new JButton( "What If");
+ butWhatIfOrder.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onWhatIfOrder();
+ }
+ });
+ JButton butPlaceOrder = new JButton( "Place Order");
+ butPlaceOrder.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onPlaceOrder();
+ }
+ });
+ JButton butCancelOrder = new JButton( "Cancel Order");
+ butCancelOrder.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelOrder();
+ }
+ });
+ JButton butExerciseOptions = new JButton( "Exercise Options");
+ butExerciseOptions.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onExerciseOptions();
+ }
+ });
+ JButton butExtendedOrder = new JButton( "Extended");
+ butExtendedOrder.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onExtendedOrder();
+ }
+ });
+ JButton butAcctData = new JButton( "Req Acct Data");
+ butAcctData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqAcctData();
+ }
+ });
+ JButton butContractData = new JButton( "Req Contract Data");
+ butContractData.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqContractData();
+ }
+ });
+ JButton butExecutions = new JButton( "Req Executions");
+ butExecutions.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqExecutions();
+ }
+ });
+ JButton butNewsBulletins = new JButton( "Req News Bulletins");
+ butNewsBulletins.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqNewsBulletins();
+ }
+ });
+ JButton butServerLogging = new JButton( "Server Logging");
+ butServerLogging.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onServerLogging();
+ }
+ });
+ JButton butAllOpenOrders = new JButton( "Req All Open Orders");
+ butAllOpenOrders.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqAllOpenOrders();
+ }
+ });
+ JButton butAutoOpenOrders = new JButton( "Req Auto Open Orders");
+ butAutoOpenOrders.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqAutoOpenOrders();
+ }
+ });
+ JButton butManagedAccts = new JButton( "Req Accounts");
+ butManagedAccts.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqManagedAccts();
+ }
+ });
+ JButton butFinancialAdvisor = new JButton( "Financial Advisor");
+ butFinancialAdvisor.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onFinancialAdvisor();
+ }
+ });
+ JButton butGlobalCancel = new JButton( "Global Cancel");
+ butGlobalCancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onGlobalCancel();
+ }
+ });
+ JButton butReqMarketDataType = new JButton( "Req Market Data Type");
+ butReqMarketDataType.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReqMarketDataType();
+ }
+ });
+
+ JButton butClear = new JButton( "Clear");
+ butClear.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClear();
+ }
+ });
+ JButton butClose = new JButton( "Close");
+ butClose.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onClose();
+ }
+ });
+
+
+ buttonPanel.add( new JPanel() );
+ buttonPanel.add( butConnect);
+ buttonPanel.add( butDisconnect);
+
+ buttonPanel.add( new JPanel() );
+ buttonPanel.add( butMktData);
+ buttonPanel.add( butCancelMktData);
+ buttonPanel.add( butMktDepth);
+ buttonPanel.add( butCancelMktDepth);
+ buttonPanel.add( butHistoricalData);
+ buttonPanel.add( butCancelHistoricalData);
+ buttonPanel.add( butRealTimeBars);
+ buttonPanel.add( butCancelRealTimeBars);
+ buttonPanel.add( butScanner);
+ buttonPanel.add( butCurrentTime);
+ buttonPanel.add( butCalculateImpliedVolatility);
+ buttonPanel.add( butCancelCalculateImpliedVolatility);
+ buttonPanel.add( butCalculateOptionPrice);
+ buttonPanel.add( butCancelCalculateOptionPrice);
+
+ buttonPanel.add( new JPanel() );
+ buttonPanel.add( butWhatIfOrder);
+ buttonPanel.add( butPlaceOrder);
+ buttonPanel.add( butCancelOrder);
+ buttonPanel.add( butExerciseOptions);
+ buttonPanel.add( butExtendedOrder);
+
+ buttonPanel.add( new JPanel() );
+ buttonPanel.add( butContractData );
+ buttonPanel.add( butOpenOrders);
+ buttonPanel.add( butAllOpenOrders);
+ buttonPanel.add( butAutoOpenOrders);
+ buttonPanel.add( butAcctData );
+ buttonPanel.add( butExecutions );
+ buttonPanel.add( butNewsBulletins );
+ buttonPanel.add( butServerLogging );
+ buttonPanel.add( butManagedAccts );
+ buttonPanel.add( butFinancialAdvisor ) ;
+ buttonPanel.add( butGlobalCancel ) ;
+ buttonPanel.add( butReqMarketDataType ) ;
+
+ buttonPanel.add( new JPanel() );
+ buttonPanel.add( butClear );
+ buttonPanel.add( butClose );
+
+ return buttonPanel;
+ }
+
+ void onConnect() {
+ m_bIsFAAccount = false;
+ // get connection parameters
+ ConnectDlg dlg = new ConnectDlg( this);
+ dlg.setVisible(true);
+ if( !dlg.m_rc) {
+ return;
+ }
+
+ // connect to TWS
+ m_disconnectInProgress = false;
+
+ m_client.eConnect( dlg.m_retIpAddress, dlg.m_retPort, dlg.m_retClientId);
+ if (m_client.isConnected()) {
+ m_TWS.add("Connected to Tws server version " +
+ m_client.serverVersion() + " at " +
+ m_client.TwsConnectionTime());
+ }
+ }
+
+ void onDisconnect() {
+ // disconnect from TWS
+ m_disconnectInProgress = true;
+ m_client.eDisconnect();
+ }
+
+ void onReqMktData() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // req mkt data
+ m_client.reqMktData( m_orderDlg.m_id, m_orderDlg.m_contract,
+ m_orderDlg.m_genericTicks, m_orderDlg.m_snapshotMktData);
+ }
+
+ void onReqRealTimeBars() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+ // req mkt data
+ m_client.reqRealTimeBars( m_orderDlg.m_id, m_orderDlg.m_contract,
+ 5 /* TODO: parse and use m_orderDlg.m_barSizeSetting */,
+ m_orderDlg.m_whatToShow, m_orderDlg.m_useRTH > 0);
+ }
+
+ void onCancelRealTimeBars() {
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+ // cancel market data
+ m_client.cancelRealTimeBars( m_orderDlg.m_id );
+ }
+
+ void onScanner() {
+ m_scannerDlg.show();
+ if (m_scannerDlg.m_userSelection == ScannerDlg.CANCEL_SELECTION) {
+ m_client.cancelScannerSubscription(m_scannerDlg.m_id);
+ }
+ else if (m_scannerDlg.m_userSelection == ScannerDlg.SUBSCRIBE_SELECTION) {
+ m_client.reqScannerSubscription(m_scannerDlg.m_id,
+ m_scannerDlg.m_subscription);
+ }
+ else if (m_scannerDlg.m_userSelection == ScannerDlg.REQUEST_PARAMETERS_SELECTION) {
+ m_client.reqScannerParameters();
+ }
+ }
+
+ void onReqCurrentTime() {
+ m_client.reqCurrentTime();
+ }
+
+ void onHistoricalData() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ if( Util.StringCompare( m_orderDlg.m_whatToShow, "estimates" ) == 0 ||
+ Util.StringCompare( m_orderDlg.m_whatToShow, "finstat" ) == 0 ||
+ Util.StringCompare( m_orderDlg.m_whatToShow, "snapshot" ) == 0 ) {
+
+ m_client.reqFundamentalData(m_orderDlg.m_id, m_orderDlg.m_contract,
+ /* reportType */ m_orderDlg.m_whatToShow);
+ return;
+ }
+
+ // req historical data
+ m_client.reqHistoricalData( m_orderDlg.m_id, m_orderDlg.m_contract,
+ m_orderDlg.m_backfillEndTime, m_orderDlg.m_backfillDuration,
+ m_orderDlg.m_barSizeSetting, m_orderDlg.m_whatToShow,
+ m_orderDlg.m_useRTH, m_orderDlg.m_formatDate );
+ }
+
+ void onCancelHistoricalData() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ if( Util.StringCompare( m_orderDlg.m_whatToShow, "estimates" ) == 0 ||
+ Util.StringCompare( m_orderDlg.m_whatToShow, "finstat" ) == 0 ||
+ Util.StringCompare( m_orderDlg.m_whatToShow, "snapshot" ) == 0 ) {
+
+ m_client.cancelFundamentalData(m_orderDlg.m_id);
+ return;
+ }
+
+ // cancel historical data
+ m_client.cancelHistoricalData( m_orderDlg.m_id );
+ }
+
+ void onReqContractData() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // req mkt data
+ m_client.reqContractDetails( m_orderDlg.m_id, m_orderDlg.m_contract );
+ }
+
+ void onReqMktDepth() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ final Integer dialogId = m_orderDlg.m_id;
+ MktDepthDlg depthDialog = m_mapRequestToMktDepthDlg.get(dialogId);
+ if ( depthDialog == null ) {
+ depthDialog = new MktDepthDlg("Market Depth ID ["+dialogId+"]", this);
+ m_mapRequestToMktDepthDlg.put(dialogId, depthDialog);
+
+ // cleanup the map after depth dialog is closed so it does not linger or leak memory
+ depthDialog.addWindowListener(new WindowAdapter() {
+ @Override public void windowClosed(WindowEvent e) {
+ m_mapRequestToMktDepthDlg.remove(dialogId);
+ }
+ });
+ }
+
+ depthDialog.setParams( m_client, dialogId);
+
+ // req mkt data
+ m_client.reqMktDepth( dialogId, m_orderDlg.m_contract, m_orderDlg.m_marketDepthRows );
+ depthDialog.setVisible(true);
+ }
+
+ void onCancelMktData() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // cancel market data
+ m_client.cancelMktData( m_orderDlg.m_id );
+ }
+
+ void onCancelMktDepth() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // cancel market data
+ m_client.cancelMktDepth( m_orderDlg.m_id );
+ }
+
+ void onReqOpenOrders() {
+ m_client.reqOpenOrders();
+ }
+
+ void onWhatIfOrder() {
+ placeOrder(true);
+ }
+
+ void onPlaceOrder() {
+ placeOrder(false);
+ }
+
+ void placeOrder(boolean whatIf) {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ Order order = m_orderDlg.m_order;
+
+ // save old and set new value of whatIf attribute
+ boolean savedWhatIf = order.m_whatIf;
+ order.m_whatIf = whatIf;
+
+ // place order
+ m_client.placeOrder( m_orderDlg.m_id, m_orderDlg.m_contract, order );
+
+ // restore whatIf attribute
+ order.m_whatIf = savedWhatIf;
+ }
+
+ void onExerciseOptions() {
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // cancel order
+ m_client.exerciseOptions( m_orderDlg.m_id, m_orderDlg.m_contract,
+ m_orderDlg.m_exerciseAction, m_orderDlg.m_exerciseQuantity,
+ m_orderDlg.m_order.m_account, m_orderDlg.m_override);
+ }
+
+ void onCancelOrder() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // cancel order
+ m_client.cancelOrder( m_orderDlg.m_id );
+ }
+
+ void onExtendedOrder() {
+ //Show the extended order attributes dialog
+ m_extOrdDlg.setVisible(true);
+ if( !m_extOrdDlg.m_rc ) {
+ return;
+ }
+
+ // Copy over the extended order details
+ copyExtendedOrderDetails( m_orderDlg.m_order, m_extOrdDlg.m_order);
+ }
+
+ void onReqAcctData() {
+ AcctUpdatesDlg dlg = new AcctUpdatesDlg(this);
+
+ dlg.setVisible(true);
+
+ if ( dlg.m_subscribe) {
+ m_acctDlg.accountDownloadBegin(dlg.m_acctCode);
+ }
+
+ m_client.reqAccountUpdates( dlg.m_subscribe, dlg.m_acctCode);
+
+ if ( m_client.isConnected() && dlg.m_subscribe) {
+ m_acctDlg.reset();
+ m_acctDlg.setVisible(true);
+ }
+ }
+
+ void onFinancialAdvisor() {
+ faGroupXML = faProfilesXML = faAliasesXML = null ;
+ faError = false ;
+ m_client.requestFA(EClientSocket.GROUPS) ;
+ m_client.requestFA(EClientSocket.PROFILES) ;
+ m_client.requestFA(EClientSocket.ALIASES) ;
+ }
+
+ void onServerLogging() {
+ // get server logging level
+ LogConfigDlg dlg = new LogConfigDlg( this);
+ dlg.setVisible(true);
+ if( !dlg.m_rc) {
+ return;
+ }
+
+ // connect to TWS
+ m_client.setServerLogLevel( dlg.m_serverLogLevel);
+ }
+
+ void onReqAllOpenOrders() {
+ // request list of all open orders
+ m_client.reqAllOpenOrders();
+ }
+
+ void onReqAutoOpenOrders() {
+ // request to automatically bind any newly entered TWS orders
+ // to this API client. NOTE: TWS orders can only be bound to
+ // client's with clientId=0.
+ m_client.reqAutoOpenOrders( true);
+ }
+
+ void onReqManagedAccts() {
+ // request the list of managed accounts
+ m_client.reqManagedAccts();
+ }
+
+ void onClear() {
+ m_tickers.clear();
+ m_TWS.clear();
+ m_errors.clear();
+ }
+
+ void onClose() {
+ System.exit(1);
+ }
+
+ void onReqExecutions() {
+ ExecFilterDlg dlg = new ExecFilterDlg(this);
+
+ dlg.setVisible(true);
+ if ( dlg.m_rc ) {
+ // request execution reports based on the supplied filter criteria
+ m_client.reqExecutions( dlg.m_reqId, dlg.m_execFilter);
+ }
+ }
+
+ void onReqNewsBulletins() {
+ // run m_newsBulletinDlg
+ m_newsBulletinDlg.setVisible(true);
+ if( !m_newsBulletinDlg.m_rc ) {
+ return;
+ }
+
+ if ( m_newsBulletinDlg.m_subscribe ) {
+ m_client.reqNewsBulletins( m_newsBulletinDlg.m_allMsgs);
+ }
+ else {
+ m_client.cancelNewsBulletins();
+ }
+ }
+
+ void onCalculateImpliedVolatility() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ m_client.calculateImpliedVolatility( m_orderDlg.m_id, m_orderDlg.m_contract,
+ m_orderDlg.m_order.m_lmtPrice, m_orderDlg.m_order.m_auxPrice);
+ }
+
+ void onCancelCalculateImpliedVolatility() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ m_client.cancelCalculateImpliedVolatility( m_orderDlg.m_id);
+ }
+
+ void onCalculateOptionPrice() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ m_client.calculateOptionPrice( m_orderDlg.m_id, m_orderDlg.m_contract,
+ m_orderDlg.m_order.m_lmtPrice, m_orderDlg.m_order.m_auxPrice);
+ }
+
+ void onCancelCalculateOptionPrice() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ m_client.cancelCalculateOptionPrice( m_orderDlg.m_id);
+ }
+
+ void onGlobalCancel() {
+ m_client.reqGlobalCancel();
+ }
+
+ void onReqMarketDataType() {
+ // run m_orderDlg
+ m_orderDlg.show();
+ if( !m_orderDlg.m_rc ) {
+ return;
+ }
+
+ // req mkt data type
+ m_client.reqMarketDataType( m_orderDlg.m_marketDataType);
+ }
+
+ 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 );
+ }
+
+ public void tickOptionComputation( int tickerId, int field, double impliedVol, double delta, double optPrice, double pvDividend,
+ double gamma, double vega, double theta, double undPrice) {
+ // received computation tick
+ String msg = EWrapperMsgGenerator.tickOptionComputation( tickerId, field, impliedVol, delta, optPrice, pvDividend,
+ gamma, vega, theta, undPrice);
+ m_tickers.add( msg );
+ }
+
+ public void tickSize( int tickerId, int field, int size) {
+ // received size tick
+ String msg = EWrapperMsgGenerator.tickSize( tickerId, field, size);
+ m_tickers.add( msg);
+ }
+
+ public void tickGeneric( int tickerId, int tickType, double value) {
+ // received generic tick
+ String msg = EWrapperMsgGenerator.tickGeneric(tickerId, tickType, value);
+ m_tickers.add( msg);
+ }
+
+ public void tickString( int tickerId, int tickType, String value) {
+ // received String tick
+ String msg = EWrapperMsgGenerator.tickString(tickerId, tickType, value);
+ m_tickers.add( msg);
+ }
+
+ public void tickSnapshotEnd(int tickerId) {
+ String msg = EWrapperMsgGenerator.tickSnapshotEnd(tickerId);
+ m_tickers.add( msg) ;
+ }
+
+ public void tickEFP(int tickerId, int tickType, double basisPoints, String formattedBasisPoints,
+ double impliedFuture, int holdDays, String futureExpiry, double dividendImpact,
+ double dividendsToExpiry) {
+ // received EFP tick
+ String msg = EWrapperMsgGenerator.tickEFP(tickerId, tickType, basisPoints, formattedBasisPoints,
+ impliedFuture, holdDays, futureExpiry, dividendImpact, dividendsToExpiry);
+ m_tickers.add(msg);
+ }
+
+ public void orderStatus( int orderId, String status, int filled, int remaining,
+ double avgFillPrice, int permId, int parentId,
+ double lastFillPrice, int clientId, String whyHeld) {
+ // received order status
+ String msg = EWrapperMsgGenerator.orderStatus( orderId, status, filled, remaining,
+ avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld);
+ m_TWS.add( msg);
+
+ // make sure id for next order is at least orderId+1
+ m_orderDlg.setIdAtLeast( orderId + 1);
+ }
+
+ public void openOrder( int orderId, Contract contract, Order order, OrderState orderState) {
+ // received open order
+ String msg = EWrapperMsgGenerator.openOrder( orderId, contract, order, orderState);
+ m_TWS.add( msg) ;
+ }
+
+ public void openOrderEnd() {
+ // received open order end
+ String msg = EWrapperMsgGenerator.openOrderEnd();
+ m_TWS.add( msg) ;
+ }
+
+ public void contractDetails(int reqId, ContractDetails contractDetails) {
+ String msg = EWrapperMsgGenerator.contractDetails( reqId, contractDetails);
+ m_TWS.add(msg);
+ }
+
+ public void contractDetailsEnd(int reqId) {
+ String msg = EWrapperMsgGenerator.contractDetailsEnd(reqId);
+ m_TWS.add(msg);
+ }
+
+ public void scannerData(int reqId, int rank, ContractDetails contractDetails,
+ String distance, String benchmark, String projection, String legsStr) {
+ String msg = EWrapperMsgGenerator.scannerData(reqId, rank, contractDetails, distance,
+ benchmark, projection, legsStr);
+ m_tickers.add(msg);
+ }
+
+ public void scannerDataEnd(int reqId) {
+ String msg = EWrapperMsgGenerator.scannerDataEnd(reqId);
+ m_tickers.add(msg);
+ }
+
+ public void bondContractDetails(int reqId, ContractDetails contractDetails)
+ {
+ String msg = EWrapperMsgGenerator.bondContractDetails( reqId, contractDetails);
+ m_TWS.add(msg);
+ }
+
+ public void execDetails(int reqId, Contract contract, Execution execution)
+ {
+ String msg = EWrapperMsgGenerator.execDetails(reqId, contract, execution);
+ m_TWS.add(msg);
+ }
+
+ public void execDetailsEnd(int reqId)
+ {
+ String msg = EWrapperMsgGenerator.execDetailsEnd(reqId);
+ m_TWS.add(msg);
+ }
+
+ public void updateMktDepth( int tickerId, int position, int operation,
+ int side, double price, int size) {
+
+ MktDepthDlg depthDialog = m_mapRequestToMktDepthDlg.get(tickerId);
+ if ( depthDialog != null ) {
+ depthDialog.updateMktDepth( tickerId, position, "", operation, side, price, size);
+ } else {
+ System.err.println("cannot find dialog that corresponds to request id ["+tickerId+"]");
+ }
+
+
+ }
+
+ public void updateMktDepthL2( int tickerId, int position, String marketMaker,
+ int operation, int side, double price, int size) {
+ MktDepthDlg depthDialog = m_mapRequestToMktDepthDlg.get(tickerId);
+ if ( depthDialog != null ) {
+ depthDialog.updateMktDepth( tickerId, position, marketMaker, operation, side, price, size);
+ } else {
+ System.err.println("cannot find dialog that corresponds to request id ["+tickerId+"]");
+ }
+ }
+
+ public void nextValidId( int orderId) {
+ // received next valid order id
+ String msg = EWrapperMsgGenerator.nextValidId( orderId);
+ m_TWS.add(msg) ;
+ m_orderDlg.setIdAtLeast( orderId);
+ }
+
+ public void error(Exception ex) {
+ // do not report exceptions if we initiated disconnect
+ if (!m_disconnectInProgress) {
+ String msg = EWrapperMsgGenerator.error(ex);
+ Main.inform( this, msg);
+ }
+ }
+
+ public void error( String str) {
+ String msg = EWrapperMsgGenerator.error(str);
+ m_errors.add( msg);
+ }
+
+ public void error( int id, int errorCode, String errorMsg) {
+ // received error
+ String msg = EWrapperMsgGenerator.error(id, errorCode, errorMsg);
+ m_errors.add( msg);
+ for (int ctr=0; ctr < faErrorCodes.length; ctr++) {
+ faError |= (errorCode == faErrorCodes[ctr]);
+ }
+ if (errorCode == MktDepthDlg.MKT_DEPTH_DATA_RESET) {
+
+ MktDepthDlg depthDialog = m_mapRequestToMktDepthDlg.get(id);
+ if ( depthDialog != null ) {
+ depthDialog.reset();
+ } else {
+ System.err.println("cannot find dialog that corresponds to request id ["+id+"]");
+ }
+ }
+ }
+
+ public void connectionClosed() {
+ String msg = EWrapperMsgGenerator.connectionClosed();
+ Main.inform( this, msg);
+ }
+
+ public void updateAccountValue(String key, String value,
+ String currency, String accountName) {
+ m_acctDlg.updateAccountValue(key, value, currency, accountName);
+ }
+
+ public void updatePortfolio(Contract contract, int position, double marketPrice,
+ double marketValue, double averageCost, double unrealizedPNL, double realizedPNL,
+ String accountName) {
+ m_acctDlg.updatePortfolio(contract, position, marketPrice, marketValue,
+ averageCost, unrealizedPNL, realizedPNL, accountName);
+ }
+
+ public void updateAccountTime(String timeStamp) {
+ m_acctDlg.updateAccountTime(timeStamp);
+ }
+
+ public void accountDownloadEnd(String accountName) {
+ m_acctDlg.accountDownloadEnd( accountName);
+
+ String msg = EWrapperMsgGenerator.accountDownloadEnd( accountName);
+ m_TWS.add( msg);
+ }
+
+ public void updateNewsBulletin( int msgId, int msgType, String message, String origExchange) {
+ String msg = EWrapperMsgGenerator.updateNewsBulletin(msgId, msgType, message, origExchange);
+ JOptionPane.showMessageDialog(this, msg, "IB News Bulletin", JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ public void managedAccounts( String accountsList) {
+ m_bIsFAAccount = true;
+ m_FAAcctCodes = accountsList;
+ String msg = EWrapperMsgGenerator.managedAccounts(accountsList);
+ m_TWS.add( msg);
+ }
+
+ public void historicalData(int reqId, String date, double open, double high, double low,
+ double close, int volume, int count, double WAP, boolean hasGaps) {
+ String msg = EWrapperMsgGenerator.historicalData(reqId, date, open, high, low, close, volume, count, WAP, hasGaps);
+ m_tickers.add( msg );
+ }
+ public void realtimeBar(int reqId, long time, double open, double high, double low, double close, long volume, double wap, int count) {
+ String msg = EWrapperMsgGenerator.realtimeBar(reqId, time, open, high, low, close, volume, wap, count);
+ m_tickers.add( msg );
+ }
+ public void scannerParameters(String xml) {
+ displayXML(EWrapperMsgGenerator.SCANNER_PARAMETERS, xml);
+ }
+
+ public void currentTime(long time) {
+ String msg = EWrapperMsgGenerator.currentTime(time);
+ m_TWS.add(msg);
+ }
+ public void fundamentalData(int reqId, String data) {
+ String msg = EWrapperMsgGenerator.fundamentalData(reqId, data);
+ m_tickers.add(msg);
+ }
+ public void deltaNeutralValidation(int reqId, UnderComp underComp) {
+ String msg = EWrapperMsgGenerator.deltaNeutralValidation(reqId, underComp);
+ m_TWS.add(msg);
+ }
+
+ void displayXML(String title, String xml) {
+ m_TWS.add(title);
+ m_TWS.addText(xml);
+ }
+
+ public void receiveFA(int faDataType, String xml) {
+ displayXML(EWrapperMsgGenerator.FINANCIAL_ADVISOR + " " + EClientSocket.faMsgTypeName(faDataType), xml);
+ switch (faDataType) {
+ case EClientSocket.GROUPS:
+ faGroupXML = xml ;
+ break ;
+ case EClientSocket.PROFILES:
+ faProfilesXML = xml ;
+ break ;
+ case EClientSocket.ALIASES:
+ faAliasesXML = xml ;
+ break ;
+ }
+
+ if (!faError &&
+ !(faGroupXML == null || faProfilesXML == null || faAliasesXML == null)) {
+ FinancialAdvisorDlg dlg = new FinancialAdvisorDlg(this);
+ dlg.receiveInitialXML(faGroupXML, faProfilesXML, faAliasesXML);
+ dlg.setVisible(true);
+
+ if (!dlg.m_rc) {
+ return;
+ }
+
+ m_client.replaceFA( EClientSocket.GROUPS, dlg.groupsXML );
+ m_client.replaceFA( EClientSocket.PROFILES, dlg.profilesXML );
+ m_client.replaceFA( EClientSocket.ALIASES, dlg.aliasesXML );
+
+ }
+ }
+
+ public void marketDataType(int reqId, int marketDataType) {
+ String msg = EWrapperMsgGenerator.marketDataType(reqId, marketDataType);
+ m_tickers.add(msg);
+ }
+
+ private void copyExtendedOrderDetails( Order destOrder, Order srcOrder) {
+ destOrder.m_tif = srcOrder.m_tif;
+ destOrder.m_ocaGroup = srcOrder.m_ocaGroup;
+ destOrder.m_ocaType = srcOrder.m_ocaType;
+ destOrder.m_openClose = srcOrder.m_openClose;
+ destOrder.m_origin = srcOrder.m_origin;
+ destOrder.m_orderRef = srcOrder.m_orderRef;
+ destOrder.m_transmit = srcOrder.m_transmit;
+ destOrder.m_parentId = srcOrder.m_parentId;
+ destOrder.m_blockOrder = srcOrder.m_blockOrder;
+ destOrder.m_sweepToFill = srcOrder.m_sweepToFill;
+ destOrder.m_displaySize = srcOrder.m_displaySize;
+ destOrder.m_triggerMethod = srcOrder.m_triggerMethod;
+ destOrder.m_outsideRth = srcOrder.m_outsideRth;
+ destOrder.m_hidden = srcOrder.m_hidden;
+ destOrder.m_discretionaryAmt = srcOrder.m_discretionaryAmt;
+ destOrder.m_goodAfterTime = srcOrder.m_goodAfterTime;
+ destOrder.m_shortSaleSlot = srcOrder.m_shortSaleSlot;
+ destOrder.m_designatedLocation = srcOrder.m_designatedLocation;
+ destOrder.m_exemptCode = srcOrder.m_exemptCode;
+ destOrder.m_ocaType = srcOrder.m_ocaType;
+ destOrder.m_rule80A = srcOrder.m_rule80A;
+ destOrder.m_allOrNone = srcOrder.m_allOrNone;
+ destOrder.m_minQty = srcOrder.m_minQty;
+ destOrder.m_percentOffset = srcOrder.m_percentOffset;
+ destOrder.m_eTradeOnly = srcOrder.m_eTradeOnly;
+ destOrder.m_firmQuoteOnly = srcOrder.m_firmQuoteOnly;
+ destOrder.m_nbboPriceCap = srcOrder.m_nbboPriceCap;
+ destOrder.m_optOutSmartRouting = srcOrder.m_optOutSmartRouting;
+ destOrder.m_auctionStrategy = srcOrder.m_auctionStrategy;
+ destOrder.m_startingPrice = srcOrder.m_startingPrice;
+ destOrder.m_stockRefPrice = srcOrder.m_stockRefPrice;
+ destOrder.m_delta = srcOrder.m_delta;
+ destOrder.m_stockRangeLower = srcOrder.m_stockRangeLower;
+ destOrder.m_stockRangeUpper = srcOrder.m_stockRangeUpper;
+ destOrder.m_overridePercentageConstraints = srcOrder.m_overridePercentageConstraints;
+ destOrder.m_volatility = srcOrder.m_volatility;
+ destOrder.m_volatilityType = srcOrder.m_volatilityType;
+ destOrder.m_deltaNeutralOrderType = srcOrder.m_deltaNeutralOrderType;
+ destOrder.m_deltaNeutralAuxPrice = srcOrder.m_deltaNeutralAuxPrice;
+ destOrder.m_deltaNeutralConId = srcOrder.m_deltaNeutralConId;
+ destOrder.m_deltaNeutralSettlingFirm = srcOrder.m_deltaNeutralSettlingFirm;
+ destOrder.m_deltaNeutralClearingAccount = srcOrder.m_deltaNeutralClearingAccount;
+ destOrder.m_deltaNeutralClearingIntent = srcOrder.m_deltaNeutralClearingIntent;
+ destOrder.m_continuousUpdate = srcOrder.m_continuousUpdate;
+ destOrder.m_referencePriceType = srcOrder.m_referencePriceType;
+ destOrder.m_trailStopPrice = srcOrder.m_trailStopPrice;
+ destOrder.m_scaleInitLevelSize = srcOrder.m_scaleInitLevelSize;
+ destOrder.m_scaleSubsLevelSize = srcOrder.m_scaleSubsLevelSize;
+ destOrder.m_scalePriceIncrement = srcOrder.m_scalePriceIncrement;
+ destOrder.m_hedgeType = srcOrder.m_hedgeType;
+ destOrder.m_hedgeParam = srcOrder.m_hedgeParam;
+ destOrder.m_account = srcOrder.m_account;
+ destOrder.m_settlingFirm = srcOrder.m_settlingFirm;
+ destOrder.m_clearingAccount = srcOrder.m_clearingAccount;
+ destOrder.m_clearingIntent = srcOrder.m_clearingIntent;
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/ScannerDlg.java b/ib/src/main/java/TestJavaClient/ScannerDlg.java
new file mode 100644
index 00000000..99f59dc2
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/ScannerDlg.java
@@ -0,0 +1,250 @@
+/*
+ * ScannerDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import com.ib.client.ScannerSubscription;
+
+public class ScannerDlg extends JDialog {
+ public static final int NO_SELECTION = 0;
+ public static final int SUBSCRIBE_SELECTION = 1;
+ public static final int CANCEL_SELECTION = 2;
+ public static final int REQUEST_PARAMETERS_SELECTION = 3;
+
+ public int m_userSelection = NO_SELECTION;
+ public int m_id;
+ public ScannerSubscription m_subscription = new ScannerSubscription();
+
+ private JTextField m_Id = new JTextField( "0");
+ private JTextField m_numberOfRows = new JTextField("10");
+ private JTextField m_instrument = new JTextField("STK");
+ private JTextField m_locationCode = new JTextField("STK.US.MAJOR");
+ private JTextField m_scanCode = new JTextField("HIGH_OPT_VOLUME_PUT_CALL_RATIO");
+ private JTextField m_abovePrice = new JTextField("3");
+ private JTextField m_belowPrice = new JTextField();
+ private JTextField m_aboveVolume = new JTextField("0");
+ private JTextField m_averageOptionVolumeAbove = new JTextField("0");
+ private JTextField m_marketCapAbove = new JTextField("100000000");
+ private JTextField m_marketCapBelow = new JTextField();
+ private JTextField m_moodyRatingAbove = new JTextField();
+ private JTextField m_moodyRatingBelow = new JTextField();
+ private JTextField m_spRatingAbove = new JTextField();
+ private JTextField m_spRatingBelow = new JTextField();
+ private JTextField m_maturityDateAbove = new JTextField();
+ private JTextField m_maturityDateBelow = new JTextField();
+ private JTextField m_couponRateAbove = new JTextField();
+ private JTextField m_couponRateBelow = new JTextField();
+ private JTextField m_excludeConvertible = new JTextField("0");
+ private JTextField m_scannerSettingPairs = new JTextField("Annual,true");
+ private JTextField m_stockTypeFilter = new JTextField("ALL");
+
+ private JButton m_requestParameters = new JButton( "Request Parameters");
+ private JButton m_subscribe = new JButton( "Subscribe");
+ private JButton m_cancel = new JButton( "Cancel Subscription");
+ private SampleFrame m_parent;
+
+ private static final int COL1_WIDTH = 30 ;
+ private static final int COL2_WIDTH = 100 - COL1_WIDTH ;
+
+ private static void addGBComponent(IBGridBagPanel panel, Component comp,
+ GridBagConstraints gbc, int weightx, int gridwidth)
+ {
+ gbc.weightx = weightx;
+ gbc.gridwidth = gridwidth;
+ panel.setConstraints(comp, gbc);
+ panel.add(comp, gbc);
+ }
+
+ public ScannerDlg( SampleFrame owner) {
+ super( owner, true);
+
+ m_parent = owner;
+ setTitle( "Sample");
+
+ java.awt.GridBagConstraints gbc = new java.awt.GridBagConstraints() ;
+ gbc.fill = gbc.BOTH ;
+ gbc.anchor = gbc.CENTER ;
+ gbc.weighty = 100 ;
+ gbc.fill = GridBagConstraints.BOTH ;
+ gbc.gridheight = 1 ;
+ // create id panel
+ IBGridBagPanel pId = new IBGridBagPanel();
+ pId.setBorder( BorderFactory.createTitledBorder( "Message Id") );
+
+ addGBComponent(pId, new JLabel( "Id"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(pId, m_Id, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+ // create contract panel
+ IBGridBagPanel pSubscriptionDetails = new IBGridBagPanel();
+ pSubscriptionDetails.setBorder( BorderFactory.createTitledBorder( "Subscription Info") );
+ addGBComponent(pSubscriptionDetails, new JLabel( "Number of Rows"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_numberOfRows, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Instrument"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_instrument, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Location Code"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_locationCode, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Scan Code"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_scanCode , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Above Price"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_abovePrice , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Below Price"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_belowPrice , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Above Volume"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_aboveVolume , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Avg Option Volume Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_averageOptionVolumeAbove, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Market Cap Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_marketCapAbove , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Market Cap Below"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_marketCapBelow , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Moody Rating Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_moodyRatingAbove , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Moody Rating Below"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_moodyRatingBelow , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "S & P Rating Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_spRatingAbove , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "S & P Rating Below"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_spRatingBelow , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Maturity Date Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_maturityDateAbove , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Maturity Date Below"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_maturityDateBelow , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Coupon Rate Above"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_couponRateAbove , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Coupon Rate Below"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_couponRateBelow , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Exclude Convertible"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_excludeConvertible , gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Scanner Setting Pairs"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_scannerSettingPairs, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+ addGBComponent(pSubscriptionDetails, new JLabel( "Stock Type Filter"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE );
+ addGBComponent(pSubscriptionDetails, m_stockTypeFilter, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_requestParameters);
+ buttonPanel.add( m_subscribe);
+ buttonPanel.add( m_cancel);
+
+ m_requestParameters.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onRequestParameters();
+ }
+ });
+ m_subscribe.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onSubscribe();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancelSubscription();
+ }
+ });
+
+ // create top panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout( new BoxLayout( topPanel, BoxLayout.Y_AXIS) );
+ topPanel.add( pId);
+ topPanel.add( pSubscriptionDetails);
+
+ // create dlg box
+ getContentPane().add( topPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ pack();
+ }
+
+ private static String pad( int val) {
+ return val < 10 ? "0" + val : "" + val;
+ }
+
+ private double parseDouble(JTextField textfield) {
+ try {
+ return Double.parseDouble(textfield.getText().trim());
+ }
+ catch (Exception ex) {
+ return Double.MAX_VALUE;
+ }
+ }
+
+ private int parseInt(JTextField textfield) {
+ try {
+ return Integer.parseInt(textfield.getText().trim());
+ }
+ catch (Exception ex) {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+
+ void onSubscribe() {
+ m_userSelection = NO_SELECTION;
+
+ try {
+ // set id
+ m_id = Integer.parseInt( m_Id.getText().trim() );
+ m_subscription.numberOfRows(parseInt(m_numberOfRows));
+ m_subscription.instrument(m_instrument.getText().trim());
+ m_subscription.locationCode(m_locationCode.getText().trim() );
+ m_subscription.scanCode(m_scanCode.getText().trim() );
+ m_subscription.abovePrice(parseDouble(m_abovePrice));
+ m_subscription.belowPrice(parseDouble(m_belowPrice));
+ m_subscription.aboveVolume(parseInt(m_aboveVolume));
+ int avgOptVolume = parseInt(m_averageOptionVolumeAbove);
+ // with Integer.MAX_VALUE creates filter in TWS
+ m_subscription.averageOptionVolumeAbove(avgOptVolume!= Integer.MAX_VALUE ? avgOptVolume : Integer.MIN_VALUE);
+ m_subscription.marketCapAbove(parseDouble(m_marketCapAbove));
+ m_subscription.marketCapBelow(parseDouble(m_marketCapBelow));
+ m_subscription.moodyRatingAbove(m_moodyRatingAbove.getText().trim());
+ m_subscription.moodyRatingBelow(m_moodyRatingBelow.getText().trim());
+ m_subscription.spRatingAbove(m_spRatingAbove.getText().trim());
+ m_subscription.spRatingBelow(m_spRatingBelow.getText().trim());
+ m_subscription.maturityDateAbove(m_maturityDateAbove.getText().trim());
+ m_subscription.maturityDateBelow(m_maturityDateBelow.getText().trim());
+ m_subscription.couponRateAbove(parseDouble(m_couponRateAbove));
+ m_subscription.couponRateBelow(parseDouble(m_couponRateBelow));
+ m_subscription.excludeConvertible(m_excludeConvertible.getText().trim());
+ m_subscription.scannerSettingPairs(m_scannerSettingPairs.getText().trim());
+ // m_subscription.stockTypeFilter(m_stockTypeFilter.getText().trim()); Peter ???
+ }
+ catch( Exception e) {
+ Main.inform( this, "Error - " + e);
+ return;
+ }
+
+ m_userSelection = SUBSCRIBE_SELECTION;
+ setVisible( false);
+ }
+
+ void onRequestParameters() {
+ m_userSelection = REQUEST_PARAMETERS_SELECTION;
+ setVisible( false);
+ }
+
+ void onCancelSubscription() {
+ m_userSelection = CANCEL_SELECTION;
+ m_id = Integer.parseInt( m_Id.getText().trim() );
+ setVisible( false);
+ }
+
+ public void show() {
+ m_userSelection = NO_SELECTION;
+ super.show();
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/TestJavaClient/SmartComboRoutingParamsDlg.java b/ib/src/main/java/TestJavaClient/SmartComboRoutingParamsDlg.java
new file mode 100644
index 00000000..d9ed5453
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/SmartComboRoutingParamsDlg.java
@@ -0,0 +1,236 @@
+/*
+ *
+ * SmartComboRoutingParamsDlg.java
+ *
+ */
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.AbstractTableModel;
+
+import com.ib.client.Order;
+import com.ib.client.TagValue;
+
+public class SmartComboRoutingParamsDlg extends JDialog {
+
+ private Order m_order;
+
+ private Vector m_smartComboRoutingParams;
+
+ private JTextField m_tag = new JTextField( "");
+ private JTextField m_value = new JTextField( "");
+
+ private JButton m_addParam = new JButton( "Add");
+ private JButton m_removeParam = new JButton( "Remove");
+
+ private JButton m_ok = new JButton( "OK");
+ private JButton m_cancel = new JButton( "Cancel");
+
+ private SmartComboRoutingParamModel m_paramModel = new SmartComboRoutingParamModel();
+ private JTable m_paramTable = new JTable(m_paramModel);
+ private JScrollPane m_paramPane = new JScrollPane(m_paramTable);
+
+ public SmartComboRoutingParamModel paramModel() { return m_paramModel; }
+
+ public SmartComboRoutingParamsDlg( Order order, JDialog owner) {
+ super( owner, true);
+
+ m_order = order;
+
+ setTitle( "Smart Combo Routing Parameters");
+
+ // create smart combo routing params panel
+ JPanel pParamList = new JPanel( new GridLayout( 0, 1, 10, 10) );
+ pParamList.setBorder( BorderFactory.createTitledBorder( "Smart Combo Routing Parameters") );
+
+ Vector smartComboRoutingParams = m_order.m_smartComboRoutingParams;
+ if (smartComboRoutingParams != null) {
+ m_paramModel.smartComboRoutingParams().addAll(smartComboRoutingParams);
+ }
+ pParamList.add( m_paramPane);
+
+ // create add/remove panel
+ JPanel pParamListControl = new JPanel( new GridLayout( 0, 2, 10, 10) );
+ pParamListControl.setBorder( BorderFactory.createTitledBorder( "Add / Remove") );
+ pParamListControl.add( new JLabel( "Param:") );
+ pParamListControl.add( m_tag);
+ pParamListControl.add( new JLabel( "Value:") );
+ pParamListControl.add( m_value);
+ pParamListControl.add( m_addParam);
+ pParamListControl.add( m_removeParam);
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_ok);
+ buttonPanel.add( m_cancel);
+
+ // create wrapper panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout( new BoxLayout( topPanel, BoxLayout.Y_AXIS) );
+ topPanel.add( pParamList);
+ topPanel.add( pParamListControl);
+
+ // create dlg box
+ getContentPane().add( topPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+
+ // create action listeners
+ m_addParam.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onAddParam();
+ }
+ });
+ m_removeParam.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onRemoveParam();
+ }
+ });
+ m_ok.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_cancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ setSize(250, 600);
+ centerOnOwner( this);
+ }
+
+ public void onAddParam() {
+ try {
+ String tag = m_tag.getText();
+ String value = m_value.getText();
+
+ m_paramModel.addParam( new TagValue(tag, value));
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ public void onRemoveParam() {
+ try {
+ if ( m_paramTable.getSelectedRowCount() != 0 ) {
+ int[] rows = m_paramTable.getSelectedRows();
+ for ( int i=rows.length -1; i>=0 ; i-- ) {
+ m_paramModel.removeParam( rows[i]);
+ }
+ }
+ }
+ catch( Exception e) {
+ reportError( "Error - ", e);
+ return;
+ }
+ }
+
+ void onOk() {
+ Vector smartComboRoutingParams = m_paramModel.smartComboRoutingParams();
+ m_order.m_smartComboRoutingParams = smartComboRoutingParams.isEmpty() ? null : smartComboRoutingParams;
+
+ setVisible( false);
+ }
+
+ void onCancel() {
+ setVisible( false);
+ }
+
+
+ void reportError( String msg, Exception e) {
+ Main.inform( this, msg + " --" + e);
+ }
+
+ private void centerOnOwner( Window window) {
+ Window owner = window.getOwner();
+ if( owner == null) {
+ return;
+ }
+ int x = owner.getX() + ((owner.getWidth() - window.getWidth()) / 2);
+ int y = owner.getY() + ((owner.getHeight() - window.getHeight()) / 2);
+ if( x < 0) x = 0;
+ if( y < 0) y = 0;
+ window.setLocation( x, y);
+ }
+}
+
+class SmartComboRoutingParamModel extends AbstractTableModel {
+
+ private Vector m_allData = new Vector();
+
+ synchronized public void addParam( TagValue tagValue)
+ {
+ m_allData.add( tagValue);
+ fireTableDataChanged();
+ }
+
+ synchronized public void removeParam( int index)
+ {
+ m_allData.remove( index);
+ fireTableDataChanged();
+ }
+
+ synchronized public void reset() {
+ m_allData.removeAllElements();
+ fireTableDataChanged();
+ }
+
+ synchronized public int getRowCount() {
+ return m_allData.size();
+ }
+
+ synchronized public int getColumnCount() {
+ return 2;
+ }
+
+ synchronized public Object getValueAt(int r, int c) {
+ TagValue tagValue = (TagValue)m_allData.get(r);
+
+ switch (c) {
+ case 0:
+ return tagValue.m_tag;
+ case 1:
+ return tagValue.m_value;
+ default:
+ return "";
+ }
+
+ }
+
+ public boolean isCellEditable(int r, int c) {
+ return false;
+ }
+
+ public String getColumnName(int c) {
+ switch (c) {
+ case 0:
+ return "Param";
+ case 1:
+ return "Value";
+ default:
+ return null;
+ }
+ }
+
+ public Vector smartComboRoutingParams() {
+ return m_allData;
+ }
+}
diff --git a/ib/src/main/java/TestJavaClient/UnderCompDlg.java b/ib/src/main/java/TestJavaClient/UnderCompDlg.java
new file mode 100644
index 00000000..60cb7333
--- /dev/null
+++ b/ib/src/main/java/TestJavaClient/UnderCompDlg.java
@@ -0,0 +1,146 @@
+/*
+ * UnderCompDlg.java
+ *
+ */
+
+package TestJavaClient;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import com.ib.client.UnderComp;
+
+public class UnderCompDlg extends JDialog {
+
+ private UnderComp m_underComp;
+
+ private JTextField m_txtConId = new JTextField();
+ private JTextField m_txtDelta = new JTextField();
+ private JTextField m_txtPrice = new JTextField();
+
+ private JButton m_btnOk = new JButton( "OK");
+ private JButton m_btnReset = new JButton( "Reset");
+ private JButton m_btnCancel = new JButton( "Cancel");
+
+ private boolean m_ok = false;
+ private boolean m_reset = false;
+
+ private static final int COL1_WIDTH = 30 ;
+ private static final int COL2_WIDTH = 100 - COL1_WIDTH ;
+
+ public UnderCompDlg(UnderComp underComp, JDialog owner) {
+ super( owner, true);
+
+ m_underComp = underComp;
+
+ // create button panel
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add( m_btnOk);
+ buttonPanel.add( m_btnReset);
+ buttonPanel.add( m_btnCancel);
+
+ // create action listeners
+ m_btnOk.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onOk();
+ }
+ });
+ m_btnReset.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onReset();
+ }
+ });
+ m_btnCancel.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ java.awt.GridBagConstraints gbc = new java.awt.GridBagConstraints() ;
+ gbc.fill = GridBagConstraints.BOTH ;
+ gbc.anchor = GridBagConstraints.CENTER ;
+ gbc.weighty = 100 ;
+ gbc.fill = GridBagConstraints.BOTH ;
+ gbc.gridheight = 1 ;
+
+ // create mid panel
+ IBGridBagPanel midPanel = new IBGridBagPanel();
+ midPanel.setBorder(BorderFactory.createTitledBorder( "Under Comp"));
+ addGBComponent(midPanel, new JLabel( "Contract Id"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(midPanel, m_txtConId, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(midPanel, new JLabel( "Delta"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(midPanel, m_txtDelta, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+ addGBComponent(midPanel, new JLabel( "Price"), gbc, COL1_WIDTH, GridBagConstraints.RELATIVE) ;
+ addGBComponent(midPanel, m_txtPrice, gbc, COL2_WIDTH, GridBagConstraints.REMAINDER) ;
+
+
+ m_txtConId.setText(Integer.toString(m_underComp.m_conId));
+ m_txtDelta.setText(Double.toString(m_underComp.m_delta));
+ m_txtPrice.setText(Double.toString(m_underComp.m_price));
+
+ // create dlg box
+ getContentPane().add( midPanel, BorderLayout.CENTER);
+ getContentPane().add( buttonPanel, BorderLayout.SOUTH);
+ setTitle( "Delta Neutral");
+ pack();
+ }
+
+
+ private void onOk() {
+
+ try {
+ int conId = Integer.parseInt(m_txtConId.getText());
+ double delta = Double.parseDouble(m_txtDelta.getText());
+ double price = Double.parseDouble(m_txtPrice.getText());
+
+ m_underComp.m_conId = conId;
+ m_underComp.m_delta = delta;
+ m_underComp.m_price = price;
+ m_ok = true;
+ setVisible( false);
+ }
+ catch ( Exception e) {
+ Main.inform( this, "Error - " + e);
+ }
+ }
+
+ private void onReset() {
+ m_underComp.m_conId = 0;
+ m_underComp.m_delta = 0;
+ m_underComp.m_price = 0;
+ m_reset = true;
+ setVisible( false);
+ }
+
+ private void onCancel() {
+ setVisible( false);
+ }
+
+ public boolean ok() {
+ return m_ok;
+ }
+
+ public boolean reset() {
+ return m_reset;
+ }
+
+ private static void addGBComponent(IBGridBagPanel panel, Component comp,
+ GridBagConstraints gbc, int weightx, int gridwidth)
+ {
+ gbc.weightx = weightx;
+ gbc.gridwidth = gridwidth;
+ panel.setConstraints(comp, gbc);
+ panel.add(comp, gbc);
+ }
+
+}
diff --git a/ib/src/main/java/com/ib/client/AnyWrapper.java b/ib/src/main/java/com/ib/client/AnyWrapper.java
new file mode 100644
index 00000000..c0380bec
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/AnyWrapper.java
@@ -0,0 +1,14 @@
+/*
+ * AnyWrapper.java
+ *
+ */
+package com.ib.client;
+
+
+public interface AnyWrapper {
+ void error( Exception e);
+ void error( String str);
+ void error(int id, int errorCode, String errorMsg);
+ void connectionClosed();
+}
+
diff --git a/ib/src/main/java/com/ib/client/AnyWrapperMsgGenerator.java b/ib/src/main/java/com/ib/client/AnyWrapperMsgGenerator.java
new file mode 100644
index 00000000..dac517d2
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/AnyWrapperMsgGenerator.java
@@ -0,0 +1,19 @@
+package com.ib.client;
+
+public class AnyWrapperMsgGenerator {
+ public static String error( Exception ex) { return "Error - " + ex;}
+ public static String error( String str) { return str;}
+
+ public static String error(int id, int errorCode, String errorMsg) {
+ String err = Integer.toString(id);
+ err += " | ";
+ err += Integer.toString(errorCode);
+ err += " | ";
+ err += errorMsg;
+ return err;
+ }
+
+ public static String connectionClosed() {
+ return "Connection Closed";
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/ComboLeg.java b/ib/src/main/java/com/ib/client/ComboLeg.java
new file mode 100644
index 00000000..e4464618
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/ComboLeg.java
@@ -0,0 +1,82 @@
+/*
+ * ComboLeg.java
+ *
+ */
+package com.ib.client;
+
+
+public class ComboLeg {
+ public final static int SAME = 0; // open/close leg value is same as combo
+ public final static int OPEN = 1;
+ public final static int CLOSE = 2;
+ public final static int UNKNOWN = 3;
+
+ public int m_conId;
+ public int m_ratio;
+ public String m_action; // BUY/SELL/SSHORT/SSHORTX
+ public String m_exchange;
+ public int m_openClose;
+
+ // for stock legs when doing short sale
+ public int m_shortSaleSlot; // 1 = clearing broker, 2 = third party
+ public String m_designatedLocation;
+ public int m_exemptCode;
+
+ public ComboLeg() {
+ this(/* conId */ 0, /* ratio */ 0, /* action */ null,
+ /* exchange */ null, /* openClose */ 0,
+ /* shortSaleSlot */ 0, /* designatedLocation*/ null, /* exemptCode */ -1);
+ }
+
+ public ComboLeg(int p_conId, int p_ratio, String p_action, String p_exchange, int p_openClose) {
+ this(p_conId, p_ratio, p_action, p_exchange, p_openClose,
+ /* shortSaleSlot */ 0, /* designatedLocation*/ null, /* exemptCode */ -1);
+
+ }
+
+ public ComboLeg(int p_conId, int p_ratio, String p_action, String p_exchange,
+ int p_openClose, int p_shortSaleSlot, String p_designatedLocation) {
+ this(p_conId, p_ratio, p_action, p_exchange, p_openClose, p_shortSaleSlot, p_designatedLocation,
+ /* exemptCode */ -1);
+
+ }
+
+ public ComboLeg(int p_conId, int p_ratio, String p_action, String p_exchange,
+ int p_openClose, int p_shortSaleSlot, String p_designatedLocation, int p_exemptCode) {
+ m_conId = p_conId;
+ m_ratio = p_ratio;
+ m_action = p_action;
+ m_exchange = p_exchange;
+ m_openClose = p_openClose;
+ m_shortSaleSlot = p_shortSaleSlot;
+ m_designatedLocation = p_designatedLocation;
+ m_exemptCode = p_exemptCode;
+ }
+
+ public boolean equals(Object p_other) {
+ if ( this == p_other ) {
+ return true;
+ }
+ else if ( p_other == null ) {
+ return false;
+ }
+
+ ComboLeg l_theOther = (ComboLeg)p_other;
+
+ if (m_conId != l_theOther.m_conId ||
+ m_ratio != l_theOther.m_ratio ||
+ m_openClose != l_theOther.m_openClose ||
+ m_shortSaleSlot != l_theOther.m_shortSaleSlot ||
+ m_exemptCode != l_theOther.m_exemptCode) {
+ return false;
+ }
+
+ if (Util.StringCompareIgnCase(m_action, l_theOther.m_action) != 0 ||
+ Util.StringCompareIgnCase(m_exchange, l_theOther.m_exchange) != 0 ||
+ Util.StringCompareIgnCase(m_designatedLocation, l_theOther.m_designatedLocation) != 0) {
+ return false;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/Contract.java b/ib/src/main/java/com/ib/client/Contract.java
new file mode 100644
index 00000000..8eab7dc5
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/Contract.java
@@ -0,0 +1,134 @@
+/*
+ * Contract.java
+ *
+ */
+package com.ib.client;
+
+import java.util.Vector;
+
+public class Contract implements Cloneable {
+
+ public int m_conId;
+ public String m_symbol;
+ public String m_secType;
+ public String m_expiry;
+ public double m_strike;
+ public String m_right;
+ public String m_multiplier;
+ public String m_exchange;
+
+ public String m_currency;
+ public String m_localSymbol;
+ public String m_primaryExch; // pick a non-aggregate (ie not the SMART exchange) exchange that the contract trades on. DO NOT SET TO SMART.
+ public boolean m_includeExpired; // can not be set to true for orders.
+
+ public String m_secIdType; // CUSIP;SEDOL;ISIN;RIC
+ public String m_secId;
+
+ // COMBOS
+ public String m_comboLegsDescrip; // received in open order version 14 and up for all combos
+ public Vector m_comboLegs = new Vector();
+
+ // delta neutral
+ public UnderComp m_underComp;
+
+ public Contract() {
+ m_conId = 0;
+ m_strike = 0;
+ m_includeExpired = false;
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ Contract retval = (Contract)super.clone();
+ retval.m_comboLegs = (Vector)retval.m_comboLegs.clone();
+ return retval;
+ }
+
+ public Contract(int p_conId, String p_symbol, String p_secType, String p_expiry,
+ double p_strike, String p_right, String p_multiplier,
+ String p_exchange, String p_currency, String p_localSymbol,
+ Vector p_comboLegs, String p_primaryExch, boolean p_includeExpired,
+ String p_secIdType, String p_secId) {
+ m_conId = p_conId;
+ m_symbol = p_symbol;
+ m_secType = p_secType;
+ m_expiry = p_expiry;
+ m_strike = p_strike;
+ m_right = p_right;
+ m_multiplier = p_multiplier;
+ m_exchange = p_exchange;
+ m_currency = p_currency;
+ m_includeExpired = p_includeExpired;
+ m_localSymbol = p_localSymbol;
+ m_comboLegs = p_comboLegs;
+ m_primaryExch = p_primaryExch;
+ m_secIdType = p_secIdType;
+ m_secId = p_secId ;
+ }
+
+ public boolean equals(Object p_other) {
+
+ if (this == p_other) {
+ return true;
+ }
+
+ if (p_other == null || !(p_other instanceof Contract)) {
+ return false;
+ }
+
+ Contract l_theOther = (Contract)p_other;
+
+ if (m_conId != l_theOther.m_conId) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_secType, l_theOther.m_secType) != 0) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_symbol, l_theOther.m_symbol) != 0 ||
+ Util.StringCompare(m_exchange, l_theOther.m_exchange) != 0 ||
+ Util.StringCompare(m_primaryExch, l_theOther.m_primaryExch) != 0 ||
+ Util.StringCompare(m_currency, l_theOther.m_currency) != 0) {
+ return false;
+ }
+
+ if (!Util.NormalizeString(m_secType).equals("BOND")) {
+
+ if (m_strike != l_theOther.m_strike) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_expiry, l_theOther.m_expiry) != 0 ||
+ Util.StringCompare(m_right, l_theOther.m_right) != 0 ||
+ Util.StringCompare(m_multiplier, l_theOther.m_multiplier) != 0 ||
+ Util.StringCompare(m_localSymbol, l_theOther.m_localSymbol) != 0) {
+ return false;
+ }
+ }
+
+ if (Util.StringCompare(m_secIdType, l_theOther.m_secIdType) != 0) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_secId, l_theOther.m_secId) != 0) {
+ return false;
+ }
+
+ // compare combo legs
+ if (!Util.VectorEqualsUnordered(m_comboLegs, l_theOther.m_comboLegs)) {
+ return false;
+ }
+
+ if (m_underComp != l_theOther.m_underComp) {
+ if (m_underComp == null || l_theOther.m_underComp == null) {
+ return false;
+ }
+ if (!m_underComp.equals(l_theOther.m_underComp)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/ContractDetails.java b/ib/src/main/java/com/ib/client/ContractDetails.java
new file mode 100644
index 00000000..99cb4db4
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/ContractDetails.java
@@ -0,0 +1,68 @@
+/*
+ * ContractDetails.java
+ *
+ */
+package com.ib.client;
+
+public class ContractDetails {
+ public Contract m_summary;
+ public String m_marketName;
+ public String m_tradingClass;
+ public double m_minTick;
+ public int m_priceMagnifier;
+ public String m_orderTypes;
+ public String m_validExchanges;
+ public int m_underConId;
+ public String m_longName;
+ public String m_contractMonth;
+ public String m_industry;
+ public String m_category;
+ public String m_subcategory;
+ public String m_timeZoneId;
+ public String m_tradingHours;
+ public String m_liquidHours;
+
+ // BOND values
+ public String m_cusip;
+ public String m_ratings;
+ public String m_descAppend;
+ public String m_bondType;
+ public String m_couponType;
+ public boolean m_callable = false;
+ public boolean m_putable = false;
+ public double m_coupon = 0;
+ public boolean m_convertible = false;
+ public String m_maturity;
+ public String m_issueDate;
+ public String m_nextOptionDate;
+ public String m_nextOptionType;
+ public boolean m_nextOptionPartial = false;
+ public String m_notes;
+
+ public ContractDetails() {
+ m_summary = new Contract();
+ m_minTick = 0;
+ m_underConId = 0;
+ }
+
+ public ContractDetails( Contract p_summary, String p_marketName, String p_tradingClass,
+ double p_minTick, String p_orderTypes, String p_validExchanges, int p_underConId, String p_longName,
+ String p_contractMonth, String p_industry, String p_category, String p_subcategory,
+ String p_timeZoneId, String p_tradingHours, String p_liquidHours) {
+ m_summary = p_summary;
+ m_marketName = p_marketName;
+ m_tradingClass = p_tradingClass;
+ m_minTick = p_minTick;
+ m_orderTypes = p_orderTypes;
+ m_validExchanges = p_validExchanges;
+ m_underConId = p_underConId;
+ m_longName = p_longName;
+ m_contractMonth = p_contractMonth;
+ m_industry = p_industry;
+ m_category = p_category;
+ m_subcategory = p_subcategory;
+ m_timeZoneId = p_timeZoneId;
+ m_tradingHours = p_tradingHours;
+ m_liquidHours = p_liquidHours;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/EClientErrors.java b/ib/src/main/java/com/ib/client/EClientErrors.java
new file mode 100644
index 00000000..52b00368
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/EClientErrors.java
@@ -0,0 +1,75 @@
+/*
+ * EClientErrors.java
+ *
+ */
+package com.ib.client;
+
+
+public class EClientErrors {
+ static final int NO_VALID_ID = -1;
+
+ static final CodeMsgPair ALREADY_CONNECTED = new CodeMsgPair(501, "Already connected.");
+ static final CodeMsgPair CONNECT_FAIL = new CodeMsgPair(502, "Couldn't connect to TWS. Confirm that \"Enable ActiveX and Socket Clients\" is enabled on the TWS \"Configure->API\" menu.");
+ static final CodeMsgPair UPDATE_TWS = new CodeMsgPair(503, "The TWS is out of date and must be upgraded.");
+ static final CodeMsgPair NOT_CONNECTED = new CodeMsgPair(504, "Not connected");
+ static final CodeMsgPair UNKNOWN_ID = new CodeMsgPair(505, "Fatal Error: Unknown message id.");
+ static final CodeMsgPair FAIL_SEND_REQMKT = new CodeMsgPair(510, "Request Market Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANMKT = new CodeMsgPair(511, "Cancel Market Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_ORDER = new CodeMsgPair(512, "Order Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_ACCT = new CodeMsgPair(513, "Account Update Request Sending Error -");
+ static final CodeMsgPair FAIL_SEND_EXEC = new CodeMsgPair(514, "Request For Executions Sending Error -");
+ static final CodeMsgPair FAIL_SEND_CORDER = new CodeMsgPair(515, "Cancel Order Sending Error -");
+ static final CodeMsgPair FAIL_SEND_OORDER = new CodeMsgPair(516, "Request Open Order Sending Error -");
+ static final CodeMsgPair UNKNOWN_CONTRACT = new CodeMsgPair(517, "Unknown contract. Verify the contract details supplied.");
+ static final CodeMsgPair FAIL_SEND_REQCONTRACT = new CodeMsgPair(518, "Request Contract Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQMKTDEPTH = new CodeMsgPair(519, "Request Market Depth Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANMKTDEPTH = new CodeMsgPair(520, "Cancel Market Depth Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_SERVER_LOG_LEVEL = new CodeMsgPair(521, "Set Server Log Level Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_FA_REQUEST = new CodeMsgPair(522, "FA Information Request Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_FA_REPLACE = new CodeMsgPair(523, "FA Information Replace Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQSCANNER = new CodeMsgPair(524, "Request Scanner Subscription Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANSCANNER = new CodeMsgPair(525, "Cancel Scanner Subscription Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQSCANNERPARAMETERS = new CodeMsgPair(526, "Request Scanner Parameter Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQHISTDATA = new CodeMsgPair(527, "Request Historical Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANHISTDATA = new CodeMsgPair(528, "Request Historical Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQRTBARS = new CodeMsgPair(529, "Request Real-time Bar Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANRTBARS = new CodeMsgPair(530, "Cancel Real-time Bar Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQCURRTIME = new CodeMsgPair(531, "Request Current Time Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQFUNDDATA = new CodeMsgPair(532, "Request Fundamental Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANFUNDDATA = new CodeMsgPair(533, "Cancel Fundamental Data Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQCALCIMPLIEDVOLAT = new CodeMsgPair(534, "Request Calculate Implied Volatility Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQCALCOPTIONPRICE = new CodeMsgPair(535, "Request Calculate Option Price Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANCALCIMPLIEDVOLAT = new CodeMsgPair(536, "Cancel Calculate Implied Volatility Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_CANCALCOPTIONPRICE = new CodeMsgPair(537, "Cancel Calculate Option Price Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQGLOBALCANCEL = new CodeMsgPair(538, "Request Global Cancel Sending Error - ");
+ static final CodeMsgPair FAIL_SEND_REQMARKETDATATYPE = new CodeMsgPair(539, "Request Market Data Type Sending Error - ");
+
+ public EClientErrors() {
+ }
+
+ static public class CodeMsgPair {
+
+ ///////////////////////////////////////////////////////////////////
+ // Public members
+ ///////////////////////////////////////////////////////////////////
+ int m_errorCode;
+ String m_errorMsg;
+
+ ///////////////////////////////////////////////////////////////////
+ // Get/Set methods
+ ///////////////////////////////////////////////////////////////////
+ public int code() { return m_errorCode; }
+ public String msg() { return m_errorMsg; }
+
+ ///////////////////////////////////////////////////////////////////
+ // Constructors
+ ///////////////////////////////////////////////////////////////////
+ /**
+ *
+ */
+ public CodeMsgPair(int i, String errString) {
+ m_errorCode = i;
+ m_errorMsg = errString;
+ }
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/EClientSocket.java b/ib/src/main/java/com/ib/client/EClientSocket.java
new file mode 100644
index 00000000..e4bd91a2
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/EClientSocket.java
@@ -0,0 +1,1968 @@
+/*
+ * EClientSocket.java
+ *
+ */
+package com.ib.client;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+
+public class EClientSocket {
+
+ // Client version history
+ //
+ // 6 = Added parentId to orderStatus
+ // 7 = The new execDetails event returned for an order filled status and reqExecDetails
+ // Also market depth is available.
+ // 8 = Added lastFillPrice to orderStatus() event and permId to execution details
+ // 9 = Added 'averageCost', 'unrealizedPNL', and 'unrealizedPNL' to updatePortfolio event
+ // 10 = Added 'serverId' to the 'open order' & 'order status' events.
+ // We send back all the API open orders upon connection.
+ // Added new methods reqAllOpenOrders, reqAutoOpenOrders()
+ // Added FA support - reqExecution has filter.
+ // - reqAccountUpdates takes acct code.
+ // 11 = Added permId to openOrder event.
+ // 12 = requsting open order attributes ignoreRth, hidden, and discretionary
+ // 13 = added goodAfterTime
+ // 14 = always send size on bid/ask/last tick
+ // 15 = send allocation description string on openOrder
+ // 16 = can receive account name in account and portfolio updates, and fa params in openOrder
+ // 17 = can receive liquidation field in exec reports, and notAutoAvailable field in mkt data
+ // 18 = can receive good till date field in open order messages, and request intraday backfill
+ // 19 = can receive rthOnly flag in ORDER_STATUS
+ // 20 = expects TWS time string on connection after server version >= 20.
+ // 21 = can receive bond contract details.
+ // 22 = can receive price magnifier in version 2 contract details message
+ // 23 = support for scanner
+ // 24 = can receive volatility order parameters in open order messages
+ // 25 = can receive HMDS query start and end times
+ // 26 = can receive option vols in option market data messages
+ // 27 = can receive delta neutral order type and delta neutral aux price in place order version 20: API 8.85
+ // 28 = can receive option model computation ticks: API 8.9
+ // 29 = can receive trail stop limit price in open order and can place them: API 8.91
+ // 30 = can receive extended bond contract def, new ticks, and trade count in bars
+ // 31 = can receive EFP extensions to scanner and market data, and combo legs on open orders
+ // ; can receive RT bars
+ // 32 = can receive TickType.LAST_TIMESTAMP
+ // ; can receive "whyHeld" in order status messages
+ // 33 = can receive ScaleNumComponents and ScaleComponentSize is open order messages
+ // 34 = can receive whatIf orders / order state
+ // 35 = can receive contId field for Contract objects
+ // 36 = can receive outsideRth field for Order objects
+ // 37 = can receive clearingAccount and clearingIntent for Order objects
+ // 38 = can receive multiplier and primaryExchange in portfolio updates
+ // ; can receive cumQty and avgPrice in execution
+ // ; can receive fundamental data
+ // ; can receive underComp for Contract objects
+ // ; can receive reqId and end marker in contractDetails/bondContractDetails
+ // ; can receive ScaleInitComponentSize and ScaleSubsComponentSize for Order objects
+ // 39 = can receive underConId in contractDetails
+ // 40 = can receive algoStrategy/algoParams in openOrder
+ // 41 = can receive end marker for openOrder
+ // ; can receive end marker for account download
+ // ; can receive end marker for executions download
+ // 42 = can receive deltaNeutralValidation
+ // 43 = can receive longName(companyName)
+ // ; can receive listingExchange
+ // ; can receive RTVolume tick
+ // 44 = can receive end market for ticker snapshot
+ // 45 = can receive notHeld field in openOrder
+ // 46 = can receive contractMonth, industry, category, subcategory fields in contractDetails
+ // ; can receive timeZoneId, tradingHours, liquidHours fields in contractDetails
+ // 47 = can receive gamma, vega, theta, undPrice fields in TICK_OPTION_COMPUTATION
+ // 48 = can receive exemptCode in openOrder
+ // 49 = can receive hedgeType and hedgeParam in openOrder
+ // 50 = can receive optOutSmartRouting field in openOrder
+ // 51 = can receive smartComboRoutingParams in openOrder
+ // 52 = can receive deltaNeutralConId, deltaNeutralSettlingFirm, deltaNeutralClearingAccount and deltaNeutralClearingIntent in openOrder
+ // 53 = can receive orderRef in execution
+
+ private static final int CLIENT_VERSION = 53;
+ private static final int SERVER_VERSION = 38;
+ private static final byte[] EOL = {0};
+ private static final String BAG_SEC_TYPE = "BAG";
+
+ // FA msg data types
+ public static final int GROUPS = 1;
+ public static final int PROFILES = 2;
+ public static final int ALIASES = 3;
+
+ public static String faMsgTypeName(int faDataType) {
+ switch (faDataType) {
+ case GROUPS:
+ return "GROUPS";
+ case PROFILES:
+ return "PROFILES";
+ case ALIASES:
+ return "ALIASES";
+ }
+ return null;
+ }
+
+ // outgoing msg id's
+ private static final int REQ_MKT_DATA = 1;
+ private static final int CANCEL_MKT_DATA = 2;
+ private static final int PLACE_ORDER = 3;
+ private static final int CANCEL_ORDER = 4;
+ private static final int REQ_OPEN_ORDERS = 5;
+ private static final int REQ_ACCOUNT_DATA = 6;
+ private static final int REQ_EXECUTIONS = 7;
+ private static final int REQ_IDS = 8;
+ private static final int REQ_CONTRACT_DATA = 9;
+ private static final int REQ_MKT_DEPTH = 10;
+ private static final int CANCEL_MKT_DEPTH = 11;
+ private static final int REQ_NEWS_BULLETINS = 12;
+ private static final int CANCEL_NEWS_BULLETINS = 13;
+ private static final int SET_SERVER_LOGLEVEL = 14;
+ private static final int REQ_AUTO_OPEN_ORDERS = 15;
+ private static final int REQ_ALL_OPEN_ORDERS = 16;
+ private static final int REQ_MANAGED_ACCTS = 17;
+ private static final int REQ_FA = 18;
+ private static final int REPLACE_FA = 19;
+ private static final int REQ_HISTORICAL_DATA = 20;
+ private static final int EXERCISE_OPTIONS = 21;
+ private static final int REQ_SCANNER_SUBSCRIPTION = 22;
+ private static final int CANCEL_SCANNER_SUBSCRIPTION = 23;
+ private static final int REQ_SCANNER_PARAMETERS = 24;
+ private static final int CANCEL_HISTORICAL_DATA = 25;
+ private static final int REQ_CURRENT_TIME = 49;
+ private static final int REQ_REAL_TIME_BARS = 50;
+ private static final int CANCEL_REAL_TIME_BARS = 51;
+ private static final int REQ_FUNDAMENTAL_DATA = 52;
+ private static final int CANCEL_FUNDAMENTAL_DATA = 53;
+ private static final int REQ_CALC_IMPLIED_VOLAT = 54;
+ private static final int REQ_CALC_OPTION_PRICE = 55;
+ private static final int CANCEL_CALC_IMPLIED_VOLAT = 56;
+ private static final int CANCEL_CALC_OPTION_PRICE = 57;
+ private static final int REQ_GLOBAL_CANCEL = 58;
+ private static final int REQ_MARKET_DATA_TYPE = 59;
+
+ private static final int MIN_SERVER_VER_REAL_TIME_BARS = 34;
+ private static final int MIN_SERVER_VER_SCALE_ORDERS = 35;
+ private static final int MIN_SERVER_VER_SNAPSHOT_MKT_DATA = 35;
+ private static final int MIN_SERVER_VER_SSHORT_COMBO_LEGS = 35;
+ private static final int MIN_SERVER_VER_WHAT_IF_ORDERS = 36;
+ private static final int MIN_SERVER_VER_CONTRACT_CONID = 37;
+ private static final int MIN_SERVER_VER_PTA_ORDERS = 39;
+ private static final int MIN_SERVER_VER_FUNDAMENTAL_DATA = 40;
+ private static final int MIN_SERVER_VER_UNDER_COMP = 40;
+ private static final int MIN_SERVER_VER_CONTRACT_DATA_CHAIN = 40;
+ private static final int MIN_SERVER_VER_SCALE_ORDERS2 = 40;
+ private static final int MIN_SERVER_VER_ALGO_ORDERS = 41;
+ private static final int MIN_SERVER_VER_EXECUTION_DATA_CHAIN = 42;
+ private static final int MIN_SERVER_VER_NOT_HELD = 44;
+ private static final int MIN_SERVER_VER_SEC_ID_TYPE = 45;
+ private static final int MIN_SERVER_VER_PLACE_ORDER_CONID = 46;
+ private static final int MIN_SERVER_VER_REQ_MKT_DATA_CONID = 47;
+ private static final int MIN_SERVER_VER_REQ_CALC_IMPLIED_VOLAT = 49;
+ private static final int MIN_SERVER_VER_REQ_CALC_OPTION_PRICE = 50;
+ private static final int MIN_SERVER_VER_CANCEL_CALC_IMPLIED_VOLAT = 50;
+ private static final int MIN_SERVER_VER_CANCEL_CALC_OPTION_PRICE = 50;
+ private static final int MIN_SERVER_VER_SSHORTX_OLD = 51;
+ private static final int MIN_SERVER_VER_SSHORTX = 52;
+ private static final int MIN_SERVER_VER_REQ_GLOBAL_CANCEL = 53;
+ private static final int MIN_SERVER_VER_HEDGE_ORDERS = 54;
+ private static final int MIN_SERVER_VER_REQ_MARKET_DATA_TYPE = 55;
+ private static final int MIN_SERVER_VER_OPT_OUT_SMART_ROUTING = 56;
+ private static final int MIN_SERVER_VER_SMART_COMBO_ROUTING_PARAMS = 57;
+ private static final int MIN_SERVER_VER_DELTA_NEUTRAL_CONID = 58;
+
+ private AnyWrapper m_anyWrapper; // msg handler
+ private DataOutputStream m_dos; // the socket output stream
+ private boolean m_connected;// true if we are connected
+ private EReader m_reader; // thread which reads msgs from socket
+ private int m_serverVersion = 0;
+ private String m_TwsTime;
+
+ public int serverVersion() { return m_serverVersion; }
+ public String TwsConnectionTime() { return m_TwsTime; }
+ public AnyWrapper wrapper() { return m_anyWrapper; }
+ public EReader reader() { return m_reader; }
+
+
+ public EClientSocket( AnyWrapper anyWrapper) {
+ m_anyWrapper = anyWrapper;
+ }
+
+ public boolean isConnected() {
+ return m_connected;
+ }
+
+ public synchronized void eConnect( String host, int port, int clientId) {
+ // already connected?
+ host = checkConnected(host);
+ if(host == null){
+ return;
+ }
+ try{
+ Socket socket = new Socket( host, port);
+ eConnect(socket, clientId);
+ }
+ catch( Exception e) {
+ eDisconnect();
+ connectionError();
+ }
+ }
+
+ protected void connectionError() {
+ m_anyWrapper.error( EClientErrors.NO_VALID_ID, EClientErrors.CONNECT_FAIL.code(),
+ EClientErrors.CONNECT_FAIL.msg());
+ m_reader = null;
+ }
+
+ protected String checkConnected(String host) {
+ if( m_connected) {
+ m_anyWrapper.error(EClientErrors.NO_VALID_ID, EClientErrors.ALREADY_CONNECTED.code(),
+ EClientErrors.ALREADY_CONNECTED.msg());
+ return null;
+ }
+ if( isNull( host) ) {
+ host = "127.0.0.1";
+ }
+ return host;
+ }
+
+ public EReader createReader(EClientSocket socket, DataInputStream dis) {
+ return new EReader(socket, dis);
+ }
+
+ public synchronized void eConnect(Socket socket, int clientId) throws IOException {
+
+ // create io streams
+ m_dos = new DataOutputStream( socket.getOutputStream() );
+
+ // set client version
+ send( CLIENT_VERSION);
+
+ // start reader thread
+ m_reader = createReader(this, new DataInputStream(
+ socket.getInputStream()));
+
+ // check server version
+ m_serverVersion = m_reader.readInt();
+ System.out.println("Server Version:" + m_serverVersion);
+ if ( m_serverVersion >= 20 ){
+ m_TwsTime = m_reader.readStr();
+ System.out.println("TWS Time at connection:" + m_TwsTime);
+ }
+ if( m_serverVersion < SERVER_VERSION) {
+ eDisconnect();
+ m_anyWrapper.error( EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(), EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ // Send the client id
+ if ( m_serverVersion >= 3 ){
+ send( clientId);
+ }
+
+ m_reader.start();
+
+ // set connected flag
+ m_connected = true;
+ }
+
+ public synchronized void eDisconnect() {
+ // not connected?
+ if( m_dos == null) {
+ return;
+ }
+
+ m_connected = false;
+ m_serverVersion = 0;
+ m_TwsTime = "";
+
+ DataOutputStream dos = m_dos;
+ m_dos = null;
+
+ EReader reader = m_reader;
+ m_reader = null;
+
+ try {
+ // stop reader thread
+ if( reader != null) {
+ reader.interrupt();
+ }
+ }
+ catch( Exception e) {
+ }
+
+ try {
+ // close socket
+ if( dos != null) {
+ dos.close();
+ }
+ }
+ catch( Exception e) {
+ }
+ }
+
+ public synchronized void cancelScannerSubscription( int tickerId) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < 24) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support API scanner subscription.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel mkt data msg
+ try {
+ send( CANCEL_SCANNER_SUBSCRIPTION);
+ send( VERSION);
+ send( tickerId);
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_CANSCANNER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqScannerParameters() {
+ // not connected?
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < 24) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support API scanner subscription.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send(REQ_SCANNER_PARAMETERS);
+ send(VERSION);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID,
+ EClientErrors.FAIL_SEND_REQSCANNERPARAMETERS, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqScannerSubscription( int tickerId,
+ ScannerSubscription subscription) {
+ // not connected?
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < 24) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support API scanner subscription.");
+ return;
+ }
+
+ final int VERSION = 3;
+
+ try {
+ send(REQ_SCANNER_SUBSCRIPTION);
+ send(VERSION);
+ send(tickerId);
+ sendMax(subscription.numberOfRows());
+ send(subscription.instrument());
+ send(subscription.locationCode());
+ send(subscription.scanCode());
+ sendMax(subscription.abovePrice());
+ sendMax(subscription.belowPrice());
+ sendMax(subscription.aboveVolume());
+ sendMax(subscription.marketCapAbove());
+ sendMax(subscription.marketCapBelow());
+ send(subscription.moodyRatingAbove());
+ send(subscription.moodyRatingBelow());
+ send(subscription.spRatingAbove());
+ send(subscription.spRatingBelow());
+ send(subscription.maturityDateAbove());
+ send(subscription.maturityDateBelow());
+ sendMax(subscription.couponRateAbove());
+ sendMax(subscription.couponRateBelow());
+ send(subscription.excludeConvertible());
+ if (m_serverVersion >= 25) {
+ send(subscription.averageOptionVolumeAbove());
+ send(subscription.scannerSettingPairs());
+ }
+ if (m_serverVersion >= 27) {
+ send(subscription.stockTypeFilter());
+ }
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_REQSCANNER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqMktData(int tickerId, Contract contract,
+ String genericTickList, boolean snapshot) {
+ 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;
+ }
+ }
+
+ final int VERSION = 9;
+
+ 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 >= 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 = (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);
+ }
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_REQMKT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelHistoricalData( int tickerId ) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < 24) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support historical data query cancellation.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel mkt data msg
+ try {
+ send( CANCEL_HISTORICAL_DATA);
+ send( VERSION);
+ send( tickerId);
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_CANHISTDATA, "" + e);
+ close();
+ }
+ }
+
+ public void cancelRealTimeBars(int tickerId) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_REAL_TIME_BARS) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support realtime bar data query cancellation.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel mkt data msg
+ try {
+ send( CANCEL_REAL_TIME_BARS);
+ send( VERSION);
+ send( tickerId);
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_CANRTBARS, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqHistoricalData( int tickerId, Contract contract,
+ String endDateTime, String durationStr,
+ String barSizeSetting, String whatToShow,
+ int useRTH, int formatDate) {
+ // not connected?
+ if( !m_connected) {
+ error( tickerId, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 4;
+
+ try {
+ if (m_serverVersion < 16) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support historical data backfill.");
+ return;
+ }
+
+ send(REQ_HISTORICAL_DATA);
+ send(VERSION);
+ send(tickerId);
+
+ // send contract fields
+ send(contract.m_symbol);
+ send(contract.m_secType);
+ send(contract.m_expiry);
+ send(contract.m_strike);
+ send(contract.m_right);
+ send(contract.m_multiplier);
+ send(contract.m_exchange);
+ send(contract.m_primaryExch);
+ send(contract.m_currency);
+ send(contract.m_localSymbol);
+ if (m_serverVersion >= 31) {
+ send(contract.m_includeExpired ? 1 : 0);
+ }
+ if (m_serverVersion >= 20) {
+ send(endDateTime);
+ send(barSizeSetting);
+ }
+ send(durationStr);
+ send(useRTH);
+ send(whatToShow);
+ if (m_serverVersion > 16) {
+ send(formatDate);
+ }
+ if (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 = (ComboLeg) contract.m_comboLegs.get(i);
+ send(comboLeg.m_conId);
+ send(comboLeg.m_ratio);
+ send(comboLeg.m_action);
+ send(comboLeg.m_exchange);
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ error(tickerId, EClientErrors.FAIL_SEND_REQHISTDATA, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqRealTimeBars(int tickerId, Contract contract, int barSize, String whatToShow, boolean useRTH) {
+ // not connected?
+ if (!m_connected ) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+ if (m_serverVersion < MIN_SERVER_VER_REAL_TIME_BARS) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support real time bars.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send req mkt data msg
+ send(REQ_REAL_TIME_BARS);
+ send(VERSION);
+ send(tickerId);
+
+ // send contract fields
+ send(contract.m_symbol);
+ send(contract.m_secType);
+ send(contract.m_expiry);
+ send(contract.m_strike);
+ send(contract.m_right);
+ send(contract.m_multiplier);
+ send(contract.m_exchange);
+ send(contract.m_primaryExch);
+ send(contract.m_currency);
+ send(contract.m_localSymbol);
+ send(barSize);
+ send(whatToShow);
+ send(useRTH);
+
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_REQRTBARS, "" + e);
+ close();
+ }
+
+ }
+
+ public synchronized void reqContractDetails(int reqId, Contract contract)
+ {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >=4
+ if( m_serverVersion < 4) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(),
+ EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ if( m_serverVersion < MIN_SERVER_VER_SEC_ID_TYPE) {
+ if (!IsEmpty(contract.m_secIdType) || !IsEmpty(contract.m_secId)) {
+ error(reqId, EClientErrors.UPDATE_TWS,
+ " It does not support secIdType and secId parameters.");
+ return;
+ }
+ }
+
+ final int VERSION = 6;
+
+ try {
+ // send req mkt data msg
+ send( REQ_CONTRACT_DATA);
+ send( VERSION);
+
+ if (m_serverVersion >= MIN_SERVER_VER_CONTRACT_DATA_CHAIN) {
+ send( reqId);
+ }
+
+ // send contract fields
+ if (m_serverVersion >= MIN_SERVER_VER_CONTRACT_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);
+ send( contract.m_currency);
+ send( contract.m_localSymbol);
+ if (m_serverVersion >= 31) {
+ send(contract.m_includeExpired);
+ }
+ if (m_serverVersion >= MIN_SERVER_VER_SEC_ID_TYPE) {
+ send( contract.m_secIdType);
+ send( contract.m_secId);
+ }
+
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQCONTRACT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqMktDepth( int tickerId, Contract contract, int numRows)
+ {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >=6
+ if( m_serverVersion < 6) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(),
+ EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ final int VERSION = 3;
+
+ try {
+ // send req mkt data msg
+ send( REQ_MKT_DEPTH);
+ send( VERSION);
+ send( tickerId);
+
+ // send contract fields
+ 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);
+ send( contract.m_currency);
+ send( contract.m_localSymbol);
+ if (m_serverVersion >= 19) {
+ send( numRows);
+ }
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_REQMKTDEPTH, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelMktData( int tickerId) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel mkt data msg
+ try {
+ send( CANCEL_MKT_DATA);
+ send( VERSION);
+ send( tickerId);
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_CANMKT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelMktDepth( int tickerId) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >=6
+ if( m_serverVersion < 6) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(),
+ EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel mkt data msg
+ try {
+ send( CANCEL_MKT_DEPTH);
+ send( VERSION);
+ send( tickerId);
+ }
+ catch( Exception e) {
+ error( tickerId, EClientErrors.FAIL_SEND_CANMKTDEPTH, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void exerciseOptions( int tickerId, Contract contract,
+ int exerciseAction, int exerciseQuantity,
+ String account, int override) {
+ // not connected?
+ if( !m_connected) {
+ error( tickerId, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ if (m_serverVersion < 21) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support options exercise from the API.");
+ return;
+ }
+
+ send(EXERCISE_OPTIONS);
+ send(VERSION);
+ send(tickerId);
+
+ // send contract fields
+ send(contract.m_symbol);
+ send(contract.m_secType);
+ send(contract.m_expiry);
+ send(contract.m_strike);
+ send(contract.m_right);
+ send(contract.m_multiplier);
+ send(contract.m_exchange);
+ send(contract.m_currency);
+ send(contract.m_localSymbol);
+ send(exerciseAction);
+ send(exerciseQuantity);
+ send(account);
+ send(override);
+ }
+ catch (Exception e) {
+ error(tickerId, EClientErrors.FAIL_SEND_REQMKT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void placeOrder( int id, Contract contract, Order order) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SCALE_ORDERS) {
+ if (order.m_scaleInitLevelSize != Integer.MAX_VALUE ||
+ order.m_scalePriceIncrement != Double.MAX_VALUE) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support Scale orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SSHORT_COMBO_LEGS) {
+ if (!contract.m_comboLegs.isEmpty()) {
+ ComboLeg comboLeg;
+ for (int i = 0; i < contract.m_comboLegs.size(); ++i) {
+ comboLeg = (ComboLeg)contract.m_comboLegs.get(i);
+ if (comboLeg.m_shortSaleSlot != 0 ||
+ !IsEmpty(comboLeg.m_designatedLocation)) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support SSHORT flag for combo legs.");
+ return;
+ }
+ }
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_WHAT_IF_ORDERS) {
+ if (order.m_whatIf) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support what-if orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_UNDER_COMP) {
+ if (contract.m_underComp != null) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support delta-neutral orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SCALE_ORDERS2) {
+ if (order.m_scaleSubsLevelSize != Integer.MAX_VALUE) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support Subsequent Level Size for Scale orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_ALGO_ORDERS) {
+ if (!IsEmpty(order.m_algoStrategy)) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support algo orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_NOT_HELD) {
+ if (order.m_notHeld) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support notHeld parameter.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SEC_ID_TYPE) {
+ if (!IsEmpty(contract.m_secIdType) || !IsEmpty(contract.m_secId)) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support secIdType and secId parameters.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_PLACE_ORDER_CONID) {
+ if (contract.m_conId > 0) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support conId parameter.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SSHORTX) {
+ if (order.m_exemptCode != -1) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support exemptCode parameter.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_SSHORTX) {
+ if (!contract.m_comboLegs.isEmpty()) {
+ ComboLeg comboLeg;
+ for (int i = 0; i < contract.m_comboLegs.size(); ++i) {
+ comboLeg = (ComboLeg)contract.m_comboLegs.get(i);
+ if (comboLeg.m_exemptCode != -1) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support exemptCode parameter.");
+ return;
+ }
+ }
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_HEDGE_ORDERS) {
+ if (!IsEmpty(order.m_hedgeType)) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support hedge orders.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_OPT_OUT_SMART_ROUTING) {
+ if (order.m_optOutSmartRouting) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support optOutSmartRouting parameter.");
+ return;
+ }
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_DELTA_NEUTRAL_CONID) {
+ if (order.m_deltaNeutralConId > 0
+ || !IsEmpty(order.m_deltaNeutralSettlingFirm)
+ || !IsEmpty(order.m_deltaNeutralClearingAccount)
+ || !IsEmpty(order.m_deltaNeutralClearingIntent)
+ ) {
+ error(id, EClientErrors.UPDATE_TWS,
+ " It does not support deltaNeutral parameters: ConId, SettlingFirm, ClearingAccount, ClearingIntent");
+ return;
+ }
+ }
+
+
+ int VERSION = (m_serverVersion < MIN_SERVER_VER_NOT_HELD) ? 27 : 35;
+
+ // send place order msg
+ try {
+ send( PLACE_ORDER);
+ send( VERSION);
+ send( id);
+
+ // send contract fields
+ if( m_serverVersion >= MIN_SERVER_VER_PLACE_ORDER_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_SEC_ID_TYPE){
+ send( contract.m_secIdType);
+ send( contract.m_secId);
+ }
+
+ // send main order fields
+ send( order.m_action);
+ send( order.m_totalQuantity);
+ send( order.m_orderType);
+ send( order.m_lmtPrice);
+ send( order.m_auxPrice);
+
+ // send extended order fields
+ send( order.m_tif);
+ send( order.m_ocaGroup);
+ send( order.m_account);
+ send( order.m_openClose);
+ send( order.m_origin);
+ send( order.m_orderRef);
+ send( order.m_transmit);
+ if( m_serverVersion >= 4 ) {
+ send (order.m_parentId);
+ }
+
+ if( m_serverVersion >= 5 ) {
+ send (order.m_blockOrder);
+ send (order.m_sweepToFill);
+ send (order.m_displaySize);
+ send (order.m_triggerMethod);
+ if (m_serverVersion < 38) {
+ // will never happen
+ send(/* order.m_ignoreRth */ false);
+ }
+ else {
+ send (order.m_outsideRth);
+ }
+ }
+
+ if(m_serverVersion >= 7 ) {
+ send(order.m_hidden);
+ }
+
+ // Send combo legs for BAG requests
+ 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 = (ComboLeg)contract.m_comboLegs.get(i);
+ send( comboLeg.m_conId);
+ send( comboLeg.m_ratio);
+ send( comboLeg.m_action);
+ send( comboLeg.m_exchange);
+ send( comboLeg.m_openClose);
+
+ if (m_serverVersion >= MIN_SERVER_VER_SSHORT_COMBO_LEGS) {
+ send( comboLeg.m_shortSaleSlot);
+ send( comboLeg.m_designatedLocation);
+ }
+ if (m_serverVersion >= MIN_SERVER_VER_SSHORTX_OLD) {
+ send( comboLeg.m_exemptCode);
+ }
+ }
+ }
+ }
+
+ if(m_serverVersion >= MIN_SERVER_VER_SMART_COMBO_ROUTING_PARAMS && BAG_SEC_TYPE.equalsIgnoreCase(contract.m_secType)) {
+ java.util.Vector smartComboRoutingParams = order.m_smartComboRoutingParams;
+ int smartComboRoutingParamsCount = smartComboRoutingParams == null ? 0 : smartComboRoutingParams.size();
+ send( smartComboRoutingParamsCount);
+ if( smartComboRoutingParamsCount > 0) {
+ for( int i = 0; i < smartComboRoutingParamsCount; ++i) {
+ TagValue tagValue = (TagValue)smartComboRoutingParams.get(i);
+ send( tagValue.m_tag);
+ send( tagValue.m_value);
+ }
+ }
+ }
+
+ if ( m_serverVersion >= 9 ) {
+ // send deprecated sharesAllocation field
+ send( "");
+ }
+
+ if ( m_serverVersion >= 10 ) {
+ send( order.m_discretionaryAmt);
+ }
+
+ if ( m_serverVersion >= 11 ) {
+ send( order.m_goodAfterTime);
+ }
+
+ if ( m_serverVersion >= 12 ) {
+ send( order.m_goodTillDate);
+ }
+
+ if ( m_serverVersion >= 13 ) {
+ send( order.m_faGroup);
+ send( order.m_faMethod);
+ send( order.m_faPercentage);
+ send( order.m_faProfile);
+ }
+ if (m_serverVersion >= 18) { // institutional short sale slot fields.
+ send( order.m_shortSaleSlot); // 0 only for retail, 1 or 2 only for institution.
+ send( order.m_designatedLocation); // only populate when order.m_shortSaleSlot = 2.
+ }
+ if (m_serverVersion >= MIN_SERVER_VER_SSHORTX_OLD) {
+ send( order.m_exemptCode);
+ }
+ if (m_serverVersion >= 19) {
+ send( order.m_ocaType);
+ if (m_serverVersion < 38) {
+ // will never happen
+ send( /* order.m_rthOnly */ false);
+ }
+ send( order.m_rule80A);
+ send( order.m_settlingFirm);
+ send( order.m_allOrNone);
+ sendMax( order.m_minQty);
+ sendMax( order.m_percentOffset);
+ send( order.m_eTradeOnly);
+ send( order.m_firmQuoteOnly);
+ sendMax( order.m_nbboPriceCap);
+ sendMax( order.m_auctionStrategy);
+ sendMax( order.m_startingPrice);
+ sendMax( order.m_stockRefPrice);
+ sendMax( order.m_delta);
+ // Volatility orders had specific watermark price attribs in server version 26
+ double lower = (m_serverVersion == 26 && order.m_orderType.equals("VOL"))
+ ? Double.MAX_VALUE
+ : order.m_stockRangeLower;
+ double upper = (m_serverVersion == 26 && order.m_orderType.equals("VOL"))
+ ? Double.MAX_VALUE
+ : order.m_stockRangeUpper;
+ sendMax( lower);
+ sendMax( upper);
+ }
+
+ if (m_serverVersion >= 22) {
+ send( order.m_overridePercentageConstraints);
+ }
+
+ if (m_serverVersion >= 26) { // Volatility orders
+ sendMax( order.m_volatility);
+ sendMax( order.m_volatilityType);
+ if (m_serverVersion < 28) {
+ send( order.m_deltaNeutralOrderType.equalsIgnoreCase("MKT"));
+ } else {
+ send( order.m_deltaNeutralOrderType);
+ sendMax( order.m_deltaNeutralAuxPrice);
+
+ if (m_serverVersion >= MIN_SERVER_VER_DELTA_NEUTRAL_CONID && !IsEmpty(order.m_deltaNeutralOrderType)){
+ send( order.m_deltaNeutralConId);
+ send( order.m_deltaNeutralSettlingFirm);
+ send( order.m_deltaNeutralClearingAccount);
+ send( order.m_deltaNeutralClearingIntent);
+ }
+ }
+ send( order.m_continuousUpdate);
+ if (m_serverVersion == 26) {
+ // Volatility orders had specific watermark price attribs in server version 26
+ double lower = order.m_orderType.equals("VOL") ? order.m_stockRangeLower : Double.MAX_VALUE;
+ double upper = order.m_orderType.equals("VOL") ? order.m_stockRangeUpper : Double.MAX_VALUE;
+ sendMax( lower);
+ sendMax( upper);
+ }
+ sendMax( order.m_referencePriceType);
+ }
+
+ if (m_serverVersion >= 30) { // TRAIL_STOP_LIMIT stop price
+ sendMax( order.m_trailStopPrice);
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_SCALE_ORDERS) {
+ if (m_serverVersion >= MIN_SERVER_VER_SCALE_ORDERS2) {
+ sendMax (order.m_scaleInitLevelSize);
+ sendMax (order.m_scaleSubsLevelSize);
+ }
+ else {
+ send ("");
+ sendMax (order.m_scaleInitLevelSize);
+
+ }
+ sendMax (order.m_scalePriceIncrement);
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_HEDGE_ORDERS) {
+ send (order.m_hedgeType);
+ if (!IsEmpty(order.m_hedgeType)) {
+ send (order.m_hedgeParam);
+ }
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_OPT_OUT_SMART_ROUTING) {
+ send (order.m_optOutSmartRouting);
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_PTA_ORDERS) {
+ send (order.m_clearingAccount);
+ send (order.m_clearingIntent);
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_NOT_HELD) {
+ send (order.m_notHeld);
+ }
+
+ 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 >= MIN_SERVER_VER_ALGO_ORDERS) {
+ send( order.m_algoStrategy);
+ if( !IsEmpty(order.m_algoStrategy)) {
+ java.util.Vector algoParams = order.m_algoParams;
+ int algoParamsCount = algoParams == null ? 0 : algoParams.size();
+ send( algoParamsCount);
+ if( algoParamsCount > 0) {
+ for( int i = 0; i < algoParamsCount; ++i) {
+ TagValue tagValue = (TagValue)algoParams.get(i);
+ send( tagValue.m_tag);
+ send( tagValue.m_value);
+ }
+ }
+ }
+ }
+
+ if (m_serverVersion >= MIN_SERVER_VER_WHAT_IF_ORDERS) {
+ send (order.m_whatIf);
+ }
+ }
+ catch( Exception e) {
+ error( id, EClientErrors.FAIL_SEND_ORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqAccountUpdates(boolean subscribe, String acctCode) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 2;
+
+ // send cancel order msg
+ try {
+ send( REQ_ACCOUNT_DATA );
+ send( VERSION);
+ send( subscribe);
+
+ // Send the account code. This will only be used for FA clients
+ if ( m_serverVersion >= 9 ) {
+ send( acctCode);
+ }
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_ACCT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqExecutions(int reqId, ExecutionFilter filter) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 3;
+
+ // send cancel order msg
+ try {
+ send( REQ_EXECUTIONS);
+ send( VERSION);
+
+ if (m_serverVersion >= MIN_SERVER_VER_EXECUTION_DATA_CHAIN) {
+ send( reqId);
+ }
+
+ // Send the execution rpt filter data
+ if ( m_serverVersion >= 9 ) {
+ send( filter.m_clientId);
+ send( filter.m_acctCode);
+
+ // Note that the valid format for m_time is "yyyymmdd-hh:mm:ss"
+ send( filter.m_time);
+ send( filter.m_symbol);
+ send( filter.m_secType);
+ send( filter.m_exchange);
+ send( filter.m_side);
+ }
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_EXEC, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelOrder( int id) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel order msg
+ try {
+ send( CANCEL_ORDER);
+ send( VERSION);
+ send( id);
+ }
+ catch( Exception e) {
+ error( id, EClientErrors.FAIL_SEND_CORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqOpenOrders() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel order msg
+ try {
+ send( REQ_OPEN_ORDERS);
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_OORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqIds( int numIds) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send( REQ_IDS);
+ send( VERSION);
+ send( numIds);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_CORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqNewsBulletins( boolean allMsgs) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send( REQ_NEWS_BULLETINS);
+ send( VERSION);
+ send( allMsgs);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_CORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelNewsBulletins() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send cancel order msg
+ try {
+ send( CANCEL_NEWS_BULLETINS);
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_CORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void setServerLogLevel(int logLevel) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send the set server logging level message
+ try {
+ send( SET_SERVER_LOGLEVEL);
+ send( VERSION);
+ send( logLevel);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_SERVER_LOG_LEVEL, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqAutoOpenOrders(boolean bAutoBind)
+ {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send req open orders msg
+ try {
+ send( REQ_AUTO_OPEN_ORDERS);
+ send( VERSION);
+ send( bAutoBind);
+ }
+ catch( Exception e) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_OORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqAllOpenOrders() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send req all open orders msg
+ try {
+ send( REQ_ALL_OPEN_ORDERS);
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_OORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqManagedAccts() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send req FA managed accounts msg
+ try {
+ send( REQ_MANAGED_ACCTS);
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_OORDER, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void requestFA( int faDataType ) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >= 13
+ if( m_serverVersion < 13) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(),
+ EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send( REQ_FA );
+ send( VERSION);
+ send( faDataType);
+ }
+ catch( Exception e) {
+ error( faDataType, EClientErrors.FAIL_SEND_FA_REQUEST, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void replaceFA( int faDataType, String xml ) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >= 13
+ if( m_serverVersion < 13) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(),
+ EClientErrors.UPDATE_TWS.msg());
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send( REPLACE_FA );
+ send( VERSION);
+ send( faDataType);
+ send( xml);
+ }
+ catch( Exception e) {
+ error( faDataType, EClientErrors.FAIL_SEND_FA_REPLACE, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqCurrentTime() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ // This feature is only available for versions of TWS >= 33
+ if( m_serverVersion < 33) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support current time requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ send( REQ_CURRENT_TIME );
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQCURRTIME, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqFundamentalData(int reqId, Contract contract,
+ String reportType) {
+ if( !m_connected) {
+ error( reqId, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if( m_serverVersion < MIN_SERVER_VER_FUNDAMENTAL_DATA) {
+ error( reqId, EClientErrors.UPDATE_TWS,
+ " It does not support fundamental data requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send req fund data msg
+ send( REQ_FUNDAMENTAL_DATA);
+ send( VERSION);
+ send( reqId);
+
+ // send contract fields
+ send( contract.m_symbol);
+ send( contract.m_secType);
+ send( contract.m_exchange);
+ send( contract.m_primaryExch);
+ send( contract.m_currency);
+ send( contract.m_localSymbol);
+
+ send( reportType);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_REQFUNDDATA, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelFundamentalData(int reqId) {
+ if( !m_connected) {
+ error( reqId, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if( m_serverVersion < MIN_SERVER_VER_FUNDAMENTAL_DATA) {
+ error( reqId, EClientErrors.UPDATE_TWS,
+ " It does not support fundamental data requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send req mkt data msg
+ send( CANCEL_FUNDAMENTAL_DATA);
+ send( VERSION);
+ send( reqId);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_CANFUNDDATA, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void calculateImpliedVolatility(int reqId, Contract contract,
+ double optionPrice, double underPrice) {
+
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_REQ_CALC_IMPLIED_VOLAT) {
+ error(reqId, EClientErrors.UPDATE_TWS,
+ " It does not support calculate implied volatility requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send calculate implied volatility msg
+ send( REQ_CALC_IMPLIED_VOLAT);
+ send( VERSION);
+ send( reqId);
+
+ // send contract fields
+ send( contract.m_conId);
+ send( contract.m_symbol);
+ send( contract.m_secType);
+ send( contract.m_expiry);
+ send( contract.m_strike);
+ send( contract.m_right);
+ send( contract.m_multiplier);
+ send( contract.m_exchange);
+ send( contract.m_primaryExch);
+ send( contract.m_currency);
+ send( contract.m_localSymbol);
+
+ send( optionPrice);
+ send( underPrice);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_REQCALCIMPLIEDVOLAT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelCalculateImpliedVolatility(int reqId) {
+
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_CANCEL_CALC_IMPLIED_VOLAT) {
+ error(reqId, EClientErrors.UPDATE_TWS,
+ " It does not support calculate implied volatility cancellation.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send cancel calculate implied volatility msg
+ send( CANCEL_CALC_IMPLIED_VOLAT);
+ send( VERSION);
+ send( reqId);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_CANCALCIMPLIEDVOLAT, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void calculateOptionPrice(int reqId, Contract contract,
+ double volatility, double underPrice) {
+
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_REQ_CALC_OPTION_PRICE) {
+ error(reqId, EClientErrors.UPDATE_TWS,
+ " It does not support calculate option price requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send calculate option price msg
+ send( REQ_CALC_OPTION_PRICE);
+ send( VERSION);
+ send( reqId);
+
+ // send contract fields
+ send( contract.m_conId);
+ send( contract.m_symbol);
+ send( contract.m_secType);
+ send( contract.m_expiry);
+ send( contract.m_strike);
+ send( contract.m_right);
+ send( contract.m_multiplier);
+ send( contract.m_exchange);
+ send( contract.m_primaryExch);
+ send( contract.m_currency);
+ send( contract.m_localSymbol);
+
+ send( volatility);
+ send( underPrice);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_REQCALCOPTIONPRICE, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void cancelCalculateOptionPrice(int reqId) {
+
+ if (!m_connected) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_CANCEL_CALC_OPTION_PRICE) {
+ error(reqId, EClientErrors.UPDATE_TWS,
+ " It does not support calculate option price cancellation.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ try {
+ // send cancel calculate option price msg
+ send( CANCEL_CALC_OPTION_PRICE);
+ send( VERSION);
+ send( reqId);
+ }
+ catch( Exception e) {
+ error( reqId, EClientErrors.FAIL_SEND_CANCALCOPTIONPRICE, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqGlobalCancel() {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_REQ_GLOBAL_CANCEL) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support globalCancel requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send request global cancel msg
+ try {
+ send( REQ_GLOBAL_CANCEL);
+ send( VERSION);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQGLOBALCANCEL, "" + e);
+ close();
+ }
+ }
+
+ public synchronized void reqMarketDataType(int marketDataType) {
+ // not connected?
+ if( !m_connected) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "");
+ return;
+ }
+
+ if (m_serverVersion < MIN_SERVER_VER_REQ_MARKET_DATA_TYPE) {
+ error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS,
+ " It does not support marketDataType requests.");
+ return;
+ }
+
+ final int VERSION = 1;
+
+ // send the reqMarketDataType message
+ try {
+ send( REQ_MARKET_DATA_TYPE);
+ send( VERSION);
+ send( marketDataType);
+ }
+ catch( Exception e) {
+ error( EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQMARKETDATATYPE, "" + e);
+ close();
+ }
+ }
+
+ protected synchronized void error( String err) {
+ m_anyWrapper.error( err);
+ }
+
+ protected synchronized void error( int id, int errorCode, String errorMsg) {
+ m_anyWrapper.error( id, errorCode, errorMsg);
+ }
+
+ protected void close() {
+ eDisconnect();
+ wrapper().connectionClosed();
+ }
+
+ private static boolean is( String str) {
+ // return true if the string is not empty
+ return str != null && str.length() > 0;
+ }
+
+ private static boolean isNull( String str) {
+ // return true if the string is null or empty
+ return !is( str);
+ }
+
+ private void error(int id, EClientErrors.CodeMsgPair pair, String tail) {
+ error(id, pair.code(), pair.msg() + tail);
+ }
+
+ protected void send( String str) throws IOException {
+ // write string to data buffer; writer thread will
+ // write it to socket
+ if( !IsEmpty(str)) {
+ m_dos.write( str.getBytes() );
+ }
+ sendEOL();
+ }
+
+ private void sendEOL() throws IOException {
+ m_dos.write( EOL);
+ }
+
+ protected void send( int val) throws IOException {
+ send( String.valueOf( val) );
+ }
+
+ protected void send( char val) throws IOException {
+ m_dos.write( val);
+ sendEOL();
+ }
+
+ protected void send( double val) throws IOException {
+ send( String.valueOf( val) );
+ }
+
+ protected void send( long val) throws IOException {
+ send( String.valueOf( val) );
+ }
+
+ private void sendMax( double val) throws IOException {
+ if (val == Double.MAX_VALUE) {
+ sendEOL();
+ }
+ else {
+ send(String.valueOf(val));
+ }
+ }
+
+ private void sendMax( int val) throws IOException {
+ if (val == Integer.MAX_VALUE) {
+ sendEOL();
+ }
+ else {
+ send(String.valueOf(val));
+ }
+ }
+
+ protected void send( boolean val) throws IOException {
+ send( val ? 1 : 0);
+ }
+
+ private static boolean IsEmpty(String str) {
+ return Util.StringIsEmpty(str);
+ }
+
+}
diff --git a/ib/src/main/java/com/ib/client/EReader.java b/ib/src/main/java/com/ib/client/EReader.java
new file mode 100644
index 00000000..8f16681d
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/EReader.java
@@ -0,0 +1,983 @@
+/*
+ * EReader.java
+ *
+ */
+
+package com.ib.client;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+public class EReader extends Thread {
+
+ // incoming msg id's
+ static final int TICK_PRICE = 1;
+ static final int TICK_SIZE = 2;
+ static final int ORDER_STATUS = 3;
+ static final int ERR_MSG = 4;
+ static final int OPEN_ORDER = 5;
+ static final int ACCT_VALUE = 6;
+ static final int PORTFOLIO_VALUE = 7;
+ static final int ACCT_UPDATE_TIME = 8;
+ static final int NEXT_VALID_ID = 9;
+ static final int CONTRACT_DATA = 10;
+ static final int EXECUTION_DATA = 11;
+ static final int MARKET_DEPTH = 12;
+ static final int MARKET_DEPTH_L2 = 13;
+ static final int NEWS_BULLETINS = 14;
+ static final int MANAGED_ACCTS = 15;
+ static final int RECEIVE_FA = 16;
+ static final int HISTORICAL_DATA = 17;
+ static final int BOND_CONTRACT_DATA = 18;
+ static final int SCANNER_PARAMETERS = 19;
+ static final int SCANNER_DATA = 20;
+ static final int TICK_OPTION_COMPUTATION = 21;
+ static final int TICK_GENERIC = 45;
+ static final int TICK_STRING = 46;
+ static final int TICK_EFP = 47;
+ static final int CURRENT_TIME = 49;
+ static final int REAL_TIME_BARS = 50;
+ static final int FUNDAMENTAL_DATA = 51;
+ static final int CONTRACT_DATA_END = 52;
+ static final int OPEN_ORDER_END = 53;
+ static final int ACCT_DOWNLOAD_END = 54;
+ static final int EXECUTION_DATA_END = 55;
+ static final int DELTA_NEUTRAL_VALIDATION = 56;
+ static final int TICK_SNAPSHOT_END = 57;
+ static final int MARKET_DATA_TYPE = 58;
+
+ private EClientSocket m_parent;
+ private DataInputStream m_dis;
+
+ protected EClientSocket parent() { return m_parent; }
+ private EWrapper eWrapper() { return (EWrapper)parent().wrapper(); }
+
+ public EReader( EClientSocket parent, DataInputStream dis) {
+ this("EReader", parent, dis);
+ }
+
+ protected EReader( String name, EClientSocket parent, DataInputStream dis) {
+ setName( name);
+ m_parent = parent;
+ m_dis = dis;
+ }
+
+ public void run() {
+ try {
+ // loop until thread is terminated
+ while( !isInterrupted() && processMsg(readInt()));
+ }
+ catch ( Exception ex ) {
+ if (parent().isConnected()) {
+ eWrapper().error( ex);
+ }
+ }
+ if (parent().isConnected()) {
+ m_parent.close();
+ }
+ }
+
+ /** Overridden in subclass. */
+ protected boolean processMsg(int msgId) throws IOException{
+ if( msgId == -1) return false;
+
+ switch( msgId) {
+ case TICK_PRICE: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ double price = readDouble();
+ int size = 0;
+ if( version >= 2) {
+ size = readInt();
+ }
+ int canAutoExecute = 0;
+ if (version >= 3) {
+ canAutoExecute = readInt();
+ }
+ eWrapper().tickPrice( tickerId, tickType, price, canAutoExecute);
+
+ if( version >= 2) {
+ int sizeTickType = -1 ; // not a tick
+ switch (tickType) {
+ case 1: // BID
+ sizeTickType = 0 ; // BID_SIZE
+ break ;
+ case 2: // ASK
+ sizeTickType = 3 ; // ASK_SIZE
+ break ;
+ case 4: // LAST
+ sizeTickType = 5 ; // LAST_SIZE
+ break ;
+ }
+ if (sizeTickType != -1) {
+ eWrapper().tickSize( tickerId, sizeTickType, size);
+ }
+ }
+ break;
+ }
+ case TICK_SIZE: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ int size = readInt();
+
+ eWrapper().tickSize( tickerId, tickType, size);
+ break;
+ }
+
+ case TICK_OPTION_COMPUTATION: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ double impliedVol = readDouble();
+ if (impliedVol < 0) { // -1 is the "not yet computed" indicator
+ impliedVol = Double.MAX_VALUE;
+ }
+ double delta = readDouble();
+ if (Math.abs(delta) > 1) { // -2 is the "not yet computed" indicator
+ delta = Double.MAX_VALUE;
+ }
+ double optPrice = Double.MAX_VALUE;
+ double pvDividend = Double.MAX_VALUE;
+ double gamma = Double.MAX_VALUE;
+ double vega = Double.MAX_VALUE;
+ double theta = Double.MAX_VALUE;
+ double undPrice = Double.MAX_VALUE;
+ if (version >= 6 || tickType == TickType.MODEL_OPTION) { // introduced in version == 5
+ optPrice = readDouble();
+ if (optPrice < 0) { // -1 is the "not yet computed" indicator
+ optPrice = Double.MAX_VALUE;
+ }
+ pvDividend = readDouble();
+ if (pvDividend < 0) { // -1 is the "not yet computed" indicator
+ pvDividend = Double.MAX_VALUE;
+ }
+ }
+ if (version >= 6) {
+ gamma = readDouble();
+ if (Math.abs(gamma) > 1) { // -2 is the "not yet computed" indicator
+ gamma = Double.MAX_VALUE;
+ }
+ vega = readDouble();
+ if (Math.abs(vega) > 1) { // -2 is the "not yet computed" indicator
+ vega = Double.MAX_VALUE;
+ }
+ theta = readDouble();
+ if (Math.abs(theta) > 1) { // -2 is the "not yet computed" indicator
+ theta = Double.MAX_VALUE;
+ }
+ undPrice = readDouble();
+ if (undPrice < 0) { // -1 is the "not yet computed" indicator
+ undPrice = Double.MAX_VALUE;
+ }
+ }
+
+ eWrapper().tickOptionComputation( tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice);
+ break;
+ }
+
+ case TICK_GENERIC: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ double value = readDouble();
+
+ eWrapper().tickGeneric( tickerId, tickType, value);
+ break;
+ }
+
+ case TICK_STRING: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ String value = readStr();
+
+ eWrapper().tickString( tickerId, tickType, value);
+ break;
+ }
+
+ case TICK_EFP: {
+ int version = readInt();
+ int tickerId = readInt();
+ int tickType = readInt();
+ double basisPoints = readDouble();
+ String formattedBasisPoints = readStr();
+ double impliedFuturesPrice = readDouble();
+ int holdDays = readInt();
+ String futureExpiry = readStr();
+ double dividendImpact = readDouble();
+ double dividendsToExpiry = readDouble();
+ eWrapper().tickEFP( tickerId, tickType, basisPoints, formattedBasisPoints,
+ impliedFuturesPrice, holdDays, futureExpiry, dividendImpact, dividendsToExpiry);
+ break;
+ }
+
+ case ORDER_STATUS: {
+ int version = readInt();
+ int id = readInt();
+ String status = readStr();
+ int filled = readInt();
+ int remaining = readInt();
+ double avgFillPrice = readDouble();
+
+ int permId = 0;
+ if( version >= 2) {
+ permId = readInt();
+ }
+
+ int parentId = 0;
+ if( version >= 3) {
+ parentId = readInt();
+ }
+
+ double lastFillPrice = 0;
+ if( version >= 4) {
+ lastFillPrice = readDouble();
+ }
+
+ int clientId = 0;
+ if( version >= 5) {
+ clientId = readInt();
+ }
+
+ String whyHeld = null;
+ if( version >= 6) {
+ whyHeld = readStr();
+ }
+
+ eWrapper().orderStatus( id, status, filled, remaining, avgFillPrice,
+ permId, parentId, lastFillPrice, clientId, whyHeld);
+ break;
+ }
+
+ case ACCT_VALUE: {
+ int version = readInt();
+ String key = readStr();
+ String val = readStr();
+ String cur = readStr();
+ String accountName = null ;
+ if( version >= 2) {
+ accountName = readStr();
+ }
+ eWrapper().updateAccountValue(key, val, cur, accountName);
+ break;
+ }
+
+ case PORTFOLIO_VALUE: {
+ int version = readInt();
+ Contract contract = new Contract();
+ if (version >= 6) {
+ contract.m_conId = readInt();
+ }
+ contract.m_symbol = readStr();
+ contract.m_secType = readStr();
+ contract.m_expiry = readStr();
+ contract.m_strike = readDouble();
+ contract.m_right = readStr();
+ if (version >= 7) {
+ contract.m_multiplier = readStr();
+ contract.m_primaryExch = readStr();
+ }
+ contract.m_currency = readStr();
+ if ( version >= 2 ) {
+ contract.m_localSymbol = readStr();
+ }
+
+ int position = readInt();
+ double marketPrice = readDouble();
+ double marketValue = readDouble();
+ double averageCost = 0.0;
+ double unrealizedPNL = 0.0;
+ double realizedPNL = 0.0;
+ if (version >=3 ) {
+ averageCost = readDouble();
+ unrealizedPNL = readDouble();
+ realizedPNL = readDouble();
+ }
+
+ String accountName = null ;
+ if( version >= 4) {
+ accountName = readStr();
+ }
+
+ if(version == 6 && m_parent.serverVersion() == 39) {
+ contract.m_primaryExch = readStr();
+ }
+
+ eWrapper().updatePortfolio(contract, position, marketPrice, marketValue,
+ averageCost, unrealizedPNL, realizedPNL, accountName);
+
+ break;
+ }
+
+ case ACCT_UPDATE_TIME: {
+ int version = readInt();
+ String timeStamp = readStr();
+ eWrapper().updateAccountTime(timeStamp);
+ break;
+ }
+
+ case ERR_MSG: {
+ int version = readInt();
+ if(version < 2) {
+ String msg = readStr();
+ m_parent.error( msg);
+ } else {
+ int id = readInt();
+ int errorCode = readInt();
+ String errorMsg = readStr();
+ m_parent.error(id, errorCode, errorMsg);
+ }
+ break;
+ }
+
+ case OPEN_ORDER: {
+ // read version
+ int version = readInt();
+
+ // read order id
+ Order order = new Order();
+ order.m_orderId = readInt();
+
+ // read contract fields
+ Contract contract = new Contract();
+ if (version >= 17) {
+ contract.m_conId = readInt();
+ }
+ contract.m_symbol = readStr();
+ contract.m_secType = readStr();
+ contract.m_expiry = readStr();
+ contract.m_strike = readDouble();
+ contract.m_right = readStr();
+ contract.m_exchange = readStr();
+ contract.m_currency = readStr();
+ if ( version >= 2 ) {
+ contract.m_localSymbol = readStr();
+ }
+
+ // read order fields
+ order.m_action = readStr();
+ order.m_totalQuantity = readInt();
+ order.m_orderType = readStr();
+ order.m_lmtPrice = readDouble();
+ order.m_auxPrice = readDouble();
+ order.m_tif = readStr();
+ order.m_ocaGroup = readStr();
+ order.m_account = readStr();
+ order.m_openClose = readStr();
+ order.m_origin = readInt();
+ order.m_orderRef = readStr();
+
+ if(version >= 3) {
+ order.m_clientId = readInt();
+ }
+
+ if( version >= 4 ) {
+ order.m_permId = readInt();
+ if ( version < 18) {
+ // will never happen
+ /* order.m_ignoreRth = */ readBoolFromInt();
+ }
+ else {
+ order.m_outsideRth = readBoolFromInt();
+ }
+ order.m_hidden = readInt() == 1;
+ order.m_discretionaryAmt = readDouble();
+ }
+
+ if ( version >= 5 ) {
+ order.m_goodAfterTime = readStr();
+ }
+
+ if ( version >= 6 ) {
+ // skip deprecated sharesAllocation field
+ readStr();
+ }
+
+ if ( version >= 7 ) {
+ order.m_faGroup = readStr();
+ order.m_faMethod = readStr();
+ order.m_faPercentage = readStr();
+ order.m_faProfile = readStr();
+ }
+
+ if ( version >= 8 ) {
+ order.m_goodTillDate = readStr();
+ }
+
+ if ( version >= 9) {
+ order.m_rule80A = readStr();
+ order.m_percentOffset = readDouble();
+ order.m_settlingFirm = readStr();
+ order.m_shortSaleSlot = readInt();
+ order.m_designatedLocation = readStr();
+ if ( m_parent.serverVersion() == 51){
+ readInt(); // exemptCode
+ }
+ else if ( version >= 23){
+ order.m_exemptCode = readInt();
+ }
+ order.m_auctionStrategy = readInt();
+ order.m_startingPrice = readDouble();
+ order.m_stockRefPrice = readDouble();
+ order.m_delta = readDouble();
+ order.m_stockRangeLower = readDouble();
+ order.m_stockRangeUpper = readDouble();
+ order.m_displaySize = readInt();
+ if ( version < 18) {
+ // will never happen
+ /* order.m_rthOnly = */ readBoolFromInt();
+ }
+ order.m_blockOrder = readBoolFromInt();
+ order.m_sweepToFill = readBoolFromInt();
+ order.m_allOrNone = readBoolFromInt();
+ order.m_minQty = readInt();
+ order.m_ocaType = readInt();
+ order.m_eTradeOnly = readBoolFromInt();
+ order.m_firmQuoteOnly = readBoolFromInt();
+ order.m_nbboPriceCap = readDouble();
+ }
+
+ if ( version >= 10) {
+ order.m_parentId = readInt();
+ order.m_triggerMethod = readInt();
+ }
+
+ if (version >= 11) {
+ order.m_volatility = readDouble();
+ order.m_volatilityType = readInt();
+ if (version == 11) {
+ int receivedInt = readInt();
+ order.m_deltaNeutralOrderType = ( (receivedInt == 0) ? "NONE" : "MKT" );
+ } else { // version 12 and up
+ order.m_deltaNeutralOrderType = readStr();
+ order.m_deltaNeutralAuxPrice = readDouble();
+
+ if (version >= 27 && !Util.StringIsEmpty(order.m_deltaNeutralOrderType)) {
+ order.m_deltaNeutralConId = readInt();
+ order.m_deltaNeutralSettlingFirm = readStr();
+ order.m_deltaNeutralClearingAccount = readStr();
+ order.m_deltaNeutralClearingIntent = readStr();
+ }
+ }
+ order.m_continuousUpdate = readInt();
+ if (m_parent.serverVersion() == 26) {
+ order.m_stockRangeLower = readDouble();
+ order.m_stockRangeUpper = readDouble();
+ }
+ order.m_referencePriceType = readInt();
+ }
+
+ if (version >= 13) {
+ order.m_trailStopPrice = readDouble();
+ }
+
+ if (version >= 14) {
+ order.m_basisPoints = readDouble();
+ order.m_basisPointsType = readInt();
+ contract.m_comboLegsDescrip = readStr();
+ }
+
+ if (version >= 26) {
+ int smartComboRoutingParamsCount = readInt();
+ if (smartComboRoutingParamsCount > 0) {
+ order.m_smartComboRoutingParams = new Vector(smartComboRoutingParamsCount);
+ for (int i = 0; i < smartComboRoutingParamsCount; ++i) {
+ TagValue tagValue = new TagValue();
+ tagValue.m_tag = readStr();
+ tagValue.m_value = readStr();
+ order.m_smartComboRoutingParams.add(tagValue);
+ }
+ }
+ }
+
+ if (version >= 15) {
+ if (version >= 20) {
+ order.m_scaleInitLevelSize = readIntMax();
+ order.m_scaleSubsLevelSize = readIntMax();
+ }
+ else {
+ /* int notSuppScaleNumComponents = */ readIntMax();
+ order.m_scaleInitLevelSize = readIntMax();
+ }
+ order.m_scalePriceIncrement = readDoubleMax();
+ }
+
+ if (version >= 24) {
+ order.m_hedgeType = readStr();
+ if (!Util.StringIsEmpty(order.m_hedgeType)) {
+ order.m_hedgeParam = readStr();
+ }
+ }
+
+ if (version >= 25) {
+ order.m_optOutSmartRouting = readBoolFromInt();
+ }
+
+ if (version >= 19) {
+ order.m_clearingAccount = readStr();
+ order.m_clearingIntent = readStr();
+ }
+
+ if (version >= 22) {
+ order.m_notHeld = readBoolFromInt();
+ }
+
+ if (version >= 20) {
+ if (readBoolFromInt()) {
+ UnderComp underComp = new UnderComp();
+ underComp.m_conId = readInt();
+ underComp.m_delta = readDouble();
+ underComp.m_price = readDouble();
+ contract.m_underComp = underComp;
+ }
+ }
+
+ if (version >= 21) {
+ order.m_algoStrategy = readStr();
+ if (!Util.StringIsEmpty(order.m_algoStrategy)) {
+ int algoParamsCount = readInt();
+ if (algoParamsCount > 0) {
+ order.m_algoParams = new Vector(algoParamsCount);
+ for (int i = 0; i < algoParamsCount; ++i) {
+ TagValue tagValue = new TagValue();
+ tagValue.m_tag = readStr();
+ tagValue.m_value = readStr();
+ order.m_algoParams.add(tagValue);
+ }
+ }
+ }
+ }
+
+ OrderState orderState = new OrderState();
+
+ if (version >= 16) {
+
+ order.m_whatIf = readBoolFromInt();
+
+ orderState.m_status = readStr();
+ orderState.m_initMargin = readStr();
+ orderState.m_maintMargin = readStr();
+ orderState.m_equityWithLoan = readStr();
+ orderState.m_commission = readDoubleMax();
+ orderState.m_minCommission = readDoubleMax();
+ orderState.m_maxCommission = readDoubleMax();
+ orderState.m_commissionCurrency = readStr();
+ orderState.m_warningText = readStr();
+ }
+
+ eWrapper().openOrder( order.m_orderId, contract, order, orderState);
+ break;
+ }
+
+ case NEXT_VALID_ID: {
+ int version = readInt();
+ int orderId = readInt();
+ eWrapper().nextValidId( orderId);
+ break;
+ }
+
+ case SCANNER_DATA: {
+ ContractDetails contract = new ContractDetails();
+ int version = readInt();
+ int tickerId = readInt();
+ int numberOfElements = readInt();
+ for (int ctr=0; ctr < numberOfElements; ctr++) {
+ int rank = readInt();
+ if (version >= 3) {
+ contract.m_summary.m_conId = readInt();
+ }
+ contract.m_summary.m_symbol = readStr();
+ contract.m_summary.m_secType = readStr();
+ contract.m_summary.m_expiry = readStr();
+ contract.m_summary.m_strike = readDouble();
+ contract.m_summary.m_right = readStr();
+ contract.m_summary.m_exchange = readStr();
+ contract.m_summary.m_currency = readStr();
+ contract.m_summary.m_localSymbol = readStr();
+ contract.m_marketName = readStr();
+ contract.m_tradingClass = readStr();
+ String distance = readStr();
+ String benchmark = readStr();
+ String projection = readStr();
+ String legsStr = null;
+ if (version >= 2) {
+ legsStr = readStr();
+ }
+ eWrapper().scannerData(tickerId, rank, contract, distance,
+ benchmark, projection, legsStr);
+ }
+ eWrapper().scannerDataEnd(tickerId);
+ break;
+ }
+
+ case CONTRACT_DATA: {
+ int version = readInt();
+
+ int reqId = -1;
+ if (version >= 3) {
+ reqId = readInt();
+ }
+
+ ContractDetails contract = new ContractDetails();
+ contract.m_summary.m_symbol = readStr();
+ contract.m_summary.m_secType = readStr();
+ contract.m_summary.m_expiry = readStr();
+ contract.m_summary.m_strike = readDouble();
+ contract.m_summary.m_right = readStr();
+ contract.m_summary.m_exchange = readStr();
+ contract.m_summary.m_currency = readStr();
+ contract.m_summary.m_localSymbol = readStr();
+ contract.m_marketName = readStr();
+ contract.m_tradingClass = readStr();
+ contract.m_summary.m_conId = readInt();
+ contract.m_minTick = readDouble();
+ contract.m_summary.m_multiplier = readStr();
+ contract.m_orderTypes = readStr();
+ contract.m_validExchanges = readStr();
+ if (version >= 2) {
+ contract.m_priceMagnifier = readInt();
+ }
+ if (version >= 4) {
+ contract.m_underConId = readInt();
+ }
+ if( version >= 5) {
+ contract.m_longName = readStr();
+ contract.m_summary.m_primaryExch = readStr();
+ }
+ if( version >= 6) {
+ contract.m_contractMonth = readStr();
+ contract.m_industry = readStr();
+ contract.m_category = readStr();
+ contract.m_subcategory = readStr();
+ contract.m_timeZoneId = readStr();
+ contract.m_tradingHours = readStr();
+ contract.m_liquidHours = readStr();
+ }
+ eWrapper().contractDetails( reqId, contract);
+ break;
+ }
+ case BOND_CONTRACT_DATA: {
+ int version = readInt();
+
+ int reqId = -1;
+ if (version >= 3) {
+ reqId = readInt();
+ }
+
+ ContractDetails contract = new ContractDetails();
+
+ contract.m_summary.m_symbol = readStr();
+ contract.m_summary.m_secType = readStr();
+ contract.m_cusip = readStr();
+ contract.m_coupon = readDouble();
+ contract.m_maturity = readStr();
+ contract.m_issueDate = readStr();
+ contract.m_ratings = readStr();
+ contract.m_bondType = readStr();
+ contract.m_couponType = readStr();
+ contract.m_convertible = readBoolFromInt();
+ contract.m_callable = readBoolFromInt();
+ contract.m_putable = readBoolFromInt();
+ contract.m_descAppend = readStr();
+ contract.m_summary.m_exchange = readStr();
+ contract.m_summary.m_currency = readStr();
+ contract.m_marketName = readStr();
+ contract.m_tradingClass = readStr();
+ contract.m_summary.m_conId = readInt();
+ contract.m_minTick = readDouble();
+ contract.m_orderTypes = readStr();
+ contract.m_validExchanges = readStr();
+ if (version >= 2) {
+ contract.m_nextOptionDate = readStr();
+ contract.m_nextOptionType = readStr();
+ contract.m_nextOptionPartial = readBoolFromInt();
+ contract.m_notes = readStr();
+ }
+ if( version >= 4) {
+ contract.m_longName = readStr();
+ }
+ eWrapper().bondContractDetails( reqId, contract);
+ break;
+ }
+ case EXECUTION_DATA: {
+ int version = readInt();
+
+ int reqId = -1;
+ if (version >= 7) {
+ reqId = readInt();
+ }
+
+ int orderId = readInt();
+
+ // read contract fields
+ Contract contract = new Contract();
+ if (version >= 5) {
+ contract.m_conId = readInt();
+ }
+ contract.m_symbol = readStr();
+ contract.m_secType = readStr();
+ contract.m_expiry = readStr();
+ contract.m_strike = readDouble();
+ contract.m_right = readStr();
+ contract.m_exchange = readStr();
+ contract.m_currency = readStr();
+ contract.m_localSymbol = readStr();
+
+ Execution exec = new Execution();
+ exec.m_orderId = orderId;
+ exec.m_execId = readStr();
+ exec.m_time = readStr();
+ exec.m_acctNumber = readStr();
+ exec.m_exchange = readStr();
+ exec.m_side = readStr();
+ exec.m_shares = readInt();
+ exec.m_price = readDouble();
+ if ( version >= 2 ) {
+ exec.m_permId = readInt();
+ }
+ if ( version >= 3) {
+ exec.m_clientId = readInt();
+ }
+ if ( version >= 4) {
+ exec.m_liquidation = readInt();
+ }
+ if (version >= 6) {
+ exec.m_cumQty = readInt();
+ exec.m_avgPrice = readDouble();
+ }
+ if (version >= 8) {
+ exec.m_orderRef = readStr();
+ }
+ eWrapper().execDetails( reqId, contract, exec);
+ break;
+ }
+ case MARKET_DEPTH: {
+ int version = readInt();
+ int id = readInt();
+
+ int position = readInt();
+ int operation = readInt();
+ int side = readInt();
+ double price = readDouble();
+ int size = readInt();
+
+ eWrapper().updateMktDepth(id, position, operation,
+ side, price, size);
+ break;
+ }
+ case MARKET_DEPTH_L2: {
+ int version = readInt();
+ int id = readInt();
+
+ int position = readInt();
+ String marketMaker = readStr();
+ int operation = readInt();
+ int side = readInt();
+ double price = readDouble();
+ int size = readInt();
+
+ eWrapper().updateMktDepthL2(id, position, marketMaker,
+ operation, side, price, size);
+ break;
+ }
+ case NEWS_BULLETINS: {
+ int version = readInt();
+ int newsMsgId = readInt();
+ int newsMsgType = readInt();
+ String newsMessage = readStr();
+ String originatingExch = readStr();
+
+ eWrapper().updateNewsBulletin( newsMsgId, newsMsgType, newsMessage, originatingExch);
+ break;
+ }
+ case MANAGED_ACCTS: {
+ int version = readInt();
+ String accountsList = readStr();
+
+ eWrapper().managedAccounts( accountsList);
+ break;
+ }
+ case RECEIVE_FA: {
+ int version = readInt();
+ int faDataType = readInt();
+ String xml = readStr();
+
+ eWrapper().receiveFA(faDataType, xml);
+ break;
+ }
+ case HISTORICAL_DATA: {
+ int version = readInt();
+ int reqId = readInt();
+ String startDateStr;
+ String endDateStr;
+ String completedIndicator = "finished";
+ if (version >= 2) {
+ startDateStr = readStr();
+ endDateStr = readStr();
+ completedIndicator += "-" + startDateStr + "-" + endDateStr;
+ }
+ int itemCount = readInt();
+ for (int ctr = 0; ctr < itemCount; ctr++) {
+ String date = readStr();
+ double open = readDouble();
+ double high = readDouble();
+ double low = readDouble();
+ double close = readDouble();
+ int volume = readInt();
+ double WAP = readDouble();
+ String hasGaps = readStr();
+ int barCount = -1;
+ if (version >= 3) {
+ barCount = readInt();
+ }
+ eWrapper().historicalData(reqId, date, open, high, low,
+ close, volume, barCount, WAP,
+ Boolean.valueOf(hasGaps).booleanValue());
+ }
+ // send end of dataset marker
+ eWrapper().historicalData(reqId, completedIndicator, -1, -1, -1, -1, -1, -1, -1, false);
+ break;
+ }
+ case SCANNER_PARAMETERS: {
+ int version = readInt();
+ String xml = readStr();
+ eWrapper().scannerParameters(xml);
+ break;
+ }
+ case CURRENT_TIME: {
+ /*int version =*/ readInt();
+ long time = readLong();
+ eWrapper().currentTime(time);
+ break;
+ }
+ case REAL_TIME_BARS: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+ long time = readLong();
+ double open = readDouble();
+ double high = readDouble();
+ double low = readDouble();
+ double close = readDouble();
+ long volume = readLong();
+ double wap = readDouble();
+ int count = readInt();
+ eWrapper().realtimeBar(reqId, time, open, high, low, close, volume, wap, count);
+ break;
+ }
+ case FUNDAMENTAL_DATA: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+ String data = readStr();
+ eWrapper().fundamentalData(reqId, data);
+ break;
+ }
+ case CONTRACT_DATA_END: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+ eWrapper().contractDetailsEnd(reqId);
+ break;
+ }
+ case OPEN_ORDER_END: {
+ /*int version =*/ readInt();
+ eWrapper().openOrderEnd();
+ break;
+ }
+ case ACCT_DOWNLOAD_END: {
+ /*int version =*/ readInt();
+ String accountName = readStr();
+ eWrapper().accountDownloadEnd( accountName);
+ break;
+ }
+ case EXECUTION_DATA_END: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+ eWrapper().execDetailsEnd( reqId);
+ break;
+ }
+ case DELTA_NEUTRAL_VALIDATION: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+
+ UnderComp underComp = new UnderComp();
+ underComp.m_conId = readInt();
+ underComp.m_delta = readDouble();
+ underComp.m_price = readDouble();
+
+ eWrapper().deltaNeutralValidation( reqId, underComp);
+ break;
+ }
+ case TICK_SNAPSHOT_END: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+
+ eWrapper().tickSnapshotEnd( reqId);
+ break;
+ }
+ case MARKET_DATA_TYPE: {
+ /*int version =*/ readInt();
+ int reqId = readInt();
+ int marketDataType = readInt();
+
+ eWrapper().marketDataType( reqId, marketDataType);
+ break;
+ }
+
+ default: {
+ m_parent.error( EClientErrors.NO_VALID_ID, EClientErrors.UNKNOWN_ID.code(), EClientErrors.UNKNOWN_ID.msg());
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ protected String readStr() throws IOException {
+ StringBuffer buf = new StringBuffer();
+ while( true) {
+ byte c = m_dis.readByte();
+ if( c == 0) {
+ break;
+ }
+ buf.append( (char)c);
+ }
+
+ String str = buf.toString();
+ return str.length() == 0 ? null : str;
+ }
+
+
+ boolean readBoolFromInt() throws IOException {
+ String str = readStr();
+ return str == null ? false : (Integer.parseInt( str) != 0);
+ }
+
+ protected int readInt() throws IOException {
+ String str = readStr();
+ return str == null ? 0 : Integer.parseInt( str);
+ }
+
+ protected int readIntMax() throws IOException {
+ String str = readStr();
+ return (str == null || str.length() == 0) ? Integer.MAX_VALUE
+ : Integer.parseInt( str);
+ }
+
+ protected long readLong() throws IOException {
+ String str = readStr();
+ return str == null ? 0l : Long.parseLong(str);
+ }
+
+ protected double readDouble() throws IOException {
+ String str = readStr();
+ return str == null ? 0 : Double.parseDouble( str);
+ }
+
+ protected double readDoubleMax() throws IOException {
+ String str = readStr();
+ return (str == null || str.length() == 0) ? Double.MAX_VALUE
+ : Double.parseDouble( str);
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/EWrapper.java b/ib/src/main/java/com/ib/client/EWrapper.java
new file mode 100644
index 00000000..30aafbcf
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/EWrapper.java
@@ -0,0 +1,56 @@
+/*
+ * EWrapper.java
+ *
+ */
+package com.ib.client;
+
+public interface EWrapper extends AnyWrapper {
+
+ ///////////////////////////////////////////////////////////////////////
+ // Interface methods
+ ///////////////////////////////////////////////////////////////////////
+ void tickPrice( int tickerId, int field, double price, int canAutoExecute);
+ void tickSize( int tickerId, int field, int size);
+ void tickOptionComputation( int tickerId, int field, double impliedVol,
+ double delta, double optPrice, double pvDividend,
+ double gamma, double vega, double theta, double undPrice);
+ void tickGeneric(int tickerId, int tickType, double value);
+ void tickString(int tickerId, int tickType, String value);
+ void tickEFP(int tickerId, int tickType, double basisPoints,
+ String formattedBasisPoints, double impliedFuture, int holdDays,
+ String futureExpiry, double dividendImpact, double dividendsToExpiry);
+ void orderStatus( int orderId, String status, int filled, int remaining,
+ double avgFillPrice, int permId, int parentId, double lastFillPrice,
+ int clientId, String whyHeld);
+ void openOrder( int orderId, Contract contract, Order order, OrderState orderState);
+ void openOrderEnd();
+ void updateAccountValue(String key, String value, String currency, String accountName);
+ void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue,
+ double averageCost, double unrealizedPNL, double realizedPNL, String accountName);
+ void updateAccountTime(String timeStamp);
+ void accountDownloadEnd(String accountName);
+ void nextValidId( int orderId);
+ void contractDetails(int reqId, ContractDetails contractDetails);
+ void bondContractDetails(int reqId, ContractDetails contractDetails);
+ void contractDetailsEnd(int reqId);
+ void execDetails( int reqId, Contract contract, Execution execution);
+ void execDetailsEnd( int reqId);
+ void updateMktDepth( int tickerId, int position, int operation, int side, double price, int size);
+ void updateMktDepthL2( int tickerId, int position, String marketMaker, int operation,
+ int side, double price, int size);
+ void updateNewsBulletin( int msgId, int msgType, String message, String origExchange);
+ void managedAccounts( String accountsList);
+ void receiveFA(int faDataType, String xml);
+ void historicalData(int reqId, String date, double open, double high, double low,
+ double close, int volume, int count, double WAP, boolean hasGaps);
+ void scannerParameters(String xml);
+ void scannerData(int reqId, int rank, ContractDetails contractDetails, String distance,
+ String benchmark, String projection, String legsStr);
+ void scannerDataEnd(int reqId);
+ void realtimeBar(int reqId, long time, double open, double high, double low, double close, long volume, double wap, int count);
+ void currentTime(long time);
+ void fundamentalData(int reqId, String data);
+ void deltaNeutralValidation(int reqId, UnderComp underComp);
+ void tickSnapshotEnd(int reqId);
+ void marketDataType(int reqId, int marketDataType);
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/EWrapperMsgGenerator.java b/ib/src/main/java/com/ib/client/EWrapperMsgGenerator.java
new file mode 100644
index 00000000..41b775e3
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/EWrapperMsgGenerator.java
@@ -0,0 +1,437 @@
+package com.ib.client;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Vector;
+
+public class EWrapperMsgGenerator extends AnyWrapperMsgGenerator {
+ public static final String SCANNER_PARAMETERS = "SCANNER PARAMETERS:";
+ public static final String FINANCIAL_ADVISOR = "FA:";
+
+ static public String tickPrice( int tickerId, int field, double price, int canAutoExecute) {
+ return "id=" + tickerId + " " + TickType.getField( field) + "=" + price + " " +
+ ((canAutoExecute != 0) ? " canAutoExecute" : " noAutoExecute");
+ }
+
+ static public String tickSize( int tickerId, int field, int size) {
+ return "id=" + tickerId + " " + TickType.getField( field) + "=" + size;
+ }
+
+ static public String tickOptionComputation( int tickerId, int field, double impliedVol,
+ double delta, double optPrice, double pvDividend,
+ double gamma, double vega, double theta, double undPrice) {
+ String toAdd = "id=" + tickerId + " " + TickType.getField( field) +
+ ": vol = " + ((impliedVol >= 0 && impliedVol != Double.MAX_VALUE) ? Double.toString(impliedVol) : "N/A") +
+ " delta = " + ((Math.abs(delta) <= 1) ? Double.toString(delta) : "N/A") +
+ " gamma = " + ((Math.abs(gamma) <= 1) ? Double.toString(gamma) : "N/A") +
+ " vega = " + ((Math.abs(vega) <= 1) ? Double.toString(vega) : "N/A") +
+ " theta = " + ((Math.abs(theta) <= 1) ? Double.toString(theta) : "N/A") +
+ " optPrice = " + ((optPrice >= 0 && optPrice != Double.MAX_VALUE) ? Double.toString(optPrice) : "N/A") +
+ " pvDividend = " + ((pvDividend >= 0 && pvDividend != Double.MAX_VALUE) ? Double.toString(pvDividend) : "N/A") +
+ " undPrice = " + ((undPrice >= 0 && undPrice != Double.MAX_VALUE) ? Double.toString(undPrice) : "N/A");
+ return toAdd;
+ }
+
+ static public String tickGeneric(int tickerId, int tickType, double value) {
+ return "id=" + tickerId + " " + TickType.getField( tickType) + "=" + value;
+ }
+
+ static public String tickString(int tickerId, int tickType, String value) {
+ return "id=" + tickerId + " " + TickType.getField( tickType) + "=" + value;
+ }
+
+ static public String tickEFP(int tickerId, int tickType, double basisPoints,
+ String formattedBasisPoints, double impliedFuture, int holdDays,
+ String futureExpiry, double dividendImpact, double dividendsToExpiry) {
+ return "id=" + tickerId + " " + TickType.getField(tickType)
+ + ": basisPoints = " + basisPoints + "/" + formattedBasisPoints
+ + " impliedFuture = " + impliedFuture + " holdDays = " + holdDays +
+ " futureExpiry = " + futureExpiry + " dividendImpact = " + dividendImpact +
+ " dividends to expiry = " + dividendsToExpiry;
+ }
+
+ static public String orderStatus( int orderId, String status, int filled, int remaining,
+ double avgFillPrice, int permId, int parentId, double lastFillPrice,
+ int clientId, String whyHeld) {
+ return "order status: orderId=" + orderId + " clientId=" + clientId + " permId=" + permId +
+ " status=" + status + " filled=" + filled + " remaining=" + remaining +
+ " avgFillPrice=" + avgFillPrice + " lastFillPrice=" + lastFillPrice +
+ " parent Id=" + parentId + " whyHeld=" + whyHeld;
+ }
+
+ static public String openOrder( int orderId, Contract contract, Order order, OrderState orderState) {
+ String msg = "open order: orderId=" + orderId +
+ " action=" + order.m_action +
+ " quantity=" + order.m_totalQuantity +
+ " symbol=" + contract.m_symbol +
+ " exchange=" + contract.m_exchange +
+ " secType=" + contract.m_secType +
+ " type=" + order.m_orderType +
+ " lmtPrice=" + order.m_lmtPrice +
+ " auxPrice=" + order.m_auxPrice +
+ " TIF=" + order.m_tif +
+ " localSymbol=" + contract.m_localSymbol +
+ " client Id=" + order.m_clientId +
+ " parent Id=" + order.m_parentId +
+ " permId=" + order.m_permId +
+ " outsideRth=" + order.m_outsideRth +
+ " hidden=" + order.m_hidden +
+ " discretionaryAmt=" + order.m_discretionaryAmt +
+ " triggerMethod=" + order.m_triggerMethod +
+ " goodAfterTime=" + order.m_goodAfterTime +
+ " goodTillDate=" + order.m_goodTillDate +
+ " faGroup=" + order.m_faGroup +
+ " faMethod=" + order.m_faMethod +
+ " faPercentage=" + order.m_faPercentage +
+ " faProfile=" + order.m_faProfile +
+ " shortSaleSlot=" + order.m_shortSaleSlot +
+ " designatedLocation=" + order.m_designatedLocation +
+ " exemptCode=" + order.m_exemptCode +
+ " ocaGroup=" + order.m_ocaGroup +
+ " ocaType=" + order.m_ocaType +
+ " rule80A=" + order.m_rule80A +
+ " allOrNone=" + order.m_allOrNone +
+ " minQty=" + order.m_minQty +
+ " percentOffset=" + order.m_percentOffset +
+ " eTradeOnly=" + order.m_eTradeOnly +
+ " firmQuoteOnly=" + order.m_firmQuoteOnly +
+ " nbboPriceCap=" + order.m_nbboPriceCap +
+ " optOutSmartRouting=" + order.m_optOutSmartRouting +
+ " auctionStrategy=" + order.m_auctionStrategy +
+ " startingPrice=" + order.m_startingPrice +
+ " stockRefPrice=" + order.m_stockRefPrice +
+ " delta=" + order.m_delta +
+ " stockRangeLower=" + order.m_stockRangeLower +
+ " stockRangeUpper=" + order.m_stockRangeUpper +
+ " volatility=" + order.m_volatility +
+ " volatilityType=" + order.m_volatilityType +
+ " deltaNeutralOrderType=" + order.m_deltaNeutralOrderType +
+ " deltaNeutralAuxPrice=" + order.m_deltaNeutralAuxPrice +
+ " deltaNeutralConId=" + order.m_deltaNeutralConId +
+ " deltaNeutralSettlingFirm=" + order.m_deltaNeutralSettlingFirm +
+ " deltaNeutralClearingAccount=" + order.m_deltaNeutralClearingAccount +
+ " deltaNeutralClearingIntent=" + order.m_deltaNeutralClearingIntent +
+ " continuousUpdate=" + order.m_continuousUpdate +
+ " referencePriceType=" + order.m_referencePriceType +
+ " trailStopPrice=" + order.m_trailStopPrice +
+ " scaleInitLevelSize=" + Util.IntMaxString(order.m_scaleInitLevelSize) +
+ " scaleSubsLevelSize=" + Util.IntMaxString(order.m_scaleSubsLevelSize) +
+ " scalePriceIncrement=" + Util.DoubleMaxString(order.m_scalePriceIncrement) +
+ " hedgeType=" + order.m_hedgeType +
+ " hedgeParam=" + order.m_hedgeParam +
+ " account=" + order.m_account +
+ " settlingFirm=" + order.m_settlingFirm +
+ " clearingAccount=" + order.m_clearingAccount +
+ " clearingIntent=" + order.m_clearingIntent +
+ " notHeld=" + order.m_notHeld +
+ " whatIf=" + order.m_whatIf
+ ;
+
+ if ("BAG".equals(contract.m_secType)) {
+ if (contract.m_comboLegsDescrip != null) {
+ msg += " comboLegsDescrip=" + contract.m_comboLegsDescrip;
+ }
+ if (order.m_basisPoints != Double.MAX_VALUE) {
+ msg += " basisPoints=" + order.m_basisPoints;
+ msg += " basisPointsType=" + order.m_basisPointsType;
+ }
+ }
+
+ if (contract.m_underComp != null) {
+ UnderComp underComp = contract.m_underComp;
+ msg +=
+ " underComp.conId =" + underComp.m_conId +
+ " underComp.delta =" + underComp.m_delta +
+ " underComp.price =" + underComp.m_price ;
+ }
+
+ if (!Util.StringIsEmpty(order.m_algoStrategy)) {
+ msg += " algoStrategy=" + order.m_algoStrategy;
+ msg += " algoParams={";
+ if (order.m_algoParams != null) {
+ Vector algoParams = order.m_algoParams;
+ for (int i = 0; i < algoParams.size(); ++i) {
+ TagValue param = (TagValue)algoParams.elementAt(i);
+ if (i > 0) {
+ msg += ",";
+ }
+ msg += param.m_tag + "=" + param.m_value;
+ }
+ }
+ msg += "}";
+ }
+
+ if ("BAG".equals(contract.m_secType)) {
+ msg += " smartComboRoutingParams={";
+ if (order.m_smartComboRoutingParams != null) {
+ Vector smartComboRoutingParams = order.m_smartComboRoutingParams;
+ for (int i = 0; i < smartComboRoutingParams.size(); ++i) {
+ TagValue param = (TagValue)smartComboRoutingParams.elementAt(i);
+ if (i > 0) {
+ msg += ",";
+ }
+ msg += param.m_tag + "=" + param.m_value;
+ }
+ }
+ msg += "}";
+ }
+
+ String orderStateMsg =
+ " status=" + orderState.m_status
+ + " initMargin=" + orderState.m_initMargin
+ + " maintMargin=" + orderState.m_maintMargin
+ + " equityWithLoan=" + orderState.m_equityWithLoan
+ + " commission=" + Util.DoubleMaxString(orderState.m_commission)
+ + " minCommission=" + Util.DoubleMaxString(orderState.m_minCommission)
+ + " maxCommission=" + Util.DoubleMaxString(orderState.m_maxCommission)
+ + " commissionCurrency=" + orderState.m_commissionCurrency
+ + " warningText=" + orderState.m_warningText
+ ;
+
+ return msg + orderStateMsg;
+ }
+
+ static public String openOrderEnd() {
+ return " =============== end ===============";
+ }
+
+ static public String updateAccountValue(String key, String value, String currency, String accountName) {
+ return "updateAccountValue: " + key + " " + value + " " + currency + " " + accountName;
+ }
+
+ static public String updatePortfolio(Contract contract, int position, double marketPrice,
+ double marketValue, double averageCost, double unrealizedPNL,
+ double realizedPNL, String accountName) {
+ String msg = "updatePortfolio: "
+ + contractMsg(contract)
+ + position + " " + marketPrice + " " + marketValue + " " + averageCost + " " + unrealizedPNL + " " + realizedPNL + " " + accountName;
+ return msg;
+ }
+
+ static public String updateAccountTime(String timeStamp) {
+ return "updateAccountTime: " + timeStamp;
+ }
+
+ static public String accountDownloadEnd(String accountName) {
+ return "accountDownloadEnd: " + accountName;
+ }
+
+ static public String nextValidId( int orderId) {
+ return "Next Valid Order ID: " + orderId;
+ }
+
+ static public String contractDetails(int reqId, ContractDetails contractDetails) {
+ Contract contract = contractDetails.m_summary;
+ String msg = "reqId = " + reqId + " ===================================\n"
+ + " ---- Contract Details begin ----\n"
+ + contractMsg(contract) + contractDetailsMsg(contractDetails)
+ + " ---- Contract Details End ----\n";
+ return msg;
+ }
+
+ private static String contractDetailsMsg(ContractDetails contractDetails) {
+ String msg = "marketName = " + contractDetails.m_marketName + "\n"
+ + "tradingClass = " + contractDetails.m_tradingClass + "\n"
+ + "minTick = " + contractDetails.m_minTick + "\n"
+ + "price magnifier = " + contractDetails.m_priceMagnifier + "\n"
+ + "orderTypes = " + contractDetails.m_orderTypes + "\n"
+ + "validExchanges = " + contractDetails.m_validExchanges + "\n"
+ + "underConId = " + contractDetails.m_underConId + "\n"
+ + "longName = " + contractDetails.m_longName + "\n"
+ + "contractMonth = " + contractDetails.m_contractMonth + "\n"
+ + "industry = " + contractDetails.m_industry + "\n"
+ + "category = " + contractDetails.m_category + "\n"
+ + "subcategory = " + contractDetails.m_subcategory + "\n"
+ + "timeZoneId = " + contractDetails.m_timeZoneId + "\n"
+ + "tradingHours = " + contractDetails.m_tradingHours + "\n"
+ + "liquidHours = " + contractDetails.m_liquidHours + "\n";
+ return msg;
+ }
+
+ static public String contractMsg(Contract contract) {
+ String msg = "conid = " + contract.m_conId + "\n"
+ + "symbol = " + contract.m_symbol + "\n"
+ + "secType = " + contract.m_secType + "\n"
+ + "expiry = " + contract.m_expiry + "\n"
+ + "strike = " + contract.m_strike + "\n"
+ + "right = " + contract.m_right + "\n"
+ + "multiplier = " + contract.m_multiplier + "\n"
+ + "exchange = " + contract.m_exchange + "\n"
+ + "primaryExch = " + contract.m_primaryExch + "\n"
+ + "currency = " + contract.m_currency + "\n"
+ + "localSymbol = " + contract.m_localSymbol + "\n";
+ return msg;
+ }
+
+ static public String bondContractDetails(int reqId, ContractDetails contractDetails) {
+ Contract contract = contractDetails.m_summary;
+ String msg = "reqId = " + reqId + " ===================================\n"
+ + " ---- Bond Contract Details begin ----\n"
+ + "symbol = " + contract.m_symbol + "\n"
+ + "secType = " + contract.m_secType + "\n"
+ + "cusip = " + contractDetails.m_cusip + "\n"
+ + "coupon = " + contractDetails.m_coupon + "\n"
+ + "maturity = " + contractDetails.m_maturity + "\n"
+ + "issueDate = " + contractDetails.m_issueDate + "\n"
+ + "ratings = " + contractDetails.m_ratings + "\n"
+ + "bondType = " + contractDetails.m_bondType + "\n"
+ + "couponType = " + contractDetails.m_couponType + "\n"
+ + "convertible = " + contractDetails.m_convertible + "\n"
+ + "callable = " + contractDetails.m_callable + "\n"
+ + "putable = " + contractDetails.m_putable + "\n"
+ + "descAppend = " + contractDetails.m_descAppend + "\n"
+ + "exchange = " + contract.m_exchange + "\n"
+ + "currency = " + contract.m_currency + "\n"
+ + "marketName = " + contractDetails.m_marketName + "\n"
+ + "tradingClass = " + contractDetails.m_tradingClass + "\n"
+ + "conid = " + contract.m_conId + "\n"
+ + "minTick = " + contractDetails.m_minTick + "\n"
+ + "orderTypes = " + contractDetails.m_orderTypes + "\n"
+ + "validExchanges = " + contractDetails.m_validExchanges + "\n"
+ + "nextOptionDate = " + contractDetails.m_nextOptionDate + "\n"
+ + "nextOptionType = " + contractDetails.m_nextOptionType + "\n"
+ + "nextOptionPartial = " + contractDetails.m_nextOptionPartial + "\n"
+ + "notes = " + contractDetails.m_notes + "\n"
+ + "longName = " + contractDetails.m_longName + "\n"
+ + " ---- Bond Contract Details End ----\n";
+ return msg;
+ }
+
+ static public String contractDetailsEnd(int reqId) {
+ return "reqId = " + reqId + " =============== end ===============";
+ }
+
+ static public String execDetails( int reqId, Contract contract, Execution execution) {
+ String msg = " ---- Execution Details begin ----\n"
+ + "reqId = " + reqId + "\n"
+ + "orderId = " + execution.m_orderId + "\n"
+ + "clientId = " + execution.m_clientId + "\n"
+ + "symbol = " + contract.m_symbol + "\n"
+ + "secType = " + contract.m_secType + "\n"
+ + "expiry = " + contract.m_expiry + "\n"
+ + "strike = " + contract.m_strike + "\n"
+ + "right = " + contract.m_right + "\n"
+ + "contractExchange = " + contract.m_exchange + "\n"
+ + "currency = " + contract.m_currency + "\n"
+ + "localSymbol = " + contract.m_localSymbol + "\n"
+ + "execId = " + execution.m_execId + "\n"
+ + "time = " + execution.m_time + "\n"
+ + "acctNumber = " + execution.m_acctNumber + "\n"
+ + "executionExchange = " + execution.m_exchange + "\n"
+ + "side = " + execution.m_side + "\n"
+ + "shares = " + execution.m_shares + "\n"
+ + "price = " + execution.m_price + "\n"
+ + "permId = " + execution.m_permId + "\n"
+ + "liquidation = " + execution.m_liquidation + "\n"
+ + "cumQty = " + execution.m_cumQty + "\n"
+ + "avgPrice = " + execution.m_avgPrice + "\n"
+ + "orderRef = " + execution.m_orderRef + "\n"
+ + " ---- Execution Details end ----\n";
+ return msg;
+ }
+
+ static public String execDetailsEnd(int reqId) {
+ return "reqId = " + reqId + " =============== end ===============";
+ }
+
+ static public String updateMktDepth( int tickerId, int position, int operation, int side,
+ double price, int size) {
+ return "updateMktDepth: " + tickerId + " " + position + " " + operation + " " + side + " " + price + " " + size;
+ }
+
+ static public String updateMktDepthL2( int tickerId, int position, String marketMaker,
+ int operation, int side, double price, int size) {
+ return "updateMktDepth: " + tickerId + " " + position + " " + marketMaker + " " + operation + " " + side + " " + price + " " + size;
+ }
+
+ static public String updateNewsBulletin( int msgId, int msgType, String message, String origExchange) {
+ return "MsgId=" + msgId + " :: MsgType=" + msgType + " :: Origin=" + origExchange + " :: Message=" + message;
+ }
+
+ static public String managedAccounts( String accountsList) {
+ return "Connected : The list of managed accounts are : [" + accountsList + "]";
+ }
+
+ static public String receiveFA(int faDataType, String xml) {
+ return FINANCIAL_ADVISOR + " " + EClientSocket.faMsgTypeName(faDataType) + " " + xml;
+ }
+
+ static public String historicalData(int reqId, String date, double open, double high, double low,
+ double close, int volume, int count, double WAP, boolean hasGaps) {
+ return "id=" + reqId +
+ " date = " + date +
+ " open=" + open +
+ " high=" + high +
+ " low=" + low +
+ " close=" + close +
+ " volume=" + volume +
+ " count=" + count +
+ " WAP=" + WAP +
+ " hasGaps=" + hasGaps;
+ }
+ public static String realtimeBar(int reqId, long time, double open,
+ double high, double low, double close, long volume, double wap, int count) {
+ return "id=" + reqId +
+ " time = " + time +
+ " open=" + open +
+ " high=" + high +
+ " low=" + low +
+ " close=" + close +
+ " volume=" + volume +
+ " count=" + count +
+ " WAP=" + wap;
+ }
+
+ static public String scannerParameters(String xml) {
+ return SCANNER_PARAMETERS + "\n" + xml;
+ }
+
+ static public String scannerData(int reqId, int rank, ContractDetails contractDetails,
+ String distance, String benchmark, String projection,
+ String legsStr) {
+ Contract contract = contractDetails.m_summary;
+ return "id = " + reqId +
+ " rank=" + rank +
+ " symbol=" + contract.m_symbol +
+ " secType=" + contract.m_secType +
+ " expiry=" + contract.m_expiry +
+ " strike=" + contract.m_strike +
+ " right=" + contract.m_right +
+ " exchange=" + contract.m_exchange +
+ " currency=" + contract.m_currency +
+ " localSymbol=" + contract.m_localSymbol +
+ " marketName=" + contractDetails.m_marketName +
+ " tradingClass=" + contractDetails.m_tradingClass +
+ " distance=" + distance +
+ " benchmark=" + benchmark +
+ " projection=" + projection +
+ " legsStr=" + legsStr;
+ }
+
+ static public String scannerDataEnd(int reqId) {
+ return "id = " + reqId + " =============== end ===============";
+ }
+
+ static public String currentTime(long time) {
+ return "current time = " + time +
+ " (" + DateFormat.getDateTimeInstance().format(new Date(time * 1000)) + ")";
+ }
+
+ static public String fundamentalData(int reqId, String data) {
+ return "id = " + reqId + " len = " + data.length() + '\n' + data;
+ }
+
+ static public String deltaNeutralValidation(int reqId, UnderComp underComp) {
+ return "id = " + reqId
+ + " underComp.conId =" + underComp.m_conId
+ + " underComp.delta =" + underComp.m_delta
+ + " underComp.price =" + underComp.m_price;
+ }
+ static public String tickSnapshotEnd(int tickerId) {
+ return "id=" + tickerId + " =============== end ===============";
+ }
+
+ static public String marketDataType(int reqId, int marketDataType){
+ return "id=" + reqId + " marketDataType = " + MarketDataType.getField(marketDataType);
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/Execution.java b/ib/src/main/java/com/ib/client/Execution.java
new file mode 100644
index 00000000..9cffb7f4
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/Execution.java
@@ -0,0 +1,69 @@
+/*
+ * Execution.java
+ *
+ */
+package com.ib.client;
+
+public class Execution {
+ public int m_orderId;
+ public int m_clientId;
+ public String m_execId;
+ public String m_time;
+ public String m_acctNumber;
+ public String m_exchange;
+ public String m_side;
+ public int m_shares;
+ public double m_price;
+ public int m_permId;
+ public int m_liquidation;
+ public int m_cumQty;
+ public double m_avgPrice;
+ public String m_orderRef;
+
+ public Execution() {
+ m_orderId = 0;
+ m_clientId = 0;
+ m_shares = 0;
+ m_price = 0;
+ m_permId = 0;
+ m_liquidation = 0;
+ m_cumQty = 0;
+ m_avgPrice = 0;
+ }
+
+ public Execution( int p_orderId, int p_clientId, String p_execId, String p_time,
+ String p_acctNumber, String p_exchange, String p_side, int p_shares,
+ double p_price, int p_permId, int p_liquidation, int p_cumQty,
+ double p_avgPrice, String p_orderRef) {
+ m_orderId = p_orderId;
+ m_clientId = p_clientId;
+ m_execId = p_execId;
+ m_time = p_time;
+ m_acctNumber = p_acctNumber;
+ m_exchange = p_exchange;
+ m_side = p_side;
+ m_shares = p_shares;
+ m_price = p_price;
+ m_permId = p_permId;
+ m_liquidation = p_liquidation;
+ m_cumQty = p_cumQty;
+ m_avgPrice = p_avgPrice;
+ m_orderRef = p_orderRef;
+ }
+
+ public boolean equals(Object p_other) {
+ boolean l_bRetVal = false;
+
+ if ( p_other == null ) {
+ l_bRetVal = false;
+ }
+ else if ( this == p_other ) {
+ l_bRetVal = true;
+ }
+ else {
+ Execution l_theOther = (Execution)p_other;
+ l_bRetVal = m_execId.equals( l_theOther.m_execId);
+ }
+ return l_bRetVal;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/ExecutionFilter.java b/ib/src/main/java/com/ib/client/ExecutionFilter.java
new file mode 100644
index 00000000..3cfad9ea
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/ExecutionFilter.java
@@ -0,0 +1,52 @@
+/*
+ * ExecutionFilter.java
+ *
+ */
+package com.ib.client;
+
+public class ExecutionFilter{
+ public int m_clientId;
+ public String m_acctCode;
+ public String m_time;
+ public String m_symbol;
+ public String m_secType;
+ public String m_exchange;
+ public String m_side;
+
+ public ExecutionFilter() {
+ m_clientId = 0;
+ }
+
+ public ExecutionFilter( int p_clientId, String p_acctCode, String p_time,
+ String p_symbol, String p_secType, String p_exchange, String p_side) {
+ m_clientId = p_clientId;
+ m_acctCode = p_acctCode;
+ m_time = p_time;
+ m_symbol = p_symbol;
+ m_secType = p_secType;
+ m_exchange = p_exchange;
+ m_side = p_side;
+ }
+
+ public boolean equals(Object p_other) {
+ boolean l_bRetVal = false;
+
+ if ( p_other == null ) {
+ l_bRetVal = false;
+ }
+ else if ( this == p_other ) {
+ l_bRetVal = true;
+ }
+ else {
+ ExecutionFilter l_theOther = (ExecutionFilter)p_other;
+ l_bRetVal = (m_clientId == l_theOther.m_clientId &&
+ m_acctCode.equalsIgnoreCase( l_theOther.m_acctCode) &&
+ m_time.equalsIgnoreCase( l_theOther.m_time) &&
+ m_symbol.equalsIgnoreCase( l_theOther.m_symbol) &&
+ m_secType.equalsIgnoreCase( l_theOther.m_secType) &&
+ m_exchange.equalsIgnoreCase( l_theOther.m_exchange) &&
+ m_side.equalsIgnoreCase( l_theOther.m_side) );
+ }
+ return l_bRetVal;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/MarketDataType.java b/ib/src/main/java/com/ib/client/MarketDataType.java
new file mode 100644
index 00000000..354fc9e9
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/MarketDataType.java
@@ -0,0 +1,29 @@
+/*
+ * MarketDataType.java
+ *
+ */
+package com.ib.client;
+
+public class MarketDataType {
+ // constants - market data types
+ public static final int REALTIME = 1;
+ public static final int FROZEN = 2;
+
+ public static String getField( int marketDataType) {
+ switch( marketDataType) {
+ case REALTIME: return "Real-Time";
+ case FROZEN: return "Frozen";
+
+ default: return "Unknown";
+ }
+ }
+
+ public static String[] getFields(){
+ int totalFields = MarketDataType.class.getFields().length;
+ String [] fields = new String[totalFields];
+ for (int i = 0; i < totalFields; i++){
+ fields[i] = MarketDataType.getField(i + 1);
+ }
+ return fields;
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/Order.java b/ib/src/main/java/com/ib/client/Order.java
new file mode 100644
index 00000000..bbe28202
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/Order.java
@@ -0,0 +1,268 @@
+/*
+ * Order.java
+ *
+ */
+package com.ib.client;
+
+import java.util.Vector;
+
+public class Order {
+ final public static int CUSTOMER = 0;
+ final public static int FIRM = 1;
+ final public static char OPT_UNKNOWN='?';
+ final public static char OPT_BROKER_DEALER='b';
+ final public static char OPT_CUSTOMER ='c';
+ final public static char OPT_FIRM='f';
+ final public static char OPT_ISEMM='m';
+ final public static char OPT_FARMM='n';
+ final public static char OPT_SPECIALIST='y';
+ final public static int AUCTION_MATCH = 1;
+ final public static int AUCTION_IMPROVEMENT = 2;
+ final public static int AUCTION_TRANSPARENT = 3;
+ final public static String EMPTY_STR = "";
+
+ // main order fields
+ public int m_orderId;
+ public int m_clientId;
+ public int m_permId;
+ public String m_action;
+ public int m_totalQuantity;
+ public String m_orderType;
+ public double m_lmtPrice;
+ public double m_auxPrice;
+
+ // extended order fields
+ public String m_tif; // "Time in Force" - DAY, GTC, etc.
+ public String m_ocaGroup; // one cancels all group name
+ public int m_ocaType; // 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
+ public String m_orderRef;
+ public boolean m_transmit; // if false, order will be created but not transmited
+ public int m_parentId; // Parent order Id, to associate Auto STP or TRAIL orders with the original order.
+ public boolean m_blockOrder;
+ public boolean m_sweepToFill;
+ public int m_displaySize;
+ public int m_triggerMethod; // 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point
+ public boolean m_outsideRth;
+ public boolean m_hidden;
+ public String m_goodAfterTime; // FORMAT: 20060505 08:00:00 {time zone}
+ public String m_goodTillDate; // FORMAT: 20060505 08:00:00 {time zone}
+ public boolean m_overridePercentageConstraints;
+ public String m_rule80A; // Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
+ public boolean m_allOrNone;
+ public int m_minQty;
+ public double m_percentOffset; // REL orders only
+ public double m_trailStopPrice; // for TRAILLIMIT orders only
+
+ // Financial advisors only
+ public String m_faGroup;
+ public String m_faProfile;
+ public String m_faMethod;
+ public String m_faPercentage;
+
+ // Institutional orders only
+ public String m_openClose; // O=Open, C=Close
+ public int m_origin; // 0=Customer, 1=Firm
+ public int m_shortSaleSlot; // 1 if you hold the shares, 2 if they will be delivered from elsewhere. Only for Action="SSHORT
+ public String m_designatedLocation; // set when slot=2 only.
+ public int m_exemptCode;
+
+ // SMART routing only
+ public double m_discretionaryAmt;
+ public boolean m_eTradeOnly;
+ public boolean m_firmQuoteOnly;
+ public double m_nbboPriceCap;
+ public boolean m_optOutSmartRouting;
+
+ // BOX or VOL ORDERS ONLY
+ public int m_auctionStrategy; // 1=AUCTION_MATCH, 2=AUCTION_IMPROVEMENT, 3=AUCTION_TRANSPARENT
+
+ // BOX ORDERS ONLY
+ public double m_startingPrice;
+ public double m_stockRefPrice;
+ public double m_delta;
+
+ // pegged to stock or VOL orders
+ public double m_stockRangeLower;
+ public double m_stockRangeUpper;
+
+ // VOLATILITY ORDERS ONLY
+ public double m_volatility;
+ public int m_volatilityType; // 1=daily, 2=annual
+ public int m_continuousUpdate;
+ public int m_referencePriceType; // 1=Average, 2 = BidOrAsk
+ public String m_deltaNeutralOrderType;
+ public double m_deltaNeutralAuxPrice;
+ public int m_deltaNeutralConId;
+ public String m_deltaNeutralSettlingFirm;
+ public String m_deltaNeutralClearingAccount;
+ public String m_deltaNeutralClearingIntent;
+
+ // COMBO ORDERS ONLY
+ public double m_basisPoints; // EFP orders only
+ public int m_basisPointsType; // EFP orders only
+
+ // SCALE ORDERS ONLY
+ public int m_scaleInitLevelSize;
+ public int m_scaleSubsLevelSize;
+ public double m_scalePriceIncrement;
+
+ // HEDGE ORDERS ONLY
+ public String m_hedgeType; // 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
+ public String m_hedgeParam; // beta value for beta hedge, ratio for pair hedge
+
+ // Clearing info
+ public String m_account; // IB account
+ public String m_settlingFirm;
+ public String m_clearingAccount; // True beneficiary of the order
+ public String m_clearingIntent; // "" (Default), "IB", "Away", "PTA" (PostTrade)
+
+ // ALGO ORDERS ONLY
+ public String m_algoStrategy;
+ public Vector m_algoParams;
+
+ // What-if
+ public boolean m_whatIf;
+
+ // Not Held
+ public boolean m_notHeld;
+
+ // Smart combo routing params
+ public Vector m_smartComboRoutingParams;
+
+ public Order() {
+ m_outsideRth = false;
+ m_openClose = "O";
+ m_origin = CUSTOMER;
+ m_transmit = true;
+ m_designatedLocation = EMPTY_STR;
+ m_exemptCode = -1;
+ m_minQty = Integer.MAX_VALUE;
+ m_percentOffset = Double.MAX_VALUE;
+ m_nbboPriceCap = Double.MAX_VALUE;
+ m_optOutSmartRouting = false;
+ m_startingPrice = Double.MAX_VALUE;
+ m_stockRefPrice = Double.MAX_VALUE;
+ m_delta = Double.MAX_VALUE;
+ m_stockRangeLower = Double.MAX_VALUE;
+ m_stockRangeUpper = Double.MAX_VALUE;
+ m_volatility = Double.MAX_VALUE;
+ m_volatilityType = Integer.MAX_VALUE;
+ m_deltaNeutralOrderType = EMPTY_STR;
+ m_deltaNeutralAuxPrice = Double.MAX_VALUE;
+ m_deltaNeutralConId = 0;
+ m_deltaNeutralSettlingFirm = EMPTY_STR;
+ m_deltaNeutralClearingAccount = EMPTY_STR;
+ m_deltaNeutralClearingIntent = EMPTY_STR;
+ m_referencePriceType = Integer.MAX_VALUE;
+ m_trailStopPrice = Double.MAX_VALUE;
+ m_basisPoints = Double.MAX_VALUE;
+ m_basisPointsType = Integer.MAX_VALUE;
+ m_scaleInitLevelSize = Integer.MAX_VALUE;
+ m_scaleSubsLevelSize = Integer.MAX_VALUE;
+ m_scalePriceIncrement = Double.MAX_VALUE;
+ m_whatIf = false;
+ m_notHeld = false;
+ }
+
+ public boolean equals(Object p_other) {
+
+ if ( this == p_other )
+ return true;
+
+ if ( p_other == null )
+ return false;
+
+ Order l_theOther = (Order)p_other;
+
+ if ( m_permId == l_theOther.m_permId ) {
+ return true;
+ }
+
+ if (m_orderId != l_theOther.m_orderId ||
+ m_clientId != l_theOther.m_clientId ||
+ m_totalQuantity != l_theOther.m_totalQuantity ||
+ m_lmtPrice != l_theOther.m_lmtPrice ||
+ m_auxPrice != l_theOther.m_auxPrice ||
+ m_ocaType != l_theOther.m_ocaType ||
+ m_transmit != l_theOther.m_transmit ||
+ m_parentId != l_theOther.m_parentId ||
+ m_blockOrder != l_theOther.m_blockOrder ||
+ m_sweepToFill != l_theOther.m_sweepToFill ||
+ m_displaySize != l_theOther.m_displaySize ||
+ m_triggerMethod != l_theOther.m_triggerMethod ||
+ m_outsideRth != l_theOther.m_outsideRth ||
+ m_hidden != l_theOther.m_hidden ||
+ m_overridePercentageConstraints != l_theOther.m_overridePercentageConstraints ||
+ m_allOrNone != l_theOther.m_allOrNone ||
+ m_minQty != l_theOther.m_minQty ||
+ m_percentOffset != l_theOther.m_percentOffset ||
+ m_trailStopPrice != l_theOther.m_trailStopPrice ||
+ m_origin != l_theOther.m_origin ||
+ m_shortSaleSlot != l_theOther.m_shortSaleSlot ||
+ m_discretionaryAmt != l_theOther.m_discretionaryAmt ||
+ m_eTradeOnly != l_theOther.m_eTradeOnly ||
+ m_firmQuoteOnly != l_theOther.m_firmQuoteOnly ||
+ m_nbboPriceCap != l_theOther.m_nbboPriceCap ||
+ m_optOutSmartRouting != l_theOther.m_optOutSmartRouting ||
+ m_auctionStrategy != l_theOther.m_auctionStrategy ||
+ m_startingPrice != l_theOther.m_startingPrice ||
+ m_stockRefPrice != l_theOther.m_stockRefPrice ||
+ m_delta != l_theOther.m_delta ||
+ m_stockRangeLower != l_theOther.m_stockRangeLower ||
+ m_stockRangeUpper != l_theOther.m_stockRangeUpper ||
+ m_volatility != l_theOther.m_volatility ||
+ m_volatilityType != l_theOther.m_volatilityType ||
+ m_continuousUpdate != l_theOther.m_continuousUpdate ||
+ m_referencePriceType != l_theOther.m_referencePriceType ||
+ m_deltaNeutralAuxPrice != l_theOther.m_deltaNeutralAuxPrice ||
+ m_deltaNeutralConId != l_theOther.m_deltaNeutralConId ||
+ m_basisPoints != l_theOther.m_basisPoints ||
+ m_basisPointsType != l_theOther.m_basisPointsType ||
+ m_scaleInitLevelSize != l_theOther.m_scaleInitLevelSize ||
+ m_scaleSubsLevelSize != l_theOther.m_scaleSubsLevelSize ||
+ m_scalePriceIncrement != l_theOther.m_scalePriceIncrement ||
+ m_whatIf != l_theOther.m_whatIf ||
+ m_notHeld != l_theOther.m_notHeld ||
+ m_exemptCode != l_theOther.m_exemptCode) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_action, l_theOther.m_action) != 0 ||
+ Util.StringCompare(m_orderType, l_theOther.m_orderType) != 0 ||
+ Util.StringCompare(m_tif, l_theOther.m_tif) != 0 ||
+ Util.StringCompare(m_ocaGroup, l_theOther.m_ocaGroup) != 0 ||
+ Util.StringCompare(m_orderRef,l_theOther.m_orderRef) != 0 ||
+ Util.StringCompare(m_goodAfterTime, l_theOther.m_goodAfterTime) != 0 ||
+ Util.StringCompare(m_goodTillDate, l_theOther.m_goodTillDate) != 0 ||
+ Util.StringCompare(m_rule80A, l_theOther.m_rule80A) != 0 ||
+ Util.StringCompare(m_faGroup, l_theOther.m_faGroup) != 0 ||
+ Util.StringCompare(m_faProfile, l_theOther.m_faProfile) != 0 ||
+ Util.StringCompare(m_faMethod, l_theOther.m_faMethod) != 0 ||
+ Util.StringCompare(m_faPercentage, l_theOther.m_faPercentage) != 0 ||
+ Util.StringCompare(m_openClose, l_theOther.m_openClose) != 0 ||
+ Util.StringCompare(m_designatedLocation, l_theOther.m_designatedLocation) != 0 ||
+ Util.StringCompare(m_deltaNeutralOrderType, l_theOther.m_deltaNeutralOrderType) != 0 ||
+ Util.StringCompare(m_deltaNeutralSettlingFirm, l_theOther.m_deltaNeutralSettlingFirm) != 0 ||
+ Util.StringCompare(m_deltaNeutralClearingAccount, l_theOther.m_deltaNeutralClearingAccount) != 0 ||
+ Util.StringCompare(m_deltaNeutralClearingIntent, l_theOther.m_deltaNeutralClearingIntent) != 0 ||
+ Util.StringCompare(m_hedgeType, l_theOther.m_hedgeType) != 0 ||
+ Util.StringCompare(m_hedgeParam, l_theOther.m_hedgeParam) != 0 ||
+ Util.StringCompare(m_account, l_theOther.m_account) != 0 ||
+ Util.StringCompare(m_settlingFirm, l_theOther.m_settlingFirm) != 0 ||
+ Util.StringCompare(m_clearingAccount, l_theOther.m_clearingAccount) != 0 ||
+ Util.StringCompare(m_clearingIntent, l_theOther.m_clearingIntent) != 0 ||
+ Util.StringCompare(m_algoStrategy, l_theOther.m_algoStrategy) != 0) {
+ return false;
+ }
+
+ if (!Util.VectorEqualsUnordered(m_algoParams, l_theOther.m_algoParams)) {
+ return false;
+ }
+
+ if (!Util.VectorEqualsUnordered(m_smartComboRoutingParams, l_theOther.m_smartComboRoutingParams)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/OrderState.java b/ib/src/main/java/com/ib/client/OrderState.java
new file mode 100644
index 00000000..fde2984d
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/OrderState.java
@@ -0,0 +1,65 @@
+/*
+ * OrderState.java
+ */
+package com.ib.client;
+
+public class OrderState {
+
+ public String m_status;
+
+ public String m_initMargin;
+ public String m_maintMargin;
+ public String m_equityWithLoan;
+
+ public double m_commission;
+ public double m_minCommission;
+ public double m_maxCommission;
+ public String m_commissionCurrency;
+
+ public String m_warningText;
+
+ OrderState() {
+ this (null, null, null, null, 0.0, 0.0, 0.0, null, null);
+ }
+
+ OrderState(String status, String initMargin, String maintMargin,
+ String equityWithLoan, double commission, double minCommission,
+ double maxCommission, String commissionCurrency, String warningText) {
+
+ m_initMargin = initMargin;
+ m_maintMargin = maintMargin;
+ m_equityWithLoan = equityWithLoan;
+ m_commission = commission;
+ m_minCommission = minCommission;
+ m_maxCommission = maxCommission;
+ m_commissionCurrency = commissionCurrency;
+ m_warningText = warningText;
+ }
+
+ public boolean equals(Object other) {
+
+ if (this == other)
+ return true;
+
+ if (other == null)
+ return false;
+
+ OrderState state = (OrderState)other;
+
+ if (m_commission != state.m_commission ||
+ m_minCommission != state.m_minCommission ||
+ m_maxCommission != state.m_maxCommission) {
+ return false;
+ }
+
+ if (Util.StringCompare(m_status, state.m_status) != 0 ||
+ Util.StringCompare(m_initMargin, state.m_initMargin) != 0 ||
+ Util.StringCompare(m_maintMargin, state.m_maintMargin) != 0 ||
+ Util.StringCompare(m_equityWithLoan, state.m_equityWithLoan) != 0 ||
+ Util.StringCompare(m_commissionCurrency, state.m_commissionCurrency) != 0) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/ScannerSubscription.java b/ib/src/main/java/com/ib/client/ScannerSubscription.java
new file mode 100644
index 00000000..03631ca6
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/ScannerSubscription.java
@@ -0,0 +1,73 @@
+package com.ib.client;
+
+public class ScannerSubscription {
+ public final static int NO_ROW_NUMBER_SPECIFIED = -1;
+
+ private int m_numberOfRows = NO_ROW_NUMBER_SPECIFIED;
+ private String m_instrument;
+ private String m_locationCode;
+ private String m_scanCode;
+ private double m_abovePrice = Double.MAX_VALUE;
+ private double m_belowPrice = Double.MAX_VALUE;
+ private int m_aboveVolume = Integer.MAX_VALUE;
+ private int m_averageOptionVolumeAbove = Integer.MAX_VALUE;
+ private double m_marketCapAbove = Double.MAX_VALUE;
+ private double m_marketCapBelow = Double.MAX_VALUE;
+ private String m_moodyRatingAbove;
+ private String m_moodyRatingBelow;
+ private String m_spRatingAbove;
+ private String m_spRatingBelow;
+ private String m_maturityDateAbove;
+ private String m_maturityDateBelow;
+ private double m_couponRateAbove = Double.MAX_VALUE;
+ private double m_couponRateBelow = Double.MAX_VALUE;
+ private String m_excludeConvertible;
+ private String m_scannerSettingPairs;
+ private String m_stockTypeFilter;
+
+ // Get
+ public int numberOfRows() { return m_numberOfRows; }
+ public String instrument() { return m_instrument; }
+ public String locationCode() { return m_locationCode; }
+ public String scanCode() { return m_scanCode; }
+ public double abovePrice() { return m_abovePrice; }
+ public double belowPrice() { return m_belowPrice; }
+ public int aboveVolume() { return m_aboveVolume; }
+ public int averageOptionVolumeAbove() { return m_averageOptionVolumeAbove; }
+ public double marketCapAbove() { return m_marketCapAbove; }
+ public double marketCapBelow() { return m_marketCapBelow; }
+ public String moodyRatingAbove() { return m_moodyRatingAbove; }
+ public String moodyRatingBelow() { return m_moodyRatingBelow; }
+ public String spRatingAbove() { return m_spRatingAbove; }
+ public String spRatingBelow() { return m_spRatingBelow; }
+ public String maturityDateAbove() { return m_maturityDateAbove; }
+ public String maturityDateBelow() { return m_maturityDateBelow; }
+ public double couponRateAbove() { return m_couponRateAbove; }
+ public double couponRateBelow() { return m_couponRateBelow; }
+ public String excludeConvertible() { return m_excludeConvertible; }
+ public String scannerSettingPairs() { return m_scannerSettingPairs; }
+ public String stockTypeFilter() { return m_stockTypeFilter; }
+
+ // Set
+ public void numberOfRows(int num) { m_numberOfRows = num; }
+ public void instrument(String txt) { m_instrument = txt; }
+ public void locationCode(String txt) { m_locationCode = txt; }
+ public void scanCode(String txt) { m_scanCode = txt; }
+ public void abovePrice(double price) { m_abovePrice = price; }
+ public void belowPrice(double price) { m_belowPrice = price; }
+ public void aboveVolume(int volume) { m_aboveVolume = volume; }
+ public void averageOptionVolumeAbove(int volume) { m_averageOptionVolumeAbove = volume; }
+ public void marketCapAbove(double cap) { m_marketCapAbove = cap; }
+ public void marketCapBelow(double cap) { m_marketCapBelow = cap; }
+ public void moodyRatingAbove(String r) { m_moodyRatingAbove = r; }
+ public void moodyRatingBelow(String r) { m_moodyRatingBelow = r; }
+ public void spRatingAbove(String r) { m_spRatingAbove = r; }
+ public void spRatingBelow(String r) { m_spRatingBelow = r; }
+ public void maturityDateAbove(String d) { m_maturityDateAbove = d; }
+ public void maturityDateBelow(String d) { m_maturityDateBelow = d; }
+ public void couponRateAbove(double r) { m_couponRateAbove = r; }
+ public void couponRateBelow(double r) { m_couponRateBelow = r; }
+ public void excludeConvertible(String c) { m_excludeConvertible = c; }
+ public void scannerSettingPairs(String val) { m_scannerSettingPairs = val; }
+ public void stockTypeFilter(String val) { m_stockTypeFilter = val; }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/TagValue.java b/ib/src/main/java/com/ib/client/TagValue.java
new file mode 100644
index 00000000..0b2adeff
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/TagValue.java
@@ -0,0 +1,38 @@
+/*
+ * UnderComp.java
+ *
+ */
+
+package com.ib.client;
+
+public class TagValue {
+
+ public String m_tag;
+ public String m_value;
+
+ public TagValue() {
+ }
+
+ public TagValue(String p_tag, String p_value) {
+ m_tag = p_tag;
+ m_value = p_value;
+ }
+
+ public boolean equals(Object p_other) {
+
+ if( this == p_other)
+ return true;
+
+ if( p_other == null)
+ return false;
+
+ TagValue l_theOther = (TagValue)p_other;
+
+ if( Util.StringCompare(m_tag, l_theOther.m_tag) != 0 ||
+ Util.StringCompare(m_value, l_theOther.m_value) != 0) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/TickType.java b/ib/src/main/java/com/ib/client/TickType.java
new file mode 100644
index 00000000..d2bd6afc
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/TickType.java
@@ -0,0 +1,131 @@
+/*
+ * TickType.java
+ *
+ */
+package com.ib.client;
+
+public class TickType {
+ // constants - tick types
+ public static final int BID_SIZE = 0;
+ public static final int BID = 1;
+ public static final int ASK = 2;
+ public static final int ASK_SIZE = 3;
+ public static final int LAST = 4;
+ public static final int LAST_SIZE = 5;
+ public static final int HIGH = 6;
+ public static final int LOW = 7;
+ public static final int VOLUME = 8;
+ public static final int CLOSE = 9;
+ public static final int BID_OPTION = 10;
+ public static final int ASK_OPTION = 11;
+ public static final int LAST_OPTION = 12;
+ public static final int MODEL_OPTION = 13;
+ public static final int OPEN = 14;
+ public static final int LOW_13_WEEK = 15;
+ public static final int HIGH_13_WEEK = 16;
+ public static final int LOW_26_WEEK = 17;
+ public static final int HIGH_26_WEEK = 18;
+ public static final int LOW_52_WEEK = 19;
+ public static final int HIGH_52_WEEK = 20;
+ public static final int AVG_VOLUME = 21;
+ public static final int OPEN_INTEREST = 22;
+ public static final int OPTION_HISTORICAL_VOL = 23;
+ public static final int OPTION_IMPLIED_VOL = 24;
+ public static final int OPTION_BID_EXCH = 25;
+ public static final int OPTION_ASK_EXCH = 26;
+ public static final int OPTION_CALL_OPEN_INTEREST = 27;
+ public static final int OPTION_PUT_OPEN_INTEREST = 28;
+ public static final int OPTION_CALL_VOLUME = 29;
+ public static final int OPTION_PUT_VOLUME = 30;
+ public static final int INDEX_FUTURE_PREMIUM = 31;
+ public static final int BID_EXCH = 32;
+ public static final int ASK_EXCH = 33;
+ public static final int AUCTION_VOLUME = 34;
+ public static final int AUCTION_PRICE = 35;
+ public static final int AUCTION_IMBALANCE = 36;
+ public static final int MARK_PRICE = 37;
+ public static final int BID_EFP_COMPUTATION = 38;
+ public static final int ASK_EFP_COMPUTATION = 39;
+ public static final int LAST_EFP_COMPUTATION = 40;
+ public static final int OPEN_EFP_COMPUTATION = 41;
+ public static final int HIGH_EFP_COMPUTATION = 42;
+ public static final int LOW_EFP_COMPUTATION = 43;
+ public static final int CLOSE_EFP_COMPUTATION = 44;
+ public static final int LAST_TIMESTAMP = 45;
+ public static final int SHORTABLE = 46;
+ public static final int FUNDAMENTAL_RATIOS = 47;
+ public static final int RT_VOLUME = 48;
+ public static final int HALTED = 49;
+ public static final int BID_YIELD = 50;
+ public static final int ASK_YIELD = 51;
+ public static final int LAST_YIELD = 52;
+ public static final int CUST_OPTION_COMPUTATION = 53;
+ public static final int TRADE_COUNT = 54;
+ public static final int TRADE_RATE = 55;
+ public static final int VOLUME_RATE = 56;
+ public static final int LAST_RTH_TRADE = 57;
+
+ public static String getField( int tickType) {
+ switch( tickType) {
+ case BID_SIZE: return "bidSize";
+ case BID: return "bidPrice";
+ case ASK: return "askPrice";
+ case ASK_SIZE: return "askSize";
+ case LAST: return "lastPrice";
+ case LAST_SIZE: return "lastSize";
+ case HIGH: return "high";
+ case LOW: return "low";
+ case VOLUME: return "volume";
+ case CLOSE: return "close";
+ case BID_OPTION: return "bidOptComp";
+ case ASK_OPTION: return "askOptComp";
+ case LAST_OPTION: return "lastOptComp";
+ case MODEL_OPTION: return "modelOptComp";
+ case OPEN: return "open";
+ case LOW_13_WEEK: return "13WeekLow";
+ case HIGH_13_WEEK: return "13WeekHigh";
+ case LOW_26_WEEK: return "26WeekLow";
+ case HIGH_26_WEEK: return "26WeekHigh";
+ case LOW_52_WEEK: return "52WeekLow";
+ case HIGH_52_WEEK: return "52WeekHigh";
+ case AVG_VOLUME: return "AvgVolume";
+ case OPEN_INTEREST: return "OpenInterest";
+ case OPTION_HISTORICAL_VOL: return "OptionHistoricalVolatility";
+ case OPTION_IMPLIED_VOL: return "OptionImpliedVolatility";
+ case OPTION_BID_EXCH: return "OptionBidExchStr";
+ case OPTION_ASK_EXCH: return "OptionAskExchStr";
+ case OPTION_CALL_OPEN_INTEREST: return "OptionCallOpenInterest";
+ case OPTION_PUT_OPEN_INTEREST: return "OptionPutOpenInterest";
+ case OPTION_CALL_VOLUME: return "OptionCallVolume";
+ case OPTION_PUT_VOLUME: return "OptionPutVolume";
+ case INDEX_FUTURE_PREMIUM: return "IndexFuturePremium";
+ case BID_EXCH: return "bidExch";
+ case ASK_EXCH: return "askExch";
+ case AUCTION_VOLUME: return "auctionVolume";
+ case AUCTION_PRICE: return "auctionPrice";
+ case AUCTION_IMBALANCE: return "auctionImbalance";
+ case MARK_PRICE: return "markPrice";
+ case BID_EFP_COMPUTATION: return "bidEFP";
+ case ASK_EFP_COMPUTATION: return "askEFP";
+ case LAST_EFP_COMPUTATION: return "lastEFP";
+ case OPEN_EFP_COMPUTATION: return "openEFP";
+ case HIGH_EFP_COMPUTATION: return "highEFP";
+ case LOW_EFP_COMPUTATION: return "lowEFP";
+ case CLOSE_EFP_COMPUTATION: return "closeEFP";
+ case LAST_TIMESTAMP: return "lastTimestamp";
+ case SHORTABLE: return "shortable";
+ case FUNDAMENTAL_RATIOS: return "fundamentals";
+ case RT_VOLUME: return "RTVolume";
+ case HALTED: return "halted";
+ case BID_YIELD: return "bidYield";
+ case ASK_YIELD: return "askYield";
+ case LAST_YIELD: return "lastYield";
+ case CUST_OPTION_COMPUTATION: return "custOptComp";
+ case TRADE_COUNT: return "trades";
+ case TRADE_RATE: return "trades/min";
+ case VOLUME_RATE: return "volume/min";
+ case LAST_RTH_TRADE: return "lastRTHTrade";
+ default: return "unknown";
+ }
+ }
+}
\ No newline at end of file
diff --git a/ib/src/main/java/com/ib/client/UnderComp.java b/ib/src/main/java/com/ib/client/UnderComp.java
new file mode 100644
index 00000000..9e0b7358
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/UnderComp.java
@@ -0,0 +1,44 @@
+/*
+ * UnderComp.java
+ *
+ */
+
+package com.ib.client;
+
+public class UnderComp {
+
+ public int m_conId;
+ public double m_delta;
+ public double m_price;
+
+ public UnderComp() {
+ m_conId = 0;
+ m_delta = 0;
+ m_price = 0;
+ }
+
+ public boolean equals(Object p_other) {
+
+ if (this == p_other) {
+ return true;
+ }
+
+ if (p_other == null || !(p_other instanceof UnderComp)) {
+ return false;
+ }
+
+ UnderComp l_theOther = (UnderComp)p_other;
+
+ if (m_conId != l_theOther.m_conId) {
+ return false;
+ }
+ if (m_delta != l_theOther.m_delta) {
+ return false;
+ }
+ if (m_price != l_theOther.m_price) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/ib/src/main/java/com/ib/client/Util.java b/ib/src/main/java/com/ib/client/Util.java
new file mode 100644
index 00000000..a8d90ef5
--- /dev/null
+++ b/ib/src/main/java/com/ib/client/Util.java
@@ -0,0 +1,71 @@
+/*
+ * Util.java
+ */
+package com.ib.client;
+
+import java.util.Vector;
+
+public class Util {
+
+ public static boolean StringIsEmpty(String str) {
+ return str == null || str.length() == 0;
+ }
+
+ public static String NormalizeString(String str) {
+ return str != null ? str : "";
+ }
+
+ public static int StringCompare(String lhs, String rhs) {
+ return NormalizeString(lhs).compareTo(NormalizeString(rhs));
+ }
+
+ public static int StringCompareIgnCase(String lhs, String rhs) {
+ return NormalizeString(lhs).compareToIgnoreCase(NormalizeString(rhs));
+ }
+
+ public static boolean VectorEqualsUnordered(Vector lhs, Vector rhs) {
+
+ if (lhs == rhs)
+ return true;
+
+ int lhsCount = lhs == null ? 0 : lhs.size();
+ int rhsCount = rhs == null ? 0 : rhs.size();
+
+ if (lhsCount != rhsCount)
+ return false;
+
+ if (lhsCount == 0)
+ return true;
+
+ boolean[] matchedRhsElems = new boolean[rhsCount];
+
+ for (int lhsIdx = 0; lhsIdx < lhsCount; ++lhsIdx) {
+ Object lhsElem = lhs.get(lhsIdx);
+ int rhsIdx = 0;
+ for (; rhsIdx < rhsCount; ++rhsIdx) {
+ if (matchedRhsElems[rhsIdx]) {
+ continue;
+ }
+ if (lhsElem.equals(rhs.get(rhsIdx))) {
+ matchedRhsElems[rhsIdx] = true;
+ break;
+ }
+ }
+ if (rhsIdx >= rhsCount) {
+ // no matching elem found
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static String IntMaxString(int value) {
+ return (value == Integer.MAX_VALUE) ? "" : "" + value;
+ }
+
+ public static String DoubleMaxString(double value) {
+ return (value == Double.MAX_VALUE) ? "" : "" + value;
+ }
+
+}
diff --git a/ib/src/main/java/samples/base/ComboContract.java b/ib/src/main/java/samples/base/ComboContract.java
new file mode 100644
index 00000000..a46afe17
--- /dev/null
+++ b/ib/src/main/java/samples/base/ComboContract.java
@@ -0,0 +1,32 @@
+/*
+ * ComboContract.java
+ */
+package samples.base;
+
+import com.ib.client.Contract;
+
+public class ComboContract extends Contract {
+
+ public ComboContract(String symbol) {
+ m_symbol = symbol;
+ m_secType = "BAG";
+ m_currency = "USD";
+ m_exchange = "SMART";
+ }
+
+ public ComboContract(String symbol, String currency) {
+ m_symbol = symbol;
+ m_secType = "BAG";
+ m_currency = currency;
+ m_exchange = "SMART";
+ }
+
+ public ComboContract(String symbol, String currency, String exchange) {
+ m_symbol = symbol;
+ m_secType = "BAG";
+ m_currency = currency;
+ m_exchange = exchange;
+ }
+}
+
+
diff --git a/ib/src/main/java/samples/base/FutContract.java b/ib/src/main/java/samples/base/FutContract.java
new file mode 100644
index 00000000..cec333a5
--- /dev/null
+++ b/ib/src/main/java/samples/base/FutContract.java
@@ -0,0 +1,25 @@
+/*
+ * FutContract.java
+ */
+package samples.base;
+
+import com.ib.client.Contract;
+
+public class FutContract extends Contract {
+
+ public FutContract(String symbol, String expiry) {
+ m_symbol = symbol;
+ m_secType = "FUT";
+ m_exchange = "ONE";
+ m_currency = "USD";
+ m_expiry = expiry;
+ }
+
+ public FutContract(String symbol, String expiry, String currency) {
+ m_symbol = symbol;
+ m_secType = "FUT";
+ m_currency = currency;
+ m_expiry = expiry;
+ }
+}
+
diff --git a/ib/src/main/java/samples/base/OptContract.java b/ib/src/main/java/samples/base/OptContract.java
new file mode 100644
index 00000000..dbc11174
--- /dev/null
+++ b/ib/src/main/java/samples/base/OptContract.java
@@ -0,0 +1,33 @@
+/*
+ * OptContract.java
+ */
+package samples.base;
+
+import com.ib.client.Contract;
+
+public class OptContract extends Contract {
+
+ public OptContract(String symbol, String expiry, double strike,
+ String right) {
+ m_symbol = symbol;
+ m_secType = "OPT";
+ m_exchange = "SMART";
+ m_currency = "USD";
+ m_expiry = expiry;
+ m_strike = strike;
+ m_right = right;
+ }
+
+ public OptContract(String symbol, String exchange,
+ String expiry, double strike, String right) {
+ m_symbol = symbol;
+ m_secType = "OPT";
+ m_exchange = exchange;
+ m_currency = "USD";
+ m_expiry = expiry;
+ m_strike = strike;
+ m_right = right;
+ }
+
+}
+
diff --git a/ib/src/main/java/samples/base/SimpleWrapper.java b/ib/src/main/java/samples/base/SimpleWrapper.java
new file mode 100644
index 00000000..957ce234
--- /dev/null
+++ b/ib/src/main/java/samples/base/SimpleWrapper.java
@@ -0,0 +1,284 @@
+package samples.base;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.ib.client.Contract;
+import com.ib.client.ContractDetails;
+import com.ib.client.EClientSocket;
+import com.ib.client.EWrapper;
+import com.ib.client.Execution;
+import com.ib.client.Order;
+import com.ib.client.OrderState;
+import com.ib.client.UnderComp;
+
+public class SimpleWrapper implements EWrapper {
+
+ private static final int MAX_MESSAGES = 1000000;
+
+ // main client
+ private EClientSocket m_client = new EClientSocket(this);
+
+ // utils
+ private long ts;
+ private PrintStream m_output;
+ private int m_outputCounter = 0;
+ private int m_messageCounter;
+ private final SimpleDateFormat m_df = new SimpleDateFormat("HH:mm:ss");
+
+ protected EClientSocket client() { return m_client; }
+
+ protected SimpleWrapper() {
+ /* */
+ initNextOutput();
+ attachDisconnectHook(this);
+ }
+
+ public void connect() {
+ connect(1);
+ }
+
+ public void connect(int clientId) {
+ String host = System.getProperty("jts.host");
+ host = host != null ? host : "";
+ m_client.eConnect(host, 7496, clientId);
+ }
+
+ public void disconnect() {
+ m_client.eDisconnect();
+ }
+
+ /* ***************************************************************
+ * AnyWrapper
+ *****************************************************************/
+
+ public void error(Exception e) {
+ e.printStackTrace(m_output);
+ }
+
+ public void error(String str) {
+ m_output.println(str);
+ }
+
+ public void error(int id, int errorCode, String errorMsg) {
+ logIn("Error id=" + id + " code=" + errorCode + " msg=" + errorMsg);
+ }
+
+ public void connectionClosed() {
+ m_output.println("--------------------- CLOSED ---------------------");
+ }
+
+ /* ***************************************************************
+ * EWrapper
+ *****************************************************************/
+
+ public void tickPrice(int tickerId, int field, double price, int canAutoExecute) {
+ logIn("tickPrice");
+ }
+
+ public void tickSize(int tickerId, int field, int size) {
+ logIn("tickSize");
+ }
+
+ public void tickGeneric(int tickerId, int tickType, double value) {
+ logIn("tickGeneric");
+ }
+
+ public void tickString(int tickerId, int tickType, String value) {
+ logIn("tickString");
+ }
+
+ public void tickSnapshotEnd(int tickerId) {
+ logIn("tickSnapshotEnd");
+ }
+
+ public void tickOptionComputation(int tickerId, int field, double impliedVol,
+ double delta, double optPrice, double pvDividend,
+ double gamma, double vega, double theta, double undPrice) {
+ logIn("tickOptionComputation");
+ }
+
+ public void tickEFP(int tickerId, int tickType, double basisPoints,
+ String formattedBasisPoints, double impliedFuture, int holdDays,
+ String futureExpiry, double dividendImpact, double dividendsToExpiry) {
+ logIn("tickEFP");
+ }
+
+ public void orderStatus(int orderId, String status, int filled, int remaining,
+ double avgFillPrice, int permId, int parentId, double lastFillPrice,
+ int clientId, String whyHeld) {
+ logIn("orderStatus");
+ }
+
+ public void openOrder(int orderId, Contract contract, Order order, OrderState orderState) {
+ logIn("openOrder");
+ }
+
+ public void openOrderEnd() {
+ logIn("openOrderEnd");
+ }
+
+ public void updateAccountValue(String key, String value, String currency, String accountName) {
+ logIn("updateAccountValue");
+ }
+
+ public void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue,
+ double averageCost, double unrealizedPNL, double realizedPNL, String accountName) {
+ logIn("updatePortfolio");
+ }
+
+ public void updateAccountTime(String timeStamp) {
+ logIn("updateAccountTime");
+ }
+
+ public void accountDownloadEnd(String accountName) {
+ logIn("accountDownloadEnd");
+ }
+
+ public void nextValidId(int orderId) {
+ logIn("nextValidId");
+ }
+
+ public void contractDetails(int reqId, ContractDetails contractDetails) {
+ logIn("contractDetails");
+ }
+
+ public void contractDetailsEnd(int reqId) {
+ logIn("contractDetailsEnd");
+ }
+
+ public void bondContractDetails(int reqId, ContractDetails contractDetails) {
+ logIn("bondContractDetails");
+ }
+
+ public void execDetails(int reqId, Contract contract, Execution execution) {
+ logIn("execDetails");
+ }
+
+ public void execDetailsEnd(int reqId) {
+ logIn("execDetailsEnd");
+ }
+
+ public void updateMktDepth(int tickerId, int position, int operation, int side, double price, int size) {
+ logIn("updateMktDepth");
+ }
+
+ public void updateMktDepthL2(int tickerId, int position, String marketMaker, int operation,
+ int side, double price, int size) {
+ logIn("updateMktDepthL2");
+ }
+
+ public void updateNewsBulletin(int msgId, int msgType, String message, String origExchange) {
+ logIn("updateNewsBulletin");
+ }
+
+ public void managedAccounts(String accountsList) {
+ logIn("managedAccounts");
+ }
+
+ public void receiveFA(int faDataType, String xml) {
+ logIn("receiveFA");
+ }
+
+ public void historicalData(int reqId, String date, double open, double high, double low,
+ double close, int volume, int count, double WAP, boolean hasGaps) {
+ logIn("historicalData");
+ }
+
+ public void scannerParameters(String xml) {
+ logIn("scannerParameters");
+ }
+
+ public void scannerData(int reqId, int rank, ContractDetails contractDetails, String distance,
+ String benchmark, String projection, String legsStr) {
+ logIn("scannerData");
+ }
+
+ public void scannerDataEnd(int reqId) {
+ logIn("scannerDataEnd");
+ }
+
+ public void realtimeBar(int reqId, long time, double open, double high, double low, double close,
+ long volume, double wap, int count) {
+ logIn("realtimeBar");
+ }
+
+ public void currentTime(long millis) {
+ logIn("currentTime");
+ }
+
+ public void fundamentalData(int reqId, String data) {
+ logIn("fundamentalData");
+ }
+
+ public void deltaNeutralValidation(int reqId, UnderComp underComp) {
+ logIn("deltaNeutralValidation");
+ }
+
+ public void marketDataType(int reqId, int marketDataType) {
+ logIn("marketDataType");
+ }
+
+ /* ***************************************************************
+ * Helpers
+ *****************************************************************/
+
+ protected void logIn(String method) {
+ m_messageCounter++;
+ if (m_messageCounter == MAX_MESSAGES) {
+ m_output.close();
+ initNextOutput();
+ m_messageCounter = 0;
+ }
+ m_output.println("[W] > " + method);
+ }
+
+ protected void consoleMsg(String str) {
+ System.out.println(Thread.currentThread().getName() + " (" + tsStr() + "): " + str);
+ }
+
+ protected String tsStr() {
+ synchronized (m_df) {
+ return m_df.format(new Date());
+ }
+ }
+
+ protected void sleepSec(int sec) {
+ sleep(sec * 1000);
+ }
+
+ protected void sleep(int msec) {
+ try {
+ Thread.sleep(msec);
+ } catch (Exception e) { /* noop */ }
+ }
+
+ protected void swStart() {
+ ts = System.currentTimeMillis();
+ }
+
+ protected void swStop() {
+ long dt = System.currentTimeMillis() - ts;
+ m_output.println("[API]" + " Time=" + dt);
+ }
+
+ private void initNextOutput() {
+ try {
+ m_output = new PrintStream(new File("sysout_" + (++m_outputCounter) + ".log"));
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ private static void attachDisconnectHook(final SimpleWrapper ut) {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ ut.disconnect();
+ }
+ });
+ }
+}
+
diff --git a/ib/src/main/java/samples/base/StkContract.java b/ib/src/main/java/samples/base/StkContract.java
new file mode 100644
index 00000000..bf9ef783
--- /dev/null
+++ b/ib/src/main/java/samples/base/StkContract.java
@@ -0,0 +1,17 @@
+/*
+ * StkContract.java
+ */
+package samples.base;
+
+import com.ib.client.Contract;
+
+public class StkContract extends Contract {
+
+ public StkContract(String symbol) {
+ m_symbol = symbol;
+ m_secType = "STK";
+ m_exchange = "SMART";
+ m_currency = "USD";
+ }
+}
+
diff --git a/ib/src/main/java/samples/rfq/RfqOrder.java b/ib/src/main/java/samples/rfq/RfqOrder.java
new file mode 100644
index 00000000..22b92fcb
--- /dev/null
+++ b/ib/src/main/java/samples/rfq/RfqOrder.java
@@ -0,0 +1,26 @@
+/*
+ * RfqOrder.java
+ */
+package samples.rfq;
+
+import com.ib.client.Order;
+
+public class RfqOrder extends Order {
+
+ public RfqOrder(int clientId, int id, int size) {
+
+ m_clientId = clientId;
+ m_orderId = id;
+ m_permId = id;
+ m_totalQuantity = size;
+ m_orderType = "QUOTE";
+
+ /*
+ * Note: this will be overridden by the backend
+ * because it could not keep such order
+ * (and it does not make too much sence)
+ */
+ m_transmit = false;
+ }
+}
+
diff --git a/ib/src/main/java/samples/rfq/SampleRfq.java b/ib/src/main/java/samples/rfq/SampleRfq.java
new file mode 100644
index 00000000..23b91d3a
--- /dev/null
+++ b/ib/src/main/java/samples/rfq/SampleRfq.java
@@ -0,0 +1,521 @@
+package samples.rfq;
+
+import samples.base.ComboContract;
+import samples.base.FutContract;
+import samples.base.OptContract;
+import samples.base.StkContract;
+import samples.base.SimpleWrapper;
+
+import com.ib.client.ComboLeg;
+import com.ib.client.Contract;
+import com.ib.client.ContractDetails;
+import com.ib.client.TickType;
+import com.ib.client.UnderComp;
+
+import java.util.Vector;
+
+
+public class SampleRfq extends SimpleWrapper {
+
+ private enum Status { None, SecDef, SecDefFMF, Rfq, Ticks, Done, Error };
+
+ private static final int MaskBidPrice = 1;
+ private static final int MaskAskPrice = 2;
+ private static final int MaskBidSize = 4;
+ private static final int MaskAskSize = 8;
+
+ private static final int MaskRecvAll = MaskBidPrice | MaskBidSize |
+ MaskAskPrice | MaskAskSize ;
+
+ private Object m_mutex = new Object();
+ private Status m_status = Status.None;
+
+ private int m_clientId;
+ private int m_rfqId;
+ private int m_mode;
+
+ private Contract m_contract = null;
+
+ private int m_underConId = 0;
+
+ private boolean m_needFrontMonthFuture = false;
+ private Contract m_frontMonthFuture = null;
+ private int m_frontMonthFutureExpiry = 0;
+ private int m_frontMonthFutureMult = 0;
+
+ private double m_bidPrice = 0;
+ private double m_askPrice = 0;
+
+ private int m_bidSize = 0;
+ private int m_askSize = 0;
+
+ private int m_receivedTicks = 0;
+
+ public SampleRfq(int clientId, int rfqId, int mode) {
+ m_clientId = clientId;
+ m_rfqId = rfqId;
+ m_mode = mode;
+ }
+
+ public void testOrder() throws Exception {
+
+ int clientId = 2;
+ connect(clientId);
+
+ if (client() != null && client().isConnected()) {
+
+ try {
+
+ synchronized (m_mutex) {
+
+ if (client().serverVersion() < 42) {
+ error ("Sample will not work with TWS older that 877");
+ }
+
+ while (m_status != Status.Done &&
+ m_status != Status.Error) {
+
+ if (m_status == Status.None) {
+ obtainContract();
+ if (m_status != Status.Error &&
+ m_status != Status.SecDef) {
+ submitRfq();
+ }
+ }
+ m_mutex.wait();
+ }
+ }
+ }
+
+ finally {
+ disconnect();
+ }
+
+ if (m_status == Status.Done) {
+
+ String msg = "Done, bid=" + m_bidSize + "@" + m_bidPrice +
+ " ask=" + m_askSize + "@" + m_askPrice;
+
+ UnderComp underComp = m_contract.m_underComp;
+ if (underComp != null) {
+ msg += " DN: conId=" + underComp.m_conId
+ + " price=" + underComp.m_price
+ + " delta=" + underComp.m_delta;
+ }
+
+ consoleMsg(msg);
+ }
+ }
+ }
+
+ private void obtainContract() {
+
+ switch (m_mode) {
+ case 0:
+ {
+ m_contract = new StkContract("IBM");
+ m_contract.m_currency = "EUR";
+ break;
+ }
+ case 1:
+ {
+ m_contract = new FutContract("IBM", "200809");
+ break;
+ }
+ case 2:
+ {
+ m_contract = new OptContract("IBM", "200809", 120, "CALL");
+ break;
+ }
+ case 3:
+ {
+ m_contract = new OptContract("Z", "LIFFE", "200809", 54.75, "CALL");
+ m_contract.m_currency = "GBP";
+ break;
+ }
+ case 4:
+ {
+ m_contract = new ComboContract("Z", "GBP", "LIFFE");
+ m_contract.m_comboLegs = new Vector(2);
+ m_contract.m_comboLegs.setSize(2);
+
+ {
+ Contract l1 = new OptContract(
+ "Z", "LIFFE", "200809", 54.75, "CALL");
+ l1.m_currency = "GBP";
+ submitSecDef(1, l1);
+ }
+
+ {
+ Contract l2 = new OptContract(
+ "Z", "LIFFE", "200810", 55.00, "CALL");
+ l2.m_currency = "GBP";
+ submitSecDef(2, l2);
+ }
+
+ m_status = Status.SecDef;
+ break;
+ }
+ case 5:
+ {
+ m_contract = new ComboContract("IBM");
+ m_contract.m_comboLegs = new Vector(1);
+ m_contract.m_comboLegs.setSize(1);
+
+ m_contract.m_underComp = new UnderComp();
+ //m_contract.m_underComp.m_delta = 0.8;
+ //m_contract.m_underComp.m_price = 120;
+
+ {
+ Contract l1 = new OptContract("IBM", "200809", 120, "CALL");
+ submitSecDef(1, l1);
+ }
+
+ m_status = Status.SecDef;
+ break;
+ }
+ case 6:
+ {
+ m_contract = new ComboContract("RUT");
+ m_contract.m_comboLegs = new Vector(1);
+ m_contract.m_comboLegs.setSize(1);
+
+ m_contract.m_underComp = new UnderComp();
+ m_needFrontMonthFuture = true;
+
+ {
+ Contract l1 = new OptContract("RUT", "200809", 740, "CALL");
+ submitSecDef(1, l1);
+ }
+
+ m_status = Status.SecDef;
+ break;
+ }
+ case 7:
+ {
+ m_contract = new ComboContract("Z", "GBP", "LIFFE");
+ m_contract.m_comboLegs = new Vector(1);
+ m_contract.m_comboLegs.setSize(1);
+
+ m_contract.m_underComp = new UnderComp();
+
+ m_needFrontMonthFuture = true;
+
+ {
+ Contract l1 = new OptContract(
+ "Z", "LIFFE", "200808", 55.00, "CALL");
+ l1.m_currency = "GBP";
+ submitSecDef(1, l1);
+ }
+
+ m_status = Status.SecDef;
+ break;
+ }
+ }
+ }
+
+ private void submitSecDef(int reqId, Contract contract) {
+
+ consoleMsg("REQ: secDef " + reqId);
+
+ client().reqContractDetails(reqId, contract);
+ }
+
+ private void submitRfq() {
+
+ consoleMsg("REQ: rfq " + m_rfqId);
+
+ m_status = m_contract.m_underComp != null ? Status.Rfq : Status.Ticks;
+
+ client().placeOrder(m_rfqId, m_contract,
+ new RfqOrder(m_clientId, m_rfqId, 1));
+ }
+
+ private void checkReceivedAllTicks() {
+
+ if ((m_receivedTicks & MaskRecvAll) == MaskRecvAll) {
+ m_status = Status.Done;
+ m_mutex.notify();
+ }
+ }
+
+ public void contractDetails(int reqId, ContractDetails contractDetails) {
+
+ consoleMsg("contractDetails: " + reqId);
+
+ try {
+
+ synchronized (m_mutex) {
+
+ if (m_status == Status.SecDef) {
+ /*
+ * Note: we are requesting SecDefs only if we need Combo's
+ */
+
+ int legId = reqId - 1;
+
+ ComboLeg comboLeg = new ComboLeg(
+ contractDetails.m_summary.m_conId, /* ratio */ 1,
+ (reqId == 1 ? "BUY" : "SELL"), m_contract.m_exchange, 0);
+
+ m_contract.m_comboLegs.set(legId, comboLeg);
+
+ /*
+ * Do we have all legs?
+ */
+ for (int i = 0; i < m_contract.m_comboLegs.size(); ++i) {
+ if (i == legId)
+ continue;
+ if (m_contract.m_comboLegs.get(i) == null)
+ return;
+ }
+
+ if (m_contract.m_underComp != null) {
+ /*
+ * Store underConId if needed
+ */
+ if (m_underConId == 0) {
+ m_underConId = contractDetails.m_underConId;
+ }
+
+ /*
+ * Do we need to request front month future for hedging?
+ */
+
+ if (m_needFrontMonthFuture) {
+ m_status = Status.SecDefFMF;
+
+ Contract futContract = new FutContract(
+ contractDetails.m_summary.m_symbol,
+ /* all expirations */ "",
+ contractDetails.m_summary.m_currency);
+
+ submitSecDef(0, futContract);
+ return;
+ }
+
+ consoleMsg("using " + m_underConId + " for hedging");
+ m_contract.m_underComp.m_conId = m_underConId;
+ }
+
+ /*
+ * And finally submit RFQ
+ */
+ submitRfq();
+ }
+ else if (m_status == Status.SecDefFMF) {
+
+ /*
+ * Ignore unknown reqId's
+ */
+
+ if (reqId != 0) {
+ return;
+ }
+
+ /*
+ * Ignore secDefs with different underConId
+ */
+ if (contractDetails.m_underConId != m_underConId) {
+ return;
+ }
+
+ Contract contract = contractDetails.m_summary;
+
+ /*
+ * Check if we have a better match
+ */
+
+ int contractExpiry = Integer.parseInt(contract.m_expiry);
+ int contractMult = Integer.parseInt(contract.m_multiplier);
+
+ if (m_frontMonthFuture != null) {
+ if (m_frontMonthFutureExpiry <= contractExpiry) {
+ return;
+ }
+ if (m_frontMonthFutureExpiry == contractExpiry &&
+ m_frontMonthFutureMult <= contractMult) {
+ return;
+ }
+ }
+
+ m_frontMonthFuture = contract;
+ m_frontMonthFutureExpiry = contractExpiry;
+ m_frontMonthFutureMult = contractMult;
+ }
+ }
+ }
+ catch (Exception e) {
+ // will update status and notify main thread
+ error (e.toString());
+ }
+ }
+
+ public void contractDetailsEnd(int reqId) {
+
+ consoleMsg("contractDetailsEnd: " + reqId);
+
+ try {
+
+ synchronized (m_mutex) {
+
+ if (m_status == Status.SecDefFMF) {
+
+ if (reqId != 0) {
+ // ignore details end for leg requests
+ return;
+ }
+
+ if (m_frontMonthFuture == null) {
+ error ("Could not find front month future for hedging");
+ return;
+ }
+
+ consoleMsg("using " + m_frontMonthFuture.m_conId +
+ " for hedging");
+
+ m_contract.m_underComp.m_conId =
+ m_frontMonthFuture.m_conId;
+
+ /*
+ * And finally submit RFQ
+ */
+ submitRfq();
+ }
+ }
+ }
+ catch (Exception e) {
+ // will update status and notify main thread
+ error (e.toString());
+ }
+ }
+
+ public void deltaNeutralValidation(int reqId, UnderComp underComp) {
+
+ consoleMsg("deltaNeutralValidation:" + reqId);
+
+ synchronized (m_mutex) {
+
+ if (m_status == Status.Rfq) {
+
+ if (reqId != m_rfqId) {
+ // unexpected dn validation
+ return;
+ }
+
+ // update underComp
+ m_contract.m_underComp = underComp;
+ m_status = Status.Ticks;
+ }
+ }
+ }
+ public void orderStatus(int orderId, String status, int filled,
+ int remaining, double avgFillPrice, int permId, int parentId,
+ double lastFillPrice, int clientId, String whyHeld) {
+
+ consoleMsg("orderStatus:" + orderId + " status=" + status);
+
+ synchronized (m_mutex) {
+ if (status.equals("Cancelled")) {
+ m_status = Status.Error;
+ m_mutex.notify();
+ }
+ }
+ }
+
+ public void tickPrice(int tickerId, int field, double price,
+ int canAutoExecute) {
+
+ consoleMsg("tickPrice:" + tickerId + " field:" + field +
+ " (" + TickType.getField(field) + ") value:" + price);
+
+ synchronized (m_mutex) {
+
+ if (m_status == Status.Ticks) {
+
+ switch (field) {
+ case TickType.BID:
+ {
+ m_bidPrice = price;
+ m_receivedTicks |= MaskBidPrice;
+ break;
+ }
+ case TickType.ASK:
+ {
+ m_askPrice = price;
+ m_receivedTicks |= MaskAskPrice;
+ break;
+ }
+ }
+ checkReceivedAllTicks();
+ }
+ }
+ }
+
+ public void tickSize(int tickerId, int field, int size) {
+
+ consoleMsg("tickSize:" + tickerId + " field:" + field +
+ " (" + TickType.getField(field) + ") value:" + size);
+
+ synchronized (m_mutex) {
+
+ if (m_status == Status.Ticks) {
+
+ switch (field) {
+ case TickType.BID_SIZE:
+ {
+ m_bidSize = size;
+ if (!(m_bidSize == 0 && m_bidPrice == -1)) {
+ m_receivedTicks |= MaskBidSize;
+ }
+ break;
+ }
+ case TickType.ASK_SIZE:
+ {
+ m_askSize = size;
+ if (!(m_askSize == 0 && m_askPrice == -1)) {
+ m_receivedTicks |= MaskAskSize;
+ }
+ break;
+ }
+ }
+ checkReceivedAllTicks();
+ }
+ }
+ }
+
+ public void error(String str) {
+ consoleMsg("Error=" + str);
+ synchronized (m_mutex) {
+ m_status = Status.Error;
+ m_mutex.notify();
+ }
+ }
+
+ public void error(int id, int errorCode, String errorMsg) {
+ consoleMsg("Error id=" + id + " code=" + errorCode + " msg=" + errorMsg);
+ if (errorCode >= 2100 && errorCode < 2200) {
+ return;
+ }
+ synchronized (m_mutex) {
+ m_status = Status.Error;
+ m_mutex.notify();
+ }
+ }
+
+ /* ***************************************************************
+ * Main Method
+ *****************************************************************/
+
+ public static void main(String[] args) {
+ try {
+ int rfqId = (int) (System.currentTimeMillis() / 1000);
+ int mode = (args.length > 0) ? Integer.parseInt(args[0]) : 0;
+ SampleRfq ut = new SampleRfq(/* clientId */ 2, rfqId, mode);
+ ut.testOrder();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+