When I set self.DefaultOrderProperties.TimeInForce = TimeInForce.Day, none of the limit orders would be filled even if I set a very high limit price. I also tried to send market orders and it didn't work either. Basically I want the orders to be automatically cancelled before the market closes on that day if they are not filled.
#region imports
from AlgorithmImports import *
#endregion
class CryingGreenDolphin(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 12, 6)
self.SetEndDate(2018, 12, 17)
self.SetCash(100000)
self.aapl = self.AddEquity("AAPL", Resolution.Daily)
self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
def OnData(self, data: Slice):
#self.MarketOrder(self.aapl.Symbol, 100)
self.LimitOrder(self.aapl.Symbol, 100, data[self.aapl.Symbol].Close * 1.2)
Fred Painchaud
Hi TC,
I ran your code and all orders are cancelled on my side except for the last one, since it is placed right before your backtest terminates.
So you set the limit to +20% of the previous day's close but that increase is not reach the next day so your limit order is cancelled. That's not what you want?
Fred
T C
Hi Fred,
Thanks for the help. The reason I set the limit order to be +20% of the previous close is to make sure the orders will definitely get filled once the market opens. I also tried to send market orders like self.MarketOrder(self.aapl.Symbol, 100), however none of them got filled and eventually were cancelled. That's definitely not what I expected. I guess the problem is that once I set self.DefaultOrderProperties.TimeInForce = TimeInForce.Day with data resolution as daily, those orders I sent became expired once the market opens the next day. It seems the logic behind TimeInForce.Day doesn't make sense here.
TC
Fred Painchaud
Hi TC,
A limit order is an order which does not execute if your limit price is not reached within the time in force period.
So, when you set your time in force to be the day and the limit price to be +20% of the previous day's close, your limit order will only be filled if the price of the asset makes a 20% increase (or more) during the day. AAPL did have nice bull periods 😊, but +20% over a day is not something that happens very often. Even with BTC, it does not happen very often.
So it is normal to see +20% day limit orders not being filled instead of “make sure the orders will definitely get filled once the market opens”.
With market orders, time in force is not really considered as they are market orders. A market order that would not execute during a full day would be for a very very very illiquid asset. Like no one is touching that asset even with a ten foot pole. If you have enough money to buy the stocks, market orders should execute.
The logic behind time in force daily is not 24h wall clock all the time. It is “1 trading day”. So it can be “until 16h00 today”, “until 20h00 today”, “in the next 24h”, …, depending on the market, regular hours/extended hours, etc.
Fred
T C
Hi Fred,
+20% is just an extreme example for me to set in order to find out whether the orders could be filled. You can try the more reasonable code below with 20 years time period and none of the orders can be filled. This time, I set the limit price to be 0.995 of the previous day's close. Still all of the orders got cancelled except for the last one which shows "Submitted". You can change it to the other numbers as well as long as you can get any filled orders. Thanks!
# region imports
from AlgorithmImports import *
# endregion
class UglyFluorescentPinkSalamander(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 2)
self.SetEndDate(2020, 12, 31)
self.SetCash(100000)
self.aapl = self.AddEquity("AAPL", Resolution.Daily)
self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
def OnData(self, data: Slice):
if data[self.aapl.Symbol] is not None:
self.LimitOrder(self.aapl.Symbol, 100, data[self.aapl.Symbol].Close * 0.995)
Best regards,
TC
Fred Painchaud
Hi TC,
Ok, this is something else now.
To use time in force daily, you need to work with intra-day data. Or when you place your order with daily data, the market needs to be open. Daily bars hit OnData at midnight.
Fred
T C
Hi Fred,
My goal is to place a limit order before the next trading day starts and the order will get expired by the end of that trading day if it's not filled. I don't really want to change the data resolution to intra-day since my signals are based on daily data. Right now, I have a walkaround solution by adding code to cancel the order at the end of the day if it's not filled, but it's a little tedious. I just want the system to automatically handle that. That's why I tought self.DefaultOrderProperties.TimeInForce = TimeInForce.Day should do the job. Thanks!
Best regards,
Yuan
Fred Painchaud
Hi Yuan,
Yep. That's what I understood so it's good we are on the same page.
The particularity you are facing is that I believe limit orders are not placed when the market is closed (outside extended hours). Hence saying the market needs to be open. The little workaround you can do is put your limit orders in a list during the night and wait for the open of the market (in OnData with a little test on Time or a scheduled event) to place your limit orders. Then, your time in force will be in force (ah ah ah). It will be more lightweight than your current workaround being managing cancellations.
Fred
T C
Hi Fred,
I will think about your suggestion which seems better than mine. The other way that I can think of is to use TimeInForce.GoodTilDate and pass self.Time + 1 business day as the parameter. Obviously you have to figure out what the next business date is. I am not sure if quantconnect has that.
Best regards,
Yuan
Fred Painchaud
Hi Yuan,
You're lucky enough that I saw a thread precisely about that, and it's been recent enough that I still remember 😊.
If you need help with the list solution, you can post your code if you want and you will get help.
Fred
T C
I will try it. Thanks Fred!
T C
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!