Hey,
I'm really new to algorithmic trading and QC, and I'm just trying to get a few of the whole system.
I'm trying to build a momentum based strategy that works as follows:
i. If the price change between 2 minutes is greater than the mean price change between 2 mins of 7 days, then go long. If the inverse is true, go short.
ii. After entering a position, if the stop loss / take profit has been hit, record it. (I want to know the ratio of trades stopped out or profit taken)
Questions:
1. What does self.spyMomentum.Updated += self.OnSpyMomentum do?
I don't understand how its adding a function?
Is it piping in the self.spyMomentum.Current.Average value into it every minute?
2. Does this self.spyMomentum = self.MOMP("SPY", 2, Resolution.Minute) measure the difference between 2 or 3 minutes?
3. The ratio of stop loss / take profits don't seem to even add up to 1.0, suggesting there are more stop losses / take profits than there are number of trades, why is that so?
4. What is the best way to conduct walk forward optimisation so I don't have to do manual updating of my parameters and introduce overfitting? I don't see any good articles on how to create a feedback loop between the backtesting engine and the parameters in the algorithm.
5. What's the best way to submit an order that actives after 5 days? For example, for every market order I submit based on my strategy, if it doesn't take profit or stop loss after 5 days, I want to liquidate it.
6. Any additional tips are always appreciated, thank you!
Oscar Lee
Question 1 has been answered, no longer need it, thanks! Would still like if anyone had answers for the rest though :)
Rahul Chowdhury
Hi Oscar,
2. self.MOMP("SPY", 2, Resolution.Minute) measures the momentum over the last 2 bars or 2 minutes.
3. The reason the ratios do not add up to one is because the stop losses are not being cancelled when the take profits are filled and vice versa then the stop losses are filled. This is why the ratios add up to greater than 1. We can remedy this by cancelling our orders when the corresponding other order fills with OrderTicket.Cancel()
4. Lean does not have any built-in parameter optimization features for backtesting. However, we have an open request for an optimization feature which generates the optimal parameters. You can follow along at the corresponding GH issues page.
5. An easy way to liquidate your position after 5 days is to keep track of the number of days you've been invested with a pointer and liquidate once that number has reached greater than 5. We can do this in a scheduled event which fires at the end of each day, OnEndOfDay().
6. Remember to check if your indicators are ready before you use them!
Check out the back test below.
Best
Rahul
Oscar Lee
Hi Rahul,
Thank you very much, those were very clear explainations and a great learning point, I truly appreciate your efforts!
I do however, have a follow up question to
5. An easy way to liquidate your position after 5 days is to keep track of the number of days you've been invested with a pointer and liquidate once that number has reached greater than 5. We can do this in a scheduled event which fires at the end of each day, OnEndOfDay().
What I mean is how to individually add a liquidate after 5 days to each security individually, as I've been buying S&P over the course of each trading day, I want to systematically liquidate each position after 5 days as opposed to liquidating everything at once in 5 days. How would you advise to achieve that?
Thank you so much again!
Rahul Chowdhury
Hey Oscar,
To accomplish this, we can declare daysInvested as a dictionary, which holds the number of days each symbol has been invested keyed by symbol. We can update the dictionary at the end of day and if any symbol has been invested in for 5 or more days, we can liquidate that symbol.
Also note that, we need to use LimitOrders for our take profit orders. When using a sell StopMarketOrder with a stop price greater than the current market price, that order will fill immediately,
self.MarketOrder("SPY", self.quantity) self.longstopLossTicket = self.StopMarketOrder("SPY", -self.quantity, self.longStopLoss) # Will fill Immediately self.longtakeProfitTicket = self.StopMarketOrder("SPY", -self.quantity, self.longTakeProfit) #Replace with self.longtakeProfitTicket = self.LimitOrder("SPY", -self.quantity, self.longTakeProfit)
Oscar Lee
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!