Hello, I receive this error message. Do't know how to add the data.

Failed to initialize algorithm: Initialize(): System.InvalidOperationException: Please implement GetSource(SubscriptionDataConfig, DateTime, bool) on your custom data type: CustomUniverse

Trying to implement this strategy:

 Scan stocks for which the following conditions are true:

       50-day SMA of SPY is above the 200-day SMA of SPY

       20-day SMA of stock price is above the 50-day SMA of price
       Buy when 
         Price has just crossed up through the eight-day SMA of the High.

       Close when 
         Price has just crossed down through the eight-day SMA of the Low.

 

What is the best way to implement this strategy? 

- Select stocks based on MovingAverages Crossing Overs (EMA20 > EM50)

- Buy if Close crosses ove SMA 8-day of Highs

Sell if Close crosses under SMA 8-day of Lows

Current code which causes an exception is atteched.

Help would be appreciated.

Ulrich

using System.Collections.Concurrent; //using System.Linq; //using QuantConnect.Data.Market; //using QuantConnect.Data.UniverseSelection; /* In the Initialize() method set the fee model AddSecurity(SecurityType.Equity."SPY"); Securities["SPY"].TransactionModel = new ConstantFeeTransActionModel(1); */ namespace QuantConnect { /* Scan stocks for which the following conditions are true: Price is above its 50-day average (SMA) 20-day SMA of price is above the 50-day SMA of price 50-day SMA of price is above the 200-day SMA of price 50-day average volume is greater than one million shares Buy when Price has just crossed up through the eight-day SMA of the High. Close when Price has just crossed down through the eight-day SMA of the Low. */ public class UW_SimpleStrategy : QCAlgorithm { private Symbol Universe = QuantConnect.Symbol.Create("LONG", SecurityType.Equity, Market.USA); //Define required variables: int quantity = 0; decimal price = 0; decimal tolerance = 1m; //0.1% safety margin in prices to avoid bouncing. string symbolStr = "SPY"; DateTime sampledToday = DateTime.Now; int number_in_Securities=0; const decimal Tolerance = 0.01m; bool BullMarket = false; private SecurityChanges _changes = SecurityChanges.None; private const decimal TargetPercent = 0.1m; private readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>(); private ExponentialMovingAverage ema_50; class CustomUniverse : BaseData { public Symbol Symbol; // Asset symbol public decimal Open; // Yesterday open price public decimal High; // Yesterday high price public decimal Low; // Yesterday low price public decimal Price; // Yesterday close price public decimal DollarVolume; // Traded shares x Price public long Volume; // Traded shares } // class used to improve readability of the coarse selection function private class SelectionData //------------------------------------------------------------------- { public readonly ExponentialMovingAverage Fast; public readonly ExponentialMovingAverage Slow; public readonly SimpleMovingAverage hSMA; public readonly SimpleMovingAverage lSMA; public SelectionData() { Fast = new ExponentialMovingAverage(50); Slow = new ExponentialMovingAverage(200); hSMA = new SimpleMovingAverage(8); //SMA(security.Symbol, 8, Resolution.Daily, Field.High); lSMA = new SimpleMovingAverage(8); // SMA(security.Symbol, 8, Resolution.Daily, Field.Low); } // computes an object score of how much large the fast is than the slow public decimal ScaledDelta { get { return (Fast - Slow)/((Fast + Slow)/2m); } } // updates the EMA50 and EMA100 indicators, returning true when they're both ready public bool Update(DateTime time, decimal value) { return Fast.Update(time, value) && Slow.Update(time, value); } // updates the SMA indicators, returning true when they're both ready public bool Update_SMA(DateTime time, decimal value1, decimal value2) { return hSMA.Update(time, value1) && lSMA.Update(time, value2); } // returns uptrend or downtrend for stocks public bool StockTrend(bool SpyTrend) { if (SpyTrend) return Fast > Slow*(1 + Tolerance); else return Fast < Slow*(1 + Tolerance); } } // end of class //Initialize the data and resolution you require for your strategy: public override void Initialize() { SetStartDate(2014, 01, 01); SetEndDate(DateTime.Now); SetCash(25000); // Subscriptions added via universe selection will have this resolution UniverseSettings.Resolution = Resolution.Daily; // Take the top 50 by dollar volume using coarse // AddUniverse(Universe.DollarVolume.Top(50)); AddSecurity(SecurityType.Equity,"SPY",Resolution.Daily); ema_50 = EMA("SPY", 50, Resolution.Daily); BullMarket = ema_50 > Securities["SPY"].Close; // if (ema_50.IsReady) Debug ("\n+Init:" + " Ema50=" + ema_50.ToString() + " Close=" + Securities["SPY"].Close.ToString()); AddUniverse <CustomUniverse>("my-custom-universe", Resolution.Daily, data => { Debug("in AddUniverse"); return from cLong in data let bar = new TradeBar(Time, cLong.Symbol, cLong.Open, cLong.High, cLong.Low, cLong.Price, cLong.Volume, TimeSpan.FromDays(1))//Resolution.Daily) let selector = _averages.GetOrAdd(cLong.Symbol, sym => new SelectionData()) where cLong.Price > 10 // Update returns true when the indicators are ready, // so don't accept until they are where selector.Update(cLong.EndTime, cLong.Price) where selector.Update_SMA(cLong.EndTime, cLong.High, cLong.Low) // only pick symbols who have their 50 day ema // over their 100 day ema where selector.Fast > selector.Slow*(1 + Tolerance) // Exclude SPY where cLong.Symbol.ToString() != "SPY" // price crossed over 8-day SMA of Low where cLong.Price > selector.lSMA orderby cLong.Volume descending select cLong.Symbol; }); } // end Initialize //Handle TradeBar Events: a TradeBar occurs on every time-interval public void OnData(TradeBars data) { int i=0; //Debug(Time.ToShortDateString() + " trace -1"); if (number_in_Securities != _changes.AddedSecurities.Count) { Debug(Time.Date.ToShortDateString() + " Number=" + _changes.AddedSecurities.Count.ToString() ); number_in_Securities = _changes.AddedSecurities.Count; } //One data point per day: // if (data.ContainsKey(symbolStr)) //if (sampledToday.Date == data[symbolStr].Time.Date) return; //Only take one data point per day (opening price) //price = Securities[symbolStr].Close; // sampledToday = data[symbolStr].Time; // Debug(Time.ToShortDateString() + " SPY Close= " + price.ToString()); // we'll simply go long each security we added to the universe foreach (var security in _changes.AddedSecurities) { i++; //SetHoldings(security.Symbol, TargetPercent); //if (i < 30) if (Time.Date == new DateTime(2017,10,21) ) Debug("Symbol= " + Time.ToShortDateString() + " " + security.Symbol.ToString()); if (Time.Date > new DateTime(2017,10,14) && Time.Date < new DateTime(2017,10,21)) Debug(Time.ToShortDateString() + " trace 1 " + security.Symbol.ToString()); //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio. decimal cash = Portfolio.Cash; int holdings = (int)Portfolio[security.Symbol].Quantity; //quantity = Convert.ToInt32((cash * 0.5m) / price); quantity = 3; if (holdings > 0 || holdings == 0) { //If we're long, or flat: check if closed crossed under 8-day SMA Low: // if (security.Close < (hSMA * (1-tolerance)) ) { //Now go short: Short-EMA signals a negative turn: reverse holdings Order(security.Symbol, -(holdings + quantity)); Log(Time.Date.ToShortDateString() + " > Go Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " ); Debug(Time.Date.ToShortDateString() + " > Go Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " ); } } else if (holdings < 0 || holdings == 0) { //If we're long, or flat: check if closed crossed over 8-day SMA High: // if ( security.Close > (lSMA * (1+tolerance))) { //Now go long: Short-EMA crossed above long-EMA by sufficient margin Order(security.Symbol, Math.Abs(holdings) + quantity); Log(Time.Date.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " ); Debug(Time.Date.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " ); } } } } /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="changes">Object containing AddedSecurities and RemovedSecurities</param> public override void OnSecuritiesChanged(SecurityChanges changes) { BullMarket = ema_50 > Securities["SPY"].Close; _changes = changes; } //public override void OnEndOfDay() { // if (!lSMA.IsReady) return; // Plot("lSMA", lSMA); // Plot("hSMA", hSMA); //} } }

Author