def maybe_create_close_position_transaction(self, asset, dt, data_portal): if not self.positions.get(asset): return None amount = self.positions.get(asset).amount price = data_portal.get_spot_value(asset, 'price', dt, self.data_frequency) # Get the last traded price if price is no longer available if isnan(price): price = self.positions.get(asset).last_sale_price return Transaction( asset=asset, amount=-amount, dt=dt, price=price, order_id=None, )
def _update_transactions(self): all_orders = list(self.orders.values()) for ib_order_id, executions in iteritems(self._tws.executions): orders = [ order for order in all_orders if order.broker_order_id == ib_order_id ] if not orders: log.warning( "No order found for executions: {}".format(executions)) continue assert len(orders) == 1 order = orders[0] for exec_id, execution in iteritems(executions): if exec_id in self._transactions: continue try: commission = self._tws.commissions[ib_order_id][exec_id]\ .m_commission except KeyError: log.warning( "Commission not found for execution: {}".format( exec_id)) commission = 0 exec_detail = execution['exec_detail'] is_buy = order.amount > 0 amount = (exec_detail.m_shares if is_buy else -1 * exec_detail.m_shares) tx = Transaction(asset=order.asset, amount=amount, dt=pd.to_datetime(exec_detail.m_time, utc=True), price=exec_detail.m_price, order_id=order.id, commission=commission) self._transactions[exec_id] = tx
def process_stock_dividends( self, share_count, cost_basis, spot_price, average_transaction_date ): if not self.amount: txn = Transaction( asset=self.asset, amount=share_count, dt=average_transaction_date, price=cost_basis, order_id=None, ) self.update(txn) return PnlRealized() else: # handle_split treats ratio as new_amount = old_amount / ratio ratio = 1 / (1 + share_count / self.amount) # a stock dividend is the same thing has a split return self.handle_split( self.asset, ratio, cost_basis=0.0, spot_price=spot_price )
def maybe_create_close_position_transaction(self, event): try: pos = self.positions[event.sid] amount = pos.amount if amount == 0: return None except KeyError: return None if 'price' in event: price = event.price else: price = pos.last_sale_price txn = Transaction( sid=event.sid, amount=(-1 * pos.amount), dt=event.dt, price=price, commission=0, order_id=0 ) return txn
def test_get_transactions(self): broker = MagicMock(Broker) blotter = BlotterLive(data_frequency='minute', broker=broker) asset1 = self.asset_finder.retrieve_asset(1) asset2 = self.asset_finder.retrieve_asset(2) broker.orders = {} broker.transactions = {} new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert not new_transactions assert not new_commissions assert not new_closed_orders broker.orders = self._get_orders(asset1, asset2) new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert not new_transactions assert not new_commissions assert not new_closed_orders broker.orders[sentinel.order_id4].filled = \ broker.orders[sentinel.order_id4].amount broker.transactions['exec_4'] = \ Transaction(asset=asset2, amount=broker.orders[sentinel.order_id4].amount, dt=pd.to_datetime('now', utc=True), price=123, order_id=sentinel.order_id4) new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert new_closed_orders == [broker.orders[sentinel.order_id4], ] assert new_commissions == [{ 'asset': asset2, 'cost': 122, 'order': broker.orders[sentinel.order_id4] }] assert new_transactions == [list(broker.transactions.values())[0], ] new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert not new_transactions assert not new_commissions assert not new_closed_orders broker.orders[sentinel.order_id3].filled = \ broker.orders[sentinel.order_id3].amount broker.transactions['exec_3'] = \ Transaction(asset=asset1, amount=broker.orders[sentinel.order_id3].amount, dt=pd.to_datetime('now', utc=True), price=1234, order_id=sentinel.order_id3) broker.orders[sentinel.order_id2].filled = \ broker.orders[sentinel.order_id2].amount broker.transactions['exec_2'] = \ Transaction(asset=asset2, amount=broker.orders[sentinel.order_id2].amount, dt=pd.to_datetime('now', utc=True), price=12.34, order_id=sentinel.order_id2) new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert len(new_closed_orders) == 2 assert broker.orders[sentinel.order_id3] in new_closed_orders assert broker.orders[sentinel.order_id2] in new_closed_orders assert len(new_commissions) == 2 assert {'asset': asset2, 'cost': 12, 'order': broker.orders[sentinel.order_id2]}\ in new_commissions assert {'asset': asset1, 'cost': 3, 'order': broker.orders[sentinel.order_id3]} \ in new_commissions assert len(new_transactions) == 2 assert broker.transactions['exec_2'] in new_transactions assert broker.transactions['exec_3'] in new_transactions new_transactions, new_commissions, new_closed_orders = \ blotter.get_transactions(None) assert not new_transactions assert not new_commissions assert not new_closed_orders