package samples.dnhedge;
import samples.base.OptContract;
import samples.base.StkContract;
import samples.base.SimpleWrapper;
import com.ib.client.Contract;
import com.ib.client.ContractDetails;
public class SampleDNHedge extends SimpleWrapper {
private enum Status { None, SecDef, Order, Done, Error };
private static final int ParentAcked = 1;
private static final int ChildAcked = 2;
private static final int AllAcked = ParentAcked | ChildAcked;
private Object m_mutex = new Object();
private Status m_status = Status.None;
private int m_clientId;
private int m_orderId;
private String m_account;
private String m_settlingFirm;
private String m_designatedLocation;
private Contract m_contract = null;
private int m_underConId = 0;
private int m_receivedAcks = 0;
public SampleDNHedge(int clientId, int orderId, String account,
String settlingFirm, String designatedLocation) {
m_clientId = clientId;
m_orderId = orderId;
m_account = account;
m_settlingFirm = settlingFirm;
m_designatedLocation = designatedLocation;
}
public void testOrder() throws Exception {
connect(m_clientId);
if (client() != null && client().isConnected()) {
try {
synchronized (m_mutex) {
if (client().serverVersion() < 66) {
error ("Sample will not work with TWS older that 932");
}
while (m_status != Status.Done &&
m_status != Status.Error) {
if (m_status == Status.None) {
obtainContract();
if (m_status != Status.Error &&
m_status != Status.SecDef) {
submitOrder();
}
}
m_mutex.wait();
}
}
}
finally {
disconnect();
}
if (m_status == Status.Done) {
consoleMsg("Done");
}
}
}
private void obtainContract() {
m_contract = new OptContract("IBM", "20121019", 200, "CALL");
m_contract.m_currency = "USD";
m_contract.m_multiplier = "100";
Contract underlying = new StkContract("IBM");
submitSecDef(1, underlying);
m_status = Status.SecDef;
}
private void submitSecDef(int reqId, Contract contract) {
consoleMsg("REQ: secDef " + reqId);
client().reqContractDetails(reqId, contract);
}
private void submitOrder() {
consoleMsg("REQ: order " + m_orderId);
m_status = Status.Order;
client().placeOrder(m_orderId, m_contract,
new DNHedgeOrder(m_clientId, m_orderId, 1, m_account,
m_settlingFirm, m_underConId, m_designatedLocation));
}
private void checkReceivedAllAcks() {
if ((m_receivedAcks & AllAcked) == AllAcked) {
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) {
/*
* Store underConId if needed
*/
if (m_underConId == 0) {
m_underConId = contractDetails.m_summary.m_conId;
}
consoleMsg("using " + m_underConId + " for hedging");
/*
* And finally submit RFQ
*/
submitOrder();
}
}
}
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.SecDef) {
error ("Could not find hedge contract id");
return;
}
}
}
catch (Exception e) {
// will update status and notify main thread
error (e.toString());
}
}
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();
}
else if (status.equals("Submitted") ||
status.equals("PreSubmitted")) {
if (orderId == m_orderId) {
m_receivedAcks |= ParentAcked;
}
else if (orderId < 0) {
m_receivedAcks |= ChildAcked;
}
checkReceivedAllAcks();
}
}
}
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 {
if (args.length < 2) {
System.err.println("Account and settlingFirm parameters " +
"are required");
return;
}
int orderId = (int) (System.currentTimeMillis() / 1000);
String account = args[0];
String settlingFirm = args[1];
String designatedLocation = (args.length >= 3) ? args[2] : "";
SampleDNHedge ut = new SampleDNHedge(/* clientId */ 2, orderId,
account, settlingFirm, designatedLocation);
ut.testOrder();
} catch (Exception e) {
e.printStackTrace();
}
}
}