-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconstant_position_sizer.py
55 lines (47 loc) · 2.07 KB
/
constant_position_sizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from math import floor
from core.event import EventType, OrderEvent
from core.pool import OrderEventPool
class ConstantPositionSizer(object):
"""
Size the order to reflect the dollar-weighting of the
current equity account size based on pre-specified
ticker weights.
"""
def initialize(self, portfolio_handler):
self.portfolio_handler = portfolio_handler
def size_order(self, weight_events):
initial_order_events = OrderEventPool(weight_events.time)
initial_order_events.type = EventType.ORDER
if weight_events.type == EventType.TARGETWEIGHT:
current_weights = self.portfolio_handler.get_current_weights()
suggested_weights = weight_events.get_weights()
for ticker in suggested_weights:
if ticker in current_weights:
changed_weight = suggested_weights[ticker] - current_weights[ticker]
else:
changed_weight = suggested_weights[ticker]
quantity = self._get_quantity_from_weight(ticker, changed_weight)
if quantity is not None:
if quantity > 0:
action = "BOT"
else:
action = "SLD"
quantity = - quantity
else:
action = None
order = OrderEvent(ticker, action, quantity)
initial_order_events.add(order)
initial_order_events.print_orders()
return initial_order_events
else:
raise NotImplemented("Unsupported event.type '%s' in size_order" % weight_events.type)
def _get_quantity_from_weight(self, ticker, weight):
price = self.portfolio_handler.get_last_close(ticker)
equity = self.portfolio_handler.portfolio.equity
dollar_weight = weight * equity
if price is not None:
weighted_quantity = int(floor(dollar_weight / price))
else:
weighted_quantity = None
quantity = weighted_quantity
return quantity