Back to Community
What is wrong with position size?

There seems to be something wrong with the algo, when I add a criteria to cover a short position on close > ema AND high > Highest High of Past 15 days, the position size seems to go haywire? If I comment out the else if and high portion the algo seems to present more normal results. Anyone know what's going on here?

Clone Algorithm
21
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
import numpy as np
# To run an algorithm in Quantopian, you need two functions: 
# initialize and handle_data.
def initialize(context):
    # The initialize function sets any data or variables that 
    # you'll use in your algorithm. 
    # For instance, you'll want to define the security 
    # (or securities) you want to backtest.  
    # You'll also want to define any parameters or values 
    # you're going to use later. 
    # It's only called once at the beginning of your algorithm.
    
    # In our example, we're looking at Apple.  
    # If you re-type this line you'll see 
    # the auto-complete that is available for security. 
    context.security = symbol('VXX')

# The handle_data function is where the real work is done.  
# This function is run either every minute 
# (in live trading and minute backtesting mode) 
# or every day (in daily backtesting mode).
def handle_data(context, data):
    # We've built a handful of useful data transforms for you to use,
    # such as moving average. 
    
    # To make market decisions, we're calculating the stock's 
    # moving average for the last 5 days and its current price. 
    average_price = data[context.security].mavg(13)
    current_price = data[context.security].price
    high_price = data[context.security].high
    #prev_close = history(2, '1d', 'price').iloc[0]
    high_history = max(np.array(history(bar_count=15, frequency='1d', field='high')))
    
    #cash = context.portfolio.cash
    
     
    # Place the buy order (positive means buy, negative means sell)
    if current_price <  average_price:    
        # Need to calculate how many shares we can buy
        number_of_shares = int(100000/current_price)
        
        order(context.security, -number_of_shares)
        log.info("Shorting %s" % (context.security.symbol))
        log.info(number_of_shares)
        

    elif current_price > average_price and high_price > high_history:
        
        # Sell all of our shares by setting the target position to zero
        order_target(context.security, 0)
        log.info("Covering %s" % (context.security.symbol))
    
    # You can use the record() method to track any custom signal. 
    # The record graph tracks up to five different variables. 
    # Here we record the Apple stock price.
    record(stock_price=data[context.security].price)
There was a runtime error.
5 responses

The only thing I can think of is in the IF statement it is continuously shorting 10,000 worth every day the statement is true, therefore compounding the trade rather then just once when the criteria is true?

Hi Nakul,

The order_target methods don't check for open orders when they make their purchasing logic. Take a look at this thread for more details: https://www.quantopian.com/posts/order-target-percent-ordering-too-much

Cheers,
Alisa

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.

I have a CSV file with data going back to 2004. However when I run the algo, it only back tests from 2009 (this is when the security began to trade, the previous 5 years data are simulated). I assume it has something to do with context.security using the Quantopian data versus my CSV? Thanks!

Clone Algorithm
21
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
import numpy as np
import pandas


def has_position(context, asset):
    return asset in context.portfolio.positions

def initialize(context):
    #context.security = symbol('VXX')
    set_benchmark(symbol('VXX'))
    fetch_csv("https://dl.dropboxusercontent.com/u/283813251/VXX.csv", date_column='Date', date_format="%Y-%m-%d", symbol = 'VXX')
    
    context.security = symbol('VXX')
# The handle_data function is where the real work is done.  
# This function is run either every minute 
# (in live trading and minute backtesting mode) 
# or every day (in daily backtesting mode).
def handle_data(context, data):
    # We've built a handful of useful data transforms for you to use,
    # such as moving average. 
    #context.security = data['VXX']
    if 'Close' in data[context.security]:        
        record(VXX2004 = data[context.security]['Close'])
    
    
        
    average_price = data[context.security].mavg(13)
    #sma4 = data[context.security].mavg(4)
    #sma20 = data[context.security].mavg(20)
    current_price = data[context.security].price
    #high_price = data[context.security].high
    #prev_close = history(2, '1d', 'price').iloc[0]
    #high_history = max(np.array(history(bar_count=15, frequency='1d', field='high')))
    notional = context.portfolio.positions[context.security].amount * current_price
    
    cash = context.portfolio.cash
    
     
    # Place the buy order (positive means buy, negative means sell)
    if current_price < average_price and notional == 0:    
        # Need to calculate how many shares we can buy
        number_of_shares = int(cash/2/current_price)
        if has_orders(context,data):
            return
        else:
            order(context.security, -number_of_shares)
            log.info("Shorting %s" % (context.security.symbol))
            log.info(number_of_shares)
        

    elif current_price > average_price: # and high_price > high_history:
        #if (not has_position(context, data)):
         #   return
        # Sell all of our shares by setting the target position to zero
        #else:
            order_target(context.security, 0)
            log.info("Covering %s" % (context.security.symbol))
    
  
    #record(pos = context.portfolio.positions_value)
    
def has_orders(context,data):
    # Return true if there are pending orders.
    has_orders = False
    for sec in data:
        orders = get_open_orders(sec)
        if orders:
            for oo in orders:                  
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=sec)  
                log.info(message)

            has_orders = True
    return has_orders     
There was a runtime error.

Hi Nakul,

You're exactly right, the algorithm only starts the backtest beginning 2009 because that's when the stock began trading. Unfortunately, even if you have simulated data for the previous 4 years, you'll only be able to actually execute orders for when we have data for the stock. E.g. order(context.security).

Does that make sense? I can clarify a little more if it doesn't.

Seong

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.

That makes sense but then makes my data pretty worthless unfortunately. Back to excel i guess!