"Stole" some other code from the community to test Market Open and Closes, trying to have my script initiate a biased position at open price which then initiates other orders if filled.
For this example, I put in an order to short at the open. If filled, it should then add to the short or cover some based on price moves, but no other orders should be placed until the original order is filled. init_order should contain the initial order object which gets created at Open. If filled, it should be set to None.
I have it logging to show me my open initial order, as well as my current position, which should signal when filled and then launch other orders. Somehow, my position changes while leaving the original order open. Any suggestions as to what I'm doing wrong?
import pytz
import zipline.finance.blotter as blotter
# Initialize the timezone:
EST = pytz.timezone('US/Eastern')
def initialize(context):
# In this example, I'm looking at AAPL (24).
context.UTCprev = None
context.stock = sid(24) #AAPL
context.max_notional = 0
context.min_notional = -3000
context.init_notional = -100
context.trade_notional = -50
context.init_order = None
context.init_order_id = 0
context.old_price = 0
def handle_data(context, data):
# timestamp of previous event (or None)
UTCprev = context.UTCprev
# timestamp of current event
UTCdate = get_datetime()
ESTdate = get_datetime().astimezone(EST)
price = data[context.stock].price
# day changed
if UTCprev and UTCprev.day <> UTCdate.day:
loginfo = '\n"prev" UTC: {} EST: {}'.format( UTCprev, UTCprev.astimezone(EST) )
loginfo +='\n"date" UTC: {} EST: {}'.format( UTCdate, ESTdate )
log.info( loginfo )
context.UTCprev = UTCdate
# test for market open by timestamp
if ESTdate.hour == 9 and ESTdate.minute == 31:
loginfo ='\n"Market Open" EST: {}'.format( ESTdate )
loginfo +='\ndaily opening pos of ' + str(context.portfolio.positions[context.stock].amount)
log.info( loginfo )
price = data[context.stock].open_price
context.old_price = price
loginfo = '\nplacing initial daily order to go short ' + str(context.init_notional) + ' shares at price ' + str(price)
log.info( loginfo )
# Placing initial order for day
context.init_order_id = order(context.stock, context.init_notional, limit_price=price)
context.init_order = get_order(context.init_order_id)
# Checking if initial order exists
if context.init_order is not None:
if context.init_order.status == blotter.ORDER_STATUS.OPEN:
log.info("Order {0} - Order amount: {1}, Fill amount: {2}".format(
context.init_order.sid,
context.init_order.amount,
context.init_order.filled))
log.info("Open order on {0} - Order amount: {1}, Fill amount: {2}".format(
context.init_order.sid,
context.init_order.amount,
context.init_order.filled))
log.info('\ncurrent pos of ' + str(context.portfolio.positions[context.stock].amount))
# This is where it should trigger subsequent orders when init order filled
elif context.init_order.status == blotter.ORDER_STATUS.FILLED:
log.info("Filled Order on {0} - Order amount: {1}, Fill amount: {2}".format(
context.init_order.sid,
context.init_order.amount,
context.init_order.filled))
loginfo = 'Placing an order of ' + str(context.trade_notional) + ' shares @ approx ' + str(price-.25)
loginfo += '\nand an order of ' + -str(context.trade_notional) + ' shares @ approx ' + str(price+.25)
order(context.stock, context.trade_notional, limit_price=price-.25)
order(context.stock, -context.trade_notional, limit_price=price+.25)
context.init_order = None
if context.init_order is None:
if price >= context.old_price +.25 and context.portfolio.positions[context.stock].amount < context.max_notional and context.portfolio.positions[context.stock].amount > context.min_notional:
log.info('placing limit order to increase short pos by 50 shares at price ' + str(price+.25))
order(context.stock, context.trade_notional, limit_price=price+.25)
log.info('placing limit order to cover 50 shares at price ' + str(price-.25))
order(context.stock, -context.trade_notional, limit_price=price-.25)
log.info('current pos of ' + str(context.portfolio.positions[context.stock].amount))
context.old_price = price
elif price <= context.old_price -.25 and context.portfolio.positions[context.stock].amount < context.max_notional and context.portfolio.positions[context.stock].amount > context.min_notional:
log.info('placing limit order to increase short pos by 50 shares at price ' + str(price+.25))
order(context.stock, context.trade_notional, limit_price=price+.25)
log.info('placing limit order to cover 50 shares at price ' + str(price-.25))
order(context.stock, -context.trade_notional, limit_price=price-.25)
log.info('current pos of ' + str(context.portfolio.positions[context.stock].amount))
context.old_price = price