Back

OnOrderEvent: MarketOrder is not assigned to variable

Hello Quantconnect Community,

maybe somebody is able to help me here, as i thought i would do something quite normal.

My Goal is to assign every Order i do to one of my variables and when OnOrderEvent is called i want to do a Log entry.
The attached backtest is a stripped down version of the log to make it more obvious what happens.

In the attached algo and Logfile you can see, that for the limit Order it is working fine. I assign the OrderTicket to the variable and the Order Event arrives i check which of the orders it is (symbolData._limitTicket.OrderId == orderEvent.OrderId) and in case of the limit order i log "Order event for _limitTicket arrived ".

But for a marketOrder the condition in the OnOrderEvent is never called and i cant find out why.

I would really appreciate any hints why this is the case.

Best Reagrds and happy holidays,
Bjorn

Update Backtest








0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


In line:

if symbolData._marketOrderTicket.OrderId == orderEvent.OrderId:

One is not equal to Two, so your condition evaluation is always false.

0

Someone please correct me if I am wrong..

This is what happens (or lifecycle of Order):

For Market orders:

1)  self.MarketOrder() is called

2) that market order is placed/submitted to broker.  Broker registers that order in its system and returns order ticket with order_status "Submitted",  Since it is market order, it is filled with current price by broker and accodingly filled, partly filled, or rejected trade ticket with respective order_status (i.e. Filled, Parlially Filled, Rejected etc.) is ALSO returned by broker

3) that two returned order ticket and trade ticket are passed to OnOrderEvent() one after another

4) that final / second returned trade ticket is passed back to calling routine (which called self.MarketOrder() )

 

For Limit Orders:

1)  self.LimitOrder() is called

2) that Limit order is placed/submitted to broker.  Broker registers that order in its system and returns order ticket with order_status "Submitted",

3) That same returned order ticket is passed on to OnOrderEvent()

4) that same returned Order ticket is passed back to calling routine (which called self.LimitOrder() )

5) at later time, Depending on conditions, broker will send back trade ticket with appropriate order_status (i.e. Filled, Partially Filled, Cancelled)

6) Every trade ticket sent by broker, is passed on to OnOrderEvent()

 

So for market orders, depending on third parameter, you may or may not have OrderTicket when OnOrderEvent() is called.  OnOrderEvent() is called for every change in Order and Order Status. 

Your variables  symbolData._..............Ticket do not have correct values when OnOrderEvent() is called. 

It seems that it is working for LimitOrder. But it is not. 

self.Log("Order event for _limitTicket arrived ") is not executed until that limit order is Filled..
Please check attched backtest. I have changed Limit Price to 1.20 so that is not filled..

 

 

1


Ivan , Shailesh thanks a lot for you Feedback.
I now atttached the logfile (a little enhanced).

Ivan Baev The logfile below shows in line 7  that the order with ID: 1 has the Tag Market order and in line 10 the variable _marketOrderTicket is assigned and also has the ID: 1. So this should be a match.

Shailesh Raval Thanks for splitting up the steps thats also a great help. The logfile from my initial backtest below shows in line 21 that the limit Order has also been filled before (and if this was a mixup, also the marketOrder has always been filled (line 7)).

After writing all of this, the problem (of why "symbolData._marketOrderTicket.OrderId == orderEvent.OrderId" in the OnOrderEvent is never "True") seems to be that the variable _marketOrderTicket. is assigned AFTER the Event arrives in the OnOrderEvent. So when the event for the marketOrder arrives the variable (_marketOrderTicket) is still 'None' and not assigned yet. 
The OnOrderEvent with the ID of the marketOrder is called before the OrderID is assigned to the variable in case of a marketorder.

I guess then I have to find another way to check if THAT Marketorder has been filled and cant use the OrderID, which would have been convenient as i could use the same logic as i do for Limit and Stoplimit Orders. I guess i will try to insert my own id within the "Tags" of the Orders, 

 

