I created a brand new algorithm and followed the documentation to create a RollingWindow of decimals. Here is my code:
from decimal import Decimal
class ParticleMultidimensionalShield(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 10, 8) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.closeWindow = RollingWindow[Decimal](4)
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
# if not self.Portfolio.Invested:
# self.SetHoldings("SPY", 1)
However, running this code returns an error:
During the algorithm initialization, the following exception has occurred: TypeError : type(s) expected
at Initialize in main.py:line 13
TypeError : type(s) expected
What's the problem?
Halldor Andersen
Hi Joseph.
In the method Initialize(), add a security using AddEquity:
# In Initialize self.spy = self.AddEquity("SPY", Resolution.Daily)
The rolling arrays are updated by adding a new element using the Add method:
# In OnData if data.ContainsKey("SPY"): # Add SPY bar close in the rolling window self.closeWindow.Add(data["SPY"].Close)
I've attached a backtest for you reference.
Joseph Testa
@Halldor,
Thanks for your response.
I added a security and copy/pasted the OnData from your backtest but it did not resolve the problem.
However, your backtest gave me a clue about the problem.
Actually, the problem stems from the import statement at the beginning of my code:
from decimal import Decimal
According to the documentation for RollingWindow in Python, we need to import Decimal. It's even in the code snippet on the documentation page and labeled as "important":
from decimal import Decimal # Important: import decimal.Decimal class
self.closeWindow = RollingWindow[Decimal](4)
self.tradeBarWindow = RollingWindow[TradeBar](2)
self.quoteBarWindow = RollingWindow[QuoteBar](2)
But this actually breaks the code. I think it's a good idea for QC to update this part of the documentation as it just led me to broken code and confusion.
Regards
Jack Simonson
Hi Joseph,
You're correct, and thank's for pointing this out and we've updated the documentation. It's a legacy from before updated LEAN so that decimal was compatible across C# and Python without the need for importing Decimal. Glad to hear the code is working for you now!
Wouter vH
Dear mister Simonson, Jack Simonson
I am struggling with the same issue, however I haven't been able to fix it. I am also getting a Type error, but for the QuoteBar, while I have followed the documentation on the QuoteBar, could you please help me out? Thank you in advance. For some reason, i can't see the most recent backtest so i am unfortunately not able to attach that. I hope the code snippet will still help
import decimal as d from datetime import timedelta class MovingAverageCrossAlgorithm(QCAlgorithm): def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.SetStartDate(2017, 1, 1) #Set Start Date self.SetEndDate(2020, 10, 1) #Set End Date self.SetCash(100000) #Set Strategy Cash self.AddForex('EURUSD', Resolution.Hour) self.SetBrokerageModel(BrokerageName.OandaBrokerage) # create a 12 day exponential moving average self.fast = self.EMA("EURUSD", 5, Resolution.Daily) # create a 48 hour exponential moving average self.slow = self.EMA("EURUSD", 25, Resolution.Daily) self.SetLeverage = 1.0 self.SetWarmUp(timedelta(days=20)) self.SMA("EURUSD", 225).Updated += self.SmaUpdated self.smaWin = RollingWindow[IndicatorDataPoint](225) def SmaUpdated(self, sender, updated): '''Adds updated values to rolling window''' self.smaWin.Add(updated) def OnData(self, data): # wait for our slow ema to fully initialize if self.IsWarmingUp: return fxQuoteBars = data.QuoteBars eurusdQuoteBar = fxQuoteBars['EURUSD'] self.window = RollingWindow[eurusdQuoteBar](2) self.window.Add(data["EURUSD"]) currSma = self.smaWin[0] pastSma = self.smaWin[self.smaWin.Count-1] slope = currSma.Value - pastSma.Value # define a small tolerance on our checks to avoid bouncing tolerance = 0.0015 holdings = self.Portfolio["EURUSD"].Quantity # we only want to go long if we're currently short or flat if holdings <= 0 and slope + tolerance > 0.002: # if the fast is greater than the slow, we'll go long self.SetHoldings("EURUSD", 1.0) # we only want to liquidate if we're currently long # if the fast is less than the slow we'll liquidate our long if holdings > 0 and slope <= 0: self.Liquidate("EURUSD")
Derek Melchin
Hi Wouter,
Refer to this related thread. In the future, please avoid creating duplicate threads.
Best,
Derek Melchin
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.
Joseph Testa
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!