我正在使用Java API,并且我已经使用按钮创建了一个简单的Swing GUI。当我按下按钮时,它会执行:
anInstance.connection.reqRealTimeBars(id, contract, 5,"TRADES",false);
// note that connection = new EClientSocket(Wrapper) which is assigned in constructor`
导致我的覆盖Wrapper函数realtimeBar执行。
我使用Joda Time和getSecondOfMinute
将包装函数中的Time转换为它的第二个。如果是55秒,我想进行交易。 (即我希望我的程序每分钟在55秒标记处进行交易)。
然而,每当我进行交易时,都会断开与API的连接。
我认为这可能与同步有关,也许还有一些死锁?无论如何,错误关闭了我与API的连接,这不是我想要的,因为我的程序的目的是不断交易。
有谁知道为什么会出现这个问题?更重要的是,我该如何解决这个问题呢?
示例代码
someWrapper.java覆盖EWrapper:
public class someWrapper implements EWrapper {
private IBProgram anInstance;
public void setReference(IBProgram anInstance){
this.anInstance = anInstance
}
// overide and implement various EWrapper methods.
// The Ewrapper method below is a sample of placing an Order
// causing problems in an EWrapper method
public void updatePortfolio(Contract contract, int position, double marketPrice, double marketValue,
double averageCost, double unrealizedPNL, double realizedPNL, String accountName){
Order myFakeOrder = new Order();
Contract myFakeContract = new Contract();
myFakeContract.m_symbol = "GOOG";
myFakeContract.m_exchange = "SMART";
myFakeContract.m_secType = "STK";
myFakeContract.m_currency = "USD";
myFakeOrder.m_action = "BUY";
myFakeOrder.m_totalQuantity = 1;
myFakeOrder.m_orderType = "LMT";
myFakeOrder.m_lmtPrice = 1;
myFakeOrder.m_tif = "DAY";
anInstance.connection.placeOrder(2124124,myFakeContract,myFakeOrder);
}
}
IBProgram.java
public class IBProgram {
someWrapper wrapper;
public EClientSocket connection;
public IBProgram() {
this.wrapper = new someWrapper();
this.connection = new EClientSocket(wrapper);
}
}
GUI
public class GUI extends javax.swing.JFrame{
private IBProgram IBProgramInstance;
public GUI(){
initComponents();
}
private void initComponents() {
myButton = new javax.swing.JButton();
myButton.setText("Start Trading");
myButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
myButtonActionPerformed(evt);
}
});
}
public void setReference(IBProgram Instance){
this.IBProgramInstance = Instance;
}
private void myButtonActionPerformed (java.awt.event.ActionEvent evt) {
IBProgramInstance.connection.reqAccountUpdates(true,"myaccountid");
}
public static void main(String args[]){
IBProgram IBPInstance = new IBProgram();
IBProgramInstance.wrapper.setReference(IBPInstance);
IBProgram.connection.eConnect("127.0.0.1",7496,12);
GUI guiInstance = new GUI();
guiInstance.setReference(IBPInstance);
guiInstance.setVisible(true);
}
添加错误消息
Exception in thread "EReader" java.lang.Error: Interrupted attempt to aquire write lock
at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1349)
at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:659)
at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718)
at IBconnect.IBTradeGui.setConnectionText(IBTradeGui.java:698)
at IBconnect.someWrapper.connectionClosed(someWrapper.java:63)
at com.ib.client.EClientSocket.close(EClientSocket.java:2004)
at com.ib.client.EReader.run(EReader.java:78)
答案 0 :(得分:0)
由于大多数Swing对象都不是线程安全的,因此您必须使用GUI
方法中的此代码创建main()
实例:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI guiInstance = new GUI();
}
});
有关Swing线程安全和事件调度线程(AKA EDT)的详细信息,请参阅this link(和以下页面)。
与具体问题无关,更注意使用类的大写名称和类实例的camelCase名称。避免在类中使用公共属性,因为它们违反了封装原则。捕获实现EWrapper
的类中的所有异常,否则IB将关闭连接。更重要的是,当您在updatePortfolio()
方法中插入订单或者覆盖EWrapper
接口方法的任何其他方法时,请大家注意,因为它们是由IB套接字触发的,您永远不知道它们何时是调用