I need some help with the order ticket system. I understand the concept fine, but I would like to know the precise syntax for doing the following:
1. Placing a market order. This is what I currently do:
OrderTicket thisOrder = MarketOrder("stock symbol","amount");
2. Storing the number of shares that was actually bought in a variable.
3. Storing the price at which the order was filled in a variable.
Regarding the order to sell, this is what I am currently doing for a market order:
OrderTicket thisOrder = MarketOrder("stock symbol",-"amount");
Is the above syntax correct? Also, instead of manually entering the quantity to sell, I would prefer to use the actual amount that was purchased and captured in a variable in 2. above.
Could somebody set me straight?
I would also greatly appreaciate it if anyone could confirm that the notify() feature only works in live trading or live paper trading. I have tried testing notify() in backtesting, but no cigar.
Thank you.
Denny Caldwell (Grinn)
I had the exact same troubles! But first, to clarify, when setting an order, you're giving the quantity of the order (# of stocks to purchase), not the dollar amount for the order. You said "amount" there, and so I wasn't certain which you meant.
As far as selling, you got it: Just give the quantity a negative number, and it will sell that portion of stocks. So if you bought 200 shares of GOOG today...
`MarketOrder("GOOG", 200);`
When you want to sell them in the future, you would simply do:
`MarketOrder("GOOG", 200);`
Here's the docs on MarketOrder. And here's the docs on orders in general.
Now, figuring out specifically what you actually bought and sold and for how much is a little less simple. That's because when you make an order, you need to await its purchase/sale by your brokerage. In other words, some infinite amount of time could ellapse before your order is filled. This is particularly true for Limit Orders where your limit price may take a while to be met - or never be met at all.
Thus the OnOrderEvent. This little fella fires whenever any order event occurs for your broker. Sell orders, buy orders, and everything in-between. All you need to do is filter these events to the ones you care about and do as you will.
public override void OnOrderEvent(OrderEvent orderEvent) { var symbol = orderEvent.Symbol; // This will never (read: should never) happen. if(!Securities.ContainsKey(symbol)) { Error(string.Format($"Security for symbol '{symbol.Value}' not found in Securities collection when processing OrderId {orderEvent.OrderId}.")); return; } // The current details of the security in question. var security = Securities[symbol]; // The OrderTicket for the order (https://www.quantconnect.com/lean/docs#topic3152.html) var order = Transactions.GetOrderById(orderEvent.OrderId); // The actual quantity filled by the broker. var quantity = orderEvent.FillQuantity; // The actual price your security went for. var price = orderEvent.FillPrice; // Holds OrderDirection.Buy or OrderDirection.Sell var direction = orderEvent.Direction; if(orderEvent.Status == OrderStatus.Invalid || orderEvent.Status == OrderStatus.Canceled) { // Be sure and do something with canceled or invalid orders. Debug(string.Format("Order {0:000} for {1} {2}.", orderEvent.OrderId, symbol.Value, orderEvent.Status)); return; } switch (orderEvent.Direction) { case OrderDirection.Buy: if(quantity != 0) { // Do something with you shiny new stocks. } break; case OrderDirection.Sell: // For a sale, the quantity is in the negative. Reverse it for logging. quantity = -quantity; if(quantity != 0) { // Do something with your new-found fortunes. } break; } }
There are a few things that I'd like to point out here:
Concerning `Notify` - I don't use it myself, but according to the specs, "These are only sent during live trading."
Alexandre Catarino
The syntax above is correct, since, if "thisOrder " is a global variable, you can track the state of your order (the average filled price, the filled quantity, etc) in OnData event handler.
However, you could use the OnOrderEvent event handler to get information about your orders when their state changes:
public override void OnOrderEvent(OrderEvent orderEvent) { // Only process filled orders if (!orderEvent.Status.IsFill()) return; var orderId = orderEvent.OrderId; // Only considers thisOrder if(thisOrder.OrderId != orderId) return; var orderTicket = Transactions.GetOrderTicket(orderId); var price = orderTicket.AverageFillPrice; var quantity = orderTicket.QuantityFilled; }
The simplest way to liquidate your holdings is to use the Liquidate method helper, since you don't neet to keep record of your current holdings.
Notifications only works on live trading.
Alexandre Catarino
Apparently Denny was answering at the same time and I didn't get a notification in time to prevent repeated information. Thank you, Denny.
Denny Caldwell (Grinn)
Haha. You're welcome. +1 for the orderEvent.Status.IsFill(). That's way better than my quantity!=0 hack!
Anton Craft
Thank you, thank you, Denny and Alexandre. Yes, Denny, I should have written "quantity" instead of "amount" as the second parameter in the order function. Quantity is certainly less confusing than amount. Thank you for the links to the specs too.
Alexandre, thanks for your contribution. I certainly didn't find it repetitive. I definitely appreciate your suggestion about liquidate, and will henceforth use it when I need to sell everything I have bought.
Anton Craft
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.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!