Robustness is a key quality of an algorithm. The algorithm should continue live trading, day over day, and handle any situation. Below is a list of tips that we've developed - keep these in mind as you're creating algos for the contest and fund!
The lucky 13 tips:
Use "context" instead of global variables to save state. This makes your algorithm more robust to starts/stops and correctly saves the state of variables. For example:
import pandas as pd timeperiod = 20 # don't use this syntax def initialize(context): context.timeperiod = 20 # use this instead
Use schedule_function to arrange the day/time for your orders and signals. Don't use a manual comparison. For example:
def initialize(context): schedule_function( # use this syntax func=myfunc, date_rule=date_rules.every_day(), time_rule=time_rules.market_open(minutes=1) ) def handle_data (context,data): if get_datetime().time()) == '9:31': # don't use this! pass
Use order_target functions instead of manually calculating the number of shares to buy. The algo shouldn't blindly buy/sell shares, but rather take existing positions into account.
Check for open orders before placing new orders using the target functions.
Add logging of intended orders (timing, symbols and order target size). This helps us monitor that the algo is behaving correctly, and was able to achieve its target positions.
Make sure algo is 'aware' of existing portfolio positions at deploy. The algo should handle starts/stops smoothly and pick up the correct positions.
Verify the algo will backfill any historical data needed to set initial parameters. The algorithm should begin trading immediately, without a warm-up period.
Use sid() instead of symbol() if hard-coding a list of securities. The sid() function is more robust to handling securities getting acquired and delisted. If you use symbol('ABC') in a live trading algo and the stock it acquired, your algo will stop trading.
Give your algorithm time to place its trades. Don't trade 1 minute before market close; try trading at 3:45PM or a VWAPBestEffort to place trades over a specific time period.
If your algo is pair trading, think about pending orders and failed orders. How will your algo react if one of the legs can't be ordered? Or if the position can't be fully reached? Have a check that if target positions aren't met after X time (3 min? 5 min?), close the pair.
Don't use deprecated functions in your algo (ie use history instead of batch_transform).
Protect yourself against bad data prints. Our data vendor, like all data vendors, sometimes passes us bad data. Those bad prints might cause an algorithm to place a trade that it shouldn't, or skip a trade that it would otherwise have made. Check if a price is outside of an interval - for example 10 standard deviations - before acting on the signal.