Back

Ema Universe

https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/EmaCrossUniverseSelectionAlgorithm.py

I notice that if you go to the above example code and you look at the code in lines 96 and 97 a ema class is initialized without using the self notation. Thus far whenever I've wanted to use an indicator I would for example do the following : self.ema(symbol,duration, resolution). But from what I've seen you don't use self.ema when filtering your coarse universe. 

 

I've noticed here to initialize your ema class all you need is the duration and the naming convention is ExponentialMovingAverage as opppose to >>>> self.EMA. Lets say I wanted to look at other examples of indicators I could use without having to use the self notation where would I look ? I want to create a universe of sercurites where all of the securities have an adx reading above 30. 

 

Thanks. 

Update Backtest








First, let me explain the difference.
When you create an indicator using its constructor (e.g.: ExponentialMovingAverage), you get basis of a functional indicator. If you want to compute it, you need to manually update it like you can see in the mentioned algorithm.
On the other hand, when you can create an indicator with a helper method, it creates an indicator using the constructor and attach it to a consolidator for automatic updates. 

Where would you look? The docs! ;-)
In the Indicator section, there is a reference table with indicator constructor and the equivalent helper method.

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.


Thanks for the information.That being said I have another question, when updating the adx, what I'm trying right now is:

the_data = self.History(the_symbol,30,Resolution.Daily).

for bar in the_data:

       adx.update(bar)

 

From what I understand the tradebar should have all the information needed to update the indicator (open, high, low, close) ? The error message the compiler is throwing me is "I'm only passing two arguments". One of course being the object it's self, the other being the tradebar. Apparently I'm missing a third argument but the documentation says I'm suppose to only pass the tradebar :/.  I'm probably missing something obvious ; if so sorry, but help is much appreciated. Thanks. 

0

We cannot tell what the issue is with those code snippets...
Please checkout the attached example where I show how to create an ADX and update it with historical data.

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.


Sorry about that Alexandre, heres a backtest and I fixed the issue I was asking about previously, but now it seems I'm getting the following error message. >>This is a forward only indicator: Input: 2013-12-12 00:00:00Z Previous: 2013-12-31 00:00:00Z. 

I've created a try,except block to handle the exception and to simply pass when an exception is caught. That being said I bet you know a better solution. I've attached the backtest, apperciate any help. Thanks. 

Edit: Sorry it says no backtest are found(maybe because the error message caused the backtest to be classified as incomplete I guess) ableit here is the code. 

class EmaCrossUniverseSelectionAlgorithm(QCAlgorithm):

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2014,01,01)  #Set Start Date
        self.SetEndDate(2015,01,01)    #Set End Date
        self.SetCash(10000)           #Set Strategy Cash

        self.UniverseSettings.Resolution = Resolution.Daily
        self.UniverseSettings.Leverage = 1

        self.coarse_count = 10
        self.adx_readings = { }
        self.AddEquity('SPY',Resolution.Daily)
        self.spyma_200 = self.SMA('SPY',200,Resolution.Daily)
        
        self.spyma_50 = self.SMA('SPY',50,Resolution.Daily)
        # this add universe method accepts two parameters:
        # - coarse selection function: accepts an IEnumerable<CoarseFundamental> and returns an IEnumerable<Symbol>
        self.AddUniverse(self.CoarseSelectionFunction)


    # sort the data by daily dollar volume and take the top 'NumberOfSymbols'
    
    def CoarseSelectionFunction(self, coarse):

        stock_prices = sorted(coarse,key=lambda x:x.Price)
        stock_prices = filter(lambda x: x.Price <5,stock_prices)
        stock_prices = stock_prices[:5]
        for cf in stock_prices:
            if cf.Symbol not in self.adx_readings:
                self.adx_readings[cf.Symbol] = SymbolData(cf.Symbol)

            # Updates the SymbolData object with current EOD price
            adx = self.adx_readings[cf.Symbol]
            self.AddEquity(str(cf.Symbol.Value)).Symbol
            price_data = self.History(str(cf.Symbol.Value),14,Resolution.Daily)
            for bar in price_data:
                adx.update(bar)
            

        # Filter the values of the dict: we only want up-trending securities
        values = filter(lambda x: x.is_uptrend,self.adx_readings.values())

        # Sorts the values of the dict: we want those with greater difference between the moving averages
        values.sort(key=lambda x: x.trend_strength, reverse=True)

        for x in values[:self.coarse_count]:
            self.Log("working")
            self.Log('symbol: ' + str(x.symbol.Value) + '  scale: ' + str(x.trend_strength))
        
        # we need to return only the symbol objects
        return [ x.symbol for x in values[:self.coarse_count] ]
    
    # this event fires whenever we have changes to our universe
    def OnSecuritiesChanged(self, changes):
        # liquidate removed securities
        
        for security in changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol)

        # we want 20% allocation in each security in our universe
        for security in changes.AddedSecurities:
            if security.Symbol != 'SPY':
                self.SetHoldings(security.Symbol,0.05)


class SymbolData(object):
    def __init__(self, symbol):
        self.symbol = symbol
        self.trend =  AverageDirectionalIndex("",14)
        self.is_uptrend = False
        self.trend_strength = 0 

    def update(self,bar):
        if self.trend.Update(bar):
            self.trend_strength = self.trend.Current.Value
            self.is_uptrend = int(self.trend.Current.Value) > 30 and self.trend.PositiveDirectionalIndex
0

Since you are making a historical data request on every AddUniverse selector call to add new values to the ADX, you are adding older data to the indicator. In order to avoid that, you can reset it before a new update:

class SymbolData(object):
def __init__(self, symbol):
self.symbol = symbol
self.trend = AverageDirectionalIndex("",14)
self.is_uptrend = False
self.trend_strength = 0

def reset(self):
self.trend.Reset()

def update(self,bar):
if self.trend.Update(bar):
self.trend_strength = self.trend.Current.Value
self.is_uptrend = int(self.trend.Current.Value) > 30 and self.trend.PositiveDirectionalIndex

In the selector, you will call that new method as soon as possible:

adx = self.adx_readings[cf.Symbol]
adx.reset()
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.


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