My goal is to create a strategy that:
1. Goes long if the previous close > close
2. Goes short if the previous close < close
I don't know where I go wrong, any help is appreciated!
import numpy as np
### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015,1,1) #Set Start Date
self.SetEndDate(2019,1,1) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.AddForex("EURUSD", Resolution.Minute)
self.quoteBarWindow = RollingWindow[QuoteBar](2)
def OnData(self, data):
if data.ContainsKey("EURUSD"):
QuoteBar = data['EURUSD']
self.qouteBarWindow.Add(data["EURUSD"])
previousClose = self.quoteBarWindow[1]
if quoteBar.Open > previousClose:
self.SetHoldings("EURUSD", 1)
if quoteBar.Open < previousClose:
self.SetHoldings("EURUSD", -1)
Senaid Kadric
deleted comment (script), added to the post
Douglas Stridsberg
Hi,
It would be easier if you attach a backtest to the forum post.
What is the error you're seeing? Firstly I can see that you're comparing the Open of the current bar with the Close of the past bar - this is likely to never trigger because in FX, the open of a new bar is almost always equal to the close of the past bar...
Senaid Kadric
Hello Douglas,
I tried adding the backtest but I couldn't find the right one tbh. I was planning to trade it with SPY but I still not savy enough to code that haha. Still learning so I appreciate your response a lot! thanks! The error I am getting is this one:
Runtime Error: ArgumentOutOfRangeException : Must be between 0 and 0 Parameter name: i Actual value was 1. at QuantConnect.Indicators.RollingWindow`1[T].get_Item (System.Int32 i) [0x0004c] in <0f3b2385f0aa4c0b8a4b99a1a9739804>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in :0 at OnData in main.py:line 27Douglas Stridsberg
Ah - that's more clear. That means you're trying to access an entry in the RollingWindow which doesn't exist yet.
Before you use the RollingWindow, you should always check if the .IsReady property is set to true. Not 100% up to speed on the Python syntax but it should be self.quoteBarWindow.IsReady. Check if the value is true - if not, then your code should not try to access anything inside it.
Senaid Kadric
I'm not sure what I'm doing wrong, I still get the same syntax error. This is now my code.
import numpy as np ### <summary> ### Basic template algorithm simply initializes the date range and cash. This is a skeleton ### framework you can use for designing an algorithm. ### </summary> class BasicTemplateAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2015,1,1) #Set Start Date self.SetEndDate(2019,1,1) #Set End Date self.SetCash(100000) #Set Strategy Cash self.AddForex("EURUSD", Resolution.Hour) bar = 2 self.quoteBarWindow = RollingWindow[QuoteBar](bar) def OnData(self, data): if data.ContainsKey("EURUSD"): QuoteBar = data['EURUSD'] self.quoteBarWindow.Add(data["EURUSD"]) previousClose = self.quoteBarWindow[1] if not self.quoteBarWindow.IsReady: return if quoteBar.Open > previousClose: self.SetHoldings("EURUSD", 1) if quoteBar.Open < previousClose: self.SetHoldings("EURUSD", -1)
Error link: https://www.quantconnect.com/backtest/43430/2510193/1e5f05cdd1c80c7e1cc382741054d7e8-log.txt
You made my day trying to help me learn coding
Link Liang
Hi Senaid,
Here are some points in your code that lead to errors:
1. The quoteBarWindow.IsReady check must be before accessing quoteBarWindow[1]. It tries to prevent you from accessing the second element in the rolling window when there is only one element in there. It happens on the very first day, when you don't have quote from yesterday. This is why you got ArgumentOutOfRangeException.
An easy way to check is to use
if not self.quoteBarWindow.Count > 1: return
It checks if there are more than 1 element in rolling window. However, we support a more handy way:
if not self.quoteBarWindow.IsReady: return
It checks if the rolling window is filled. For example, if today is the 8th day, meaning there are 8 elements in our rolling window, but the size of our rolling window is 10, then ourRollingWindow.IsReady will return false. It returns true when (# of elements = size of rolling window).
2. QuoteBar was defined on line 21 but quoteBar is called on line 29 and 31.
A suggestion for naming variable is using lower case and avoid using type name as variable names.
3. previousClose is a QuoteBar, not a number. I believe you want to compare quote.Open with the close price of previous quote, and previousClose.Close is what you are looking for.
Here is an attempt with your design. You may also find help here
import numpy as np ### <summary> ### Basic template algorithm simply initializes the date range and cash. This is a skeleton ### framework you can use for designing an algorithm. ### </summary> class BasicTemplateAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2015,1,1) #Set Start Date self.SetEndDate(2019,1,1) #Set End Date self.SetCash(100000) #Set Strategy Cash self.AddForex("EURUSD", Resolution.Hour) bar = 2 self.quoteBarWindow = RollingWindow[QuoteBar](bar) def OnData(self, data): if data.ContainsKey("EURUSD"): quote = data['EURUSD'] self.quoteBarWindow.Add(data["EURUSD"]) # if not self.quoteBarWindow.Count > 1: if not self.quoteBarWindow.IsReady: return previousQuote = self.quoteBarWindow[1] if quote.Open > previousQuote.Close: self.SetHoldings("EURUSD", 1) if quote.Open < previousQuote.Close: self.SetHoldings("EURUSD", -1)
Senaid Kadric
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!