Back

Close-to-open indicator for custom universe

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.

Update Backtest








 

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?

0

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.


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.

0

Recommend retrying with top 500. We made a fundamental change to the byte

code of compiled algorithms last week which has improved memory performance

alot.
0

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.


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);
}
}
}
}
0

Please where possible attach backtest not code snippet
0

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.


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:

0


And the one using the RateOfChange indicator:

0


Update Backtest





0

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.


Loading...

This discussion is closed