Hi,
I am just trying a very simple algorithm as shown in the code snippet below. When backtesting the algorithm will execute orders when I set the resolution to second but when I switch to tick resolution no order gets executed. Are there any limitations on tick data order execution? In the log output I can see the log statement but still the order does not get executed.
Thanks for any help.
import random
from datetime import timedelta
class BaseLine(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 28) # Set Start Date
self.SetEndDate(2020, 1, 29) # Set End Date
self.SetCash(100000) # Set Strategy Cash
#1. Subscribe to some stocks
self.stocks = ["AAPL", "MSFT", "FB"]
for stock in self.stocks:
self.AddEquity(stock, Resolution.Tick)
self.Securities[stock].SetDataNormalizationMode(DataNormalizationMode.Raw)
self.NextOrderTime = self.Time
def OnData(self, data):
if self.Time > self.NextOrderTime:
self.canInvest = False
stock = random.choice(self.stocks)
self.Log("{0}: Purchasing stock {1}".format(self.Time, stock))
# Create market order to buy 50 units of stock
self.MarketOrder(stock, 50)
self.StopMarketOrder(stock,-50,self.Securities[stock].Price*0.9)
self.LimitOrder(stock,-50,self.Securities[stock].Price*1.1)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Filled:
order = self.Transactions.GetOrderById(orderEvent.OrderId)
self.Log("{0}: {1}: {2}".format(self.Time, order.Type, orderEvent))
if order.Type == OrderType.Market:
stock = orderEvent.Symbol
self.Log("{0}: Setting upper and lower limits for stock {1}".format(self.Time, stock))
if order.Type == OrderType.StopMarket or order.Type == OrderType.StopLimit:
stock = orderEvent.Symbol
self.Log("{0}: Canceling all trades for stock {1}".format(self.Time, stock))
self.Transactions.CancelOpenOrders()
self.NextOrderTime = self.Time + timedelta(seconds = 10)
Rahul Chowdhury
Hey Artur,
The culprit is this line if self.Time > self.NextOrderTime. This is true until either a LimitOrder or a StopMarketOrder is filled. This means that until one of those orders are filled, you are executing self.MarketOrder(stock, 50) every second (because tick data is aggregated and returned every second). Even for the least expensive symbol in your list, MSFT, you would send an order to purchase $10,000 of MSFT stocks every second. You might see where this is going.
Your algorithm quickly runs out of buying power and you get an endless stream of runtime errors:
Backtest Handled Error: Order Error: id: 4393, Insufficient buying power to complete order (Value:15625), Reason: Id: 4393, Initial Margin: 7813.5, Free Margin: 3856.21
The algorithm will invalidate any MarketOrder made for which there is not enough buying power to execute it.To bypass this, we can simply increase our restrictions for when we trade.
For example, let's only send a MarketOrder if we are not already invested.
if self.Time > self.NextOrderTime and not self.Portfolio.Invested:
Artur
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!