Back

Universe filter not matching trade results

Hi there,

I am trying to use the Universe feature to apply some filters on the securities to trade. 
However when I test it out with a very simple filter, I already get some securities that should not go through. 

AddUniverse(coarse => {
return (from c in coarse
where c.Price < 30
orderby c.DollarVolume descending
select c.Symbol).Take(10);
});


Then in the event "OnSecuritiesChanged", I am performing a MarketOnOpenOrder on the Universe filtered Securities. 
 

foreach (Security security in changes.AddedSecurities)
{
MarketOnOpenOrder(security.Symbol, 100);
}



However in the traded securities I can see the following:
2011-05-03 00:00:00 C $43.55112507  MarketOnOpen Long Filled
2011-05-03 00:00:00 BAC $11.64248332 MarketOnOpen Long Filled
2011-05-01 00:00:00 SPY $119.889125334 MarketOnOpen Long Filled

Why did the universe catch those Equities for which the price is higher than 30? 
Is it a bug or did I miss something?
 

Update Backtest








Edit: sorry for Python code, that's all I have

 

I had the same problem, but found the solution. I might be wrong on some of this stuff but this is how I understand it:

Basically, the universe uses raw (non-adjusted) prices that don't take into account splits and some other factors. This isn't really an issue on recent backtests or live trading but it's a signifigant issue when you are looking far into the past. The solution to this is to add an additional price filter to your securities, outside of the universe function, based on history data which is adjusted.

def OnData(self, data):
# if we have no changes, do nothing
if not self.changes == SecurityChanges.None:
# liquidate removed securities
for security in self.changes.RemovedSecurities:
if security in self.stocks_long:
self.stocks_long.remove(security)
#Add securities to long list that meet our price criteria
for security in self.changes.AddedSecurities:
if not security in self.stocks_long:
history = self.History(security.Symbol, 1, Resolution.Daily)
if history.empty: continue
if (len(self.stocks_long) < 100) and (history['close'][0] <= self.PriceLimit):
self.stocks_long.append(security)
else:
pass
#self.RemoveSecurity(security.Symbol)
self.changes = SecurityChanges.None



# this event fires whenever we have changes to our universe
def OnSecuritiesChanged(self, changes):
self.changes = changes

2

Thanks! Great answer!
Could it be for the same reason explaining why I don't get the exact same results on historical data when I compare the prices between the backtest (few years in the past) with  "tradingview"?

0

A word of caution about using 'History' to check for absolute values like price. 

Lukel is correct that (as of this posting) the prices and volumes returned are adjusted values. However, they are adjusted with splits and dividends all the way forward in time to the current date.

Take stock XYZ that sold for $11 on 6/1/2015. That is the actual price one could buy it for on that date. (this is referred to as the 'raw' value in QC). Now assume there is a 2:1 stock split on 9/1/2016.

The course universe selection uses actual (ie 'raw') data. It will correctly filter any absolute values like 'price > 10'. However, the 'History' method returns adjusted values and includes splits that haven't even happened yet. It will include the future 2:1 split and return a price of $5.50 for stock XYZ on 6/1/2015 (which is clearly wrong). Filtering on these 'History' values like 'price > 10' would incorrectly filter out our XYZ stock.

I believe this 'bug' in the 'History' method is being addressed (

https://www.quantconnect.com/forum/discussion/1492/is-it-possible-to-get-historical-data-in-datanormalizationmoderaw

) but as of this posting, the only thing that History data should probably be used for is relative comparisons like percent change or simple directional (higher or lower) checks.

1

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