Hello Weiyi and all,
I've pieced together an algorithm that handles the case of thinly traded securities. It also uses the built-in cost basis computation provided by Quantopian (nice). I have a few more tweaks, so I am posting it here for review before doing a separate post. Let me know what you think. Instead of logging the cost basis at every tic, I plan to modify the code so that it only writes it out when there is a change (buy/sell). Also, I'd like to see if I can capture the datetimes when the orders are actually fulfilled.
I can't get the "Add Backtest" function to work, so I've pasted the code below.
import numpy as np
def initialize(context):
#context.stocks = [sid(5729), sid(1637), sid(27558), sid(2190), sid(35920), sid(32146), sid(35902)]
context.stocks = [sid(41290),sid(41425),sid(39479),sid(33972),sid(41159)]
context.m = len(context.stocks)
context.basis = np.zeros(context.m)
context.bought = False
context.sold = [False]*context.m
context.sell_limit = 1.1 # relative price limit to submit sell order
def handle_data(context, data):
# record share prices at time of order fulfillment (0.0 if not yet fulfilled)
for i, stock in enumerate(context.stocks):
context.basis[i] = context.portfolio.positions[stock].cost_basis
log.info(context.basis)
# create numpy array of current security prices (0.0 if no tic)
current_prices = np.zeros(context.m) # set prices to 0.0
for i, stock in enumerate(context.stocks):
if stock in data:
current_prices[i] = data[stock].price
# submit sell order if relative security price reaches limit
if context.bought:
for i, stock in enumerate(context.stocks):
if context.basis[i] != 0.0 and current_prices[i] != 0.0:
relative_price = current_prices[i]/context.basis[i]
if relative_price >= context.sell_limit and context.sold[i] == False:
order(stock, -500)
context.sold[i] = True # switch flag if sell order submitted
log.info(context.sold) # output sold flags
# submit initial order of basket of securities
if not context.bought:
for i, stock in enumerate(context.stocks):
order(stock, 500)
log.info("500 share buy order submitted: " + str(stock))
context.bought = True