Disclaimer: I'm a beginner
Hey, I've been working on this algorithm, that trades BTC (so far) based on MFI. When the MFI for last 3 hours is greater or equal to 100 and the last candle is upward trending it should submit firstly a short order and then long after hitting the short stop loss.
The main problem I see right now is that the algorithm submits orders when the MFI is not ≥= 100. I compared the entries to the MFI data on BTC and from what I can see, the entries are completely different from the times MFI hits 100.
I tried various things, but I can't seem to figure out a solution.
Thank you!
PS: This is only a part of the code, that which I thought is the most relevant.
class BTCTradingBot(QCAlgorithm):
def Initialize(self):
# add MFI indicator; hour resolution
self.btc_money_flow = self.MFI(self.tick, 3, Resolution.Hour)
# history data to check if the candle is upward or downward trending
self.close_price_history = RollingWindow[float](4)
self.open_price_history = RollingWindow[float](4)
def OnData(self, data):
self.short_order = None
self.long_order = None
# history data to check if the candle is upward or downward trending
if data.ContainsKey(self.tick):
self.close_price_history.Add(data[self.tick].Close)
previous_close = self.close_price_history[0]
self.open_price_history.Add(data[self.tick].Open)
previous_open = self.open_price_history[0]
self.Debug("// Setting rolling windows -- working")
if (self.btc_money_flow.Current.Value >= 100) and (previous_close > previous_open):
#SHORT ORDER
self.short_order = self.StopMarketOrder(self.tick, -0.1, self.Securities[self.tick].Close - self.Securities[self.tick].Close * 0.005, "Short order")
self.short_id = self.short_order.OrderId
#Stop loss for short order
if self.close_price_history[0] >= (self.close_price_history[1] + self.close_price_history[1] * 0.003):
# self.trailing_sl_short = self.MarketOrder(self.tick, 0.1, "Short order stop loss")
self.trailing_sl_short = self.LimitOrder(self.tick, 0.1, self.Securities[self.tick].Close + self.Securities[self.tick].Close * 0.003, "Short order stop loss")
self.Debug("// Short stop loss -- working")
#LONG ORDER
if self.trailing_sl_short.Status == OrderStatus.Filled:
self.long_order = self.StopMarketOrder(self.tick, 0.1, self.Securities[self.tick].Close, "Long order")
self.long_id = self.long_order.OrderId
#Stop loss for long order
if self.close_price_history[1] >= (self.close_price_history[1] * 0.005):
# self.trailing_sl_long = self.MarketOrder(self.tick, -0.1, "Long order stop loss")
self.trailing_sl_long = self.LimitOrder(self.tick, -0.1, self.Securities[self.tick].Close * 0.005, "Long order stop loss")
self.Debug("// Long stop loss -- working")
#TIME BASED STOP LOSSES
#For short orders
if (self.short_order in locals()) or (self.short_order in globals()) and (self.short_order.Status == OrderStatus.Filled):
self.short_fill_time = self.Time
self.Debug("// Short time based stop loss -- working")
#For long orders
if (self.long_order in locals()) or (self.long_order in globals()) and (self.short_order.Status == OrderStatus.Filled):
self.long_fill_time = self.Time
self.Debug("// Long time based stop loss -- working")
Louis Szeto
Hi Matyas
I'll try to help. I quoted your code's ordering hierarchy:
First short condition seems match what you have described your entry condition, the problem is your order type, your order will only be executed when the price acrossed the set stop price. If your preset condition is trading-signal based, it would be the best practice to just simply use market order for minimal delay, that is the sacrifice you would trade for a worse price even if there is chance of getting a better quote, otherwise limit order but not stop order.
Second, the trailing stop loss should not be set like this, it will not be updated, and only be sent out when at that slice both condition 1 & 2 are satisfied. You need to call for immediate stop market/limit order just after your short sell (i.e. under condition 1), and if certain conditions is true/false to update its stop price. Similar for the one in condition 4. BTW the stop price of condition 4 is a bit strange.
Third, condition 3 should not be encapsulated inside condition 1, otherwise it'll never sent out unless both the short sell and its trailing stop got executed immediately after sent out. Similar problem of order type like at condition 1.
Fourth, logical problem, maybe just you didn't show all your code: you never set any normal exit condition. This part I am not able help you with.
See if this could get what you need, I only include relevant parts:
CheersLouis
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.
Matyáš Bureš
Thanks for responding Louis
After implementing your suggestions the code is definitely cleaner, but so far only the first trade (short and short stop loss) gets executed. Probably some of the conditions won't reset, so the first section won't get initialized again - I'm looking into that. I had a similar problem when trying to restrict placing trades by “if not self.Portfolio.Invested”.
Also, it still runs into problems when it comes to the MFI. The time order is submitted, which if I understand this correctly should happen immediately after meeting the conditions, isn't correlating with the time the MFI hits 100.
Have a great day,
Matyas
Louis Szeto
Hi Matyas
My test didm't replicate your repeating problem on MFI (see image, the MFI is indeed 100), also the trade count seems normal.
Anyway I attach my backtest for your reference. FYI I corrected some of the wrong code given to you earlier.
Cheers
Louis
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.
Matyáš Bureš
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!