2017-07-03 09:31:00 : ---------------
2017-07-03 09:31:00 : OnOrderEvent:: New Entry
2017-07-03 09:31:00 : OnOrderEvent:: Orderevent: Time: 07/03/2017 13:31:00 OrderID: 1 Symbol: OILU Status: Submitted
2017-07-03 09:31:00 : OnOrderEvent:: ordertickets.TAG: Marketorder
2017-07-03 09:31:00 : ---------------
2017-07-03 09:31:00 : OnOrderEvent:: New Entry
2017-07-03 09:31:00 : OnOrderEvent:: Orderevent: Time: 07/03/2017 13:31:00 OrderID: 1 Symbol: OILU Status: Filled Quantity: 1 FillPrice: 20.09 USD OrderFee: 1 USD
2017-07-03 09:31:00 : OnOrderEvent:: ordertickets.TAG: Marketorder
2017-07-03 09:31:00 : ------
2017-07-03 09:31:00 : OnData:: symbolData._marketOrderTicket is assigned
2017-07-03 09:31:00 : OnData:: Ticket Value (_marketOrderTicket):: 1: OrderId: 1 (BrokerId: 1) Filled Market order for 1 unit of OILU Request Count: 1 Response Count: 1
2017-07-03 09:31:00 : ---------------
2017-07-03 09:31:00 : OnOrderEvent:: New Entry
2017-07-03 09:31:00 : OnOrderEvent:: Orderevent: Time: 07/03/2017 13:31:00 OrderID: 2 Symbol: OILU Status: Submitted
2017-07-03 09:31:00 : OnOrderEvent:: ordertickets.TAG: LimitOrder
2017-07-03 09:31:00 : ------
2017-07-03 09:31:00 : OnData:: symbolData._limitTicket is assigned
2017-07-03 09:31:00 : OnData:: Ticket Value (_limitTicket):: 2: OrderId: 2 (BrokerId: 2) Submitted Limit order for 1 unit of OILU at limit 20.09 Request Count: 1 Response Count: 1
2017-07-05 09:31:00 : ---------------
2017-07-05 09:31:00 : OnOrderEvent:: New Entry
2017-07-05 09:31:00 : OnOrderEvent:: Orderevent: Time: 07/05/2017 13:31:00 OrderID: 2 Symbol: OILU Status: Filled Quantity: 1 FillPrice: 20.09 USD OrderFee: 1 USD
2017-07-05 09:31:00 : OnOrderEvent:: ordertickets.TAG: LimitOrder
2017-07-05 09:31:00 : Order event for _limitTicket arrived

 

0

Bjorn, you can do something similar like this:

class GenericCounters:

def __init__(self):
self.CounterValues = {}

def new (self, CounterName, StartValue = 0):
self.CounterValues[CounterName] = StartValue
return self.CounterValues[CounterName]

def inc (self, CounterName, increment = 1):
self.CounterValues[CounterName] += increment
return self.CounterValues[CounterName]

def dec (self, CounterName, decrement = 1):
self.CounterValues[CounterName] -= decrement
return self.CounterValues[CounterName]

class AnyName(QCAlgorithm):

def mylog (self, MsgLevel, strObj = "", *argv ):
if MsgLevel > self.DebugLevel:
LineOut = strObj + ">"
cntr = 0
for arg in argv:
cntr += 1
LineOut += "|{0}:{1} :".format(cntr , arg)
LineOut += "<# "
self.Log(LineOut)
# End of mylog()

def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

self.OpenTag = "open"
self.CloseTag = "close"
self.DebugLevel = 6 #messages with less level do not print

self.FCC = GenericCounters()
self.FCC.new("DP") # DataPoint
self.FCC.new("OE") # OrderEvent
self.FCC.new("OC") # OrderCount
self.FCC.new("OBO") # OpenBuyOrder

def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
DP = "DP:{0}:".format(self.FCC.inc("DP"))
for key in data.Keys:
self.mylog( 5, DP, data.Time, key.Value, data[key].Price,
self.Securities[key.Value].Price, self.Portfolio[key.Value].Quantity )

OC = "OC:{0}:".format(self.FCC.inc("OC"))
OrderQty = ...
OrderPrice = ...
OrderTag = DP + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"
OT = self.LimitOrder(key.Value, OrderQty, OrderPrice, OrderTag)
self.mylog( 5, DP+"HLess OBO OT" , OT.OrderId, OT.Symbol, OT.Quantity, OrderPrice, OT.Time, OT.Status, OT.Tag)


def OnOrderEvent(self, OrderEvent):
if OrderEvent.Status != OrderStatus.Filled :
return

OE = "OE:{0}:".format(self.FCC.inc("OE"))
self.mylog( 5, OE+"param: ", OrderEvent.OrderId, OrderEvent.Symbol, OrderEvent.Status,
OrderEvent.FillPrice, OrderEvent.FillQuantity, OrderEvent.Direction, OrderEvent.Message )



I did mention::

Your variables  symbolData._..............Ticket do not have correct values when OnOrderEvent() is called. 

Hope it helps. 

 

1

 Shailesh Raval    Yes, this help! 

Thanks for taking the time!

0

Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed