Hello,
I'm brand new to QuantConnect and this is my first post. I'm going through the tutorial on coding up an EMA cross strategy (youtube link) and have found a weird issue, not sure if it could be a bug. When I run a C# algo for the following parameters:
security: SPY
time period: between 3/20/14 and 3/21/14
resolutions: Second, Minute, Hour
I get an error:
"Runtime Error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform member binding on `null' value"
This happens with C# and does not happen with Python.
Here is my C# code:
namespace QuantConnect
{
public class BasicTemplateAlgorithm : QCAlgorithm
{
string symbol = "SPY";
public override void Initialize()
{
SetStartDate(2014, 3, 20);
SetEndDate(2014, 3, 21);
SetCash(30000);
AddEquity(symbol, Resolution.Minute);
}
public override void OnData(Slice data)
{
decimal price = data[symbol].Close;
}
}
}
Here is my Python code:
class BasicTemplateAlgorithm(QCAlgorithm):
def Initialize(self):
self._symbol = "SPY"
self.SetStartDate(2014,3,20)
self.SetEndDate(2014,3,21)
self.SetCash(30000)
self.AddEquity(self._symbol, Resolution.Minute)
def OnData(self, slice):
if slice[self._symbol] is None: return
self.lastPrice = slice[self._symbol].Close
price = str(self.lastPrice)
# self.Debug(price)
Here is the stack trace:
Runtime Error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform member binding on `null' value
at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object)
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet] (System.Runtime.CompilerServices.CallSite site, T0 arg0) [0x00127] in <63992662b765477a898ef49cdcc99ee2>:0
at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object)
at QuantConnect.BasicTemplateAlgorithm.OnData (QuantConnect.Data.Slice data) [0x00095] in <88556ecddcf344799948cd3cd676333b>:0
at QuantConnect.Lean.Engine.AlgorithmManager.Run (QuantConnect.Packets.AlgorithmNodePacket job, QuantConnect.Interfaces.IAlgorithm algorithm, QuantConnect.Lean.Engine.DataFeeds.IDataFeed feed, QuantConnect.Lean.Engine.TransactionHandlers.ITransactionHandler transactions, QuantConnect.Lean.Engine.Results.IResultHandler results, QuantConnect.Lean.Engine.RealTime.IRealTimeHandler realtime, QuantConnect.Lean.Engine.Server.ILeanManager leanManager, QuantConnect.Lean.Engine.Alpha.IAlphaHandler alphas, System.Threading.CancellationToken token) [0x01258] in <11f348cb016f463b86b03dce3a52e390>:0 (Open Stacktrace)
Derek Tishler
You may have luck with the github example repo; the basic template example there seems to create a Symbol object, _spy, using QuantConnect.Symbol.Create. If you emulate the attached example in this way, vs your use of a string, it might help get you closer to replicating the python code:
Specifically, replacing your definition of symbol with:
private Symbol _spy = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA);
From the looks of this example's OnData, the above edit should prevent the error you are seeing in OnData when trying to get the Price... I think.
Wriju Bhattacharya
Thanks for the feedback Derek. I updated my code to follow the examples but got the same results as before. The weird thing is it works for some datetime ranges and doesn't work for others.
Here's my updated C# code with hourly resolution and some extra logging:
namespace QuantConnect { public class BasicTemplateAlgorithm : QCAlgorithm { private Symbol _spy = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA); public override void Initialize() { SetStartDate(2014, 3, 20); SetEndDate(2014, 3, 21); SetCash(30000); AddEquity(_spy, Resolution.Hour); } public override void OnData(Slice data) { decimal price = data[_spy].Price; String debug = "OnData(" + _spy + "): [" + data[_spy].Time + "], price = " + Math.Round(price, 2); Debug(debug); } } }
And here's the output:
OnData(SPY): [3/20/2014 9:00:00 AM], price = 171.87 OnData(SPY): [3/20/2014 10:00:00 AM], price = 172.52 OnData(SPY): [3/20/2014 11:00:00 AM], price = 172.69 OnData(SPY): [3/20/2014 12:00:00 PM], price = 173.21 OnData(SPY): [3/20/2014 1:00:00 PM], price = 173.23 OnData(SPY): [3/20/2014 2:00:00 PM], price = 173.14 OnData(SPY): [3/20/2014 3:00:00 PM], price = 173.22 Runtime Error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform member binding on `null' value at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet] (System.Runtime.CompilerServices.CallSite site, T0 arg0) [0x00127] in <63992662b765477a898ef49cdcc99ee2>:0 at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object) at QuantConnect.BasicTemplateAlgorithm.OnData (QuantConnect.Data.Slice data) [0x00090] in <0b12aa04d49e4067a8fd17a685bbb098>:0 at QuantConnect.Lean.Engine.AlgorithmManager.Run (QuantConnect.Packets.AlgorithmNodePacket job, QuantConnect.Interfaces.IAlgorithm algorithm, QuantConnect.Lean.Engine.DataFeeds.IDataFeed feed, QuantConnect.Lean.Engine.TransactionHandlers.ITransactionHandler transactions, QuantConnect.Lean.Engine.Results.IResultHandler results, QuantConnect.Lean.Engine.RealTime.IRealTimeHandler realtime, QuantConnect.Lean.Engine.Server.ILeanManager leanManager, QuantConnect.Lean.Engine.Alpha.IAlphaHandler alphas, System.Threading.CancellationToken token) [0x01258] in <11f348cb016f463b86b03dce3a52e390>:0 (Open Stacktrace)
Wriju Bhattacharya
Found the issue (or workaround) - it's in the signature for OnData(). This signature works for all data points:
public void OnData(TradeBars data)
while this signature doesn't work for a select set of data points:
public override void OnData(Slice data)
I'm still learning the framework and am a newbie to C#, so not sure when one would be more appropriate over the other. But I'll be sticking with the first in the mean time
Jared Broad
Wriju Bhattacharya -- you need to check if the data is there before accessing the dictionary -- this is the case in all dictionaries including TradeBars. You cannot assume there is a price when the algorithm starts.
if (data.Bars.ContainsKey("AAPL")) {
use data.Bars["AAPL"]
}
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.
Wriju Bhattacharya
Thaks Jared! That fixed everything
Wriju Bhattacharya
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!