Back

OnOrderEvent method and locking

Hi there folks!

I have a strategy class, the signals given by the strategy depend on the actual stock position (long sell, or not invested). The actual stock position is an encapsulated field in the strategy class. So, I made an implementation in the OnOrderEvent method that changes the actual stock position in the strategy if the order is filled.
public override void OnOrderEvent(OrderEvent orderEvent)
{
OrderTicket actualOrderTicket = Transactions.GetOrderTickets(t => t.OrderId == orderEvent.OrderId).Last();
StockState newStockState = (actualOrderTicket.Quantity > 0) ? StockState.longPosition : StockState.shortPosition;

switch (actualOrderTicket.Status)
{
case OrderStatus.Filled:
Strategy.Position = newStockState;
break;
default:
break;
}
}

But I have another method in the main algorithm that relies in the stock position to make decisions. So, as far I can understand I have to make locks to avoid problems; isn’t?

I saw how you lock some of the fields in the OrderTicket class and after some search I made this encapsulation in the Strategy class:
public enum StockState
{
shortPosition, // The Portfolio has short position in this bar.
longPosition, // The Portfolio has short position in this bar.
noInvested, // The Portfolio hasn't any position in this bar.
};

public class SomeRandomStrategy
{
#region Fields

private readonly object _positionLock = new object();

private StockState _position = StockState.noInvested;

public StockState Position
{
get
{
lock(_positionLock)
{
return _position;
}
}
set
{
lock(_positionLock)
{
_position = value;
}
}
}

#endregion

#region Constructors

public SomeRandomStrategy()
{
}

#endregion

}

Again, the locking stuff was copied without fully understanding it. And in some places I saw that as right and in others as incorrect. So, I’d like to know if by chance, the code will work. And obviously, any hint will be much appreciated.

Thanks in advance, JJ

P.S.: in the OnOrderEvent implementation I assumed that the OrderEvent.OrderID refers to a unique OrderTicket. Am I right?
Update Backtest






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.



Deep questions! -- Locks allow multiple threads to use the same objects (so only one thread will use it at a time). You normally use a lock on the location you want to ensure you're the only one accessing the data.

With the code above there's a small chance one thread will be getting, while the other is setting. But because there is very little code inside the lock method your code should be safe.'

OrderId is the id of the order which was placed. Even though they are hidden, we still have order objects, we just hide them so you cannot modify them after being submitted. The order ticket is the "controller" for updating / changing the orders.
1

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.


Thank you very much @Jared!

I think I don’t understand the answer to the second question, let me reformulate it.

In the OnOrderEvent I use this procedure to retrieve an order ticket:
OrderTicket actualOrderTicket = Transactions.GetOrderTickets(t => t.OrderId == orderEvent.OrderId).Last();
The reasoning is that the predicate will return only one OrderTicket (of the subyacent hidden order), so I use the Last() method to retrieve it directly. Without the Last() method, the procedure returns an IEnumerable object.
var actualOrderTicket = Transactions.GetOrderTickets(t => t.OrderId == orderEvent.OrderId);

The question is: Is the OrderID unique? Or; Can two different order (different time / symbol / type) have the same ID? Or; Can that predicate return more than one OrderTicket?

If the OrderID isn’t unique, I should do a second filter to work with the correct OrderTicket.

Best, JJ
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.


Sorry my misunderstanding - yes the order id is unique (and internally auto-assigned), and I believe there is only one order ticket per order so your last() system is safe.
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.


OK! Thank you again Jared.
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.


@JJ - This is a minor thing, but I would recommend using First() so you don't need to loop through every order every time :) Using Last requires complete enumeration. Also, not sure if you know but both the .First() and .Last() extensions will throw exceptions if there's no elements returned.
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.


Hey @Michael, nice to see you again!

I'll take note of the detail, thanks!

Now, why are you saying "loop through every order every time"? The whole point of my second post is if there is more than one order ticket with the same OrderID. And I understood that, no.
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.


Ah, indeed you are correct. The GetOrderTickets(t => t.OrderId == id) will return an enumerable with exactly one element if it exists, so First and Last should behave with identical performance :) Apologies for the confusion.
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.


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