Hello eveyone,
We're trying to create a close-to-open indicator to use with a custom universe. We found the RateOfChange indicator, but that seems to be a close-to-close indicator,
So we tried creating a custom indicator for a close-to-open rate, but CoarseFundamental and IndicatorDataPoint seem to only have a Value property. Our understanding is that Value would be the last close value, but we're not clear as to whether that's the previous day's close, or the previous minute close if the universe resolution is set to a minute. If it's a minute close value, then presumably the difference between the last two minute close prices, if checked at 9:31 ET should yield the 9:30 AM close minus the 4:30 PM close from the previous day? If not, would there be a way to add an OpenPrice proptery to CoarseFundamental or IndicatorDataPoint?
Thanks.
Jared Broad
Can you subscribe to a universe of say the top 500 and find the Close to Open jumps you need? Do you need all 8k?
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.
Quantithmar
We have a couple of strategies, one based on top 500, the other on top 1500 average dollar volume, then picking the top 5 to 10 close-to-open gainers to monitor for the day--and the day only. When we tried calcluting the jump using the History object, the algorithm inevitably times out. We tried to manage the assets manually in the Universe and/or in the Securities collection with no luck: the algo would fail because it still kept attempting pipe certain data (e.g. dividends) to the assets we had manually removed to avoid the timeout. When using the RateOfChange indicator, the performance is leaps and bounds better--though still had to manually remove assets when running multi-long backtests to improve performance, and that worked brilliantly--but again couldn't figure out how to create an indicator for close-to-open gap. We'd be happy to post the code here if it helps--we should have the different versions saved somewhere.
Jared Broad
code of compiled algorithms last week which has improved memory performance
alot.
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.
Quantithmar
It didn't time out this time around, but it was very slow overall. It took 82 minutes for a 3-month-long backtest. Might be something we're doing wrong in the code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using QuantConnect.Data; using QuantConnect.Data.Market; using System.Diagnostics; using QuantConnect.Data.UniverseSelection; namespace QuantConnect.Algorithm.CSharp { class TopGainers : QCAlgorithm { private int _universeSize = 500, _trackerCount = 5; private List<QuantConnect.Securities.Security> _dailyTrackers = new List<QuantConnect.Securities.Security>(); /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2017, 08, 01); SetCash(100000); Schedule.On(DateRules.EveryDay(), TimeRules.At(9, 31), SelectStocks); //SetRunMode(RunMode.Parallel); UniverseSettings.Resolution = Resolution.Daily; AddUniverse(Universe.DollarVolume.Top(_universeSize)); Debug(Time.ToString()); } private void SelectStocks() { Dictionary<QuantConnect.Securities.Security, decimal> changes = new Dictionary<QuantConnect.Securities.Security, decimal>(); IEnumerable<Slice> slices = History(TimeSpan.FromDays(2), Resolution.Daily); foreach (var s in Securities) { var symbol = s.Value.Symbol; if (slices.Count() > 0 && s.Value.Price > 0) { IEnumerable<decimal> closingPrices = slices.Get(symbol, Field.Close); var previous = closingPrices.FirstOrDefault(); var gap = previous == 0 ? 0 : (s.Value.Price - previous) / previous; changes.Add(s.Value, gap * 100); } //Securities.Remove(symbol); //RemoveSecurity(symbol); //SubscriptionManager.Subscriptions.RemoveWhere(x => x.Symbol == symbol); } if (changes.Count > 0) { _dailyTrackers = changes.OrderByDescending(x => x.Value).Take(_trackerCount).Select(x => x.Key).ToList(); var _changes = changes.OrderByDescending(x => x.Value).Take(_trackerCount).Select(x => x.Value).ToList(); Debug(Time.ToShortDateString() + ": " + String.Join(", ", _dailyTrackers.Select(x => x.Symbol))); Debug("Gap: " + String.Join(", ", _changes)); } } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { } } }
In contrast, using the RateOfChange indicator (coupled with removing untracked securities, which has an sizable impact the longer the backtest period) as per below takes 25 seconds for the same period:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using QuantConnect.Data; using QuantConnect.Data.Market; using System.Diagnostics; using System.Collections.Concurrent; using QuantConnect.Indicators; using QuantConnect.Data.UniverseSelection; namespace QuantConnect.Algorithm.CSharp { class TopGainers : QCAlgorithm { private int _universeSize = 500, _trackerCount = 5; private readonly ConcurrentDictionary<Symbol, UniverseSelectionData> universeSelectionData = new ConcurrentDictionary<Symbol, UniverseSelectionData>(); /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetCash(100000); SetStartDate(2017, 08, 01); UniverseSettings.Resolution = Resolution.Minute; AddUniverse(coarse => { // define universe of top N stocks by dollar volume // while doing this, update our selection data to track // our rate of change per security var topDollarVolume = from c in coarse let data = universeSelectionData.GetOrAdd(c.Symbol, sym => new UniverseSelectionData(this, sym)) where data.Update(c) orderby c.DollarVolume descending select data; // now that we're ordered by dollar volume and have updated // our data for each security, take the top N by dollar volume // and then take the top M by rate of change return topDollarVolume.Take(_universeSize) .OrderByDescending(d => d.RateOfChange) .Take(_trackerCount) .Select(d => d.Symbol); }); Schedule.On(DateRules.EveryDay(), TimeRules.At(9, 31), SelectStocks); } private void SelectStocks() { var members = UniverseManager.SingleOrDefault(u => u.Key.Value == "QC-UNIVERSE-COARSE-USA").Value.Members; Debug(Time.ToShortDateString() + ": " + String.Join(", ", members.Select(x => x.Key))); foreach (var s in Securities) { if (members.Count(x => x.Key == s.Key) > 0 && s.Key.Value != "SPY") Securities.Remove(s.Key); } } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { } class UniverseSelectionData { public readonly Symbol Symbol; public readonly RateOfChange RateOfChange; public UniverseSelectionData(QCAlgorithm algorithm, Symbol symbol) { Symbol = symbol; RateOfChange = new RateOfChange("ROC-" + symbol, 2); } public bool Update(CoarseFundamental coarse) { return RateOfChange.Update(coarse.EndTime, coarse.Value); } } } }
Jared Broad
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.
Quantithmar
The algorithm isn't actually opening any positions since we haven't managed to get past the selection criteria, but here's the first backtest that took nearly 82 minutes that checks the price gap from History:
Quantithmar
And the one using the RateOfChange indicator:
Quantithmar
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!