Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
New to Python/Quantopian - few questions on my algo

Hi - I am hoping that someone can help me overcome some of the issues I'm running into on my algo build. I am developing a system that leverages volatility. One key component to my system is an EWMA of volatility, leveraging weights built off lambda. The challenges that I'm running into are two-fold:

1) The lambda weights will be a list that is multiplied against another variable (x). This list of weights should be the length of the entire backtest period and the values of the weights are:

n0, (1-lambda_constant)*(lambda_constant)^0  
n1, (1-lambda_constant)*(lambda_constant)^1  
n2, (1-lambda_constant)*(lambda_constant)^2  
etc...  

How do I create this variable? Is there a way to create a variable based on the start bar and end bar and subtract the two to determine the length of the list? I was planning to create the weights using the function below where x is the length of a series indexed by the dates of the security's price:

        def lambda_val(x):  
            mylambda=somevalue  
            length=pd.Series((range(len(x))[::-1]))  
            list_length=length  
            constant_weight=(1-mylambda)+(list_length*0)  
            lambda_weight=mylambda+(list_length*0)  
            lambda_calc=constant_weight*(lambda_weight**list_length)  
            return lambda_calc  

The issue that I'm running into here is that on line 3 of the function above I am getting an error: Runtime exception: TypeError: object of type 'float' has no len(). However, x is a list of close prices within handle_data...so I'm confused as to why this isn't working. I think it has something to do with arguments passing through handle_data...

        close_price = data[stock].close_price  

In addition, I tried creating

2) Once I have a solve to create the lambda weight list, I need to turn this into a series or dataframe with a date index using the dates of the entire backtest. How do I pull the timestamp of the stock prices as a variable to pass through the dataframe such as index=data.index?

Again, the end goal in mind is to multiple the lambda weight list by another variable (x) to create new variable (y), which is what I will be using as a rolling average - or my EWMA.

Separately and on a side note - why would I use history(bar_count) on a backtest? Doesn't the backtest leverage the inputted dates that I assign for all calculations?

Sorry if this is an obvious answer, but thanks for your help!

9 responses

Hello Mark,

What are the n0, n1, n2, ... values above? Or are they just labels? There's probably an elegant way of doing the computation using numpy; I just wanted to make sure I understand that you are just using the n's as labels, and not something else.

Grant

Thanks Grant! Those are just labels. Think of them as the index of the output

Mark,

Here's a numpy example:

import numpy as np

def initialize(context):  
    context.spy = symbols('SPY')  
    context.n = 1  
def handle_data(context, data):  
    print getWeights(context.n)  
    context.n += 1

def getWeights(n):  
    lam = 0.1  
    l = lam*np.ones(n)  
    w = np.ones(n) - l  
    c = np.arange(n)  
    return np.multiply(w,np.power(l,c))  

The output is:

2015-01-05 PRINT [ 0.9]  
2015-01-06 PRINT [ 0.9 0.09]  
2015-01-07 PRINT [ 0.9 0.09 0.009]  
2015-01-08 PRINT [ 0.9 0.09 0.009 0.0009]  
2015-01-09 PRINT [ 9.00000000e-01 9.00000000e-02 9.00000000e-03 9.00000000e-04 9.00000000e-05]  

Based on the output, it appears to be working correctly.

I'm not clear on what you are trying to do, but note that Pandas has a built-in EWMA function. See:

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.stats.moments.ewma.html
http://pandas.pydata.org/pandas-docs/stable/computation.html

So, you might just store your volatility measure in a Pandas DataFrame and then apply the Pandas EWMA to it to smooth the data.

Grant

Note that post by Gary Hawkins was deleted. I am keeping this post, since it is germane.

Hello Gary,

I don't have time for a tutorial (and I'm no expert), but you might have a look at https://www.quantopian.com/posts/working-with-history-dataframes. Scott provides some guidance there, and I posted a simple algo to his thread that makes use of Pandas. If you have specific questions, you could revive the thread and post them there. Then Scott, Thomas, and others can respond, as well.

Grant

Grant - thanks for taking a stab at this! It looks like the np.ones function is not quite what I need. Let me try to explain again what I'm working on. My goal is to calculate an EWMA leveraging a decay of 0.94 to build weights. For example:

weight 0 = (1-0.94)(0.94)^0
weight 1 = (1-0.94)(0.94)^1
... weight 576 = (1.0.94)(0.94)^571

These weights will be multiplied by series-z to develop a new series of weighted values. The purpose of the weights is to put more weight on the more recent numbers in my formula. I will then take the simple moving average of this weighted series.

Is there a simple way to determine the # of bars in the backtest? I can then use this # in a range function to build my count for weights 0 through n for the exponent in my formula...

When I try x=len(context.stocks), it prints a value of 1 vs .the total length of stock data. The reason why I don't want to use the ones formula is because I only need one weight per date...it looks like one spits out multiple values per weight.

Hi Mark,
Can you use one of the Python package TA-Lib exponential moving average functions to calculate it directly? This package is available in Quantopian. Here is another post that has some example code for how to call it. https://www.quantopian.com/posts/ema-50-vs-100 Just go to the source code tab to see example usage.

Basically you can call it by doing: talib.EMA( timeseries, lookback_window)

There is also double, and triple exponential weighted moving averages available in this TA-Lib package.

You can also find info for all of the pre-built TA-Lib functions here if its helpful:
http://ta-lib.org/function.html

Disclaimer

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 Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian 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.

Thanks for the input Justin and the example...I will definitely look through it. The reason why I'm calculating manually is so that I can use my own decay rate to customize the weights...hence the EWMA vs. EMA

Is there a simple way to determine the # of bars in the backtest?

Mark,

In my example code above, the cumulative number of bars in the backtest is stored in context.n (assuming that you are not using the history API, which provides a trailing window of bar data at the backtest start).

Note that the weights become itsy bitsy looking back in time, so you don't need to accumulate a trailing window of every backtest bar. Your best approach will probably be to get the data via the history API and then apply a canned smoothing function (from Pandas, TA-Lib, etc.). If you need to apply your own custom smoothing routine, the Pandas rolling_apply is handy (see http://pandas.pydata.org/pandas-docs/stable/computation.html).

Grant

I'm making some progress here...hopefully you can help me in the final stages! So I have the following code:

        current_price = data[stock].price  
        close_series=pd.Series(current_price, index=prices.index)  
        length=np.array(range(len(close_series)))[::-1]  

I'm trying to create a count column for the entire length of the price history series with the most recent date beginning with "0". This is easy to do in ipython, but I think the datatype pulled from Quantopian is making the conversion from ipython to quantopian difficult. I'm going to use this count as the exponent in the ewma formula. When I print length, the results return:

2014-01-06PRINT[29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  
  4  3  2  1  0]  
2014-01-07PRINT[29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  
  4  3  2  1  0]  
2014-01-08PRINT[29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  
  4  3  2  1  0]  

The count is looking at 30 day containers within each datetime stamp. Why does the result not just show something like the below:

2014-01-06PRINT[29]  
2014-01-07PRINT[28]  
2014-01-08PRINT[27]  

I want one exponent per date because I need one weight per date (or bar). Hence, why I require the later vs. the former example.

Please let me know what I'm doing wrong!