Author |
Topic: What is the proper way to send this OSO and OCO orders? (11 messages, Page 1 of 1) |
||||
---|---|---|---|---|---|
Moderators: VPfau | |||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
I'm still a little new to this so pardon my terminology, trying to use as much API syntax as possible to make this clear. Questions at end of post.
In the scenario I explain below, we are selling short 2 contracts with a StopLimit at prices 100.00 and 99.98 with an OSO for a Stop-Loss of 2 contracts at 100.10 Also we want to set a profit target order for 1 contract at 99.90 which changes (does OCO only cancel or can it change an existing order?) the Stop-Loss of 2 contracts described above to a Stop-Loss of the 1 remaining contract and change the Stop price to 100.00 Send Order 1 SellShort 2 @ StopLimit (100.00, 99.98) [becomes OECorderId #1] OSO Buy 2 @ Stop (100.10) [becomes OECorderId #2] -- 2nd half of the OSO is the Stop-Loss Send Order 2 Buy 1 @ Stop (99.90) [becomes OECorderId #3] OCO (OECorderId #2) Buy 1 @ Stop (100.00) [stays OECorderId #2] -- 2nd half of the OCO is the new Stop-Loss of the remaining 1 contract Q1) Do we need to only send the two orders I described above? Q2) I found the method: OECClient.SendOCOOrders description says it cancels other orders - is this the method I need to use or do you offer a change order method? Q3) I was not able to find a similar method such as: OECClient.SendOSOOrders - does it exist? Q4) If our stop loss order on 2 contracts executes before our profit target order, does the system know to cancel the profit target order automatically or does our program need to do this some how? How do you recommend we send this contingent order? John Gagnon |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
In the advanced example I found function:
private void btSendBracket_Click( object sender, EventArgs e ) and it ends up calling: OECClient.Global.SendLinkedOrders( mainOrder, draft1, draft2 ); I think I am on the right track, mainOrder would be my: SellShort 2 @ StopLimit (100.00, 99.98) draft1 would be my: Buy 1 @ Limit 99.90 // profit target #1 draft2 would be my: Buy 2 @ Stop 100.10 // stop loss So I think I am close, now I just need to figure out how to trap the event when one of these fires to link up additional trades. For example if draft2 fires above - no linked trade, we're done. However if draft1 fires above then I would want another set of order pairings (OCO?): Buy 1 @ Stop 100.00 // stop loss Buy 1 @ Limit 99.80 John Gagnon |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
Ok, I am getting closer - could use a response here please...
Here is the results of my sendlinkedorders code: http://img29.imageshack.us/img29/176/sendlinkedorders.jpg Here is the code I am using, do you see anything I am doing wrong to cause the 2nd one to get rejected?? -----------snip----------- private void PlaceOrder() { foreach(var futureOrder in futureOrders) { try { OrderDraft mainOrder = GetOrderDraft(OECClient.Global.CreateDraft(), "Regular", futureOrder); OrderDraft profit1Order = GetOrderDraft(OECClient.Global.CreateDraft(), "Regular", futureOrder); OrderDraft stopLossOrder = GetOrderDraft(OECClient.Global.CreateDraft(), "Regular", futureOrder); profit1Order.Quantity = futureOrder.OrderProfitTargetContracts; profit1Order.Price = Convert.ToDouble(futureOrder.OrderTargetProfit1Price); stopLossOrder.Quantity = mainOrder.Quantity; stopLossOrder.Price = Convert.ToDouble(futureOrder.OrderTargetStopLossPrice); profit1Order.Contract = stopLossOrder.Contract = mainOrder.Contract; profit1Order.Type = OEC.Data.OrderType.Limit; stopLossOrder.Type = OEC.Data.OrderType.Stop; if (mainOrder.Side == OEC.Data.OrderSide.Buy) { profit1Order.Side = OEC.Data.OrderSide.Sell; stopLossOrder.Side = OEC.Data.OrderSide.Sell; } else { profit1Order.Side = OEC.Data.OrderSide.Buy; stopLossOrder.Side = OEC.Data.OrderSide.Buy; } if (mainOrder == null) return; if (profit1Order.Quantity > 0) { if (MessageBox.Show("Send linked orders \n" + mainOrder.ToString() + "\n" + profit1Order.ToString() + "\n" + stopLossOrder.ToString(), "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return; OECClient.Global.SendLinkedOrders(mainOrder, profit1Order, stopLossOrder); } else { if (MessageBox.Show("Send linked orders \n" + mainOrder.ToString() + "\n" + stopLossOrder.ToString(), "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return; OECClient.Global.SendLinkedOrders(mainOrder, stopLossOrder); } } catch (Exception ex) { MessageBox.Show("Error sending order : " + ex.Message); } } } -----------snip----------- John Gagnon |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
Ok, looks like the code above worked since when I woke up this morning the rejected trade actually filled (after the sellshort filled).
My next challenge is to capture the trade fills so I can create trades (stop loss and profit #2) for the remaining 1 contract. John Gagnon |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
Actually I am still looking into this, the profit order was working and eventually filled, but the stoploss order was rejected (and hence never working) any ideas why?
John Gagnon |
||||
RuslanK Posts: 69 Joined: Jun 02, 2010 |
Hello,
SendOCOOrders method is intended to send OCO orders. If any leg of OCO order gets filled the other one gets cancelled automatically by server. If you want to send an OSO order - you should use SendLinkedOrders method. So, your guess about this was correct. About rejected order - I'm looking into this now and will come back with the results shortly. Ruslan Kartokhin Software Developer |
||||
RuslanK Posts: 69 Joined: Jun 02, 2010 |
Your order with id 202254138 got rejected with "Invalid trigger price" comment which means that stop price was lower than current at the moment of order execution.
Ruslan Kartokhin Software Developer |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
Thanks ruslanK -
Problem I started having was that when using: SendLinkedOrders If the mainOrder (first order in the chain) was rejected, the 2nd and 3rd orders would become working causing unintended trades. Is this normal? I understand why the rejection was happening, but now I am trying to intercept filled orders to call SendOCOOrders so that only OCO orders are sent after mainOrder is filled. John Gagnon |
||||
RuslanK Posts: 69 Joined: Jun 02, 2010 |
Yes, this is normal behaviour for linked orders.
According to our paradigm - it's up to 3rd party application to decide what to do with remaining orders - either cancel them or let them stay. Your code should monitor order states by handling OnOrderStateChanged event. Ruslan Kartokhin Software Developer |
||||
JGagnon Posts: 95 Joined: Apr 11, 2011 |
Thanks Ruslan -
I am still having a problem - I am able to intercept the event OnOrderStateChanged - but the linked orders are not getting cancelled - do you see what the problem with my code is? I have included the console output at the end of this message too. The "CancelOrder" code below executes, but the linked orders still go to "working" and "filled". _______________ private void oecClient1_OnOrderStateChanged(OEC.API.Order Order, OEC.Data.OrderState OldOrderState) { Console.WriteLine("OnOrderStateChanged: {0}: {2} -> {1} ", Order.ID, Order.CurrentState, OldOrderState); if (Order.Comments == "1" && Order.CurrentState == OEC.Data.OrderState.Rejected) { if (Order.Linked == null) return; else OECClient.Global.CancelOrder(Order.Linked); } } _______________ Console output: OnOrderStateChanged: -1: Unknown -> Sent OnOrderStateChanged: -2: Unknown -> Sent OnOrderStateChanged: -3: Unknown -> Sent Send order Sell Short 2 6EH2 STP 1031.37 LMT 1031.37 OnOrderConfirmed: -1 -> 202257973 OnOrderStateChanged: 202257973: Sent -> Sent OnOrderStateChanged: 202257973: Sent -> Sent OnOrderConfirmed: -2 -> 202257974 OnOrderStateChanged: 202257974: Sent -> Sent OnOrderStateChanged: 202257974: Sent -> Sent OnOrderConfirmed: -3 -> 202257975 OnOrderStateChanged: 202257975: Sent -> Sent OnOrderStateChanged: 202257975: Sent -> Sent OnOrderStateChanged: 202257973: Sent -> Accepted OnOrderStateChanged: 202257974: Sent -> Accepted OnOrderStateChanged: 202257975: Sent -> Accepted OnOrderStateChanged: 202257973: Accepted -> Rejected OnOrderStateChanged: 202257974: Accepted -> Working OnOrderStateChanged: 202257974: Working -> Working Order #202257974 (Buy 1 6EH2 LMT 1031.36) filled : 1@131.44 OnOrderStateChanged: 202257974: Working -> Completed OnOrderStateChanged: 202257975: Accepted -> Working OnOrderStateChanged: 202257975: Working -> Working OnOrderStateChanged: 202257975: Working -> Cancelled John Gagnon |
||||
RuslanK Posts: 69 Joined: Jun 02, 2010 |
As I see in our database you sent three cancel requests for order #202257974.
First one failed because original order has been in processing by exchange at the moment. Two others were sent after order became completed. You should handle OnCommandUpdatedEvent to track state of each command execution. You can retrieve failure reason from ResultComments field of Command. Also, for this specific case: your limit price (1031.36) was a way higher than current price (131.44) - that's why order was executed by exchange momentarily leaving you without a chance to cancel it. Ruslan Kartokhin Software Developer |
||||