Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
'str' object has no attribute 'end_date'

I have the following error: 'str' object has no attribute 'end_date', in line 155. It was working util I changed the line 114 and I do not know how to inform the end_date. Could you help me? Thank you very much

import pipeline methods

from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline

import built in factors and filters

import quantopian.pipeline.factors as Factors
import quantopian.pipeline.filters as Filters
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.factors import CustomFactor
import quantopian.optimize as opt
from quantopian.pipeline.data import morningstar

import any datasets we need

from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import EquityPricing
from quantopian.pipeline.data import Fundamentals

from scipy.stats.mstats import winsorize
from sklearn import preprocessing

import numpy and pandas just in case

import numpy as np
import pandas as pd

WIN_LIMIT = 0.0

class Momentum(CustomFactor):
# Default inputs
inputs = [EquityPricing.close]

# Compute momentum  
def compute(self, today, assets, out, close):  
    out[:] = close[-1] / close[0]  

def preprocess(a):
a = np.nan_to_num(a - np.nanmean(a))
a = winsorize(a, limits=[WIN_LIMIT,WIN_LIMIT])
return preprocessing.scale(a)

class Piotroski(CustomFactor):
inputs = [
Fundamentals.roa,
Fundamentals.operating_cash_flow,
Fundamentals.cash_flow_from_continuing_operating_activities,
Fundamentals.long_term_debt_equity_ratio,
Fundamentals.current_ratio,
Fundamentals.shares_outstanding,
Fundamentals.gross_margin,
Fundamentals.assets_turnover,
]

    window_length = 100  

    def compute(self, today, assets, out,roa, cash_flow, cash_flow_from_ops, long_term_debt_ratio, current_ratio, shares_outstanding, gross_margin, assets_turnover):  

        profit = (  
                    (roa[-1] > 0).astype(int) +  
                    (cash_flow[-1] > 0).astype(int) +  
                    (roa[-1] > roa[0]).astype(int) +  
                    (cash_flow_from_ops[-1] > roa[-1]).astype(int)  
                 )  

        leverage = (  
                    (long_term_debt_ratio[-1] < long_term_debt_ratio[0]).astype(int) +  
                    (current_ratio[-1] > current_ratio[0]).astype(int) +  
                    (shares_outstanding[-1] <= shares_outstanding[0]).astype(int)  
                    )  

        operating = (  
                    (gross_margin[-1] > gross_margin[0]).astype(int) +  
                    (assets_turnover[-1] > assets_turnover[0]).astype(int)  
                    )  

        out[:] = preprocess(profit + leverage + operating)  

def initialize(context):
set_benchmark(symbol('SPY'))
# Create and attach pipeline to get data
attach_pipeline(my_pipeline(context), name='my_pipe')

# Rebalance monthly on the first day of the month at market open  
schedule_function(rebalance,  
                  #date_rule=date_rules.week_start(),  
                  date_rule=date_rules.month_start(),  
                  time_rule=time_rules.market_open())  
context.long_num = 20  

def my_pipeline(context):
base_universe = QTradableStocksUS()
piotroski = Piotroski()
momentum_1m = Momentum(window_length=22)
momentum_6m = Momentum(window_length=132)
momentum_2_6m = momentum_6m/momentum_1m

market_cap = Fundamentals.market_cap.latest  

return Pipeline(  
    columns = {  
        'momentum': momentum_2_6m,  
        'piotroski': piotroski > 1.7,  
        'market cap':market_cap  
        #'factor to analyze': factor_to_analyze  
    },  
    screen= base_universe & (market_cap > 4000000000) & (momentum_2_6m > 1)  

)  

def before_trading_start(context, data):
"""
Setting long positions.
"""
context.output = pipeline_output('my_pipe')

# List of long positions.  
context.longs = context.output.sort_values('momentum', ascending=False).iloc[:50]  

# Gathering weights from assign_weights().  
context.long_weight = assign_weights(context,data)  

def assign_weights(context,data):
"""
Assign weights to securities that we want to order.
"""
# Initialize empty target weights dictionary.
# This will map securities to their target weight.
weights = {}
# Set long weights.
if len(context.longs) > 0:
long_weight = 1.1 / len(context.longs)
#if long_weight > 0.05:
# long_weight = 0.05
log.info(long_weight)
else:
return weights
# Exit positions in our portfolio if they are not
# in our longs or shorts lists.
for security in context.portfolio.positions:
if security not in context.longs and data.can_trade(security):
weights[security] = 0

for security in context.longs:  
    weights[security] = long_weight  

return weights  

def rebalance(context,data):
today = get_datetime()
if today.month in [1]:
# It's January so just return
# Calculate target weights to rebalance
target_weights = assign_weights(context,data)

    if target_weights:  
        order_optimal_portfolio(  
            objective=opt.TargetWeights(target_weights),  
            constraints=[],  
        )

if today.month in [7]:  

    # It's January so just return  
    # Calculate target weights to rebalance  
    target_weights = assign_weights(context, data)  

    if target_weights:  
        order_optimal_portfolio(  
            objective=opt.TargetWeights(target_weights),  
            constraints=[],  
        )  

return  
2 responses

The issue actually starts with the following code in the assign_weights function.

    for security in context.longs:  
        weights[security] = long_weight  

Not sure if this was the intent, but 'context.longs' is a dataframe (from the pipeline) having three columns named 'momentum', 'piotroski', and 'market cap'. Using a for loop to iterate a dataframe as in the above code iterates over the column names. That is, the first pass security='momentum', the second security='piotroski', and the third security= 'market cap'. Probably not was intended. The intention was to iterate over the securities which are in the index. Therefore something like this is required

    for security in context.longs.index:  
        weights[security] = long_weight  

That should fix the error. Good luck.

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.

Fixed. Thank you very much!