Unless your algorithm has a single point of portfolio rebalancing (daily, weekly, monthly, whatever rebalancing) it is difficult to keep track of leverage, long and short exposure and long/short balancing.
Think of an algorithm that constantly scans a big universe of stocks looking for some events, at any minute of the day the algorithm might decide to enter some positions (long or short) or exit few others (again long or short). Once the algorithm finds an event, it needs to know if there is some cash available (given a target leverage) and it actually needs to know how much cash is available to enter long positions and how much for short positions (given a target percentage of long vs short exposure).
To properly handle the above scenario I wrote a class that, given a target leverage and a target short/long percentage exposure, it calculates at any time the following:
- the cash available for entering new positions, if any
- how much of the above cash should be used for long and how much for short positions
To use it:
def initialize(context):
# Define your targets at initialization: I want leverage 1.3 and 60%/40% Long/Short balance
context.exposure = ExposureMngr(target_leverage = 1.3,
target_long_exposure_perc = 0.60,
target_short_exposure_perc = 0.40)
def handle_data(context, data):
#
# update internal state (open orders and positions)
# Don't need to call this every minute, only when you call the methods below
#
context.exposure.update(context, data)
#
# After update is called, you can access the following information
#
# how much cash available for trading
context.exposure.get_available_cash(consider_open_orders = True)
# get long and short available cash as two distinct values
context.exposure.get_available_cash_long_short(consider_open_orders = True)
# same as account.leverage but this keeps track of open orders
context.exposure.get_current_leverage(consider_open_orders = True)
# sum of long and short positions current value
context.exposure.get_exposure(consider_open_orders = True)
# get long and short position values as two distinct values
context.exposure.get_long_short_exposure(consider_open_orders = True)
# get long and short exposure as percentage
context.exposure.get_long_short_exposure_pct(consider_open_orders = True, consider_unused_cash = True)
I really appreciate bug fixes and improvements. Also if you have a better idea on how to keep track of leverage and long/short exposure I'd like to know.
Attached an example algorithm: intraday mean reversion (trades every 20 minutes the best/worst performing securities in the last 90 minutes). It's just an example on how to use the class, it is not intended to be profitable