def add_to_position(session, raw, pos): # find opening commission transaction logger.debug("Adding raw trade %d to position %d for %s", raw.id, pos.id, raw.broker_ref) comm = get_comm_for_position(session, raw.ref_date, raw.broker_ref) if len(comm) > 1: logger.info("%d commissions found for multi-tranche %s", len(comm), raw.broker_ref) pos.num_closes += 1 pos.entry_quantity += raw.size c_open = None c_close = None if len(comm) > 0: c_close = comm[-1] pos.brokerage += c_close.amount logger.debug("Using commission %d for ANOTHER close of %s", c_close.id, raw.broker_ref) if c_close.ref_date != raw.ref_date: logger.error("CLOSING COMMISSION DATE MISMATCH on %d for close of %s", c_close.id, raw.broker_ref) # TODO: Handle/Check for more than 2 commissions? Check dates?? # Closing commission should be on same date as closing trade. a_close = StockActivity(ActionType.CLOSE, raw=raw, comm=c_close) # Update quantity in first open activity. # The underlying logic only works if there is only one open, but multiple closes. a_open = get_position_activities(session, pos, True) a_open.quantity += raw.size trade = StockTrade(a_open, a_close, raw) session.add(trade) session.add(a_close) session.commit() if c_close: c_close.position_id = pos.id c_close.activity_id = a_close.id a_close.position_id = pos.id a_close.trade_id = trade.id
def new_position(session, raw): # find opening commission transaction logger.debug("Creating new position for %s", raw.broker_ref) q = session.query(RawData).filter( RawData.category == RawData.CAT_RISK, RawData.ref_date <= raw.ref_date, RawData.description.like("%" + raw.broker_ref + "%"), ) other_fees = q.all() total_other_fees = D(0) if len(other_fees): for fee in other_fees: total_other_fees += fee.amount logger.debug("Total of %d other fees for %s: %s", len(other_fees), raw.broker_ref, total_other_fees) comm = get_comm_for_position(session, raw.ref_date, raw.broker_ref) if len(comm) == 2: logger.debug("%d commissions found for %s", len(comm), raw.broker_ref) else: logger.warn("FOUND %d COMMISSIONS FOR %s (%s)", len(comm), raw.broker_ref, raw.description) pos = StockPosition(raw.description, raw.description, raw.ref_date) pos.broker_ref = raw.broker_ref pos.num_opens += 1 pos.num_closes += 1 pos.entry_quantity += raw.size pos.fees += total_other_fees c_open = None c_close = None if len(comm) > 0: c_open = comm[0] pos.brokerage += c_open.amount logger.debug("Using commission %d for open of %s", c_open.id, raw.broker_ref) if len(comm) > 1: c_close = comm[1] pos.brokerage += c_close.amount logger.debug("Using commission %d for close of %s", c_close.id, raw.broker_ref) if c_close.ref_date != raw.ref_date: logger.error("CLOSING COMMISSION DATE MISMATCH on %d for close of %s", c_close.id, raw.broker_ref) # TODO: Handle/Check for more than 2 commissions? Check dates?? # Closing commission should be on same date as closing trade. a_open = StockActivity(ActionType.OPEN, raw=raw, comm=c_open) a_open.fees = total_other_fees a_close = StockActivity(ActionType.CLOSE, raw=raw, comm=c_close) trade = StockTrade(a_open, a_close, raw) session.add(pos) session.add(trade) session.add(a_open) session.add(a_close) session.commit() if c_open: c_open.position_id = pos.id c_open.activity_id = a_open.id if c_close: c_close.position_id = pos.id c_close.activity_id = a_close.id if len(other_fees): for fee in other_fees: fee.position_id = pos.id fee.activity_id = a_open.id trade.position_id = pos.id a_open.position_id = pos.id a_close.position_id = pos.id a_open.trade_id = trade.id a_close.trade_id = trade.id