Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Stop loss simulator strategy
- - buys all stocks in universe that would not have been sold by a stop loss
- anchored on the worst possible entry price (aka trailing stop)
- """
- import datetime
- import sqlalchemy
- def initialize(context):
- """
- Called once at the start of the algorithm.
- """
- # parameters
- context.lookback_days = 251 # 1 year in trading days
- context.cutoff = 0.8 # -20% trail stop
- # state
- context.longs = []
- # Rebalance every day, 1 hour after market open.
- schedule_function(rebalance, date_rules.month_start()) #.week_start
- def rebalance(context, data):
- """
- Buy stocks with drawdown within lookback period less than VIX
- """
- # prices: timestamps rows * stock columns
- prices = data.history(context.stocks, 'price', context.lookback_days, '1d')
- # compute drawdown
- lastday = prices.index.max()
- lastprices = prices[lastday:lastday].max() # better way to extract a row?
- change_from_max = lastprices / prices.max()
- # keep things that would not be taken out by a stop loss
- winners = change_from_max[change_from_max > context.cutoff]
- context.longs = winners.index
- # and buy them all
- lotpc = 1.0 / len(context.longs)
- # sell stuff we don't want anymore
- assert len(get_open_orders()) == 0
- leavers = set(context.portfolio.positions) - set(context.longs)
- log.info('Rebalance {} stocks in, {} sold, out of {}'.format(len(context.longs), len(leavers), len(context.stocks)))
- for stock in leavers:
- order_target_value(stock, 0)
- # buy new stuff
- for stock in context.longs:
- assert data.can_trade(stock)
- order_target_percent(stock, lotpc)
- record(winners=len(winners), leavers=len(leavers))
- def before_trading_start(context, data):
- """
- Called every day before market open.
- """
- context.stocks = top_stocks()
- def top_stocks(count=500):
- """
- Find the top 'count' US stocks by market cap, approximating large cap indices
- """
- fundies_exchange = fundamentals.company_reference.primary_exchange_id
- stocks = get_fundamentals(
- query(fundamentals.valuation.market_cap)
- .filter(fundamentals.valuation.market_cap > 1e8) # 100m
- .filter(fundamentals.share_class_reference.is_primary_share == True)
- .filter(fundamentals.company_reference.country_id == "USA")
- .filter(sqlalchemy.or_(fundies_exchange == "NAS", fundies_exchange == "NYS"))
- .order_by(fundamentals.valuation.market_cap.desc())
- .limit(count),
- datetime.date.today())
- return stocks.transpose().index
Advertisement
Add Comment
Please, Sign In to add comment