Hello, I have written some code that isn't placing trades and I could use some assistance. What I am trying to test is a system where the 10 day ema of the security is the directional bias, the 10 hour ema is a confirmation of direction, the 14 period hourly rsi is a pullback parameter with signals at 30 for upward bias and 80 for downward bias, and finally using the 1 minute rsi for timing of entries and exits to be on the side of momentum. It should go long when the above params are met for longs and the 1 minute rsi is above 50 and close when it drops below 30, and go short when under 50 and close our above 80 when the above params indicates a bias short.
Ps. Code is written in python.
class HyperActiveMagentaAlligator(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 12, 26) # Set Start Date
self.SetEndDate(2022,2,26)
self.SetCash(100000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
self.spy = self.AddSecurity("SPY",Resolution.Minute)
self.bias = self.EMA("SPY", 10, Resolution.Daily)
self.confirmation = self.EMA("SPY", 10, Resolution.Hour)
self.pullback = self.RSI("SPY", 14, Resolution.Hour)
self.timing = self.RSI("SPY", 14, Resolution.Minute)
def OnData(self, data):
if not self.Portfolio.Invested:
if self.Securities["SPY"].Close > self.bias.Current.Value:
if self.Securities["SPY"].Close > self.confirmation.Current.Value:
if self.pullback < 30:
if self.timing > 50:
self.SetHoldings("SPY", 1)
if self.Securities["SPY"].Close < self.bias.Current.Value:
if self.Securities["SPY"].Close < self.confirmation.Current.Value:
if self.pullback > 80:
if self.timing < 50:
self.SetHoldings("SPY", -1)
if self.Portfolio.Invested:
if self.Holdings > 0:
if self.timing < 30:
self.SetHoldings("SPY", 0)
if self.Holdings < 0 :
if self.timing > 80:
self.SetHoldings("SPY", 0)
Fred Painchaud
Hi,
It looks like your RSI constraints are never satisfied. Or at least the “pullback” one… So you never enter.
Refer to attached backtest.
Fred
AegeanFutures
Fred, I spent yesterday working on this and am having some trouble with it still. This is where I am at,
class SmoothApricotCaribou(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 8, 28) # Set Start Date
self.SetEndDate(2022,2,1)
self.SetCash(50000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
crudeoilwti = self.AddFuture(Futures.Energies.CrudeOilWTI)
self.slowema = self.EMA("CrudeOilWTI", 21, Resolution.Daily)
self.fastema = self.EMA("CrudeOilWTI", 21, Resolution.Hourly)
self.rsi = self.RSI(14)
self.RegisterIndicator("CrudeOilWTI", self.rsi, timedelta(minutes=10))
self.Schedule.On(self.DateRules.EveryDay("CrudeOilWTI"), self.TimeRules.At(1, 00), self.ClosePositions)
self.SetBenchmark("CrudeOilWTI")
self.SetWarmUp(timedelta(21))
def OnData(self, data):
if not self.Portfolio.Invested:
if self.Securities["CrudeOilWTI"].Close > self.slowema.Current.Value:
if self.Securities["CrudeOilWTI"].Close > self.fastema.Current.Value:
if self.rsi <= 30:
self.MarketOrder("CrudeOilWTI", 1)
if self.Securities["CrudeOilWTI"].Close < self.slowema.Current.Value:
if self.Securities["CrudeOilWTI"].Close < self.fastema.Current.Value:
if self.rsi >= 70:
self.MarketOrder("CrudeOilWTI", -1)
if self.Portfolio.Invested.IsLong:
if self.Securities["CrudeOilWTI"].Close < self.fastema.Current.Value:
self.Liquidate("CrudeOilWTI")
if self.Portfolio.Invested.IsShort:
if self.Securities["CrudeOilWTI"].Close > self.fastema.Current.Value:
self.Liquidate("CrudeOilWTI")
def ClosePositions(self):
self.Liquidate("CrudeOilWTI")
Thank you for the time !
Fred Painchaud
Hi,
Now that you are working with futures, I believe this post could help you, with an example and everything.
Fred
AegeanFutures
Fred, I am trying to limit the OnData method to only run during the day sessions for the different futures markets I trade but cannot find anything online on how to implement this. Is it possible for me to set the Ondata to run from 8 am cst to 1pm cst?
Fred Painchaud
Hi,
Short answer: no. Not as you seem to intend, i.e., a simple “setting”.
Long answer: OnData is called whenever there is data for your resolution. In it, you can look at self.Time to determine what time it is (it will correspond to the end of the bar). So, you could decide to guard your code with:
if self.Time.Hour ≥ 8 and self.Time.Hour ≤ 12: # 12 since when it is 13:00, you do not want to do something… you'll miss 12:59-13:00 at minute res. If you want 13:00, you need to look at minutes too….
…
Since you want CST, you need to make sure that your zone is set properly and I would also Log a bit the first time to make sure it works as intended with respect to time zones, etc. In other words, make sure that self.Time IS CST…
Fred
AegeanFutures
Fred, Ive tried to put this into a simple Algo to test but am getting an error. Also can you advice me how to Log in order to make sure my Algo is executing as intended? Thank you again for all the help!
class SmoothApricotCaribou(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2019, 1, 1) # Set Start Date
self.SetEndDate(2020,1,1)
self.SetCash(50000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
self.y5treasurynote = self.AddFuture(Futures.Financials.Y5TreasuryNote)
self.slowema = self.EMA(self.y5treasurynote.Symbol, 21, Resolution.Minute)
self.fastema = self.EMA(self.y5treasurynote.Symbol, 9, Resolution.Minute)
self.Schedule.On(self.DateRules.EveryDay(self.y5treasurynote.Symbol), self.TimeRules.At(13, 00), self.ClosePositions)
self.SetBenchmark("Futures.Financials.Y5TreasuryNote")
def OnData(self, data):
if self.Time.Hour ≥ 9 and self.Time.Hour ≤ 12:
if not self.Portfolio.Invested:
if self.fastema.Current.Value > self.slowema.Current.Value:
self.MarketOrder(self.y5treasurynote.Symbol, 1)
if self.fastema.Current.Value < self.slowema.Current.Value:
self.MarketOrder(self.y5treasurynote.Symbol, -1)
if self.Portfolio[self.y5treasurynote.Symbol].Quantity > 0:
if self.fastema.Current.Value < self.slowema.Current.Value:
self.MarketOrder(self.y5treasurynote.Symbol, -2)
if self.Portfolio[self.y5treasurynote.Symbol].Quantity < 0:
if self.fastema.Current.Value > self.slowema.Current.Value:
self.MarketOrder(self.y5treasurynote.Symbol, 2)
else pass:
def ClosePositions(self):
self.Liquidate(self.y5treasurynote.Symbol)
Fred Painchaud
Hi,
There you go… Modified the code to correct errors and changed the period of the backtest so the logs are shorter since you are at minute res.
Fred
AegeanFutures
Fred, I've spent some time practicing with python as well as watching the videos available on YouTube for quantconnect but have hit a wall with this project. I am not sure why I cannot get it to run but I believe I must be using the consolidators incorrectly. Would you please take a look at this code for me and tell me where I'm going wrong. Thank you for all the help!
class SmoothApricotCaribou(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2019, 1, 1) # Set Start Date
self.SetEndDate(2019, 3, 1)
self.SetCash(50000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
self.y5treasurynote = self.AddFuture(Futures.Financials.Y5TreasuryNote, Resolution.Minute).Symbol
self.Consolidate(self.y5treasurynote, Resolution.Weekly, self.WeeklyBarHandler)
self.ema = self.EMA(self.WeeklyBarHandler, 10)
self.Consolidate(self.y5treasurynote, Resolution.Daily, self.DailyBarHandler)
self.confirmation = self.RSI(self.DailyBarHandler, 14)
self.Consolidate(self.y5treasurynote, Resolution.Hour, self.HourlyBarHandler)
self.timing = self.RSI(self.HourlyBarHandler, 14)
self.Schedule.On(self.DateRules.EveryDay(self.y5treasurynote.Symbol), self.TimeRules.At(13, 00), self.ClosePositions)
self.Schedule.On(self.DateRules.EveryDay(self.y5treasurynote.Symbol), self.TimeRules.Every(timedelta(hours=1)), self.PlotEMAs)
def OnData(self, data):
if self.Time.hour >= 9 and self.Time.hour <= 12:
self.Debug(f"Time is between 9h and 12h inclusive. Time is: {self.Time}")
if not self.Portfolio.Invested:
if self.Securities[self.y5treasurynote].Close > self.ema.Current.Value and self.confirmation > 50:
if self.timing.Current.Value <= 30:
self.MarketOrder(self.y5treasurynote, 1)
if self.Securities[self.y5treasurynote].Close < self.ema.Current.Value and self.confirmation < 50:
if self.timing.Current.Value >= 70:
self.MarketOrder(self.y5treasurynote, -1)
def ClosePositions(self):
self.Liquidate(self.y5treasurynote.Symbol)
Fred Painchaud
Hi,
Yeah, in
you declare that the handlers for your consolidators are WeeklyBarHandler, DailyBarHandler and HourlyBarHandler. So you need to define those with:
And also, your indicators should be like this:
Not sure the resolutions are the ones you wanted, just assuming.
Fred
AegeanFutures
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!