Back to Community
New Feature: Symbol() to Reference Securities

We’ve just introduced a new way to reference securities in your algorithm: symbol. You can now reference securities using their ticker!

We had a preview release a few months ago and got great feedback. Read more about the details here.

Below are the new methods:

  • symbol() takes a symbol string and returns a security.
    Example: symbol('ba')
  • symbols() creates a list of multiple securities. Each ticker is a string.
    Example: symbols('amzn', 'yhoo')
  • set_symbol_lookup_date() is used to differentiate between companies that have used the same ticker, since exchanges recycle tickers as companies get delisted and new companies form. This is an optional field and should be called before your symbol() or symbols() function.

Attached below is an example of the new function using a long-only tech portfolio that re-balances every 30 days. For more information on symbols, take a look at the help documentation. We’re always excited to release new features and we’re eager to hear your feedback.

Clone Algorithm
67
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
''' 
    This algorithm defines a target long-only diversified tech portfolio and rebalances 
    every 30 days.
'''

import datetime
import pytz
import pandas as pd
from zipline.utils.tradingcalendar import get_early_closes

def initialize(context):
    # Define the securities in the portfolio:
    set_symbol_lookup_date('2008-01-01')
    context.stocks = symbols('amzn', 'csco', 'yhoo', 'msft', 'g')
    
    # Define the benchmark (used to get early close dates for reference).
    context.spy           = sid(8554)
    
    start_date = context.spy.security_start_date
    end_date   = context.spy.security_end_date
    
    # Initialize context variables the define rebalance logic:
    context.rebalance_date = None
    context.next_rebalance_Date = None
    context.rebalance_days = 30
    
    # Get the dates when the market closes early:
    context.early_closes = get_early_closes(start_date, end_date).date

    set_commission(commission.PerTrade(cost=1))

def handle_data(context, data):
    # Get the current exchange time, in local timezone: 
    exchange_time = pd.Timestamp(get_datetime()).tz_convert('US/Eastern')
    
    # If it is rebalance day, rebalance:
    if context.rebalance_date == None or exchange_time >= context.next_rebalance_date:
       # If we are in rebalance window but there are open orders, wait til next minute
       if has_open_orders(data,context) == True:
            log.info('Has open orders, not rebalancing.')
       else:
           # If there are no open orders we can rebalance.
           rebalance(context, data, exchange_time) 
           log.info('Rebalanced portfolio to target weights at %s' % exchange_time)

           # Update the current and next rebalance dates
           context.rebalance_date = exchange_time 
           context.next_rebalance_date = context.rebalance_date + datetime.timedelta(days=context.rebalance_days)      
           print(context.next_rebalance_date)

#Rebalance to equal weights in portfolio
def rebalance(context,data,exchange_time):    
    for symbol in context.stocks:
        if symbol in data:
            order_target_percent(symbol, 1.0 / len(context.stocks))

def has_open_orders(data,context):               
    # Only rebalance when we have zero pending orders.
    has_orders = False
    for stk in data:
        orders = get_open_orders(stk)
        if orders:
            for oo in orders:                  
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=stk)  
            has_orders = True
    return has_orders           
There was a runtime error.
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.