I have some code that I use sometimes to log the details of what is happening minute by minute in my portfolio (mostly debugging my live trading algorithms when that was an option). There are two functions,
track_orders
and track_positions
:
2017-08-14 16:35 track_positions: H x 234 profit -1 (cost 57.10 close 57.10 open 57.06 high 57.10 low 57.05 vol 6410)
2017-08-14 16:35 track_positions: DY x 16 profit -4 (cost 85.19 close 84.94 open 84.94 high 84.94 low 84.94 vol 100)
2017-08-14 16:35 track_positions: EGRX x 70 profit -1 (cost 56.03 close 56.02 open 55.98 high 56.02 low 55.97 vol 1400)
2017-08-14 16:35 track_positions: PLCE x 20 profit -15 (cost 106.17 close 105.4 open 105.4 high 105.4 low 105.40 vol 100)
2017-08-14 16:35 track_positions: XEC x -25 profit -1 (cost 96.98 close 97.03 open 97.03 high 97.03 low 97.03 vol 100)
2017-08-14 16:35 track_orders: Open order PLCE -25/-45 shares, limit None, commission 1.00
2017-08-14 16:35 track_orders: Open order DY -25/-41 shares, limit None, commission 1.00
2017-08-14 16:35 track_orders: Filled order H 234/234 shares, limit None, commission 1.17
2017-08-14 16:35 track_orders: Filled order EGRX 70/70 shares, limit None, commission 1.00
2017-08-14 16:35 track_orders: Cancelled order XEC -25/-123 shares, limit None, commission 1.00
2017-08-14 16:36 track_positions: H x 234 profit -20 (cost 57.10 close 57.02 open 57.11 high 57.16 low 57.02 vol 16132)
2017-08-14 16:36 track_positions: DY x 16 profit nan (cost 85.19 close nan open nan high nan low nan vol 0)
2017-08-14 16:36 track_positions: EGRX x 70 profit 6 (cost 56.03 close 56.12 open 55.98 high 56.12 low 55.98 vol 1394)
2017-08-14 16:36 track_positions: XEC x -25 profit 1 (cost 96.98 close 96.94 open 97.06 high 97.06 low 96.94 vol 2006)
2017-08-14 16:36 track_orders: Open order DY -25/-41 shares, limit None, commission 1.00
2017-08-14 16:36 track_orders: Filled order PLCE -45/-45 shares, limit None, commission 1.00
Use the code like this:
def handle_data(context, data):
track_positions(context, data)
#
# Add your algorithm logic here
#
track_orders(context, data)
Here is the code:
def track_positions(context, data):
"""
Print information about current portfolio positions
"""
for sec, position in context.portfolio.positions.iteritems():
if data.can_trade(sec):
amount = position.amount
cost_basis = position.cost_basis
open,close,high,low,volume = data.current(sec, ['open','close','high','low','volume'])
profit = amount*(close-cost_basis)
log.info('Pos %-6s x %4d profit %.0f (cost %.2f close %.2f open %.2f high %.2f low %.2f volume %d, port.ret %.3f)' %
(sec.symbol,amount,profit,cost_basis,close,open,high,low,volume,context.portfolio.returns))
def track_orders(context, data):
"""
Print information about orders since last call to this function
"""
if 'orders' not in context:
context.orders = set()
for stock, orders in get_open_orders().iteritems():
for o in orders:
context.orders.add(o.id)
messages = []
to_delete = []
for id in context.orders:
if id is None:
to_delete.append(id)
continue
o = get_order(id)
m = 'order %s %d/%d shares, limit %s, commission %.2f' % (o.sid.symbol, o.filled, o.amount, str(o.limit), o.commission)
messages.append( (o.status,m) )
if o.status == 0: # open
continue
elif o.status == 1: # Filled
if o.amount != o.filled:
continue
elif o.status == 2: # Cancelled
pass
elif o.status == 3: # Rejected
pass
elif o.status == 4: # Held
log.warn(m)
continue
else:
log.warn("Unknown order status %d" % (o.status))
to_delete.append(o.id)
for id in to_delete:
context.orders.remove(id)
for status, m in sorted(messages, key=lambda t: t[0]):
if status == 0: m = 'Open ' + m
elif status == 1: m = 'Filled ' + m
elif status == 2: m = 'Cancelled ' + m
elif status == 3: m = 'Rejected ' + m
elif status == 4: m = 'Held ' + m
else: m = ('Unknown (%d) ' % status) + m
log.debug(m)