Skip to content

Instantly share code, notes, and snippets.

@HumanRupert
Last active June 11, 2021 14:01
Show Gist options
  • Save HumanRupert/ce45d2bc7c020a523da8a7d7c9bb2bc2 to your computer and use it in GitHub Desktop.
Save HumanRupert/ce45d2bc7c020a523da8a7d7c9bb2bc2 to your computer and use it in GitHub Desktop.
def handle_data(context, data):
current_dt = zp.api.get_datetime()
prices = data.history(context.stocks, "price", bar_count=200, frequency="1d")
# look for new trades
for ix, pattern in context.patterns.iterrows():
# skip if asset is already in portfolio
open_positions = set(context.portfolio.positions.keys())
symbol = zp.api.symbol(pattern["symbol"])
is_open = symbol in open_positions
if(is_open): continue
# check date window from handleLowDate to N days after
is_in_window = (pattern["handleLowDate"] <= current_dt) and (pattern["handleLowDate"] >= (current_dt - pd.DateOffset(WATCHLIST_WINDOW_DAYS)))
if (not is_in_window): continue
# get symbol and price history
price_history = prices[symbol]
# check price above pivot
pivot_price_date = pattern["pivotPriceDate"]
try:
pivot_price = price_history[pivot_price_date]
except KeyError:
pivot_price = None
current_price = data.current(symbol, "price")
if(current_price / pivot_price < ABOVE_PIVOT_PCT): continue
# check short MA above long MA
short_ma = price_history.tail(SHORT_MA_LEN).mean()
long_ma = price_history.tail(LONG_MA_LEN).mean()
if(long_ma > short_ma): continue
# add new position and update previous ones
open_positions.add(symbol)
target_pct = 1 / len(open_positions)
for position in open_positions:
zp.api.order_target_percent(position, target_pct)
context.position_dates[symbol] = current_dt
# look for closing positions
open_positions = context.portfolio.positions
for position in open_positions.values():
current_price = position.last_sale_price
buy_price = position.cost_basis
should_take_profit = (current_price / buy_price) > TAKE_PROFIT_PCT
should_stop_loss = (current_price / buy_price) < STOP_LOSS_PCT
does_exceed_patience = (current_dt - pd.DateOffset(PATIENCE_WINDOW_DAYS)) >= context.position_dates[position.asset]
should_close_position = should_take_profit or does_exceed_patience or should_stop_loss
if(should_close_position): zp.api.order_target_percent(position.asset, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment