Back to Community
Sell after a given time interval

Dear all,

First I would like to say that I enjoy quantopian very much. I think it is a fascinating idea and the implementation of the IDE and backtester is very well done!

I am new to algorithmic trading and I have some basic questions about pitfalls, in particular in the light of global variables.

I would like to design an algorithm that buys stocks, holds them for a given fixed time and then sells them. This means, a function will decide at the point the item is bought also the time it is sold.

I have attached a template which illustrates how I imagine this could be done, but I would be interested in possible better ways of doing this. In particular, I have to introduce a global variable which keeps track of all the stock that is in the portfolio with a date when to sell it.

Are there any concerns using global variables for such long running jobs? Is there a built in global variable that I should use instead? The goal is live trading - is there any pitfalls with this approach?

best regards
Wolfgang

Clone Algorithm
18
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 datetime

# a global variable is defined to store the dates at which stocks should be sold. 
globaldata = {}

def initialize(context):
    context.security = symbol('AAPL')
    # this dictionary uses sid as key and stores either: -1 which means we don't own any of it,
    # or a date at which it should be sold.
    globaldata[context.security.symbol] = -1
    
def handle_data(context, data):
    # This is a possible template for an algorithm which buys at a given date
    # and sells after a given time. These calculations will be done in the function
    # analyse(sid) which gives back the number of days after which sid should be sold.
    
    exchange_time = get_datetime()
    # if we don't have it already, we may buy 
    if globaldata[context.security.symbol] == -1:
        #analyse does all the work in deciding whether sid should be bought and when to sell it
        buynow,percentage,sellafter = analyse(context.security.symbol)
        if buynow:
            order_percent(context.security, percentage)
            globaldata[context.security.symbol] = exchange_time +  datetime.timedelta(days=sellafter)   
    else:
    # if we do have sid lets see if its time to sell it.     
        if exchange_time > globaldata[context.security.symbol]:
            order_target(context.security, 0)
            globaldata[context.security.symbol] = -1
            
    
    record(stock_price=data[context.security].price)
    
    

def analyse(sid):
    # This function will contain the analysis of the current market situation.
    # It returns three values:
    # boolean buynow : should we buy the stock sid now
    # float percentage : how much should we buy
    # int sellafter: sell it after a fixed number of days
    
    #for illustration this is set to constants
    return True,0.5,50


    
There was a runtime error.
2 responses

To my knowledge maintaining state in a global collection is the only way to manage conditional changes over time. I would point out that using a fixed number of periods would give you a calendar based offset which would not reflect actual trading periods transpired. 50 days calendar would end up being perhaps only 35 days trading. Incrementing or decrementing a state counter would give you a more accurate trading periods lapsed count.

If you are using a period count exit for testing of "edge" then you would want to use actual trading period counts and not calendar durations.

Hi Wolfgang,

Is there a reason that you're using a global variable versus 'context'? Here's an example with context

import datetime

def initialize(context):  
    context.security = symbol('AAPL')  
    # this dictionary uses sid as key and stores either: -1 which means we don't own any of it,  
    # or a date at which it should be sold.  
    context.global_data = {context.security.symbol : -1}  
def handle_data(context, data):  
    # This is a possible template for an algorithm which buys at a given date  
    # and sells after a given time. These calculations will be done in the function  
    # analyse(sid) which gives back the number of days after which sid should be sold.  
    exchange_time = get_datetime()  
    # if we don't have it already, we may buy  
    if context.global_data[context.security.symbol] == -1:  
        #analyse does all the work in deciding whether sid should be bought and when to sell it  
        buynow,percentage,sellafter = analyse(context.security.symbol)  
        if buynow:  
            order_percent(context.security, percentage)  
            context.global_data[context.security.symbol] = exchange_time +  datetime.timedelta(days=sellafter)  
    else:  
    # if we do have sid lets see if its time to sell it.  
        if exchange_time > context.global_data[context.security.symbol]:  
            order_target(context.security, 0)  
            context.global_data[context.security.symbol] = -1  

    record(stock_price=data[context.security].price)  


def analyse(sid):  
    # This function will contain the analysis of the current market situation.  
    # It returns three values:  
    # boolean buynow : should we buy the stock sid now  
    # float percentage : how much should we buy  
    # int sellafter: sell it after a fixed number of days  
    #for illustration this is set to constants  
    return True,0.5,50  
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.