| 1 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # Copyright 2015 Quantopian, Inc. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # you may not use this file except in compliance with the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | # You may obtain a copy of the License at | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | #     http://www.apache.org/licenses/LICENSE-2.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | # Unless required by applicable law or agreed to in writing, software | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | # See the License for the specific language governing permissions and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | # limitations under the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | from __future__ import division | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | import logbook | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | import numpy as np | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | from collections import namedtuple | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | from zipline.finance.performance.position import Position | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | from zipline.finance.transaction import Transaction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     # optional cython based OrderedDict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     from cyordereddict import OrderedDict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | except ImportError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     from collections import OrderedDict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | from six import iteritems, itervalues | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | from zipline.protocol import Event, DATASOURCE_TYPE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | from zipline.utils.serialization_utils import ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     VERSION_LABEL | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | import zipline.protocol as zp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | from zipline.assets import ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     Equity, Future | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | from zipline.errors import PositionTrackerMissingAssetFinder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  | from . position import positiondict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | log = logbook.Logger('Performance') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | PositionStats = namedtuple('PositionStats', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |                            ['net_exposure', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |                             'gross_value', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                             'gross_exposure', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |                             'short_value', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |                             'short_exposure', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                             'shorts_count', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |                             'long_value', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |                             'long_exposure', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |                             'longs_count', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |                             'net_value']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  | def calc_position_values(amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |                          last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |                          value_multipliers): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     iter_amount_price_multiplier = zip( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |         itervalues(value_multipliers), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |     return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         price * amount * multiplier for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         price, amount, multiplier in iter_amount_price_multiplier | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  | def calc_net(values): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     # Returns 0.0 if there are no values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     return sum(values, np.float64()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  | def calc_position_exposures(amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |                             last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |                             exposure_multipliers): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     iter_amount_price_multiplier = zip( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         itervalues(exposure_multipliers), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         price * amount * multiplier for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         price, amount, multiplier in iter_amount_price_multiplier | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  | def calc_long_value(position_values): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |     return sum(i for i in position_values if i > 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  | def calc_short_value(position_values): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |     return sum(i for i in position_values if i < 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  | def calc_long_exposure(position_exposures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     return sum(i for i in position_exposures if i > 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  | def calc_short_exposure(position_exposures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     return sum(i for i in position_exposures if i < 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  | def calc_longs_count(position_exposures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     return sum(1 for i in position_exposures if i > 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  | def calc_shorts_count(position_exposures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |     return sum(1 for i in position_exposures if i < 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  | def calc_gross_exposure(long_exposure, short_exposure): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |     return long_exposure + abs(short_exposure) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  | def calc_gross_value(long_value, short_value): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |     return long_value + abs(short_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  | def calc_position_stats(positions, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                         position_value_multipliers, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |                         position_exposure_multipliers): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |     amounts = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     last_sale_prices = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |     for pos in itervalues(positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         amounts.append(pos.amount) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |         last_sale_prices.append(pos.last_sale_price) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |     position_values = calc_position_values( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |         last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |         position_value_multipliers | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |     position_exposures = calc_position_exposures( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         amounts, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         last_sale_prices, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         position_exposure_multipliers | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |     long_value = calc_long_value(position_values) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |     short_value = calc_short_value(position_values) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |     gross_value = calc_gross_value(long_value, short_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |     long_exposure = calc_long_exposure(position_exposures) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |     short_exposure = calc_short_exposure(position_exposures) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |     gross_exposure = calc_gross_exposure(long_exposure, short_exposure) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |     net_exposure = calc_net(position_exposures) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |     longs_count = calc_longs_count(position_exposures) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |     shorts_count = calc_shorts_count(position_exposures) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |     net_value = calc_net(position_values) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |     return PositionStats( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         long_value=long_value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |         gross_value=gross_value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |         short_value=short_value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         long_exposure=long_exposure, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |         short_exposure=short_exposure, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         gross_exposure=gross_exposure, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         net_exposure=net_exposure, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         longs_count=longs_count, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         shorts_count=shorts_count, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         net_value=net_value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  | class PositionTracker(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |     def __init__(self, asset_finder, data_portal, data_frequency): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |         self.asset_finder = asset_finder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |         # FIXME really want to avoid storing a data portal here, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |         # but the path to get to maybe_create_close_position_transaction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |         # is long and tortuous | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |         self._data_portal = data_portal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |         # sid => position object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |         self.positions = positiondict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |         # Arrays for quick calculations of positions value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |         self._position_value_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |         self._position_exposure_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |         self._position_payout_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |         self._unpaid_dividends = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |         self._unpaid_stock_dividends = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         self._positions_store = zp.Positions() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         # Dict, keyed on dates, that contains lists of close position events | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |         # for any Assets in this tracker's positions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         self._auto_close_position_sids = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |         self.data_frequency = data_frequency | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |     def _update_asset(self, sid): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |             self._position_value_multipliers[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |             self._position_exposure_multipliers[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |             self._position_payout_multipliers[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         except KeyError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |             # Check if there is an AssetFinder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |             if self.asset_finder is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |                 raise PositionTrackerMissingAssetFinder() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |             # Collect the value multipliers from applicable sids | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |             asset = self.asset_finder.retrieve_asset(sid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |             if isinstance(asset, Equity): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |                 self._position_value_multipliers[sid] = 1 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |                 self._position_exposure_multipliers[sid] = 1 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |                 self._position_payout_multipliers[sid] = 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |             if isinstance(asset, Future): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |                 self._position_value_multipliers[sid] = 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |                 self._position_exposure_multipliers[sid] = \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |                     asset.contract_multiplier | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |                 self._position_payout_multipliers[sid] = \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |                     asset.contract_multiplier | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |                 # Futures auto-close timing is controlled by the Future's | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |                 # auto_close_date property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |                 self._insert_auto_close_position_date( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |                     dt=asset.auto_close_date, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |                     sid=sid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |                 ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |     def _insert_auto_close_position_date(self, dt, sid): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |         Inserts the given SID in to the list of positions to be auto-closed by | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |         the given dt. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         Parameters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |         ---------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |         dt : pandas.Timestamp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |             The date before-which the given SID will be auto-closed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |         sid : int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |             The SID of the Asset to be auto-closed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |         if dt is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |             self._auto_close_position_sids.setdefault(dt, set()).add(sid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |     def auto_close_position_events(self, next_trading_day): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |         Generates CLOSE_POSITION events for any SIDs whose auto-close date is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |         before or equal to the given date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |         Parameters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         ---------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |         next_trading_day : pandas.Timestamp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |             The time before-which certain Assets need to be closed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |         Yields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |         ------ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |         Event | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |             A close position event for any sids that should be closed before | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |             the next_trading_day parameter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |         past_asset_end_dates = set() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |         # Check the auto_close_position_dates dict for SIDs to close | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |         for date, sids in self._auto_close_position_sids.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |             if date > next_trading_day: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |                 continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |             past_asset_end_dates.add(date) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |             for sid in sids: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |                 # Yield a CLOSE_POSITION event | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |                 event = Event({ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |                     'dt': date, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |                     'type': DATASOURCE_TYPE.CLOSE_POSITION, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |                     'sid': sid, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |                 }) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |                 yield event | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |         # Clear out past dates | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |         while past_asset_end_dates: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |             self._auto_close_position_sids.pop(past_asset_end_dates.pop()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |     def update_positions(self, positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |         # update positions in batch | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |         self.positions.update(positions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |         for sid, pos in iteritems(positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |             self._update_asset(sid) | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 283 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 284 |  |  |     def update_position(self, sid, amount=None, last_sale_price=None, | 
            
                                                                        
                            
            
                                    
            
            
                | 285 |  |  |                         last_sale_date=None, cost_basis=None): | 
            
                                                                        
                            
            
                                    
            
            
                | 286 |  |  |         if sid not in self.positions: | 
            
                                                                        
                            
            
                                    
            
            
                | 287 |  |  |             position = Position(sid) | 
            
                                                                        
                            
            
                                    
            
            
                | 288 |  |  |             self.positions[sid] = position | 
            
                                                                        
                            
            
                                    
            
            
                | 289 |  |  |         else: | 
            
                                                                        
                            
            
                                    
            
            
                | 290 |  |  |             position = self.positions[sid] | 
            
                                                                        
                            
            
                                    
            
            
                | 291 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 292 |  |  |         if amount is not None: | 
            
                                                                        
                            
            
                                    
            
            
                | 293 |  |  |             position.amount = amount | 
            
                                                                        
                            
            
                                    
            
            
                | 294 |  |  |             self._update_asset(sid=sid) | 
            
                                                                        
                            
            
                                    
            
            
                | 295 |  |  |         if last_sale_price is not None: | 
            
                                                                        
                            
            
                                    
            
            
                | 296 |  |  |             position.last_sale_price = last_sale_price | 
            
                                                                        
                            
            
                                    
            
            
                | 297 |  |  |         if last_sale_date is not None: | 
            
                                                                        
                            
            
                                    
            
            
                | 298 |  |  |             position.last_sale_date = last_sale_date | 
            
                                                                        
                            
            
                                    
            
            
                | 299 |  |  |         if cost_basis is not None: | 
            
                                                                        
                            
            
                                    
            
            
                | 300 |  |  |             position.cost_basis = cost_basis | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |     def execute_transaction(self, txn): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |         # Update Position | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |         # ---------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |         sid = txn.sid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |         if sid not in self.positions: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |             position = Position(sid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |             self.positions[sid] = position | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |             position = self.positions[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |         position.update(txn) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |         self._update_asset(sid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |     def handle_commission(self, sid, cost): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |         # Adjust the cost basis of the stock if we own it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |         if sid in self.positions: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |             self.positions[sid].\ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |                 adjust_commission_cost_basis(sid, cost) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |     def handle_splits(self, splits): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |         Processes a list of splits by modifying any positions as needed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |         Parameters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |         ---------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |         splits: list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |             A list of splits.  Each split is a tuple of (sid, ratio). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |         Returns | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |         ------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |         None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |         for split in splits: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |             sid = split[0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |             if sid in self.positions: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |                 # Make the position object handle the split. It returns the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |                 # leftover cash from a fractional share, if there is any. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |                 position = self.positions[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |                 leftover_cash = position.handle_split(sid, split[1]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |                 self._update_asset(split[0]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |                 return leftover_cash | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |     def earn_dividends(self, dividends, stock_dividends): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |         Given a list of dividends whose ex_dates are all the next trading day, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |         calculate and store the cash and/or stock payments to be paid on each | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |         dividend's pay date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |         for dividend in dividends: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |             # Store the earned dividends so that they can be paid on the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |             # dividends' pay_dates. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |             div_owed = self.positions[dividend.sid].earn_dividend(dividend) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |             try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |                 self._unpaid_dividends[dividend.pay_date].append( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |                     div_owed) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |             except KeyError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |                 self._unpaid_dividends[dividend.pay_date] = [div_owed] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |         for stock_dividend in stock_dividends: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |             div_owed = self.positions[stock_dividend.sid].earn_stock_dividend( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |                 stock_dividend) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |             try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |                 self._unpaid_stock_dividends[stock_dividend.pay_date].\ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |                     append(div_owed) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |             except KeyError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |                 self._unpaid_stock_dividends[stock_dividend.pay_date] = \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |                     [div_owed] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |     def pay_dividends(self, next_trading_day): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |         Returns a cash payment based on the dividends that should be paid out | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |         according to the accumulated bookkeeping of earned, unpaid, and stock | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |         dividends. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         net_cash_payment = 0.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |             payments = self._unpaid_dividends[next_trading_day] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |             # Mark these dividends as paid by dropping them from our unpaid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |             del self._unpaid_dividends[next_trading_day] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |         except KeyError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |             payments = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |         # representing the fact that we're required to reimburse the owner of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |         # the stock for any dividends paid while borrowing. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |         for payment in payments: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |             net_cash_payment += payment['amount'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |         # Add stock for any stock dividends paid.  Again, the values here may | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         # be negative in the case of short positions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |             stock_payments = self._unpaid_stock_dividends[next_trading_day] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |         except: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |             stock_payments = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |         for stock_payment in stock_payments: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |             stock = stock_payment['payment_sid'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |             share_count = stock_payment['share_count'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |             # note we create a Position for stock dividend if we don't | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |             # already own the asset | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |             if stock in self.positions: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |                 position = self.positions[stock] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |             else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |                 position = self.positions[stock] = Position(stock) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |             position.amount += share_count | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |             self._update_asset(stock) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |         return net_cash_payment | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |     def maybe_create_close_position_transaction(self, event): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |         if not self.positions.get(event.sid): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |         amount = self.positions.get(event.sid).amount | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |         price = self._data_portal.get_spot_value( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |             event.sid, 'close', event.dt, self.data_frequency) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |         txn = Transaction( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |             sid=event.sid, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |             amount=(-1 * amount), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |             dt=event.dt, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |             price=price, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |             commission=0, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |             order_id=0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |         ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |         return txn | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |     def get_positions(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |         positions = self._positions_store | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |         for sid, pos in iteritems(self.positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |             if pos.amount == 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |                 # Clear out the position if it has become empty since the last | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |                 # time get_positions was called.  Catching the KeyError is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |                 # faster than checking `if sid in positions`, and this can be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |                 # potentially called in a tight inner loop. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |                 try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |                     del positions[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |                 except KeyError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |                     pass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |                 continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |             # Note that this will create a position if we don't currently have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |             # an entry | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |             position = positions[sid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |             position.amount = pos.amount | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |             position.cost_basis = pos.cost_basis | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |             position.last_sale_price = pos.last_sale_price | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |             position.last_sale_date = pos.last_sale_date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |         return positions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  |     def get_positions_list(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |         positions = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |         for sid, pos in iteritems(self.positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  |             if pos.amount != 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |                 positions.append(pos.to_dict()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |         return positions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |     def sync_last_sale_prices(self, dt): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |         data_portal = self._data_portal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |         for sid, position in iteritems(self.positions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |             position.last_sale_price = data_portal.get_spot_value( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  |                 sid, 'close', dt, self.data_frequency) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |     def stats(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |         return calc_position_stats(self.positions, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  |                                    self._position_value_multipliers, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  |                                    self._position_exposure_multipliers) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 |  |  |     def __getstate__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 |  |  |         state_dict = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 |  |  |         state_dict['asset_finder'] = self.asset_finder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 |  |  |         state_dict['positions'] = dict(self.positions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 |  |  |         state_dict['unpaid_dividends'] = self._unpaid_dividends | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  |         state_dict['unpaid_stock_dividends'] = self._unpaid_stock_dividends | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  |         state_dict['auto_close_position_sids'] = self._auto_close_position_sids | 
            
                                                                                                            
                            
            
                                    
            
            
                | 483 |  |  |         state_dict['data_frequency'] = self.data_frequency | 
            
                                                                                                            
                            
            
                                    
            
            
                | 484 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 485 |  |  |         STATE_VERSION = 3 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 486 |  |  |         state_dict[VERSION_LABEL] = STATE_VERSION | 
            
                                                                                                            
                            
            
                                    
            
            
                | 487 |  |  |         return state_dict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 488 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 489 |  |  |     def __setstate__(self, state): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 490 |  |  |         OLDEST_SUPPORTED_STATE = 3 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 491 |  |  |         version = state.pop(VERSION_LABEL) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 492 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 493 |  |  |         if version < OLDEST_SUPPORTED_STATE: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 494 |  |  |             raise BaseException("PositionTracker saved state is too old.") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  |         self.asset_finder = state['asset_finder'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  |         self.positions = positiondict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  |         self.data_frequency = state['data_frequency'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  |         # note that positions_store is temporary and gets regened from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  |         # .positions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  |         self._positions_store = zp.Positions() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 |  |  |         self._unpaid_dividends = state['unpaid_dividends'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 |  |  |         self._unpaid_stock_dividends = state['unpaid_stock_dividends'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 505 |  |  |         self._auto_close_position_sids = state['auto_close_position_sids'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 506 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 507 |  |  |         # Arrays for quick calculations of positions value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 508 |  |  |         self._position_value_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 509 |  |  |         self._position_exposure_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 510 |  |  |         self._position_payout_multipliers = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 511 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 512 |  |  |         # Update positions is called without a finder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 513 |  |  |         self.update_positions(state['positions']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 514 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 515 |  |  |         # FIXME | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 516 |  |  |         self._data_portal = None | 
            
                                                        
            
                                    
            
            
                | 517 |  |  |  |