Notice since overnight_returns are then positives and negatives, you could try feeding that directly to order_optimal_portfolio's MaximizeAlpha() and skip all the rest. If it doesn't go well, add a minus sign.
Full disclosure almost, I was messing around with your prior code ... didn't intend to post this and lazily using o twice, standing for order and overnight.
from quantopian.pipeline.filters import QTradableStocksUS
import quantopian.optimize as op
def initialize(context):
c = context
c.nullzone = .2
...
def mrkt_open(context, data):
''' short if the 'overnight returns' are positive and long otherwise, only for the best, worst n%
'''
c = context
if not c.portfolio.positions: return
cancel_orders(context, data)
# open today and the close of yesterday assumes run at 1 minute after open.
prices = data.history(c.portfolio.positions.keys(), 'price', 2, '1m')
onr = prices.pct_change().iloc[-1].dropna() # overnight_returns
if not len(onr): return
o = onr # for logging the difference
o = o[ (o > (o.max() * (c.nullzone * .5))) | (o < (o.min() * (c.nullzone * .5))) ]
log.info('{} {}'.format(len(onr), len(o)))
order_optimal_portfolio(
#objective = op.TargetWeights( o ),
objective = op.MaximizeAlpha( -o ),
constraints = [
op.PositionConcentration.with_equal_bounds(-.03, .03),
op.MaxGrossExposure(1.0),
op.Frozen( set(c.portfolio.positions.keys()) - set(o.index) ),
],)
def cancel_orders(context, data):
c = context
oos = get_open_orders()
for s in c.portfolio.positions:
if s in oos:
for o in oos[s]:
cancel_order(o.id)