Back

RSI + SMA strategy - stocks filtered with coarse universe

Hello all,

I have some problems with implementation of my strategy.
As I'm not experienced in programming and it's first time I deal with C#, could be that I've made some really basic mistakes.

Strategy description:
- filtering the stocks by coarse universe method (selecting stocks with price greater than 25 and volume greater than 500000),
- two indicators - simple moving average of highs and relative strength index,
- additional rolling window to store previous bar high and close values,
- all in minute bars resolution,
- long-only positions, investing 50% of capital per trade,
- going through stocks and buying when RSI lower than 5 AND previous bar high is under SMA of highs,
- sell when previous bar high crosses SMA of highs OR if 'take profit' 1% activated

Problems and questions:
1. Blocking point: I get the runtime error during backtest:
Runtime Error: Unable to create SPY Minute consolidator because SPY is registered for Daily data. Consolidators require higher resolution data to produce lower resolution data.
I guess that it's connected somehow with coarse universe selection, but I've no idea how to solve it.

2. Is my general approach for applying indicators for each of stocks from universe correct?

3. I didn't find anywhere definition of moving averages for highs, lows or volume.
Is my definition correct? How it will look like in case of volume - Field.Volume?
SMA(Stock.Symbol, hPeriods, Resolution.Minute, Field.High);
4. Is the rolling window the best option to get previous bar values?
RollingWindow lastMinute = new RollingWindow(1);
lastMinute.Add(data[Stock.Symbol]);

Or maybe would be better to implement History function.

5. If using rolling window, the last data from the window is the previous bar data or current bar data?
lastMinute[0].High
6. Regarding LimitOrder as it needs number of shares in integer argument - what is the best practice to get it automatically?
LimitOrder(Stock.Symbol, - Stock.Holdings.Quantity, takeProfit);
7. Is there search through codes published on forum possible? It's really hard to find any examples of some features implementation on forum. GitHub is working fine for that but there are not too many examples.


I will be really grateful for any help.
Some additional tips are also welcome.

Regards,
Andrzej Fudala
Update Backtest








1. This is happening you have a subscription to daily SPY (potentially added because it is the benchmark) and then you're trying to create a minute level SMA. Other thoughts, it looks like you're overwriting the value of hSMA in your loop. Indicators take time to 'warm up' and become ready. If you don't want to wait, use the History function to pass data into your indicators to warm them up.

2. You need to maintain separate variable for each stock. It looks like you overwrite your variables on each stock. Check out the link below in #4 referencing SymbolData.

3. Your definition is correct for the high. I can add a Field.Volume for the next deploy, for now you can use the following:SMA(Stock.Symbol, hPeriods, Resolution.Minute, x => ((TradeBar)x).Volume);
4. The rolling window is the best option, but you'll need a different one for each symbol. Maybe use a Dictionary> to make a map, or use the 'SymbolData' pattern to hold all the data for each symbol in your algorithm.

5. window[0] will always return the most recently added piece of data. window[1] will return the second most recently added data. You can use window.MostRecentlyRemoved to get the piece of data that just 'fell-off' the back of the window. Also, you can use window.IsReady to test if it is ready for use (full of data).

6. I'm not sure I understand your question. The code you posted will work for liquidating a security at a given price. If you're trying to open a new position you'll need to compute the number of shares manually.

7. I don't think the search currently searches through user code, but that is a cool idea! Github should be a pretty good source for examples of the various features. If you'd like a specific example you can submit an issue to Github, or post here with a question.
1

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.


First of all, many thanks for the feedback!
I'm few steps closer to make it working.

I've implemented this additional class DataSymbol for storing each universe stock values.
However, I don't know if I correctly initiated objects of this class for each universe stock.
During backtest I received following error:
Runtime Error: Sequence contains no elements (Open Stacktrace)

And I'm doing it like this:
foreach (var security in sChanges.AddedSecurities)
{
Data.Add(security.Symbol, new SymbolData(security.Symbol, this));
}


