Skip to content

Commit

Permalink
Merge eb93c60 into 65c038d
Browse files Browse the repository at this point in the history
  • Loading branch information
jlowin committed Jan 28, 2015
2 parents 65c038d + eb93c60 commit 53a03e7
Showing 1 changed file with 95 additions and 7 deletions.
102 changes: 95 additions & 7 deletions zipline/algorithm.py
Expand Up @@ -861,16 +861,87 @@ def data_frequency(self, value):
assert value in ('daily', 'minute')
self.sim_params.data_frequency = value

def get_market_value(self, mv_type=None, filter_fn=None):
"""
Returns the requested market value.
Options for mv_type are:
portfolio (default): net portfolio value
cash: available cash
ex-cash: net invested capital, ex-cash
longs: long invested capital
shorts: short invested capital
Alternatively, a filter_fn can be supplied. The filter_fn
should accept a Position and return True if that Position's
market_value should be included in the total and False otherwise.
"""
# first try the filter_fn, if supplied
if filter_fn is not None:
mv = sum(
p.amount * p.last_sale_price
for p in self.portfolio.positions.values()
if filter_fn(p))

# net portfolio value
elif mv_type is None or mv_type == 'portfolio':
mv = self.portfolio.portfolio_value

# portfolio cash
elif mv_type == 'cash':
mv = self.portfolio.cash

# net invested capital
elif mv_type == 'ex-cash':
mv = self.portfolio.portfolio_value - self.portfolio.cash

# long invested capital
elif mv_type == 'longs':
mv = sum(
p.amount * p.last_sale_price
for p in self.portfolio.positions.values()
if p.amount > 0)

# short invested capital
elif mv_type == 'shorts':
mv = sum(
p.amount * p.last_sale_price
for p in self.portfolio.positions.values()
if p.amount < 0)

else:
raise ValueError(
'Unrecognized value for "mv_type": {}'.format(mv_type))

return mv

@api_method
def order_percent(self, sid, percent,
limit_price=None, stop_price=None, style=None):
limit_price=None,
stop_price=None,
style=None,
percent_of=None,
percent_of_fn=None):
"""
Place an order in the specified security corresponding to the given
percent of the current portfolio value.
percent of some market value. If no market value is specified (via
`percent_of`) then the net portfolio value is used.
Options for percent_of are:
portfolio (default): net portfolio value
cash: available cash
ex-cash: net invested capital, ex-cash
longs: long invested capital
shorts: short invested capital
Alternatively, a percent_of_fn can be supplied. The percent_of_fn
should accept a Position and return True if that Position's
market_value should be included in the total and False otherwise.
Note that percent must expressed as a decimal (0.50 means 50\%).
"""
value = self.portfolio.portfolio_value * percent
mv = self.get_market_value(mv_type=percent_of, filter_fn=percent_of_fn)
value = percent * mv
return self.order_value(sid, value,
limit_price=limit_price,
stop_price=stop_price,
Expand Down Expand Up @@ -924,17 +995,34 @@ def order_target_value(self, sid, target,

@api_method
def order_target_percent(self, sid, target,
limit_price=None, stop_price=None, style=None):
limit_price=None,
stop_price=None,
style=None,
percent_of=None,
percent_of_fn=None):
"""
Place an order to adjust a position to a target percent of the
current portfolio value. If the position doesn't already exist, this is
Place an order to adjust a position to a target percent of some market
value. If no market value is specified (via `percent_of`) then the net
portfolio value is used. If the position doesn't already exist, this is
equivalent to placing a new order. If the position does exist, this is
equivalent to placing an order for the difference between the target
percent and the current percent.
Options for percent_of are:
portfolio (default): net portfolio value
cash: available cash
ex-cash: net invested capital, ex-cash
longs: long invested capital
shorts: short invested capital
Alternatively, a percent_of_fn can be supplied. The percent_of_fn
should accept a Position and return True if that Position's
market_value should be included in the total and False otherwise.
Note that target must expressed as a decimal (0.50 means 50\%).
"""
target_value = self.portfolio.portfolio_value * target
mv = self.get_market_value(mv_type=percent_of, filter_fn=percent_of_fn)
target_value = target * mv
return self.order_target_value(sid, target_value,
limit_price=limit_price,
stop_price=stop_price,
Expand Down

0 comments on commit 53a03e7

Please sign in to comment.