Hello all:
I apologize for being such a raw beginner at this, but the code used in Quantopian seems to be changing quite quickly and as a beginner it is challenging to keep up. I have experience with FORTRAN, BASIC, and C as well as NinjaTrader and MetaTrader. I know more about the stock market than I do computers though. I see the power of the Pipeline API; it allows for automation not possible with other the above systems.
By watching this video: https://www.youtube.com/watch?v=BLJHuFGjBDg
I was able to put together a Pipeline screen that assembles a nice list of about 10 stocks with high EPS growth, profit margins, and market cap, as well as low debt.
I would like to buy the top ten stocks I produce in my Pipeline screen with 8% stop-losses and 25% profit targets if the RSI of the SPY falls below 30 and move the entire portfolio to cash if the RSI of the SPY rises above 70.
I found this RSI example that works well, but it only works with three coded stocks. I don't understand how to refer to the Pipeline I have created in the for loop that buys when the SPY RSI is below 30. https://www.quantopian.com/posts/simple-system
In the YouTube video the for loops reads:
for stock in context. top500.index:
In the Quantopian RSI example, with only the three coded stocks and no pipeline, the for loop reads:
for stock in context.stocks:
It appears to me that the method used in the YouTube video may be outdated, as I get runtime errors that direct me to this link:
https://www.quantopian.com/quantopian2/migration#data-history
Here is my code that is successfully building a nice looking list of stocks using Pipeline:
An algorithm that uses Pipeline to screen the ten $15+ stocks with highest EPS growth among those with debt near zero, market cap above $5 billion, and profit margins above 20%.
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
def initialize(context):
# Create and attach an empty Pipeline.
pipe = Pipeline()
attach_pipeline(pipe,'universe')
# Get EPS growth.
revenuegrowth = morningstar.earnings_ratios.diluted_eps_growth.latest
pipe.add(revenuegrowth, 'revenuegrowth')
# Get market cap.
marketcap = morningstar.valuation.market_cap.latest
pipe.add (marketcap, 'marketcap')
# Get debt to equity ratio.
debt = morningstar.operation_ratios.long_term_debt_equity_ratio.latest
pipe.add (debt, 'debt')
# Get price.
price = USEquityPricing.close.latest
pipe.add(price, 'price')
# Get profit margin.
profitmargin = morningstar.operation_ratios.normalized_net_profit_margin.latest
pipe.add (profitmargin, 'profitmargin')
# Screen for min $5B market cap, 25 EPS growth, no debt, $15+, 20%+ profit margin companies.
pipe.set_screen((marketcap > 5000000000) & (revenuegrowth > 0.25) & (debt < 0.05) & (price > 15) & (profitmargin > 0.20))
def before_trading_start(context, data):
context.output = pipeline_output('universe')
universe = context.output.fillna(0)
universe['sid'] = universe.index
universe['symbol'] = universe.sid.apply(lambda x: x.symbol)
universe = universe[universe.symbol.apply(lambda x: not x.endswith('_WI'))]
log.info(context.output.head(10))
Here is how I have attempted to integrate the sample RSI algorithm to buy the list of stocks created in my Pipeline when the RSI of the SPY falls below 30 and sell when it rises above 70. I haven't progressed to the point adding stop-losses and profit targets yet.
An algorithm that buys the ten $15+ stocks with highest EPS growth among those with
debt near zero, market cap above $5 billion, and profit margins above 20%.
import talib
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
def initialize(context):
# From 'Practice RSI Example'
context.stocks = symbols('SPY')
context.max_cash_per_stock = 100000.0 / len(context.stocks)
context.LOW_RSI = 30
context.HIGH_RSI = 70
# Create a variable to track the date change
context.date = None
# End 'Practice RSI Example' code
# Create and attach an empty Pipeline.
pipe = Pipeline()
attach_pipeline(pipe,'universe')
# Get EPS growth.
revenuegrowth = morningstar.earnings_ratios.diluted_eps_growth.latest
pipe.add(revenuegrowth, 'revenuegrowth')
# Get market cap.
marketcap = morningstar.valuation.market_cap.latest
pipe.add (marketcap, 'marketcap')
# Get debt to equity ratio.
debt = morningstar.operation_ratios.long_term_debt_equity_ratio.latest
pipe.add (debt, 'debt')
# Get price.
price = USEquityPricing.close.latest
pipe.add(price, 'price')
# Get profit margin.
profitmargin = morningstar.operation_ratios.normalized_net_profit_margin.latest
pipe.add (profitmargin, 'profitmargin')
# Screen for min $5B market cap, 25 EPS growth, no debt, $15+, 20%+ profit margin companies.
pipe.set_screen((marketcap > 5000000000) & (revenuegrowth > 0.25) & (debt < 0.05) & (price > 15) & (profitmargin > 0.20))
def before_trading_start(context, data):
context.output = pipeline_output('universe')
universe = context.output.fillna(0)
universe['sid'] = universe.index
universe['symbol'] = universe.sid.apply(lambda x: x.symbol)
universe = universe[universe.symbol.apply(lambda x: not x.endswith('_WI'))]
log.info(context.output.head(10))
# From 'Practice RSI Example'
def handle_data(context, data):
todays_date = get_datetime().date()
# Do nothing unless the date has changed
if todays_date == context.date:
return
# Set the new date
context.date = todays_date
cash = context.portfolio.cash
# Load historical data for the stocks
prices = history(15, '1d', 'price')
# Use pandas dataframe.apply to get the last RSI value
# for for each stock in our basket
rsi = prices.apply(talib.RSI, timeperiod=14).iloc[-1]
# Loop through our list of stocks
#Baffled by correct way to refer to the list of stocks created in Pipeline in this for loop.
for stock in context.universe.index:
current_position = context.portfolio.positions[stock].amount
# RSI is above 70 and we own shares, time to sell
if rsi[sid(8554)] > context.HIGH_RSI and current_position > 0:
order_target(stock, 0)
log.info('{0}: RSI is at {1}, selling {2} shares'.format(
stock.symbol, rsi[sid(8554)], current_position
))
# RSI is below 30 and we don't have any shares, time to buy
elif rsi[sid(8554)] < context.LOW_RSI and current_position == 0:
# Use floor division to get a whole number of shares
target_shares = cash // data[stock].price
order_target(stock, target_shares)
log.info('{0}: RSI is at {1}, buying {2} shares.'.format(
stock.symbol, rsi[sid(8554)], target_shares
))
# record the current RSI values of each stock
record(spy_rsi=rsi[symbol('SPY')])
# End 'Practice RSI Example' code
Can anyone help me? Being able to get this one under my belt would give me the tools I need to learn more. I would be forever grateful. Thanks so much!