On the other hand, what happens when new stocks are added to the universe and how to assure SymbolData objects will be created for them?

And two questions regarding DataSymbol class itself.
Have I defined correctly Quantity variable?
Is the Close variable defined through Identity(symbol) the same what most actual price?

I'll appreciate any additional remarks.
0


Hi Andrzej

I've been working on this coarse universe selection as well. I'm doing similar similar stuff as you are - it seems to work if you do the data add in the " public override void OnSecuritiesChanged(SecurityChanges changes)" function

I've only been on quantconnect for a few days so if I made a mistake I apoligise.

Andrew
1

Thanks Andrew for the relevant remark!

I've added this piece of code:
public override void OnSecuritiesChanged(SecurityChanges changes)
{
sChanges = changes;
foreach (var removed in changes.RemovedSecurities)
{
if (removed.Invested)
{
Liquidate(removed.Symbol);
}
}

foreach (var added in changes.AddedSecurities)
{
Data.Add(added.Symbol, new SymbolData(added.Symbol, this));
}
}


But anyway still same error occurs:
Runtime Error: Sequence contains no elements (Open Stacktrace)

Has somebody idea what is the root cause of problem?
0


Hi again

While trying to sort out my problem I looked at yours again. It seemed to me that nothing was coming out of your " adduniverse" code - no idea if right.
So I added some Logs to to your OnSecurityChanged code. Nothing.
So added "Addsecurty ... SPY" and for whatever reason the adduniverse started to work????.

Then you get "Duplicate key error" - seen that before so you'll see the code I added to stop adding duplicate codes. I couldn't see a more elegant way other that the loop so if anyone has a better way I'm all ears (or eyes).

The Log report is useful - limited length though ??
1

Is this some kind of bug or do I need to somehow initialize SymbolData objects in Initialize section in order to prevent empty loop.
Adding a security makes it running but later I have these runtime errors of duplicating keys in dictionary or that data didn't load for the security I added by AddSecurity:

Runtime Error: An item with the same key has already been added.
No data loaded for SPY because there were no tradeable dates for this security.
0

Hey guys, sorry for the delay answering here. We looked into it and its the SetWarmup call that caused the "sequence contains no elements" issue you saw. We've fixed it here: https://github.com/QuantConnect/Lean/commit/13014c80ecf44a90d6ab6b808a613648170c37f0

You're seeing this "An item with the same key has already been added." because you're adding to the dictionary without checking if its already there e.g. foreach (var added in changes.AddedSecurities)
{
if (!Data.ContainsKey(added.Symbol)) Data.Add(added.Symbol, new SymbolData(added.Symbol, this));
}
1

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.


Hi Jared, no problem.
Thanks, but anyway I still have same error.. sequence contains no elements..
Should I add anything more to code or is this update not yet implemented in engine?
0

Correct its not in the engine yet, fix for today/tomorrow is remove SetWarmup or add at least 1 security to your algorithm.
2

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.


Quick question: How to get most easily the number of opened positions?
0

You can use the following to get a list of all currently open orders:List openOrders = Transactions.GetOpenOrders();
You can further filter the list if needed by other criteria using a Where clause:var spyOpenOrders = openOrders.Where(x => x.Symbol == "SPY").ToList();

EDIT: You can get the number of open using the following:var openOrdersCount = Transactions.GetOpenOrders().Count;
1

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.


In case of situation when many limit orders are placed, this is not sufficent.
Would be great if you will consider implementing some function in portfolio manager which returns number of opened positions on the market. Thanks anyway!
0

I think I misunderstood your request. I understood your request as open orders, not open positions. If you define an 'open' position has holding stock, then you can use something like the following:var securitiesWithHoldings = Securities.Values.Where(sec => sec.HoldStock).ToList();
This will return all Security objects that hold stock into a list. You can then use the Count property to check the total number of securities that currently have holdings. All of the data needed is in memory and available to your algorithm.

If I've still misunderstood your request, please provide a use case/scenario and maybe I can be of further assistance.
1

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.


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